<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>got1_c.log</title>
        <link>https://velog.io/</link>
        <description>초보</description>
        <lastBuildDate>Sat, 08 Nov 2025 19:05:51 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>got1_c.log</title>
            <url>https://velog.velcdn.com/images/got1_c/profile/dc4dd63a-3a95-471b-abd8-04be0ffec1b2/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. got1_c.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/got1_c" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[데이터 표현 & SIMD]]></title>
            <link>https://velog.io/@got1_c/%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%91%9C%ED%98%84-SIMD</link>
            <guid>https://velog.io/@got1_c/%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%91%9C%ED%98%84-SIMD</guid>
            <pubDate>Sat, 08 Nov 2025 19:05:51 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>&quot;컴퓨터는 숫자를 어떻게 저장하고, 한 번에 얼마나 많이 계산할까?&quot;</p>
</blockquote>
<p>이 글에서는 CPU 내부의 표현 방식과, 현대 CPU의 핵심 기술인 SIMD 구조를 정리하겠다.</p>
<hr>
<h2 id="1-데이터-표현의-기본-bit">1. 데이터 표현의 기본: Bit</h2>
<p>모든 데이터는 결국 0과 1로 표현된다. </p>
<table>
<thead>
<tr>
<th>단위</th>
<th>크기</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td>1 bit</td>
<td>0 또는 1</td>
<td>1개의 전기 신호</td>
</tr>
<tr>
<td>8 bits</td>
<td>1 byte</td>
<td>‘A’ = <code>01000001</code></td>
</tr>
<tr>
<td>16 bits</td>
<td>2 bytes</td>
<td>UTF-16 문자 등</td>
</tr>
<tr>
<td>32 bits</td>
<td>4 bytes</td>
<td>일반적인 정수형(int)</td>
</tr>
<tr>
<td>64 bits</td>
<td>8 bytes</td>
<td>CPU 레지스터 크기(현대 기준)</td>
</tr>
</tbody></table>
<h2 id="2-정수의-표현-2의-보수">2. 정수의 표현: 2의 보수</h2>
<p>CPU는 음수를 표현하기 위해 2의 보수 방식을 사용한다.</p>
<table>
<thead>
<tr>
<th>십진수</th>
<th>이진수 (8bit)</th>
<th>비고</th>
</tr>
</thead>
<tbody><tr>
<td>+5</td>
<td><code>0000 0101</code></td>
<td>양수 그대로 저장</td>
</tr>
<tr>
<td>-5</td>
<td><code>1111 1011</code></td>
<td>2의 보수 형태로 저장</td>
</tr>
</tbody></table>
<blockquote>
<h4 id="2의-보수-만드는-법">2의 보수 만드는 법</h4>
</blockquote>
<ol>
<li>양수의 비트를 모두 뒤집는다 (1의 보수)</li>
<li>+1을 더한다 -&gt; <code>0000 0101 -&gt; 1111 1010 -&gt; 1111 1011</code></li>
</ol>
<p>이 방식 덕분에 CPU는
<strong>&quot;덧셈 회로 하나로 뺄셈까지 계산할 수 있다.&quot;</strong></p>
<h2 id="3-실수의-표현-ieee-754">3. 실수의 표현: IEEE 754</h2>
<p>실수는 IEEE 754 부동소수점 표준으로 표현된다.</p>
<pre><code class="language-css">[ 부호(S) | 지수(E) | 가수(M) ]
   1bit      8bit      23bit</code></pre>
<table>
<thead>
<tr>
<th>구분</th>
<th>비트 수</th>
<th>역할</th>
</tr>
</thead>
<tbody><tr>
<td>부호(S)</td>
<td>1</td>
<td>0 = +, 1 = -</td>
</tr>
<tr>
<td>지수(E)</td>
<td>8</td>
<td>소수점의 위치 (2의 지수 표현)</td>
</tr>
<tr>
<td>가수(M)</td>
<td>23</td>
<td>실제 숫자의 유효한 부분 (정밀도)</td>
</tr>
</tbody></table>
<blockquote>
<p>예시)
<strong>10.5를 IEEE 754로 표현</strong></p>
</blockquote>
<ol>
<li>10.5 = 1010.1 (2진수)</li>
<li>정규화 -&gt; 1.0101 * 2^3 (컴퓨터는 2진수로 동작하기 때문에 2의 제곱을 기준으로 소수점이 움직인다.)</li>
<li>지수 = 3 + 127 = 130 (10000010)</li>
<li>부호 = 0, 가수 = 0101...</li>
</ol>
<p>-&gt; 따라서 저장 비트: <code>0 10000010 01010000000000000000000</code></p>
<h4 id="요약">요약</h4>
<table>
<thead>
<tr>
<th>항목</th>
<th>의미</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td>부호 비트</td>
<td>양수/음수 결정</td>
<td>0 = +, 1 = -</td>
</tr>
<tr>
<td>지수</td>
<td>소수점 위치 이동량</td>
<td>+127을 더해서 저장</td>
</tr>
<tr>
<td>가수</td>
<td>실수의 유효자리</td>
<td>소수 이하를 2진수로 표현</td>
</tr>
</tbody></table>
<hr>
<h3 id="simd의-핵심-개념"><strong>SIMD의 핵심 개념</strong></h3>
<p><strong>Single Instruction, Multiple Data</strong> 
&quot;한 번의 명령으로 여러 데이터를 동시에 계산한다.&quot;</p>
<h2 id="simd란">SIMD란?</h2>
<p>일반적인 CPU 명령어는 한 번에 하나의 데이터 쌍만 계산한다. 하지만 비슷한 계산을 반복적으로 수행해야 하는 작업에서는 이 방식이 너무 느리다.</p>
<p>그래서 CPU는 SIMD라는 구조를 도입했다.
<strong>&quot;명령어는 한 번, 데이터는 여러 개&quot;</strong></p>
<p>예시)</p>
<table>
<thead>
<tr>
<th>방식</th>
<th>설명</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td><strong>일반 연산 (Scalar)</strong></td>
<td>한 번에 하나씩 계산</td>
<td><code>a1 + b1</code>, <code>a2 + b2</code>, <code>a3 + b3</code></td>
</tr>
<tr>
<td><strong>SIMD 연산</strong></td>
<td>한 번에 여러 개를 동시에 계산</td>
<td><code>[a1,a2,a3,a4] + [b1,b2,b3,b4]</code></td>
</tr>
</tbody></table>
<h2 id="simd-레지스터-구조">SIMD 레지스터 구조</h2>
<p>CPU는 SIMD를 위해 특수한 레지스터를 갖고 있다.</p>
<table>
<thead>
<tr>
<th>세대</th>
<th>명령어 집합</th>
<th>레지스터 크기</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td>SSE (Streaming SIMD Extensions)</td>
<td>128bit</td>
<td><code>xmm0</code> ~ <code>xmm15</code></td>
<td></td>
</tr>
<tr>
<td>AVX (Advanced Vector Extensions)</td>
<td>256bit</td>
<td><code>ymm0</code> ~ <code>ymm15</code></td>
<td></td>
</tr>
<tr>
<td>AVX-512</td>
<td>512bit</td>
<td><code>zmm0</code> ~ <code>zmm31</code></td>
<td></td>
</tr>
<tr>
<td>하나의 레지스터에 32bit 실수 4개를 담으면, <code>addps</code> 명령 한번으로 4개의 덧셈이 동시에 일어난다.</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody></table>
<pre><code class="language-asm">section .data
    A dd 1.0, 2.0, 3.0, 4.0
    B dd 5.0, 6.0, 7.0, 8.0
section .text
    global _start
_start:
    movaps xmm0, [A]    ; xmm0 = {1.0, 2.0, 3.0, 4.0}
    movaps xmm1, [B]    ; xmm = {5.0, 6.0, 7.0, 8.0}

    addps xmm0, xmm1    ; xmm0 = {6.0, 8.0, 10.0, 12.0}
    mulps xmm0, xmm1    ; xmm0 = {30.0, 48.0, 70.0, 96.0}

    mov eax, 60
    xor edi, edi
    syscall</code></pre>
<p><strong>해석</strong></p>
<blockquote>
<ul>
<li><code>movaps</code>: 128비트를 한 번에 복사</li>
</ul>
</blockquote>
<ul>
<li><code>addps</code>: &quot;Add Packed Single&quot; - 실수 4개를 병렬로 더함</li>
<li><code>mulps</code>: &quot;Multiply Packed Single&quot; - 실수 4개를 병렬로 곱함</li>
</ul>
<h3 id="simd의-장점">SIMD의 장점</h3>
<table>
<thead>
<tr>
<th>구분</th>
<th>일반 연산</th>
<th>SIMD 연산</th>
</tr>
</thead>
<tbody><tr>
<td>명령어 수</td>
<td>4회 반복</td>
<td>1회만 실행</td>
</tr>
<tr>
<td>레지스터 접근</td>
<td>매번 필요</td>
<td>한 번에 4개</td>
</tr>
<tr>
<td>처리 속도</td>
<td>느림</td>
<td>3~8배 빠름</td>
</tr>
<tr>
<td>SIMD는 CPU 성능을 폭발적으로 끌어올리는 핵심 기술이다.</td>
<td></td>
<td></td>
</tr>
</tbody></table>
<h3 id="실제-cpu-내부-동작">실제 CPU 내부 동작</h3>
<p>SIMD 명령은 내부적으로 ALU가 여러 개 병렬로 연결되어 있다.
즉, 하나의 명령이 내려오면</p>
<ul>
<li>ALU0은 첫 번째 데이터,</li>
<li>ALU1은 두 번째 데이터,</li>
<li>ALU2는 세 번째 데이터...
이런 식으로 같은 연산을 동시에 수행한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[메모리 주소 지정 방식]]></title>
            <link>https://velog.io/@got1_c/%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%A3%BC%EC%86%8C-%EC%A7%80%EC%A0%95-%EB%B0%A9%EC%8B%9D</link>
            <guid>https://velog.io/@got1_c/%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%A3%BC%EC%86%8C-%EC%A7%80%EC%A0%95-%EB%B0%A9%EC%8B%9D</guid>
            <pubDate>Sat, 01 Nov 2025 17:11:09 GMT</pubDate>
            <description><![CDATA[<p>CPU가 명령어를 실행할 때, 데이터는 단순한 숫자값이 아니라 메모리 어딘가에 저장된 값이다.</p>
<p>따라서 CPU는 </p>
<blockquote>
<p>&quot;어떤 메모리 주소에서 데이터를 읽을지&quot;
&quot;어떤 주소에 값을 저장할지&quot;</p>
</blockquote>
<p>이걸 알아야한다.</p>
<p>이 주소를 어떻게 계산하고 지정할지를 정한 규칙이 바로 <strong>메모리 주소 지정 방식</strong>이다.</p>
<hr>
<h2 id="데이터-이동과-관련된-어셈블리어-명령어">데이터 이동과 관련된 어셈블리어 명령어</h2>
<p><code>mov</code>, <code>lea</code>, <code>add</code>, <code>sub</code></p>
<h3 id="mov">mov</h3>
<p><code>mov</code>는 <strong>데이터 복사</strong> 명령어이다.</p>
<pre><code class="language-asm">mov eax, [ebx]</code></pre>
<p>ebx의 주소가 가리키는 값을 eax에 복사한다.</p>
<h3 id="lea">lea</h3>
<p><code>lea</code>는 <strong>주소 계산 후 로드</strong>하는 명령어이다.</p>
<pre><code class="language-asm">lea eax, [ebx+4*ecx]</code></pre>
<p>ebx+4*ecx의 주소값을 계산한 후 eax에 저장한다.</p>
<h3 id="addsub">add/sub</h3>
<p><code>add</code>, <code>sub</code>은 <strong>덧셈, 뺄셈 연산</strong>을 하는 명령어이다.</p>
<pre><code class="language-asm">add eax, 4
sub eax, 4</code></pre>
<p>eax에 4를 더하고 4를 뺀다.</p>
<hr>
<h2 id="메모리-주소-지정-방식의-종류">메모리 주소 지정 방식의 종류</h2>
<p>CPU는 명령어를 실행할 때, <strong>주소를 어떻게 계산해서 접근할 것인가</strong>에 따라서 주소 지정 방식이 달라진다.</p>
<h3 id="1-즉시-주소-지정">1. 즉시 주소 지정</h3>
<p>명령어 안에 값 자체가 직접 포함되어 있다.
CPU가 메모리를 읽을 필요 없이, 명령어에 적힌 값을 그대로 사용한다.</p>
<pre><code class="language-asm">mov eax, 10</code></pre>
<p>eax에 10을 그대로 저장한다.(메모리 접근이 없어 가장 빠른 방식이다.)</p>
<h3 id="2-직접-주소-지정">2. 직접 주소 지정</h3>
<p>명령어가 메모리의 고정된 주소를 직접 지정한다.</p>
<pre><code class="language-asm">mov eax, [val]</code></pre>
<pre><code class="language-asm">section .data
val dd 1234</code></pre>
<p>메모리 변수 val이 저장된 주소에 접근하여,
그 안의 값을 eax로 가져온다.</p>
<h3 id="3-간접-주소-지정">3. 간접 주소 지정</h3>
<p>레지스터가 주소를 저장하고, 그 주소가 가리키는 메모리의 값을 읽는다.</p>
<pre><code class="language-asm">mov eax, [ebx]</code></pre>
<p>ebx가 가리키는 주소의 값이 eax에 복사된다.</p>
<h3 id="4-인덱스-주소-지정">4. 인덱스 주소 지정</h3>
<p>기준 주소(base)에 <strong>인덱스 값(첨자)</strong>을 더해 접근한다.</p>
<pre><code class="language-asm">mov eax, [ebx + esi]</code></pre>
<p>ebx는 배열의 시작 주소, esi는 인덱스 역할을 한다.</p>
<pre><code class="language-C">eax = arr[i];</code></pre>
<p>위의 C코드와 같은 의미이다.</p>
<h3 id="5-기반-주소--변위">5. 기반 주소 + 변위</h3>
<p>기준 주소(base)에 <strong>상수(변위, displacement)</strong>를 더해서 접근한다.</p>
<pre><code class="language-asm">mov eax, [ebx + 4]</code></pre>
<p>ebx 기준으로 4바이트 떨어진 곳의 데이터를 읽는다.</p>
<h3 id="6-기반--인덱스-주소">6. 기반 + 인덱스 주소</h3>
<p>기준 주소(base)에 <strong>인덱스(index) * 자료형 크기(scale)</strong>을 더해 접근한다.</p>
<pre><code class="language-asm">mov eax, [ebx + esi*4]</code></pre>
<p>ebx는 배열의 시작 주소, esi는 인덱스(배열 첨자), 4는 각 원소의 크기이다.</p>
<h3 id="7-복합-주소-지정">7. 복합 주소 지정</h3>
<p>기준 주소, 인덱스, 변위를 모두 조합한 가장 일반적인 형태이다.</p>
<pre><code class="language-asm">mov eax, [ebx + esi*4 + 8]</code></pre>
<p>ebx + (esi*4) + 8 위치의 메모리에서 값을 가져온다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스택으로 이해하는 함수 호출 규약]]></title>
            <link>https://velog.io/@got1_c/%EC%8A%A4%ED%83%9D%EC%9C%BC%EB%A1%9C-%EC%9D%B4%ED%95%B4%ED%95%98%EB%8A%94-%ED%95%A8%EC%88%98-%ED%98%B8%EC%B6%9C-%EA%B7%9C%EC%95%BD</link>
            <guid>https://velog.io/@got1_c/%EC%8A%A4%ED%83%9D%EC%9C%BC%EB%A1%9C-%EC%9D%B4%ED%95%B4%ED%95%98%EB%8A%94-%ED%95%A8%EC%88%98-%ED%98%B8%EC%B6%9C-%EA%B7%9C%EC%95%BD</guid>
            <pubDate>Sat, 01 Nov 2025 04:49:24 GMT</pubDate>
            <description><![CDATA[<p>우리가 C코드에서</p>
<pre><code class="language-C">int result = add(2, 3);</code></pre>
<p>이런 코드를 쓸 때 겉으로는 단순히 함수를 <strong>호출</strong>하는 한 줄이지만, CPU 입장에서는 스택 조작, 레지스터 관리, 복귀 주소 저장 등 복잡한 절차가 일어난다.</p>
<p>이때 이 복잡한 과정을 <strong>누가, 어떤 순서로, 어떤 규칙에 따라</strong> 처리할지 정확히 정한 약속이 없으면 프로그램이 제대로 동작할 수 없다.</p>
<p>이 약속이 바로 <strong>함수 호출 규약</strong>이다.</p>
<hr>
<p>보통 <strong>&quot;간단한 프로그래밍 문제를 풀 때는 내 컴퓨터 1개인데 저런 규약이 왜 필요한가?&quot;</strong> 라는 궁금증이 생겼다.</p>
<p>이 궁금증에 대한 대답은 이렇게 답할 수 있다.</p>
<blockquote>
<p>프로그램 하나는 하나의 컴파일러로만 만들어지지 않는다.</p>
</blockquote>
<p>예를 들어</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;windows.h&gt;

int main() {
    printf(&quot;Hello from C Standard Library!\n&quot;);     // libc (cdecl)
    MessageBoxA(NULL, &quot;Hi&quot;, &quot;Windows API&quot;, 0);       // WinAPI (stdcall)
    return 0;
}</code></pre>
<p>이러한 코드가 실행될 때 CPU는 </p>
<ol>
<li><code>main()</code>은 GCC가 만든 규약(cdecl)으로 실행된다.</li>
<li><code>printf()</code>는 C 표준 라이브러리 쪽에서 정의한 함수이다. 이 또한 cdecl을 따른다.</li>
<li><code>MessageBoxA()</code>는 Window OS 내부의 DLL 함수이므로 stdcall 규약을 따른다.</li>
</ol>
<p>즉, 같은 프로그램 안에서도 서로 다른 호출 규약의 함수가 공존한다.</p>
<p>여기서</p>
<h3 id="왜-함수-호출-규약이-여러개여도-오류가-나지-않을까">왜 함수 호출 규약이 여러개여도 오류가 나지 않을까?</h3>
<p>프로그램에는 1개 이상의 다양한 함수가 존재하는데, 일반적으로 함수들은 각각 <strong>함수호출규약</strong>을 가진다. 순차적으로 프로그램이 실행되며 스택에는 각 함수에 알맞는(함수호출규약에 따라) <strong>스택프레임</strong>이 생성된다. 따라서 오류가 나지 않는다.
<img src="https://velog.velcdn.com/images/got1_c/post/7d01d5b5-615f-4e3b-b2d3-82a1abab52ec/image.png" alt="">
출처:김놀자(티스토리) - Stack Frame과 함수 호출 규약(__stdcall)</p>
<hr>
<h2 id="함수호출규약은-스택을-어떻게-다루는가">함수호출규약은 스택을 어떻게 다루는가</h2>
<p><code>add(2,3)</code>같은 함수를 호출할 때, CPU는 다음 순서로 동작한다.</p>
<ol>
<li>인자들을 스택에 push</li>
<li>call 명령으로 함수 진입</li>
<li>함수 내부에서 새로운 스택프레임 생성</li>
<li>함수 실행 후 ret 명령으로 복귀</li>
<li>스택 정리
이때 &quot;스택을 누가 정리하느냐&quot;가 규약마다 다르다. <code>cdecl</code>과 <code>stdcall</code>을 설명하며 함께 설명하도록 하겠다.</li>
</ol>
<h3 id="cdecl">cdecl</h3>
<p><code>cdecl</code>은 C/C++ 프로그램에 대한 호출규약이다. 함수를 호출한 호출자(caller)가 스택을 정리하는 규약이다.
예시 C코드</p>
<pre><code class="language-C">int add(int a, int b) {return a+b;}
int main() {add(2,3);}</code></pre>
<h4 id="어셈블리-동작">어셈블리 동작</h4>
<pre><code class="language-asm">push 3    ; 두번째 인자 
push 2    ; 첫번째 인자
call add    ; 함수호출(복귀 주소 push)
add esp, 8    ; 호출자가 스택 정리(8바이트 제거)</code></pre>
<p><strong>특징</strong></p>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>인수 전달 순서</strong></td>
<td>오른쪽에서 왼쪽</td>
</tr>
<tr>
<td><strong>스택 유지 관리 책임</strong></td>
<td>호출하는 함수(caller)가 스택에서 인수를 꺼냄</td>
</tr>
<tr>
<td><strong>이름 데코레이션 규칙</strong></td>
<td>C 링크를 사용하는 <code>__cdecl</code> 함수를 내보낼 경우를 제외하고, 밑줄(<code>_</code>)이 이름 앞에 접두사로 붙음</td>
</tr>
<tr>
<td><strong>대/소문자 변환 규칙</strong></td>
<td>대/소문자 변환은 수행되지 않음</td>
</tr>
</tbody></table>
<h3 id="stdcall">stdcall</h3>
<p>stdcall은 주로 Windows API에서 사용되는 함수 호출 규약이다.
cdecl과 달리, <strong>피호출자(callee)</strong> 가 스택을 정리한다.
즉, 함수를 호출한 쪽에서는 스택을 복원하지 않아도 된다.
정해진 인자 개수를 가진 함수에서 효율적이다.</p>
<p>예시 C코드</p>
<pre><code class="language-C">int __stdcall add(int a, int b) { return a + b; }
int main() { add(2, 3); }</code></pre>
<p><strong>어셈블리 동작</strong></p>
<pre><code class="language-asm">push 3            ; 두 번째 인자
push 2            ; 첫 번째 인자
call add          ; 함수 호출 (복귀 주소 push)
; 호출자는 스택 정리하지 않음</code></pre>
<p>add() 함수 내부:</p>
<pre><code class="language-asm">mov eax, [ebp+8]  ; a
mov ecx, [ebp+12] ; b
add eax, ecx
ret 8             ; 피호출자가 스택 정리 (8바이트 제거)</code></pre>
<p><strong>특징</strong></p>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>인수 전달 순서</strong></td>
<td>오른쪽에서 왼쪽</td>
</tr>
<tr>
<td><strong>스택 유지 관리 책임</strong></td>
<td>피호출자(callee)가 스택에서 인수를 꺼내며 정리</td>
</tr>
<tr>
<td><strong>이름 데코레이션 규칙</strong></td>
<td>이름 앞에 밑줄(<code>_</code>)이 붙고, 인자의 총 바이트 크기를 <code>@</code> 뒤에 표시 (예: <code>_add@8</code>)</td>
</tr>
<tr>
<td><strong>대/소문자 변환 규칙</strong></td>
<td>대/소문자 변환은 수행되지 않음</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[Stack Frame]]></title>
            <link>https://velog.io/@got1_c/Stack-Frame</link>
            <guid>https://velog.io/@got1_c/Stack-Frame</guid>
            <pubDate>Sat, 18 Oct 2025 15:23:36 GMT</pubDate>
            <description><![CDATA[<h2 id="스택이란--sp">스택이란? + SP</h2>
<blockquote>
<p><a href="https://velog.io/@got1_c/Stack">https://velog.io/@got1_c/Stack</a></p>
</blockquote>
<h2 id="스택-프레임">스택 프레임</h2>
<p>스택 프레임(Stack Frame)은 <strong>함수가 호출될 때 스택 내에 새롭게 형성되는 독립적인 영역</strong>이다.  </p>
<p>이 영역에는 함수가 실행되는 동안 필요한 <strong>매개변수(Arguments)</strong>,  
함수 실행 후 돌아갈 <strong>복귀 주소(Return Address)</strong>,  
그리고 함수 내부에서 선언된 <strong>지역 변수(Local Variables)</strong> 등이 저장된다.</p>
<h2 id="스택-프레임이-필요한-이유">스택 프레임이 필요한 이유</h2>
<p>프로그램은 한 번에 여러개의 함수를 호출할 수 있고, 재귀 호출도 가능하다.</p>
<p>이때, 각 함수의 <strong>매개변수</strong>, <strong>복귀 주소</strong>, <strong>지역 변수</strong>가 섞이지 않도록 함수마다 독립적인 저장 공간이 필요하다.</p>
<p>그 공간이 바로 <strong>스택 프레임</strong>이다.</p>
<hr>
<h2 id="call과-ret--명령어-포인터">call과 ret &amp; 명령어 포인터</h2>
<h3 id="명령어-포인터eip">명령어 포인터(EIP)</h3>
<p>CPU가 <strong>다음에 실행할 명령어의 메모리 주소</strong>를 가리키는 레지스터이다.</p>
<h3 id="call"><code>call</code></h3>
<p><code>call</code>명령은 두 가지 일을 동시에 수행한다.</p>
<ol>
<li><strong>명령어 포인터(EIP)</strong>가 가리키는 주소값(복귀 주소)을 스택에 push한다.</li>
<li>EIP주소를 <strong>함수의 시작 주소</strong>로 바꾼다.<h3 id="ret"><code>ret</code></h3>
<code>ret</code>은 스택에 저장돼 있던 <strong>복귀 주소</strong>를 <code>pop</code>하여 <code>EIP</code>에 넣는다.<h3 id="간단한-흐름-예시">간단한 흐름 예시</h3>
<pre><code class="language-asm">main:
 call func
 mov eax, 5 
</code></pre>
</li>
</ol>
<p>func:
    mov ebx, 10
    ret</p>
<pre><code>&gt;
1. main에서 call 실행시 EIP가 가리키는 주소값(복귀 주소)을 스택에 push
2. func의 시작 주소를 EIP로 바꿈 = func 시작
3. ebx에 10이 저장
4. 스택에 저장된 복귀주소를 pop하여 EIP에 넣음 = EIP에 `mov eax, 5`의 주소를 저장
5. eax = 5, ebx = 10이 저장됨

----
## BP(Base Pointer)
BP는 **메모리의 주소값**을 담는 레지스터이다.
### 그렇다면 BP는 어떤 때에 사용이 될까?
BP는 함수가 호출될 때, 해당 함수의 **스택 프레임**의 **기준점(base)**로 사용된다.
&gt; 즉, 함수 내부의 **지역변수**나 **매개변수**들에 접근할 때 &quot;스택의 어디에 있는지&quot;를 BP를 기준으로 계산할 수 있게 해준다.

-----
## 함수 호출 과정
예를 들어, 이러한 C코드가 있을때
```c
void fn()
{
    int a = 1, b = 2, c;
    c = function(a, b, 3);
}

int function(int x, int y, int z)
{
    int sum;
    sum = x + y + z;
    return sum;
}</code></pre><p>fn() 함수가 실행되다가 function()을 호출하면,
CPU는 함수 호출을 위해 스택을 이용해 여러 가지 데이터를 차례로 저장한다.
이 과정을 단계별로 살펴보면 다음과 같다.</p>
<h3 id="1인자arguments-저장">1.인자(Arguments) 저장</h3>
<p>먼저 호출자(fn)는 피호출자(function)에게 전달할 인자 a, b, 3을
오른쪽에서 왼쪽 순서로 스택에 push한다.
이제 스택의 최상단(top)에는 x, y, z가 차례로 쌓여 있다.</p>
<pre><code class="language-asm">push 3        ; z
push b        ; y
push a        ; x
call function ; 복귀 주소 push + EIP 변경</code></pre>
<h3 id="2-call-명령어-실행">2. call 명령어 실행</h3>
<ol>
<li>return adress(복귀 주소) = <code>call</code> 다음 명령의 주소를 스택에 push</li>
<li>EIP를 <code>function</code>의 시작 주소로 변경</li>
</ol>
<h4 id="현재-스택-구조">현재 스택 구조</h4>
<pre><code>z
y
x
return adress    &lt;--- SP</code></pre><h3 id="3-스택-프레임-생성">3. 스택 프레임 생성</h3>
<p>함수가 시작되면, 기존의 BP값을 저장하고 새로운 스택 프레임을 만든다.</p>
<pre><code class="language-asm">push ebp        ;이전 함수의 bp 저장
mov ebp, esp    ;현재 sp를 새 bp로 설정
sub esp, 4        ;지역 변수(sum)를 위한 공간 확보</code></pre>
<pre><code class="language-c">int sum</code></pre>
<p>int는 4바이트이므로 top을 가리키는 주소에서 4만큼 낮은 주소로 이동시켜 그만큼의 공간을 마련해야한다.</p>
<h4 id="생성된-스택프레임">생성된 스택프레임</h4>
<pre><code>z                 &lt;---- ebp+16
y                 &lt;---- ebp+12
x                 &lt;---- ebp+8
return address   &lt;---- ebp+4
previous ebp     &lt;---- ebp
sum (local)      &lt;---- ebp-4
ESP(top)         &lt;---- esp</code></pre><h3 id="4-함수-본문-실행">4. 함수 본문 실행</h3>
<p>스택 프레임이 생성되면 함수의 본문이 실행된다.
함수의 본문에서는 <strong>EBP</strong>를 기준으로 <strong>지역 변수</strong>, <strong>매개 변수</strong>에 접근할 수 있다.</p>
<pre><code class="language-c">sum = x + y + z</code></pre>
<p>이 c코드는 어셈블리어로 다음과 같다</p>
<pre><code class="language-asm">mov eax, [ebp+8]    
add eax, [ebp+12]   
add eax, [ebp+16]   
mov [ebp-4], eax    </code></pre>
<h3 id="5-스택-프레임-정리-및-복귀">5. 스택 프레임 정리 및 복귀</h3>
<p>함수 실행이 끝나면, 스택을 정리하고 저장해두었던 <strong>return address</strong>로 돌아가기 위해 <strong>SP</strong>와 <strong>BP</strong>를 복원한다.</p>
<pre><code class="language-asm">mov esp, ebp   ; 스택 포인터 복원 (지역 변수 제거)
pop ebp        ; 이전 함수의 EBP 복원
ret            ; 복귀 주소 pop → EIP로 이동</code></pre>
<h3 id="6-스택-정리">6. 스택 정리</h3>
<p><code>ret</code>으로 복귀하면, 스택에는 여전히 호출할 때 <code>push</code>했던 인자(x, y, z)가 남아 있다.</p>
<p>스택을 그대로 두면 ESP가 함수 호출 전 위치로 돌아가지 않기 때문에, 다음 함수 호출 시 스택이 겹치거나 주소 계산이 꼬일 수 있다.</p>
<p>따라서 함수 호출이 끝나면 인자들이 차지했던 공간을 해제해 스택을 원래 상태로 되돌리는 과정이 필요하다.</p>
<blockquote>
<p>이 과정이 바로 “스택 정리(Stack Cleanup)”이며, 누가 이 정리를 담당하느냐(호출자 or 피호출자)는 호출 규약(Calling Convention) 에 따라 달라진다.
(호출 규약은 다음 글에서 다룬다.)</p>
</blockquote>
<h1 id="궁금한점">궁금한점</h1>
<p>호출규약관련된 모든것들</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Stack]]></title>
            <link>https://velog.io/@got1_c/Stack</link>
            <guid>https://velog.io/@got1_c/Stack</guid>
            <pubDate>Sat, 18 Oct 2025 07:41:49 GMT</pubDate>
            <description><![CDATA[<h2 id="스택-stack">스택 (Stack)</h2>
<p>스택은 데이터가 들어오는 순서대로 쌓아서 저장하고 마지막에 들어온 데이터부터 꺼내서 사용할 수 있는 후입선출(LIFO,Last-In-First-Out)형태의 자료구조이다.
<img src = "https://velog.velcdn.com/images/got1_c/post/bab0aefb-aa42-4d44-86a2-e242bc732740/image.png" width="50%" height="50%">
이러한 특징을 가진 스택은 <strong>임시데이터</strong>를 저장하거나, <strong>함수 호출 시 복귀 주소와 인자</strong>, <strong>지역 변수</strong>를 관리하는데 사용된다.</p>
<h2 id="top">top</h2>
<p><strong>top</strong>은 스택의 최상단을 말한다.
<code>push</code>수행 시: 스택의 최상단에 새로운 값이 들어오기 때문에 top이 한 칸 내려간다.
<code>pop</code>수행 시: 스택의 최상단에 새로운 값이 들어오기 때문에 top이 한 칸 올라간다.</p>
<p><img src="https://velog.velcdn.com/images/got1_c/post/6a650441-787a-40e5-be3d-efb5a33bb20c/image.png" alt=""></p>
<h2 id="스택-포인터sp-stack-pointer">스택 포인터(SP, Stack Pointer)</h2>
<p>스택 포인터는 <strong>top을 가리키는 주소 레지스터</strong>를 말한다.
--&gt; 마지막으로 데이터가 추가된 곳을 가리키는 레지스터</p>
<h3 id="sp가-하는-역할">SP가 하는 역할</h3>
<p>SP는 top을 가리키는 주소 레지스터이므로, CPU가 스택에 접근할때 항상 이 값을 기준으로 한다.
즉, <strong>top</strong>이 변하면 <strong>SP</strong>도 변한다.
<code>push</code>: SP가 감소하고 새 데이터가 [SP]에 저장된다.
<code>pop</code>: [SP]의 데이터를 꺼내오고 [SP]가 증가한다.</p>
<h4 id="cpu에-따라서-스택의-성장-방향이-달라지기도-한다">CPU에 따라서 스택의 성장 방향이 달라지기도 한다.</h4>
<p>x86,ARM등 대부분의 CPU는 <code>push</code>시 아래에 데이터가 쌓이는 <strong>하향 스택</strong>을 사용하기 때문에 이 글에서도 하향 스택을 기준으로 설명하도록 하겠다. </p>
<p>총알을 저장하는 구조를 생각하면 이해하기 편하다.(일단 나는 그랬음)
<img src="https://velog.velcdn.com/images/got1_c/post/98d72109-c8ec-400b-9ca4-f41c3bd39e5c/image.png" alt=""></p>
<h2 id="스택의-동작">스택의 동작</h2>
<p>데이터를 저장하는 명령어 <code>push</code> <code>pop</code></p>
<h3 id="push">push</h3>
<p><code>push</code>는 스택에 데이터를 삽입하는 명령어다.
어떤 값을 스택의 맨 위(top)에 삽입(<code>push</code>)한다는 의미이다.</p>
<p><code>push eax</code> = &quot;eax에 들어있는 데이터를 스택에 저장해라&quot;</p>
<h3 id="pop">pop</h3>
<p><code>pop</code>은 스택에서 데이터를 제거하는 명령어다.
스택 top에 저장된 데이터가 &quot;톡 하고 빠져나온다&quot;(<code>pop</code>)는 의미이다.</p>
<p><code>pop eax</code> = &quot;스택에서 데이터를 빼와서 eax에 저장해라&quot; </p>
<h1 id="궁금한점">궁금한점</h1>
<p>왜 대부분의 CPU는 하향스택을 선택하는가?</p>
<ul>
<li>힙과의 충돌 때문이라는데 추가 조사 필요</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[어셈블리어는 왜 공부해야하는가]]></title>
            <link>https://velog.io/@got1_c/%EC%96%B4%EC%85%88%EB%B8%94%EB%A6%AC%EC%96%B4%EB%8A%94-%EC%99%9C-%EA%B3%B5%EB%B6%80%ED%95%B4%EC%95%BC%ED%95%98%EB%8A%94%EA%B0%80</link>
            <guid>https://velog.io/@got1_c/%EC%96%B4%EC%85%88%EB%B8%94%EB%A6%AC%EC%96%B4%EB%8A%94-%EC%99%9C-%EA%B3%B5%EB%B6%80%ED%95%B4%EC%95%BC%ED%95%98%EB%8A%94%EA%B0%80</guid>
            <pubDate>Mon, 13 Oct 2025 13:10:12 GMT</pubDate>
            <description><![CDATA[<p>어셈블리어를 공부하기 전 <strong>&quot;어셈블리어를 왜 공부해야하는가&quot;</strong>에 대해서 자신의 생각을 정리하고 공부하면 조금 더 구체적으로 공부 방향성을 잡을 수 있어서 블로그를 작성하게 되었다.</p>
<h2 id="우선-어셈블리어란-무엇인가">우선 어셈블리어란 무엇인가?</h2>
<p><strong>어셈블리어</strong>는 바이너리 코드를 사람이 읽을 수 있도록 나타낸 저수준 언어이다.</p>
<p><strong>어셈블리어</strong>는 기계어와 1대1로 대응되는 가장 저수준 언어이기 때문에 <strong>하드웨어의 동작</strong>과도 밀접하게 연관되어 있다.</p>
<p>맛보기로 예시를 들자면 
<code>add eax, ebx</code>
는 EAX 레지스터에 EBX 레지스터의 값을 더한 뒤, 그 결과를 다시 EAX에 저장하는 명령이다.</p>
<h4 id="즉-cpu-내부의-산술논리연산장치alu가-두-레지스터의-값을-더하고-결과를-eax로-되돌려-쓴다">즉, CPU 내부의 산술논리연산장치(ALU)가 두 레지스터의 값을 더하고, 결과를 EAX로 되돌려 쓴다.</h4>
<blockquote>
<p>ALU는 무엇인가?</p>
</blockquote>
<ul>
<li>산술 논리 장치(Arithmetic and Logical Unit, ALU)는 산술연산과 논리연산을 계산하는 디지털 회로이다.
<a href="https://ko.wikipedia.org/wiki/%EC%82%B0%EC%88%A0_%EB%85%BC%EB%A6%AC_%EC%9E%A5%EC%B9%98">자세한 정보(나중에 ALU에 관해 제 블로그 써서 링크 넣을게염)</a></li>
</ul>
<hr>
<h2 id="어셈블리어는-왜-공부해야할까">어셈블리어는 왜 공부해야할까?</h2>
<p>어셈블리어를 왜 공부해야하는지에 대해서 <strong>컴퓨터 구조</strong>, <strong>보안적 관점</strong>, <strong>최적화 관점</strong> 총 3가지 관점에서 생각해보았다.</p>
<h3 id="💻컴퓨터-구조-관점">💻컴퓨터 구조 관점</h3>
<p>컴퓨터 구조는 하드웨어(레지스터, 메모리, 캐시, 파이프라인 등)가 명령을 어떻게 처리하는지 보는 분야다.<br>어셈블리어는 그런 하드웨어 동작을 ‘직접 보여주는’ 언어라서, 컴퓨터 구조를 공부할 때 함께 보면 이해가 훨씬 쉬워진다.</p>
<h4 id="예시">예시</h4>
<h4 id="명령어isa와-레지스터-동작-보기">명령어(ISA)와 레지스터 동작 보기</h4>
<ul>
<li>어셈블리로 명령 하나하나를 보면 어떤 레지스터를 쓰고 결과를 어디에 두는지 바로 알 수 있다.  </li>
<li><em>예시:*</em> <code>mov</code>, <code>add</code> 같은 명령이 레지스터를 어떻게 바꾸는지 확인한다.</li>
</ul>
<hr>
<h3 id="🔐보안적-관점">🔐보안적 관점</h3>
<p>보안은 컴퓨터 시스템의 내부 동작을 이해하는 학문이다.<br>어셈블리어는 하드웨어와 소프트웨어의 경계를 직접 다루는 언어이므로 보안 분야에서 필수적이다.<br>아래는 어셈블리어가 특히 많이 쓰이는 리버싱 기반의 실무 활동들이다.</p>
<blockquote>
<h3 id="리버싱">리버싱</h3>
<p>리버싱은 컴파일된 실행 파일(바이너리)를 분석하는 과정이다. 이 과정에서 실행 파일을 분석할때 
어셈블리어는 필수적이다.</p>
</blockquote>
<h3 id="리버싱을-이용한-실무-예시">리버싱을 이용한 실무 예시</h3>
<h4 id="1-취약점-분석-vulnerability-research">1. 취약점 분석 (Vulnerability Research)</h4>
<p>취약점 분석은 프로그램의 설계·구현상 결함을 찾아내어 악용 가능성을 평가하는 작업이다. 어셈블리 코드를 보면 함수의 스택 프레임, 메모리 접근 오프셋, 경계 검사 여부 등을 직접 확인할 수 있으므로, 버퍼 오버플로우나 잘못된 포인터 사용과 같은 결함을 정확히 식별하고 영향 범위를 평가할 수 있다.</p>
<h4 id="2-익스플로잇-개발-exploit-development">2. 익스플로잇 개발 (Exploit Development)</h4>
<p>익스플로잇 개발은 발견된 취약점을 실제로 악용해 시스템 동작을 제어하는 페이로드를 만드는 과정이다. 이 과정에서는 리턴 주소(EIP/RIP) 조작, 레지스터 값 설정, 시스템 콜 호출 방식 등 어셈블리 수준의 제어가 전제되어야 하므로 어셈블리 이해가 필수적이다.</p>
<h4 id="3-악성코드-분석-malware-analysis">3. 악성코드 분석 (Malware Analysis)</h4>
<p>악성코드는 소스 없이 배포되는 경우가 대부분이고 난독화·패킹이 자주 사용된다. 어셈블리 수준에서 코드 흐름과 API 호출 패턴을 읽을 수 있어야 파일 암호화 루틴, 키로깅, 네트워크 통신 등 악성 행위를 분해·추적하고 대응 방안을 세울 수 있다.</p>
<hr>
<h3 id="⚙️최적화-관점">⚙️최적화 관점</h3>
<p>최적화는 코드가 하드웨어에서 더 빠르고 효율적으로 실행되도록 만드는 작업이다.<br>어셈블리어는 컴파일러가 실제로 내보낸 명령어 시퀀스를 그대로 보여주기 때문에, 성능 문제의 원인을 바로 확인하고 직접 개선할 수 있게 해준다.</p>
<h4 id="예시-1">예시</h4>
<h4 id="레지스터-중심-최적화">레지스터 중심 최적화</h4>
<ul>
<li>어셈블리를 보면 값이 메모리와 레지스터 사이에서 어떻게 오가는지 보인다.  </li>
<li><em>예시:*</em> 반복문 안에서 자주 쓰는 값을 레지스터에 유지해 메모리 접근을 줄이는 방식으로 성능을 개선한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[어셈블리어 데이터 이동, 산술, 분기]]></title>
            <link>https://velog.io/@got1_c/%EC%96%B4%EC%85%88%EB%B8%94%EB%A6%AC%EC%96%B4-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95-%EB%A0%88%EC%A7%80%EC%8A%A4%ED%84%B0</link>
            <guid>https://velog.io/@got1_c/%EC%96%B4%EC%85%88%EB%B8%94%EB%A6%AC%EC%96%B4-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95-%EB%A0%88%EC%A7%80%EC%8A%A4%ED%84%B0</guid>
            <pubDate>Sun, 12 Oct 2025 11:00:57 GMT</pubDate>
            <description><![CDATA[<h2 id="데이터-이동-산술-분기에-맞춰서-어셈블리어-문법-다시-작성할-예정">데이터 이동 산술 분기에 맞춰서 어셈블리어 문법 다시 작성할 예정</h2>
<h3 id="어셈블리어-기본-문법">어셈블리어 기본 문법</h3>
<p><code>mov</code> <code>add</code> <code>sub</code> <code>cmp</code> <code>jmp</code> </p>
<h4 id="mov"><code>mov</code></h4>
<blockquote>
<p> <code>mov</code>는 두 번째 피연산자의 값을 첫 번째 피연산자로 <strong>복사</strong>하는 명령어다.
<code>mov eax,ebx</code> = &quot;ebx의 값을 eax로 복사한다.&quot;</p>
</blockquote>
<h4 id="add"><code>add</code></h4>
<blockquote>
<p><code>add</code>는 첫 번째 피연산자에 두번째 피연산자의 값을 <strong>더한</strong> 결과를 저장하는 명령어다.
<code>add eax, ebx</code>     = &quot;eax에 ebx를 더한 값을 eax에 저장한다.&quot; (+=)</p>
<blockquote>
<ul>
<li><strong>플래그 변화</strong> (연산 결과에 따라 플래그 값이 변경된다. 추후 플래그에 대해서 더 알아보도록 하겠다.) 
<code>ZF</code> (Zero Flag): 결과가 0이면 1
<code>CF</code> (Carry Flag): overflow 발생 시 1
<code>SF</code> (Sign Flag): 결과가 음수이면 1</li>
</ul>
</blockquote>
</blockquote>
<h4 id="sub"><code>sub</code></h4>
<blockquote>
<p><code>sub</code>는 첫 번째 피연산자에서 두 번째 피연산자의 값을 <strong>뺀</strong> 결과를 저장하는 명령어다.
<code>sub eax, ebx</code> = “eax에서 ebx를 뺀 값을 eax에 저장한다.” (-=)</p>
<blockquote>
<ul>
<li><strong>플래그 변화</strong> 
<code>ZF</code>: 결과가 0이면 1
<code>CF</code>: Borrow 발생 시 1
<code>SF</code>: 결과가 음수이면 1</li>
</ul>
</blockquote>
</blockquote>
<h4 id="cmp"><code>cmp</code></h4>
<blockquote>
<p><code>cmp</code>는 두 피연산자의 값을 <strong>비교</strong>하는 명령어다.
내부적으로는 <code>sub</code>와 동일하게 뺄셈을 수행하지만, 결과를 저장하지 않고 플래그만 변경한다.
<code>cmp eax, ebx</code> = &quot;eax와 ebx를 비교한다.&quot; (eax-ebx 수행 후 결과 버림)</p>
<blockquote>
<ul>
<li>플래그 변화
<code>ZF</code>: 두 값이 같으면 1 (eax == ebx)
<code>CF</code>: Borrow 발생 시 1 (eax &lt; ebx)
<code>SF</code>: 결과가 음수면 1 (eax &lt; ebx)</li>
</ul>
</blockquote>
</blockquote>
<h4 id="jmp"><code>jmp</code></h4>
<blockquote>
<p><code>jmp</code>는 프로그램의 실행 흐름을 <strong>다른 위치로 이동</strong> 시키는 명령어다.
-&gt; 다음에 실행할 명령어의 주소(label)를 바꿔서 코드의 흐름을 제어
<code>jmp label</code> = &quot;label 위치로 이동하여 그곳부터 실행을 계속한다.&quot;</p>
<blockquote>
<ul>
<li><code>jmp</code> 기본 구조 </li>
</ul>
</blockquote>
</blockquote>
<pre><code class="language-nasm">section .text
global _start
; -----------------
_start:
    jmp skip_part
; --(실행되지 않음)--
    mov eax, 1
    mov ebx, 2
; -----------------
skip_part:
    mov eax, 10
    mov ebx, 20</code></pre>
<h3 id="register">Register</h3>
<p>레지스터는 CPU 내부에 위치한 임시저장공간이다.</p>
<p>레지스터는 다양한 종류가 있지만 여기서는 <strong>범용 레지스터</strong>와 <strong>플래그 레지스터</strong>만 다루겠다.</p>
<hr>
<h4 id="범용레지스터-general-purpose-register-gpr">범용레지스터 (General Purpose Register, GPR)</h4>
<p>x86(32비트)에는 <code>EAX</code>, <code>EBX</code>, <code>ECX</code>, <code>EDX</code>, <code>EDI</code>, <code>ESI</code>, <code>ESP</code>, <code>EBP</code> 총 8가지 <strong>범용 레지스터</strong>가 있다.</p>
<p>산술 연산, 반복문, 스택 관리, 메모리 접근 등 거의 모든 연산의 중심이 된다.</p>
<table>
<thead>
<tr>
<th>레지스터</th>
<th>이름(의미)</th>
<th>주요 역할</th>
</tr>
</thead>
<tbody><tr>
<td><strong>EAX</strong></td>
<td>Accumulator</td>
<td>연산 결과나 함수 리턴값 저장</td>
</tr>
<tr>
<td><strong>EBX</strong></td>
<td>Base</td>
<td>메모리 주소 계산에 사용</td>
</tr>
<tr>
<td><strong>ECX</strong></td>
<td>Counter</td>
<td>루프나 반복문 제어에 사용</td>
</tr>
<tr>
<td><strong>EDX</strong></td>
<td>Data</td>
<td>곱셈·나눗셈 시 보조 역할</td>
</tr>
<tr>
<td><strong>ESI</strong></td>
<td>Source Index</td>
<td>문자열/배열 복사 시 입력 위치</td>
</tr>
<tr>
<td><strong>EDI</strong></td>
<td>Destination Index</td>
<td>문자열/배열 복사 시 출력 위치</td>
</tr>
<tr>
<td><strong>EBP</strong></td>
<td>Base Pointer</td>
<td>스택 프레임 기준 주소 (함수 내부 변수 참조)</td>
</tr>
<tr>
<td><strong>ESP</strong></td>
<td>Stack Pointer</td>
<td>스택의 최상단(Top)을 가리킴</td>
</tr>
</tbody></table>
<blockquote>
<p>💡 참고: 64비트(x86-64) 환경에서는 <code>EAX → RAX</code>, <code>EBX → RBX</code>처럼<br><code>R</code> 접두사가 붙으며, <code>R8 ~ R15</code>까지 추가 레지스터가 존재한다.</p>
</blockquote>
<hr>
<h4 id="플래그-레지스터-flag-register">플래그 레지스터 (Flag Register)</h4>
<p><strong>플래그 레지스터</strong>는 CPU가 연산을 수행한 후<br>그 결과의 상태를 기록하는 <strong>상태 저장 레지스터</strong>이다.<br>조건문(<code>cmp</code>, <code>je</code>, <code>jne</code>, <code>jg</code>, <code>jl</code> 등)은 이 플래그 값을 참조하여 분기 여부를 결정한다.</p>
<table>
<thead>
<tr>
<th>플래그</th>
<th>의미</th>
<th>역할</th>
</tr>
</thead>
<tbody><tr>
<td><strong>ZF (Zero Flag)</strong></td>
<td>0 플래그</td>
<td>연산 결과가 0이면 1로 설정</td>
</tr>
<tr>
<td><strong>SF (Sign Flag)</strong></td>
<td>부호 플래그</td>
<td>결과가 음수이면 1로 설정</td>
</tr>
<tr>
<td><strong>CF (Carry Flag)</strong></td>
<td>캐리 플래그</td>
<td>자리올림(또는 자리내림) 발생 시 1</td>
</tr>
<tr>
<td><strong>OF (Overflow Flag)</strong></td>
<td>오버플로 플래그</td>
<td>부호 있는 연산에서 오버플로 발생 시 1</td>
</tr>
<tr>
<td><strong>PF (Parity Flag)</strong></td>
<td>패리티 플래그</td>
<td>결과의 1 비트 개수가 짝수면 1</td>
</tr>
</tbody></table>
<blockquote>
<p>💡 예시:  </p>
<pre><code class="language-asm">cmp eax, ebx    ; EAX와 EBX 비교 → EFLAGS 설정
je equal_label  ; ZF=1이면(equal) 점프 수행</code></pre>
</blockquote>
<hr>
<h3 id="추가로-조사할-점">추가로 조사할 점</h3>
<ul>
<li>ALU는 무엇인가</li>
<li>CPU 내부 동작 방식 (세부적으로)</li>
<li>16비트 32비트 64비트 간의 차이점</li>
<li>자리올림/내림은 어떻게 이루어지는가</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[어셈블리어의 기본 구조]]></title>
            <link>https://velog.io/@got1_c/%EC%96%B4%EC%85%88%EB%B8%94%EB%A6%AC%EC%96%B4%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EA%B5%AC%EC%A1%B02%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@got1_c/%EC%96%B4%EC%85%88%EB%B8%94%EB%A6%AC%EC%96%B4%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EA%B5%AC%EC%A1%B02%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Sat, 11 Oct 2025 16:49:30 GMT</pubDate>
            <description><![CDATA[<h4 id="프로그램의-전체-구성">프로그램의 전체 구성</h4>
<pre><code class="language-assembly">section .data    ; 데이터(변수) 선언 영역
section .bss    ; 초기화되지 않은 변수 영역
section .text    ; 실행 코드 영역
global _start    ; 프로그램의 진입점</code></pre>
<p><code>.data</code> 초기값이 있는 변수 저장
<code>.bss</code> 초기값이 없는 변수 저장
<code>.text</code> 실제 명령어 저장
<code>.start</code> 프로그램 실행이 시작되는 위치</p>
<h4 id="기본-실행-흐름">기본 실행 흐름</h4>
<p>CPU는 프로그램을 명령어 단위로 읽고 실행한다.</p>
<ol>
<li>명령어 읽기</li>
<li>피연산자 해석</li>
<li>해당 동작 수행</li>
<li>다음 명령어로 이동 <h4 id="명령어-기본-형태">명령어 기본 형태</h4>
<code>명령어 목적지, 원본</code><h4 id="피연산자">피연산자</h4>
<table>
<thead>
<tr>
<th align="left">종료</th>
<th align="left">설명</th>
<th align="left">예시</th>
</tr>
</thead>
<tbody><tr>
<td align="left">Register</td>
<td align="left">CPU 내부 고속 저장 공간</td>
<td align="left"><code>eax</code>,<code>ebx</code>,<code>ecx</code></td>
</tr>
<tr>
<td align="left">Immediate</td>
<td align="left">코드 안에 직접 적힌 상수</td>
<td align="left"><code>mov eax, 5</code></td>
</tr>
<tr>
<td align="left">Memory</td>
<td align="left">실제 메모리 주소에 있는 값</td>
<td align="left"><code>mov eax, [num]</code></td>
</tr>
</tbody></table>
</li>
</ol>
<p><em>메모리 접근 시 반드시 대괄호 []를 써야한다.</em></p>
<h4 id="데이터-정의변수-선언">데이터 정의(변수 선언)</h4>
<table>
<thead>
<tr>
<th align="left">키워드</th>
<th align="left">의미</th>
<th align="left">예시</th>
</tr>
</thead>
<tbody><tr>
<td align="left">db</td>
<td align="left">byte (1바이트)</td>
<td align="left"><code>msg db &#39;A&#39;</code></td>
</tr>
<tr>
<td align="left">dw</td>
<td align="left">word (2바이트)</td>
<td align="left"><code>num dw 1234</code></td>
</tr>
<tr>
<td align="left">dd</td>
<td align="left">double word (4바이트)</td>
<td align="left"><code>value dd 10</code></td>
</tr>
<tr>
<td align="left">dq</td>
<td align="left">quad word (8바이트)</td>
<td align="left"><code>big dq 12345678</code></td>
</tr>
</tbody></table>
<blockquote>
<p>word는 CPU가 한 번에 처리할 수 있는 데이터 단위(Unit)를 말한다.</p>
</blockquote>
<p>예시</p>
<pre><code class="language-assembly">section .data
num dd 10    ; 정수형 변수 num = 10
msg db &#39;A&#39;    ; 문자형 변수 msg =&#39;A&#39;</code></pre>
<h4 id="어셈블리어의-실행-단위">어셈블리어의 실행 단위</h4>
<p>CPU는 명령어를 하나씩 실행하면서 현재 위치(Program Counter, PC)를 관리한다.</p>
<table>
<thead>
<tr>
<th align="left">구조</th>
<th align="left">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="left">순차 실행</td>
<td align="left">위에서 아래로 한 줄씩 실행</td>
</tr>
<tr>
<td align="left">비순차 실행</td>
<td align="left">분기문으로 흐름 변경</td>
</tr>
</tbody></table>
<blockquote>
<p><code>jmp</code>같은 분기문이 등장하기 전까지 CPU는 <code>.text</code> 내부 명령을 순서대로 실행하는 단순한 구조다.</p>
</blockquote>
<h4 id="프로그램의-종료-구조">프로그램의 종료 구조</h4>
<pre><code class="language-assembly">mov eax, 1    ;sys_exit 호출 번호
mov ebx, 0    ;종료 코드 0
int 0x80    ;리눅스 커널에 &quot;프로그램 종료&quot; 요청 (프로그램 종료)</code></pre>
<p>추가적으로 알아보고 싶은 것
<strong>왜 프로그램 종료 구조는 저렇게 되는가</strong>
<strong>NASM, MASM, GAS 등 어셈블러 별 차이점과 공통점</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CRSF 실습]]></title>
            <link>https://velog.io/@got1_c/CRSF-%EC%8B%A4%EC%8A%B5</link>
            <guid>https://velog.io/@got1_c/CRSF-%EC%8B%A4%EC%8A%B5</guid>
            <pubDate>Wed, 21 May 2025 17:43:53 GMT</pubDate>
            <description><![CDATA[<h1 id="crsf">CRSF</h1>
<blockquote>
<p>Cross Site Request Forgery(사이트 간 요청 위조)는 사용자가 인증된 상태에서 공격자가 의도한 요청을 자동으로 수행하게 만드는 공격이다. 예를 들어, 사용자가 은행 웹사이트에 로그인한 상태에서 악성 웹페이지를 방문하면, 해당 페이지의 스크립트가 사용자의 권한으로 은행에 돈을 이체하는 요청을 보낼 수 있다.</p>
</blockquote>
<h2 id="crsf-동작원리">CRSF 동작원리</h2>
<p>CSRF 공격은 다음과 같은 과정을 통해서 이루어진다.</p>
<blockquote>
<p><strong>1. 사용자 로그인</strong>: 사용자가 웹사이트에 로그인하면, 브라우저는 세션을 유지하기 위해 쿠키를 저장한다.
<strong>2. 악성 사이트 방문</strong>: 사용자가 공격자가 만든 악성 웹페이지를 방문한다.
<strong>3. 자동 요청 전송</strong>: 악성 페이지의 스크립트가 사용자의 브라우저를 통해 웹사이트에 요청을 보낸다. 이때, 브라우저는 저장된 쿠키를 함께 전송한다.
<strong>4. 서버 처리</strong>: 웹사이트는 쿠키를 기반으로 요청을 인증된 사용자로 인식하고, 요청을 처리한다.</p>
</blockquote>
<p>이러한 방식으로 공격자는 사용자의 권한을 악용하여 원하지 않는 작업을 수행할 수 있다.</p>
<h1 id="crsf-실습">CRSF 실습</h1>
<p>DVWA CRSF 창에서 패스워드 변경 요청이 어떤 방식으로 웹 서버에 전송되는지 확인하기 위해 Burp suite를 이용해서 패킷을 스니핑한 결과
<img src="https://velog.velcdn.com/images/got1_c/post/2d9f650b-d5fa-4193-a263-cb965cb30ad3/image.png" alt="">
패스워드 변경 텍스트란에 입력한 값이 password_new, password_conf 파라미터에 저장되고 change 파라미터와 함께 GET 메소드를 이용하여 서버에 전송되는 것을 확인할 수 있다.</p>
<p>해당 요청 정보를 이용해 공격자는 피해자에게 자신이 원하는 패스워드가 설정된 URL을 전달한다.
전달된 URL로 접속했을때 패스워드 변경 요청이 웹 서버로 전송되게 되어 계정의 패스워드가 공격자가 원하는 패스워드로 변경된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[XSS 실습]]></title>
            <link>https://velog.io/@got1_c/XSS-%EC%8B%A4%EC%8A%B5</link>
            <guid>https://velog.io/@got1_c/XSS-%EC%8B%A4%EC%8A%B5</guid>
            <pubDate>Wed, 21 May 2025 16:25:56 GMT</pubDate>
            <description><![CDATA[<h1 id="html-기본-구조-이해">HTML 기본 구조 이해</h1>
<hr>
<blockquote>
<p>HTML의 기본 구조는 <strong>문서 형식 선언(Doctype), 루트 요소(html), 헤드(head), 본문(Body)</strong>로 구성된다.</p>
</blockquote>
<h3 id="tag와-속성">tag와 속성</h3>
<h3 id="tag">tag</h3>
<p> 태그는 HTML 요소의 시작과 끝을 나타내는 표시자이다. 일반적으로 <code>&lt;열리는태그&gt;와 &lt;/닫히는태그&gt;</code>로 구성된다.</p>
<h3 id="속성">속성</h3>
<p> 속성은 태그에 추가적인 정보를 부여한다. 보통 <code>속성명 = &quot;값&quot;</code> 형태로 쓰인다.
 예시 <code>&lt;a href=&quot;https://example.com&quot; target=&quot;_blank&quot;&gt;링크&lt;/a&gt;</code></p>
<h4 id="예시-속성">예시 속성</h4>
<blockquote>
<table>
<thead>
<tr>
<th>속성</th>
<th>설명</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td><code>id</code></td>
<td>요소 고유 식별자 (JS, CSS에 사용)</td>
<td><code>&lt;div id=&quot;header&quot;&gt;</code></td>
</tr>
<tr>
<td><code>class</code></td>
<td>여러 요소에 공통 스타일 적용</td>
<td><code>&lt;p class=&quot;notice&quot;&gt;</code></td>
</tr>
<tr>
<td><code>style</code></td>
<td>인라인 CSS 스타일 적용</td>
<td><code>&lt;h1 style=&quot;color:red;&quot;&gt;</code></td>
</tr>
<tr>
<td><code>href</code></td>
<td>링크의 대상 주소</td>
<td><code>&lt;a href=&quot;https://example.com&quot;&gt;</code></td>
</tr>
<tr>
<td><code>src</code></td>
<td>이미지, 스크립트 등 외부 파일 경로</td>
<td><code>&lt;img src=&quot;logo.png&quot;&gt;</code></td>
</tr>
<tr>
<td><code>alt</code></td>
<td>이미지가 로딩되지 않을 때 표시할 텍스트</td>
<td><code>&lt;img alt=&quot;로고&quot;&gt;</code></td>
</tr>
<tr>
<td><code>title</code></td>
<td>마우스 올리면 툴팁 표시</td>
<td><code>&lt;button title=&quot;저장&quot;&gt;</code></td>
</tr>
<tr>
<td><code>type</code></td>
<td>입력창, 버튼 등의 타입 설정</td>
<td><code>&lt;input type=&quot;text&quot;&gt;</code></td>
</tr>
<tr>
<td><code>value</code></td>
<td>기본값 설정</td>
<td><code>&lt;input value=&quot;홍길동&quot;&gt;</code></td>
</tr>
<tr>
<td><code>placeholder</code></td>
<td>입력창 안내 텍스트</td>
<td><code>&lt;input placeholder=&quot;이름 입력&quot;&gt;</code></td>
</tr>
</tbody></table>
</blockquote>
<h3 id="doctype">Doctype</h3>
<p>Doctype은 문서의 형식을 브라우저에 알려주는 선언문이다. (HTML의 가장 첫 줄에 위치)</p>
<p><code>&lt;!DOCTYPE&gt;</code>은 &quot;Documeent Type DEclartaion&quot;의 줄임말로, HTML 문서가 어떤 HTML 버전으로 작성되었는지를 웹 브라우저에 알리는 역할이다. 이를 통해 브라우저는 해당 문서를 어떤 방식으로 *렌더링 해야 할지를 결정한다.</p>
<p>*렌더링: 코드나 데이터를 화면에 보이도록 그림을 바꾸는 과정</p>
<h3 id="html">html</h3>
<p>html은 HTML 문서의 최상위 요소이며, 모든 다른 HTML 요소들을 포함하는 부모 요소이다.</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ko&quot;&gt;
  &lt;!-- HTML 문서의 내용 --&gt;
&lt;/html&gt;</code></pre><p><code>&lt;html&gt;</code>요소에는 <code>lang</code>속성이 포함될 수 있다. 만약, 영어로 작성된 문서라면 <code>lang=&quot;en&quot;</code>과 같이 작성된다.</p>
<h3 id="head">head</h3>
<p><code>&lt;head&gt;</code> 요소는 HTML 문서에서 사용자에게 직접 보이지 않는 메타데이터를 담는 부분이다. 웹 브라우저는 이 정보를 참고해서 문서를 어떻게 표시할지, 어떤 문자 인코딩을 쓸지, 외부 파일을 어떻게 연결할지 등을 결정한다</p>
<p>헤더 요소의 대표적 태그(tag)
<code>&lt;title&gt;</code>: :브라우저 탭에 표시될 제목
<code>&lt;meta&gt;</code>: 문서의 특성 정보를 정의
<code>&lt;link&gt;</code>: 외부 CSS 파일 등과 연결
<code>&lt;style&gt;</code>: 문서 안에 직접 CSS 작성
<code>&lt;script&gt;</code>: JavaScript 코드 삽입 또는 외부 JS 파일 연결
<code>&lt;base&gt;</code>: 문서 내 모든 링크의 기본 RL 지정</p>
<h3 id="body">body</h3>
<p><code>&lt;body&gt;</code> 요소는 HTML 문서의 실제 내용을 담고 있는 본문이다. 웹 페이지를 구성하는 모든 텍스트, 이미지, 링크, 테이블, 폼 등의 콘텐츠는 <code>&lt;body&gt;</code> 요소 내에 포함된다. </p>
<p>바디 요소의 대표적 태그(tag)
 <code>&lt;h1&gt;</code> ~ <code>&lt;h6&gt;</code>: 제목 (헤딩)<br> <code>&lt;p&gt;</code>: 문단 (paragraph)<br> <code>&lt;img&gt;</code>: 이미지 삽입<br> <code>&lt;a&gt;</code>: 하이퍼링크<br> <code>&lt;ul&gt;</code>, <code>&lt;ol&gt;</code>, <code>&lt;li&gt;</code>: 리스트 (unordered, ordered, list item) 
 <code>&lt;div&gt;</code>, <code>&lt;span&gt;</code>: 구역 및 인라인 요소 (CSS와 함께 자주 사용)<br> <code>&lt;table&gt;</code>: 표<br> <code>&lt;form&gt;</code>: 입력 폼 (로그인, 회원가입 등)<br> <code>&lt;button&gt;</code>, <code>&lt;input&gt;</code>: 버튼 및 입력 필드<br> <code>&lt;script&gt;</code>: JavaScript 코드                      </p>
<h1 id="javascript-기본-문법-정리">JavaScript 기본 문법 정리</h1>
<hr>
<h2 id="1-alert">1. <code>alert()</code></h2>
<p>브라우저에서 <strong>팝업 창을 띄워 알림을 보여주는 함수</strong>이다.</p>
<pre><code class="language-js">alert(&quot;안녕하세요!&quot;); // 알림창에 메시지를 표시</code></pre>
<ul>
<li>사용자의 입력은 받을 수 없고, 확인 버튼만 있는 단순한 알림</li>
</ul>
<h2 id="2-locationhref">2. <code>location.href</code></h2>
<p><code>location.href</code>는 <strong>현재 페이지의 URL을 가져오거나, 변경하여 이동</strong> 할 수 있는 속성이다.</p>
<pre><code class="language-js">console.log(location.href); // 현재 URL 출력

// 다른 페이지로 이동
location.href = &quot;https://www.google.com&quot;;</code></pre>
<ul>
<li>링크 클릭 없이도 페이지 이동을 JS로 제어할 수 있다.<h2 id="3-documentcookie">3. document.cookie</h2>
<code>document.cookie</code>는 웹 페이지에서 <strong>쿠키를 읽거나 설정하는 데 사용</strong>된다.<pre><code class="language-js">// 쿠키 설정
document.cookie = &quot;username=shinwon; path=/;&quot;;
</code></pre>
</li>
</ul>
<p>// 쿠키 확인
console.log(document.cookie); // 출력: &quot;username=shinwon&quot;</p>
<pre><code>* 쿠키는 문자열로 저장되며, ```;```로 여러 항목을 구분한다.

## 4. 이벤트 핸들링
### `onclick`
```onclick```이벤트는 클릭 동작이 발생했을 때 실행할 코드를 지정한다.
```html
&lt;button onclick = &quot;alert(&#39;버튼이 클릭되었습니다!&#39;)&quot;&gt;클릭&lt;/button&gt;</code></pre><p>또는 JavaScript로 직접 설정할 수 있다.</p>
<pre><code class="language-js">document.getElementById(&quot;btn&quot;).onclick = funtion() {
  alert(&quot;클릭 이벤트 발생!&quot;);
};</code></pre>
<h3 id="onerror"><code>onerror</code></h3>
<p><code>onerror</code>는 이미지나 스크립트가 로딩에 실행했을 때 실행된다.</p>
<pre><code class="language-html">&lt;img src=&quot;없는이미지.png&quot; onerror=&quot;alert(&#39;이미지를 불러올 수 없습니다.&#39;)&quot;&gt;</code></pre>
<ul>
<li>주로 이미지 대체 처리나 로깅 용도로 활용된다.</li>
</ul>
<h1 id="xss-실습">XSS 실습</h1>
<h2 id="xss란">XSS란?</h2>
<blockquote>
<p>XSS는 웹 페이지에 악성 스크립트를 삽입하여 사용자에게 실행되도록 만드는 공격이다. 주로 사용자의 쿠키 탈취, 세션 하이재킹, 피싱 등으로 이어질 수 있다.</p>
</blockquote>
<h3 id="1reflected-xss">1.Reflected XSS</h3>
<blockquote>
<p>공격자가 악성 스크립트가 담긴 URL을 생성하여 메일 등을 통해 사용자에게 전달한 후 실행하도록 하는 공격</p>
</blockquote>
<p><code>What&#39;s your name?</code> 에 got1을 입력하니
<img src="https://velog.velcdn.com/images/got1_c/post/067eef0e-fe11-40b3-aa68-31729adb3569/image.png" alt="">
입력한 값이 URL을 통해 서버로 전송되고 페이지를 구성한다는 것을 알 수 있다.
위의 URL을 수정하여 google.com으로 웹 페이지를 변경해보겠다.
<code>http://localhost/vulnerabilities/xss_r/?name=&lt;script&gt;location.href=&quot;https://www.google.com&quot;&lt;/script&gt;</code>을 작성하고 Enter을 누르면 구글로 웹페이지가 변경되는 것을 확인할 수 있다.
<img src="https://velog.velcdn.com/images/got1_c/post/570c684b-3b65-4ede-bc75-3f3b48511353/image.png" alt="">
<img src="https://velog.velcdn.com/images/got1_c/post/1ca7cd84-07e3-462e-87af-e7ce3077ee4f/image.png" alt=""></p>
<h3 id="2-stored-xss">2. Stored XSS</h3>
<blockquote>
<ul>
<li>서버 DB 등에 저장 -&gt; 나중에 다른 사용자가 그 페이지에 들어오면 자동 실행된다.</li>
<li>위험도 매우 높다.(피싱, 세션 탈취 등)</li>
</ul>
</blockquote>
<p><img src="https://velog.velcdn.com/images/got1_c/post/e194d5b9-61d9-4688-a9e9-5bdf42a13310/image.png" alt="">
위 이미지와 같이 Message 부분에 웹 페이지에 쿠키를 팝업창에 띄워주는 스크립트를 작성하고 Sign Guestbook에 저장하면
이 페이지에 접속할때마다 쿠키 정보를 알려주는 팝업창이 뜨게 된다.
<img src="https://velog.velcdn.com/images/got1_c/post/291994af-0dd7-4d52-bf89-ea7bd6e3c19f/image.png" alt=""></p>
<h3 id="3-dom-based-xss">3. DOM-based XSS</h3>
<blockquote>
<p>DOM 구조를 이용하여 요소들을 수정하거나 추가하는 등 동적 행위를 할 때 접근하는 JavaScript에 악성 스크립트를 삽입하여 클라이언트 측 브라우저에서 악성 스크립트가 실행되도록 하는 공격</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/got1_c/post/58976816-55db-4f4f-9f17-a416acc3f81a/image.png" alt="">
Select 버튼을 클릭하면 위 URL에 default라는 이름의 매개변수 값이 설정되는 것을 확인할 수 있다.
<img src="https://velog.velcdn.com/images/got1_c/post/f04e2577-1e34-42c8-99c6-c64cc3630911/image.png" alt="">
위 URL 매개변수 값을 임의로 수정하여 전송하면 English가 수정한 매개변수 값으로 바뀐 것을 확인할 수 있다.
<img src="https://velog.velcdn.com/images/got1_c/post/9ed1082f-4c47-496c-b9c6-ee7000ef29a4/image.png" alt="">
default 매개변수의 값을 사용자가 직접 URL로 조작가능한 것을 확인할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/got1_c/post/f4be8ff9-de64-444b-bb83-269b8e835532/image.png" alt="">
default 매개변수 값에 </p>
<pre><code class="language-js">&lt;script&gt;document.write(document.cookie)&lt;/script&gt;
``` 을 입력하면 드롭다운 목록 최상위에 document.cookie 값이 나오는 것을 확인할 수 있다.

궁금한점
</code></pre>
<p><a href="http://localhost/vulnerabilities/xss_r/?name=%E3%85%87%E3%84%B4#">http://localhost/vulnerabilities/xss_r/?name=%E3%85%87%E3%84%B4#</a></p>
<p>name전에 ?는 무엇인가</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Command Injection 실습]]></title>
            <link>https://velog.io/@got1_c/Command-Injection-%EC%8B%A4%EC%8A%B5</link>
            <guid>https://velog.io/@got1_c/Command-Injection-%EC%8B%A4%EC%8A%B5</guid>
            <pubDate>Wed, 14 May 2025 18:35:26 GMT</pubDate>
            <description><![CDATA[<h3 id="리눅스-기본-명령어-학습">리눅스 기본 명령어 학습</h3>
<p><code>ls</code> List의 약자로 해당 디렉터리(폴더)에 있는 파일 목록을 나열하는 명령어
<code>cd</code> Change Directory의 약자로 디렉터리를 이동하는 명령어
<code>pwd</code> Print Working Directory의 약자로 현재 디렉터리의 전체 경로를 화면에 표시하는 명령어
<code>mkdir</code> Make Directory의 약자로 새로운 디렉터리를 생성하는 명령어
<code>touch</code> 크기가 0인 새 파일을 생성하거나 생성된 파일이 존재한다면 파일의 최종 수정 시간을 변경하는 명령어
<code>cp</code> Copy의 약자로 파일이나 디렉터리를 복사하는 명령어
<code>mv</code> Move의 약자로 파일이나 디렉터리의 이름을 변경하거나 다른 디렉터리로 옮길 때 사용하는 명령어
<code>rm</code> Remove의 약자로 파일이나 디렉터리를 삭제하는 명령어
<code>rmdir</code> Remove Directory의 약자로 디렉터리를 삭제하는 명령어 (파일이 있는 디렉터리를 삭제하려면 rm -r 명령을 실행해야한다.)
<code>cat</code> Concatenate의 약자로 파일 내용을 화면에 출력하는 명령어
<code>whoami</code> 현재 명령을 실행하고 있는 사용자 이름 출력
<code>id</code> 사용자 id, 그룹 id, 속한 그룹 목록을 보여주는 명령어
<code>ping</code> 다른 시스템에 네트워크 요청을 보내는 명령어</p>
<h3 id="command-injection-공격-원리">Command Injection 공격 원리</h3>
<p><strong>Command Injection</strong>은 SQL injection과 같이 유저의 입력을 받는 과정에서 발생하는 보안 취약점으로 <a href="https://velog.io/@ymail837/Linux-Shell-%EB%A9%94%ED%83%80-%EB%AC%B8%EC%9E%90">쉘 명령어</a>를 조합하여 다양한 기능을 수행하게 도와주는 쉘 메타 문자를 통해 발생한다.</p>
<h3 id="command-injection-취약점-실습">Command Injection 취약점 실습</h3>
<p><img src="https://velog.velcdn.com/images/got1_c/post/161e1e0a-41f8-41f6-a3f4-0a52aaa16bdd/image.png" alt="">
DVWA 웹 페이지에서 Command injection을 들어간다.
Enter an IP address: 에 입력한 IP를 대상으로 일반적인 <code>ping</code> 명령어를 수행하는 기능이 구현되어져 있다.
<img src="https://velog.velcdn.com/images/got1_c/post/4b212ef1-e55c-4c61-b7d1-a2e402b0e26a/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/got1_c/post/dc77cd43-0a47-4ed7-8fc7-aec935f7cc8f/image.png" alt="">
위 기능을 구현한 소스코드를 살펴보면 텍스트 란에 입력한 값이 아무런 검증 없이 target이라는 매개변수에 저장되어 ping 명령어 뒤쪽에 입력되어 사용되어지는 것을 확인할 수 있다. </p>
<p>따라서 ping 명령어 뒤쪽에 다양한 쉘 메타 문자를 입력하여 추가적으로 다른 시스템 명령을 수행할 수 있을 것 같다.<img src="https://velog.velcdn.com/images/got1_c/post/3913a9d7-9d2a-4cd9-b1c0-f3bcd5839cbf/image.png" alt="">
이렇게 <code>127.0.0.1; cat /etc/passwd</code>를 입력하면 사용자 계정 정보가 담긴 파일 내용이 추가로 출력된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SQL Injection (SQLi) 실습]]></title>
            <link>https://velog.io/@got1_c/SQL-Injection-SQLi-%EC%8B%A4%EC%8A%B5</link>
            <guid>https://velog.io/@got1_c/SQL-Injection-SQLi-%EC%8B%A4%EC%8A%B5</guid>
            <pubDate>Wed, 14 May 2025 18:00:57 GMT</pubDate>
            <description><![CDATA[<h3 id="sql-structured-query-language">SQL (Structured Query Language)</h3>
<p>SQL은 *관계형 데이터 베이스에서 데이터를 관리하고 처리하기 위한 프로그래밍 언어이다.
즉, 데이터베이스에서 저장된 정보를 검색, 삽입, 수정, 삭제하는 데 사용되는 언어이다.</p>
<p>*관계형 데이터 베이스: 데이터가 열과 행의 테이블에 데이터를 저장하는 데이터베이스</p>
<h3 id="sql-기본-문법">SQL 기본 문법</h3>
<h4 id="sql-문법-공부-및-실습-사이트"><a href="https://sqlbolt.com/lesson/introduction">SQL 문법 공부 및 실습 사이트</a></h4>
<blockquote>
</blockquote>
<h4 id="1-select---데이터를-조회할-때">1. SELECT - 데이터를 조회할 때</h4>
<p><code>SELET</code> 가져올 열을 지정(열_이름, *(모든 열을 가져올때))</p>
<h4 id="2-from---db-지정">2. FROM - DB 지정</h4>
<p><code>FROM</code> 데이터를 가져올 테이블 이름 지정</p>
<h4 id="3-where---조건식-지정">3. WHERE - 조건식 지정</h4>
<p><code>WHERE</code> 조건을 지정해서 필터링</p>
<h4 id="4-order-by---결과-정렬">4. ORDER BY - 결과 정렬</h4>
<h4 id="5-distinct---중복-제거">5. DISTINCT - 중복 제거</h4>
<p><code>ORDER BY</code> ASC(오름차순), DESC(내림차순)</p>
<h4 id="6-limit---결과-개수-제한">6. LIMIT - 결과 개수 제한</h4>
<h4 id="7-offset---건너뛰기">7. OFFSET - 건너뛰기</h4>
<pre><code>SELECT DISTINCT 열1, 열2, ...
FROM 테이블명
WHERE 조건
ORDER BY 열 [ASC|DESC]
LIMIT 개수 OFFSET 시작위치;</code></pre><h4 id="8-insert---데이터-추가">8. INSERT - 데이터 추가</h4>
<p><code>INSERT</code> 새 데이터를 테이블에 추가</p>
<h4 id="9-union---합치기">9. UNION - 합치기</h4>
<p><code>UNION</code> SELECT 결과들을 이어붙임</p>
<h3 id="sql-injection-개념-이해">SQL Injection 개념 이해</h3>
<p><strong>SQL Injection</strong>은 사용자 입력값을 검증하지 않는 경우 설계된 쿼리문에 의도하지 않은 쿼리를 임의로 삽입할 수 있는 공격이다. 공격자는 쿼리를 악의적으로 주입하여 데이터베이스의 데이터를 무단으로 탈취할 수 있다.</p>
<h3 id="dvwa-sql-injection-취약점-실습">DVWA SQL Injection 취약점 실습</h3>
<p><img src="https://velog.velcdn.com/images/got1_c/post/df59cfde-ba5e-49bc-a9bb-41742611065b/image.png" alt="">DVWA 웹 페이지에서 SQL Injection에 들어간다. (보안 레벨은 low로!!)
<img src="https://velog.velcdn.com/images/got1_c/post/af3217ef-84dd-44d6-a68f-e42d31da2bb8/image.png" alt=""></p>
<p>User ID:<code></code>에 1,2,3,4,5를 넣었을때 지정된 First name과 Surname이 나온다.    </p>
<p>이때 SQL Injection의 쿼리를 분석해보았을때
<img src="https://velog.velcdn.com/images/got1_c/post/53351f99-ccf5-4f25-9e33-1ca93bc21412/image.png" alt="">
전송된 SQL 구문은 다음과 같다.
<code>SELECT first_name,last_name FROM users WHERE user_id = &#39;$id&#39;;</code></p>
<p>이때 <code>$</code>은 PHP 변수 기호이다. 사용자가 URL로 보낸 값(<code>?id=1</code>)을 받아오는 PHP변수이다. (아무런 검증 조치 없이 저장됨)</p>
<p>따라서 <code>WHERE</code>구문을 우회할 수 있는 or 연산자와 언제나 참이되는 값을 입력하여 전송한 결과는 데이터베이스에 저장된 모든 계정의 first_name과 last_name이 출력되는 모습을 확인할 수 있다. (ex -&gt; <code>&#39; or 1=1--</code> 입력 -&gt;전송된 SQL구문 = <code>SELECT first_name,last_name FROM users WHERE user_id = &#39;&#39; or 1=1 -- ;</code>
<img src="https://velog.velcdn.com/images/got1_c/post/8948c956-073d-4f05-8dda-9d4cd2883281/image.png" alt="">
이러한 방식으로 로그인 폼을 우회하여 접속을 할 경우 가장 첫 번째로 생성된 계정의 권한으로 로그인 되는데 보통 관리자 권한의 계정인 경우가 많아 공격에 많이 활용된다고 한다.</p>
<h4 id="order-by-union-활용하여-공격">ORDER BY, UNION 활용하여 공격</h4>
<p><code>ORDER BY</code>를 활용하여 원본 <code>SELECT</code>가 검색하는 열의 개수를 알아내는 공격이다. 해당 공격을 수행하는 이유는 뒤에 나올 <code>UNION</code>을 이용한 공격을 수행하기 위해 우선 열의 개수를 알아내야하기 때문이다.
<img src="https://velog.velcdn.com/images/got1_c/post/002f9a0f-0597-4642-92b0-3215730a9710/image.png" alt=""></p>
<p><code>1&#39; ORDER BY 1 --</code> 와 <code>1&#39; ORDER BY 2 --</code>의 first_name과 last_name의 출력은 잘 나온다. 하지만 <code>1&#39; ORDER BY 3 #</code>을 했을때는 
<img src="https://velog.velcdn.com/images/got1_c/post/48a5119d-01eb-4ca3-9e6c-3ddb82d56e8e/image.png" alt="">
위 내용 처럼 3열을 찾을 수 없다며 에러가 뜬다. 즉, <code>SELECT</code>문이 검색하는 열의 개수는 2개인 것을 확인할 수 있다.</p>
<p><code>ORDER BY</code>를 활용하여 알아낸 열의 개수를 기반으로 <code>UNION</code>을 작성하고 database()함수와 version(), user()을 입력하여 DB이름, DBMS 정보, 사용자를 조회하는 공격을 수행할 수 있다.
<img src="https://velog.velcdn.com/images/got1_c/post/e1ea5551-3ff4-495d-b1ab-5797e8616af8/image.png" alt="">
<img src="https://velog.velcdn.com/images/got1_c/post/1d94b88a-a617-41df-a3b3-2c434da71c18/image.png" alt="">
null은 출력 안 되는 자리, database()는 출력될 자리로 선택
<img src="https://velog.velcdn.com/images/got1_c/post/07d0ae36-c766-4d6e-8b6b-e4db82b4253f/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Proxy]]></title>
            <link>https://velog.io/@got1_c/Proxy</link>
            <guid>https://velog.io/@got1_c/Proxy</guid>
            <pubDate>Tue, 06 May 2025 17:42:09 GMT</pubDate>
            <description><![CDATA[<h3 id="burp-suite-설치-및-프록시-설정">Burp Suite 설치 및 프록시 설정</h3>
<p><a href="https://portswigger.net/burp/releases/professional-community-2025-3-3">Burp Suite</a> 사이트에 접속하여 자신의 상황에 맞는 버전을 설치한다.
_주의!! _Burp Suite Community Edition 설치해야한다.<img src="https://velog.velcdn.com/images/got1_c/post/3d03cf7c-bc2c-4f56-9281-513ffcb1cb6e/image.png" alt="">
burp suite 설치후 next를 2번 누르면
<img src="https://velog.velcdn.com/images/got1_c/post/e2bdeab0-6718-4497-893e-c29028bc3189/image.png" alt="">
위 화면이 나온다.</p>
<p>상단의 proxy를 클리하고 intercept off를 클리하여 intercept on으로 바꿔준다.
<img src="https://velog.velcdn.com/images/got1_c/post/f03cb14e-ec47-4237-bf9f-f36a019ad4ed/image.png" alt=""></p>
<h4 id="burf-suited의-내장-브라우저를-열어-dvwa에-대한-요청과-응답-분석">Burf Suited의 내장 브라우저를 열어 dvwa에 대한 요청과 응답 분석</h4>
<p>request</p>
<pre><code>GET / HTTP/1.1
Host: localhost
sec-ch-ua: &quot;Chromium&quot;;v=&quot;135&quot;, &quot;Not-A.Brand&quot;;v=&quot;8&quot;
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: &quot;macOS&quot;
Accept-Language: ko-KR,ko;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,...
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
</code></pre><table>
<thead>
<tr>
<th>항목</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><strong>메서드</strong></td>
<td><code>GET</code> – 리소스를 요청</td>
</tr>
<tr>
<td><strong>요청 경로</strong></td>
<td><code>/</code> – 루트 페이지(DVWA 홈)</td>
</tr>
<tr>
<td><strong>Host</strong></td>
<td><code>localhost</code> – 로컬 서버에 요청</td>
</tr>
<tr>
<td><strong>User-Agent</strong></td>
<td>클라이언트 브라우저/OS 정보 (macOS + Chrome 기반)</td>
</tr>
<tr>
<td><strong>Accept</strong></td>
<td>서버에 HTML, 이미지 등을 요청</td>
</tr>
<tr>
<td><strong>Accept-Encoding</strong></td>
<td><code>gzip, deflate, br</code> – 응답 압축 방식 허용</td>
</tr>
<tr>
<td><strong>sec-ch-</strong>*</td>
<td>최신 브라우저에서 추가된 client hint 보안 정보</td>
</tr>
<tr>
<td><strong>Connection</strong></td>
<td>keep-alive – 연결 재사용 요청</td>
</tr>
<tr>
<td>response</td>
<td></td>
</tr>
<tr>
<td>```</td>
<td></td>
</tr>
<tr>
<td>HTTP/1.1 302 Found</td>
<td></td>
</tr>
<tr>
<td>Date: Tue, 06 May 2025 17:18:31 GMT</td>
<td></td>
</tr>
<tr>
<td>Server: Apache/2.4.25 (Debian)</td>
<td></td>
</tr>
<tr>
<td>Set-Cookie: PHPSESSID=st23e8tcef7c12nar3g8ov9nf7; path=/</td>
<td></td>
</tr>
<tr>
<td>Set-Cookie: security=low</td>
<td></td>
</tr>
<tr>
<td>Expires: Thu, 19 Nov 1981 08:52:00 GMT</td>
<td></td>
</tr>
<tr>
<td>Cache-Control: no-store, no-cache, must-revalidate</td>
<td></td>
</tr>
<tr>
<td>Pragma: no-cache</td>
<td></td>
</tr>
<tr>
<td>Location: login.php</td>
<td></td>
</tr>
<tr>
<td>Content-Length: 0</td>
<td></td>
</tr>
<tr>
<td>Keep-Alive: timeout=5, max=100</td>
<td></td>
</tr>
<tr>
<td>Connection: Keep-Alive</td>
<td></td>
</tr>
<tr>
<td>Content-Type: text/html; charset=UTF-8</td>
<td></td>
</tr>
<tr>
<td>```</td>
<td></td>
</tr>
<tr>
<td>항목</td>
<td>설명</td>
</tr>
<tr>
<td>------------------</td>
<td>--------------------------------------------------------</td>
</tr>
<tr>
<td><strong>상태 코드</strong></td>
<td><code>302 Found</code> – 클라이언트를 <code>login.php</code>로 리디렉션</td>
</tr>
<tr>
<td><strong>Set-Cookie</strong></td>
<td><code>PHPSESSID</code> – 세션 쿠키 설정<br><code>security=low</code> – DVWA 보안 레벨 설정</td>
</tr>
<tr>
<td><strong>Location</strong></td>
<td><code>login.php</code> – 리디렉션 대상</td>
</tr>
<tr>
<td><strong>Cache-Control</strong></td>
<td>캐시 방지: 보안 강화를 위한 설정</td>
</tr>
<tr>
<td><strong>Server</strong></td>
<td>Apache/2.4.25 (Debian) – 서버 정보</td>
</tr>
<tr>
<td><strong>Content-Length</strong></td>
<td>0 – 본문 없음 (리디렉션이므로 HTML 없음)</td>
</tr>
</tbody></table>
<p>활동을 하며 궁금한점</p>
<ul>
<li>웹 브라우저에 한번 검색하면 많은 요청과 응답이 오가는 이유</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTTP 프로토콜 기본 이해]]></title>
            <link>https://velog.io/@got1_c/HTTP-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C-%EA%B8%B0%EB%B3%B8-%EC%9D%B4%ED%95%B4</link>
            <guid>https://velog.io/@got1_c/HTTP-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C-%EA%B8%B0%EB%B3%B8-%EC%9D%B4%ED%95%B4</guid>
            <pubDate>Tue, 06 May 2025 15:32:27 GMT</pubDate>
            <description><![CDATA[<h3 id="http-요청응답-구조">http 요청/응답 구조</h3>
<h4 id="http란">http란?</h4>
<ul>
<li>HTML 문서를 교환하기 위해 만들어진 프로토콜이다.</li>
<li>http는 기본적으로 요청/응답 구조로 되어있다.
-&gt; 클라이언트가 http request를 서버에 보내면 서버는 http response를 보내는 구조</li>
</ul>
<blockquote>
<h4 id="http-request-구조">HTTP request 구조</h4>
<p>http request 구조는 공백을 제외하고 3가지 부분으로 나뉜다.</p>
</blockquote>
<ul>
<li>start line</li>
<li>headers</li>
<li>body
<img src="https://velog.velcdn.com/images/got1_c/post/fd37d630-9138-49b6-926c-67639679942c/image.png" alt=""><blockquote>
<blockquote>
<h4 id="start-line">start line</h4>
<ul>
<li>http method</li>
</ul>
</blockquote>
</blockquote>
<ul>
<li>요청의 의도를 담고 있는 GET, POST, PUT, DELETE등이 있다.<blockquote>
<blockquote>
<ul>
<li>request target</li>
</ul>
</blockquote>
</blockquote>
</li>
<li>http request가 전송되는 목표 주소<blockquote>
<blockquote>
<ul>
<li>http version</li>
</ul>
</blockquote>
</blockquote>
</li>
<li>version에 따라 request 메세지 구조나 데이터가 다를 수 있어      <blockquote>
<blockquote>
<h4 id="headers">headers</h4>
<p>해당 request에 대한 추가 정보를 담고 있는 부분 
헤더도 크게 3가지 부분으로 나뉜다. (general, request, entity)
Key : Value 형태로 구성</p>
</blockquote>
</blockquote>
</li>
</ul>
</li>
<li><code>Host</code> 요청하려는 서버 호스트 이름과 포트번호</li>
<li><code>User-agent</code> 클라이언트 프로그램 정보. 이 정보를 통해 서버는 클라이언트 프로그램(브라우저)에 맞는 최적의 데이터를 보내줄 수 있다.</li>
<li><code>Referer</code> 바로 직전에 머물렀던 웹 링크 주소 </li>
<li><code>Accept</code> 클라이언트가 처리 가능한 미디어 타입 종류 나열</li>
<li><code>If-Modified-Since</code>If-Modified-Since 여기에 쓰여진 시간 이후로 변경된 리소스 취득. 페이지가 수정되었으면 최신 페이지로 교체한다.</li>
<li><code>Authorization</code> 인증 토큰을 서버로 보낼 때 쓰이는 Header</li>
<li><code>Origin</code> 서버로 Post 요청을 보낼 때 요청이 어느 주소에 시작되었는지 나타내는 값. 이 값으로 요청을 보낸 주소와 받는 주소가 다르면 CORS(Cross-Origin Resource Sharing) 에러가 발생한다.</li>
<li><code>Cookie</code> 쿠키 값이 key-value로 표현된다.<blockquote>
<blockquote>
<h4 id="body">body</h4>
<p>http request가 전송하는 데이터를 담고 있는 부분
전송하는 데이터가 없다면 body 부분은 비어있다.</p>
</blockquote>
</blockquote>
</li>
</ul>
<blockquote>
<h4 id="http-response-구조">HTTP response 구조</h4>
<p>http response 구조도 공백 제외하고 3가지 부분으로 나뉜다.</p>
</blockquote>
<ul>
<li>status line</li>
<li>headers</li>
<li>body<blockquote>
<p><img src="https://velog.velcdn.com/images/got1_c/post/5bacc5e3-a432-4cec-bf13-92a07d18854c/image.png" alt=""></p>
<blockquote>
<h4 id="status-line">status line</h4>
<p>http response의 상태를 간략하게 나타내주는 부분</p>
</blockquote>
</blockquote>
</li>
<li>http version</li>
<li>status code: 응답 상태를 나타내는 코드</li>
<li>status text: 응답 상태를 간결하게 설명해주는 부분<pre><code>HTTP/1.1 200 OK
[HTTP version] [Status Code] [Status Text]
&gt;
&gt;&gt; #### headers - request의 headers와 동일
&gt;
&gt;&gt; #### body - request의 body와 일반적으로 동일
</code></pre></li>
</ul>
<h3 id="주요-메서드-특징-정리">주요 메서드 특징 정리</h3>
<h4 id="get-메서드">GET 메서드</h4>
<p>GET 메서드는 서버에서 특정 데이터를 가져와 클라이언트가 조회할 수 있도록 보여주는 용도의 메소드이다.</p>
<blockquote>
<h4 id="get-메서드-사용방법">GET 메서드 사용방법</h4>
<p>URL의 끝에 ?를 붙이고, 요청정보가(Key=value)의 해시맵 형태의 쌍을 ?뒤에 붙여서 서버로 전송한다. 요청정보가 여러개일 경우 &#39;&amp;&#39;로 구분한다.
ex)<code>www.url.com?name1=value1&amp;name2=value2</code></p>
</blockquote>
<blockquote>
<h4 id="get-메서드-특징">GET 메서드 특징</h4>
</blockquote>
<ul>
<li>URL에 요청 정보를 붙여서 전송하며, 요청 정보가 이어붙기 때문에 길이 제한이 있어 대용량의 데이터를 전송하기 어렵다.<ul>
<li>한번 요청시 전송 데이터의 양(url+파라미터)은 255자로 제한된다.</li>
</ul>
</li>
<li>URL에 정보들이 그대로 노출되기 때문에 POST 방식에 비해 보안에 취약하다.</li>
<li>http 패킷의 body는 비어있는 상태로 전송<ul>
<li>body의 데이터 타입을 표현하는 &#39;Content-Type&#39;필드도 http     request headers에 들어가지 않음</li>
</ul>
</li>
<li>GET 메서드는 캐싱을 사용할 수 있어 POST방식보다 빠르다</li>
</ul>
<h4 id="post-메서드">POST 메서드</h4>
<p>POST 메서드는 클라이언트가 서버의 값이나 상태를 바꾸기 위한 용도의 메소드이다.</p>
<blockquote>
<h4 id="post-메서드-사용-방법">POST 메서드 사용 방법</h4>
<p>요청 정보를 http 패킷의 body안에 숨겨 서버로 전송한다. request header의 Content-Type에 해당 데이터 타입이 표현되며, 전송하고자하는 데이터 타입을 적어주어야 한다.
ex)</p>
</blockquote>
<pre><code>POST /members HTTP/1.1 
Content-Type: application/json
{
    &quot;username&quot;: &quot;hello&quot;,
    &quot;age&quot;: 20 
}</code></pre><blockquote>
<h4 id="post-메서드-특징">POST 메서드 특징</h4>
</blockquote>
<ul>
<li>body 안에 요청정보를 숨겨 서버에 전송하기 때문에 GET 방식보다 보안상 안전하다.</li>
<li>body 안에 요청정보를 숨겨 서버에 전송하기 때문에 대용량의 데이터를 전송하기에 적합하다.</li>
<li>POST 요청은 GET 방식과는 다르게 캐시되지 않으며 브라우저 히스토리에 남지 않는다.</li>
<li>클라이언트에서 데이터를 인코딩하여 서버로 전송하고, 이를 받은 서버에서 해당 데이터를 디코딩한다.</li>
</ul>
<h3 id="http-상태코드">http 상태코드</h3>
<p>위에서 http response 구조에서 status line에 status code가 http의 상태 코드이다.</p>
<h4 id="http-상태코드는-왜-필요한가">http 상태코드는 왜 필요한가?</h4>
<p>클라이언트가 보낸 요청을 서버가 어떻게 처리했는지 한번에 알려주는 3자리 숫자이다. status line에 들어가며, 5개 범주로 나뉜다.</p>
<ul>
<li>1XX: Informational(정보 제공)
  -임시 응답으로 현재 클라이언트의 요청까지는 처리되었으니 계속 진행하라는 의미</li>
<li>2XX: Success<ul>
<li>클라이언트의 요청이 서버에서 성공적으로 처리되었다는 의미</li>
</ul>
</li>
<li>3XX: Redirection<ul>
<li>완전히 처리를 위해서 추가 동작이 필요한 경우이다. 주로 서버의 주소 또는 요청한 URL이 웹 문서가 이동되었으니 그 주소로 다시 시도하라는 의미이다.</li>
</ul>
</li>
<li>4XX: Client Error<ul>
<li>없는 페이지를 요청하는 등 클라이언트의 요청 메시지 내용이 잘못된 경우를 의미</li>
</ul>
</li>
<li>5XX: Server Error<ul>
<li>서버 사정으로 메세지 처리에 문제가 발생한 경우</li>
</ul>
</li>
</ul>
<h3 id="http의-stateless-보완-방법">HTTP의 stateless 보완 방법</h3>
<h4 id="stateless란">stateless란?</h4>
<p>http의 비연결성 특징으로 인해 서버는 클라이언트를 식별할 수 없는데, 이를 stateless라 한다.
--&gt; 매번 새로운 인증을 해야하는 번거로움이 발생</p>
<h4 id="상태를-기억하는-방법">상태를 기억하는 방법</h4>
<ol>
<li><p>쿠키
쿠키는 웹 브라우저가 보관하는 데이터이다. 
웹 서버는 쿠키를 생성하여 웹 브라우저에 정보를 전송 할 수 있다. 
쿠키는 key-value 형태로 웹 브라우저의 쿠키 저장소에 저장된다. 
서버로부터 쿠키를 전달 받은 웹 브라우저는 이후 웹 서버에 요청을 보낼 때 쿠키를 헤더에 실어서 함께 전송한다. 
이를 이용하여 웹 서버와 클라이언트는 필요한 값을 공유하고 상태를 유지할 수 있다.
<img src="https://velog.velcdn.com/images/got1_c/post/16f2086a-2e9c-412f-81ff-a072713d46f4/image.png" alt="">
클라이언트에 보관된 쿠키는 유효기간 설정이 가능하다. 유효기간을 설정하지 않을 시에는 브라우저 종료와 함께 종료된다.
하지만 쿠키만으로 로그인을 구현하는 것에 한계가 존재한다. 쿠키는 네트워크를 통해 전달되기 대문에 중간에 쿠키를 탈취할 수 있다는 취약점이 있다. 이를 보완하고자 세션을 사용한다.</p>
</li>
<li><p>세션
세션도 마찬가지로 클라이언트의 상태를 저장할 수 있다. 쿠키와 다른 점은 쿠키는 각 브라우저의 별도 쿠키 저장소에 저장되는 반면에 세션은 서버에 저장된다.</p>
<p>웹 브라우저는 각각 별도의 세션을 갖는다. 각 세션을 구분하기 위해 고유 ID를 할당하고, 웹 서버는 각 브라우저에 세션 ID를 전송한다. 우베 브라우저는 웹 서버에 연결 시 매번 세션 ID를 보내서 웹 서버가 어떤 세션을 사용할지 알 수 있도록 한다. 이때, 웹 서버와 웹 브라우저가 세션 ID를 주고받기 위해서 사용하는 것이 쿠키이다.<img src="https://velog.velcdn.com/images/got1_c/post/3c3a8d8b-90e6-4bfd-bd25-ebd640c04233/image.png" alt="">
세션은 브라우저가 아닌 서버에서 사용자 정보를 저장하는 구조이기에 쿠키보다는 안전하다.
하지만 세션 정보도 중간에 탈취 당할 수 있기에 보안에 완벽하다고 할 수 없다. 또한 세션을 사용하면 서버의 메모리를 차지하게 되고 동시 접속자가 많은 서비스일 경우 서버 과부화의 원인이 된다.</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[Docker에서 DVWA웹 서버 구축]]></title>
            <link>https://velog.io/@got1_c/Docker%EC%97%90%EC%84%9C-DVWA%EC%9B%B9-%EC%84%9C%EB%B2%84-%EA%B5%AC%EC%B6%95</link>
            <guid>https://velog.io/@got1_c/Docker%EC%97%90%EC%84%9C-DVWA%EC%9B%B9-%EC%84%9C%EB%B2%84-%EA%B5%AC%EC%B6%95</guid>
            <pubDate>Tue, 06 May 2025 08:57:26 GMT</pubDate>
            <description><![CDATA[<h3 id="container란">Container란?</h3>
<p>앱이 실행되는 작은 가상 컴퓨터(필요한 것만 갖고 있고, 빠르게 실행)</p>
<blockquote>
<h4 id="vm과-container의-차이점">VM과 Container의 차이점</h4>
<blockquote>
<p>VM - 독립적인 플랫폼을 하나씩 증가시킬 때마다 불필요한 OS를 만드는 작업이 요구된다.
Container - 하나의 Host OS위에서 마치 각각의 독립적인 프로그램처럼 관리되고 실행된다. 
 <img src="https://velog.velcdn.com/images/got1_c/post/d4b6783c-f7b5-49b4-9a25-36f2071a6fce/image.avif" alt=""></p>
</blockquote>
</blockquote>
<h3 id="docker-image란">Docker image란?</h3>
<p>도커 이미지란 컨테이너를 만들기 위한 &#39;설치 패키지 테플릿&#39; 이다.</p>
<ul>
<li>이미지 = 애플리케이션 + 실행환경 + 설정 파일 + OS 라이브러리 + 명령어들</li>
<li>이미지는 변하지 않는 구조로 저장</li>
<li>이미지로부터 컨테이너를 실행하면, 그때 실제로 돌아가는 프로그램이 만들어짐</li>
</ul>
<h3 id="docker란">Docker란?</h3>
<p>Docker는 애플리케이션을 컨테이너(Container)라는 단위로 패키징하고 실행할 수 있게 해주는 가상화 플랫폼이다. </p>
<p>특징: Docker는 클라이언트-서버 아키텍처이다. 도커 클라이언트와 도커 데몬이 RestApi를 사용하여 통신</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/got1_c/post/9556e806-6be1-4fbf-b35f-abacc16873e2/image.png" alt=""></p>
</blockquote>
<h4 id="1-docker-client">1. Docker Client</h4>
<p>클라이언트는 도커 데몬에게 RestApi 요청을 보내서 실제 작업을 요청한다.
ex) </p>
<h4 id="2-docker-daemon">2. Docker Daemon</h4>
<p>백그라운드에서 동작하며, 이미지 빌드, 컨테이너 실행, 네트워크 관리 등 실제 작업을 수행하는 핵심 엔진이다.</p>
<h4 id="3-docker-registry">3. Docker Registry</h4>
<p>도커 이미지를 업로드하고 다운로드할 수 있는 중앙 저장소</p>
<h3 id="왜-docker가-필요할까">왜 Docker가 필요할까?</h3>
<blockquote>
<h4 id="1-환경-일치성">1. 환경 일치성</h4>
<p>다양한 환경에서 동일한 실행 환경을 보장한다. 개발 환경과 운영 환경의 차이로 인한 문제를 방지하며, 응용 프로그램을 어디서든 실행 할 수 있다.</p>
</blockquote>
<h4 id="2-편리한-배포">2. 편리한 배포</h4>
<p>도커 컨테이너는 이미지로 패키징되어 배포되므로, 애플리케이션 배포가 간단해진다. 이미지를 공유하거나 배포할 때 용이하며, 빠른 확장이 가능하다.</p>
<h4 id="3-격리된-환경">3. 격리된 환경</h4>
<p>도커는 각 컨테이너를 격리된 환경으로 실행하므로, 하나의 컨테이너에서 발생한 문제가 다른 컨테이너에 영향을 주지 않는다.</p>
<h4 id="4-자원-표율성">4. 자원 표율성</h4>
<p>가상 머신과 비교해 더 가볍고 빠르며, 호스트 시스템의 리소스를 효율적으로 활용할 수 있다.</p>
<h4 id="5-스케일링">5. 스케일링</h4>
<p>컨테이너 기반 아키텍처는 쉬운 스케일링이 가능하여 요구에 따라 응용 프로그램을 확장할 수 있다.</p>
<h3 id="docker-desktop-설치">Docker Desktop 설치</h3>
<p><a href="https://www.docker.com">Docker</a>
<img src="https://velog.velcdn.com/images/got1_c/post/1f6c67f1-ee16-4b51-9e30-3ab25079ba97/image.png" alt="">
홈페이지에 접속하여 자신에게 알맞는 버전을 설치하면 된다.</p>
<h3 id="dvwa-이미지-다운로드-및-컨테이너-실행mac-기준">DVWA 이미지 다운로드 및 컨테이너 실행(Mac 기준)</h3>
<ol>
<li><p>terminal을 실행시켜<code>docker pull vulnerabels/web-dvwa</code>를 입력한다.
<img src="https://velog.velcdn.com/images/got1_c/post/1b1bba05-60bc-43de-b7e7-7a1f5cbdc628/image.png" alt="">위 사진과 같이 docker image가 생성된 것을 확인 할 수 있다.</p>
</li>
<li><p>terminal에 <code>docker run -d -p 80:80 vulnerables/web-dvwa</code>를 입력한다.<img src="https://velog.velcdn.com/images/got1_c/post/d6adef85-6b05-4de7-9678-5b749d4d895a/image.png" alt="">
위 사진과 같이 컨테이너를 실행시킨 것을 확인 할 수 있다.(localhost 80포트에서 웹 서버 실행)</p>
</li>
<li><p>localhost:80에 접속
<img src="https://velog.velcdn.com/images/got1_c/post/de5677a3-9362-4f3d-b78d-70b85a200c7b/image.png" alt="">
사진 속 네모 안의 부분을 클릭하여 접속한다.
<img src="https://velog.velcdn.com/images/got1_c/post/f875f171-1420-4cf9-921e-ee7c61c64aaa/image.png" alt=""></p>
</li>
</ol>
<p><code>Username: admin    Password: password</code>를 입력한다.</p>
<ol start="4">
<li>로그인 후 아래에서 Create / Reset Database 버튼 클릭</li>
<li>다시 로그인 창으로 돌아가지면 <code>Username: admin Password: password</code>를 다시 입력하면 웹 해킹할 가상환경 구축이 완료된다.</li>
</ol>
<h3 id="dvwa-설정-초기화-및-보안-레벨-설정">DVWA 설정 초기화 및 보안 레벨 설정</h3>
<ul>
<li>DVWA 상단 메뉴에서 Setup/Reset DB에 들어간다.</li>
<li>아래의 Create/Reset Database를 클릭 --&gt; 내부 DB 및 설정 초기화</li>
</ul>
<h4 id="보안-레벨-설정-방법">보안 레벨 설정 방법</h4>
<ol>
<li>메뉴에서 DVWA Security에 들어간다.</li>
<li>보안수준을 선택한다.</li>
<li>선택 후 Submit을 클릭한다.</li>
</ol>
]]></description>
        </item>
    </channel>
</rss>