1. SQL injection이란

2. SQL injection의 종류

3. 대응방법

1. SQL injection이란

출처:안랩

SQL injection은 Database의 취약점을 이용하여 정상적이지 않은 동작을 하도록 하는 SQL문을 입력하여 공격자가 원하는 작업을 수행하거나 정보를 유출하게되는 공격입니다.

 

SQL injection은 최근까지도 많이 일어나고 있는 공격기법 중 하나입니다.

 

2. SQL injection의 종류

2.1 Normal SQL injection

출처:안랩

Normal SQL injection은 논리적 에러를 이용한 SQL injection으로 위의 로그인 예시에서 ' OR 1=1 --와 같이 값을 입력해주게 되면 OR 1=1에 의해 항상 참, --에 의해 뒷 부분은 주석처리가 되며 로그인에 성공하게 됩니다.

 

2.2 Error based SQL injection

https://www.bugbountyclub.com/pentestgym/view/53

Error based SQL injection은 주로 데이터베이스에 대한 정보를 획득하기 위해 사용됩니다. SQL의 잘못된 문법이나 자료형 불일치 등에 의해 데이터베이스가 알려주는 데이터베이스 오류 메시지에 의존하여 수행되는 공격 기법입니다.

 

2.3 Union based SQL injection

출처 : 안랩

SQL의 Union이라는 구문을 사용하는 공격인 Union based SQL injection은 Union을 이용하여 원래의 요청에 하나의 추가 쿼리를 삽입하는 공격입니다.

이 때 필요한 전제조건으로 Union하는 두 쿼리의 컬럼의 개수와 데이터 형식이 같아야합니다.

 

위의 사진의 경우 게시글을 찾는 쿼리문에 Union을 넣어 Users 테이블의 id, 패스워드를 읽어오는 공격입니다.

 

2.4 Blind SQL injection - Boolean based SQL

출처 : 안랩

 

위의 사진은 MySQL 에서 테이블 명을 조회하는 구문으로 limit 키워드를 통해 하나의 테이블만 조회하고, SUBSTR 함수로 첫 글자만, 그리고 마지막으로 ASCII 를 통해서 ascii 값으로 변환해줍니다

만약에 조회되는 테이블 명이 Users 라면 ‘U’ 자가 ascii 값으로 조회가 될 것이고, 뒤의 100 이라는 숫자 값과 비교를 하게 됩니다.

U의 ascii 값은 125이므로 뒤의 100의 값을 변경해가면 125일때 거짓이 나오므로 첫 글자가 U라는것을 알 수 있습니다.

이를 자동화하여 테이블명을 알아내는 방법입니다.

 

2.5 Blind SQL injection - Time based SQL

출처 : 안랩

위의 그림은 Time based SQL Injection을 사용하여 현재 사용하고 있는 데이터베이스의 길이를 알아내는 방법입니다. 로그인 폼에 주입이 되었으며 임의로 abc123 이라는 계정을 생성해 두었습니다.

악의적인 사용자가 abc123’ OR (LENGTH(DATABASE())=1 AND SLEEP(2)) -- 이라는 구문을 주입하였습니다. 여기서 LENGTH 함수는 문자열의 길이를 반환하고, DATABASE 함수는 데이터베이스의 이름을 반환합니다.

주입된 구문에서, LENGTH(DATABASE()) = 1 가 참이면 SLEEP(2) 가 동작하고, 거짓이면 동작하지 않습니다.

 

이를 통해서 숫자 1 부분을 조작하여 데이터베이스의 길이를 알아 낼 수 있습니다. 만약에 SLEEP 이라는 단어가 치환처리 되어있다면, 또 다른 방법으로 BENCHMARK  WAIT 함수를 사용 할 수 있습니다.

 

3. 대응방법

입력 값에 대한 검증

사용자의 입력이 올바른 값인지 검증합니다. 사용자가 공격할 가능성이 있는 키워드들을 검증하고 차단합니다.

 

 

Prepared Statement 구문사용

 Prepared Statement 구문을 사용하게 되면, 사용자의 입력 값이 데이터베이스의 파라미터로 들어가기 전에DBMS가 미리 컴파일 하여 실행하지 않고 대기합니다. 그 후 사용자의 입력 값을 문자열로 인식하게 하여 공격쿼리가 들어간다고 하더라도, 사용자의 입력은 이미 의미 없는 단순 문자열 이기 때문에 전체 쿼리문도 공격자의 의도대로 작동하지 않습니다.

 

 

Error Message 노출 금지

공격자가 SQL Injection을 수행하기 위해서는 데이터베이스의 정보(테이블명, 컬럼명 등)가 필요합니다. 데이터베이스 에러 발생 시 따로 처리를 해주지 않았다면, 에러가 발생한 쿼리문과 함께 에러에 관한 내용을 반환해 줍니다. 여기서 테이블명 및 컬럼명 그리고 쿼리문이 노출이 될 수 있기 때문에, 데이터 베이스에 대한 오류발생 시 사용자에게 보여줄 수 있는 페이지를 제작 혹은 메시지박스를 띄우도록 하여야 합니다.

 

웹 방화벽 사용

웹 공격 방어에 특화되어있는 웹 방화벽을 사용하는 것도 하나의 방법입니다. 웹 방화벽은 소프트웨어 형, 하드웨어 형, 프록시 형 이렇게 세가지 종류로 나눌 수 있는데 소프트웨어 형은 서버 내에 직접 설치하는 방법이고, 하드웨어 형은 네트워크 상에서 서버 앞 단에 직접 하드웨어 장비로 구성하는 것이며 마지막으로 프록시 형은 DNS 서버 주소를 웹 방화벽으로 바꾸고 서버로 가는 트래픽이 웹 방화벽을 먼저 거치도록 하는 방법입니다.

'Security > Webhacking' 카테고리의 다른 글

CSRF 공격  (0) 2024.05.12
XSS문제 실습  (0) 2024.05.10
Cookie & Session  (0) 2024.05.08
  1. CSRF란
  2. CSRF의 원리
  3. CSRF 방어 방법

1. CSRF란

CSRF는 공격자가 만든 악성 스크립트가 포함된 URL을 사용자가 실행하게 되면, 사용자의 세션을 이용하여 사용자가 의도하지 않은 작업을 수행하는 공격입니다.

대표적으로 패스워드 변경, 송금 등이 있습니다.

 

2. CSRF의 원리

CSRF 공격이 성립하기 위해 충족되야하는 조건이 있습니다.

1. 사용자는 보안이 취약한 서버로부터 이미 로그인되어 있는 상태여야 합니다.
2. 쿠키 기반의 서버 세션 정보를 획득할 수 있어야 합니다.
3. 공격자는 서버를 공격하기 위한 요청 방법에 대해 미리 파악하고 있어야 합니다.

 

위 조건이 만족되었을 때  CSRF공격이 가능하게 됩니다.

 

CSRF공격의 시나리오는 다음과 같습니다. 

1. 사용자가 보안이 취약한 서버에 로그인되어있다.

2. 공격자의 악성 스크립트가 포함된 URL을 사용자가 접속하게된다.

3. 악성 스크립트에 담겨있는 내용이 사용자 세션 ID를 이용해 실행되게된다.

4. 서버는 해당 내용을 사용자가 요청한것으로 인식하고 실행하게 된다.

3. CSRF 방어방법

1. Referrer 검증

Request header에 포함된 Referer는 현재 요청된 페이지의 링크 이전의 웹페이지 주소를 포함합니다.

Referrer를 검증해서 해당 요청이 요청될 수 있는 위치인지 검사를 하면 CSRF를 막을 수 있습니다.

 

2. CSRF 토큰 검증

로그인을 할 때 CSRF 토큰을 생성하여 세션에 저장해 둡니다.

CSRF 토큰을 페이지 요청태그의 hidden값에 넣어줍니다.

Ex) <input type="hidden" name="_csrf" value="${CSRF_TOKEN}" />

이후 요청을 할 때마다 CSRF 토큰을 같이 보내어, 서버에서 토큰을 검증합니다.

'Security > Webhacking' 카테고리의 다른 글

SQL injection 공격  (0) 2024.05.12
XSS문제 실습  (0) 2024.05.10
Cookie & Session  (0) 2024.05.08

https://xss-game.appspot.com/

 

XSS game

Welcome, recruit! Cross-site scripting (XSS) bugs are one of the most common and dangerous types of vulnerabilities in Web applications. These nasty buggers can allow your enemies to steal or modify user data in your apps and you must learn to dispatch the

xss-game.appspot.com

위 사이트에서 진행하였다. 문제는 총 6문제이다.

1번 문제

 

간단하게 <script>alert()</script>를 넣어주면 풀리는 문제

 

2번 문제

 

<script>가 통하지 않아 <img>의 onerror를 이용하여 alert()를 작동시켰다.

 

3번 문제

 

코드를 보면 <img src='/static/level3/cloud{num}.jpg/>로 값을 넣어주는것을 확인할 수 있다.

문제 2번과 마찬가지로 onerror를 쓰면 되는것으로 보이지만 사용자가 입력을 하는 부분이 없다.

 

 

이럴때는 URL을 이용하여 원하는 값을 입력해주면 된다.

frame#뒤에 없는 번호인 5번을 넣어 error를 발생시키고, onerror를 통해 alert()함수를 실행시켜보았다.

 

4번 문제

 

 

위의 input상자에 넣은 값을 <img>의 onload="startTimer('{{timer}}');"에 넣어주는 것을 볼 수 있다.

timer의 따옴표를 탈출하고 alert()를 실행시키기 위해서 -1');를 통해 startTimer('-1');를 만들어주자

이어서 뒤에 alert(' 를 붙여줌으로써 alert('');를 만들어준다

다음과 같이 입력하면 된다.

 

전체 입력 = -1');alert('

입력 시 실행되는 함수 = startTimer('-1');alert('');

 

5번 문제

signup.html

이번 문제에는 3가지 html페이지가 있지만 여기서는 signup.html만 보면 된다.

level.py

level.py의 코드를 보면 next값을 get요청이 들어왔을 때 들어오는 값으로 설정해주고 있는 것을 알 수 있다.

 

signup.html

signup.html의 코드를 보면 <a href="{{next}}">로 되어있는 부분이 있는데, <a>태그의 href에는 주소 뿐만이 아니라 자바스크립트 코드가 들어가서 실행될 수도 있다.

next의 값에 javascript:alert();를 입력하면 되지 않을까?

 

 

URL의 next값에 javascript:alert()를 넣어준 후 next버튼을 눌러주면 alert가 실행되면서 성공하게 된다!

 

6번문제

 

/* This is a completely awesome invisible gadget */

gadget.js

<!doctype html>
<html>
  <head>
    <!-- Internal game scripts/styles, mostly boring stuff -->
    <script src="/static/game-frame.js"></script>
    <link rel="stylesheet" href="/static/game-frame-styles.css" />
 
    <script>
    function setInnerText(element, value) {
      if (element.innerText) {
        element.innerText = value;
      } else {
        element.textContent = value;
      }
    }
 
    function includeGadget(url) {
      var scriptEl = document.createElement('script');
 
      // This will totally prevent us from loading evil URLs!
      if (url.match(/^https?:\/\//)) {
        setInnerText(document.getElementById("log"),
          "Sorry, cannot load a URL containing \"http\".");
        return;
      }
 
      // Load this awesome gadget
      scriptEl.src = url;
 
      // Show log messages
      scriptEl.onload = function() { 
        setInnerText(document.getElementById("log"),  
          "Loaded gadget from " + url);
      }
      scriptEl.onerror = function() { 
        setInnerText(document.getElementById("log"),  
          "Couldn't load gadget from " + url);
      }
 
      document.head.appendChild(scriptEl);
    }
 
    // Take the value after # and use it as the gadget filename.
    function getGadgetName() { 
      return window.location.hash.substr(1) || "/static/gadget.js";
    }
 
    includeGadget(getGadgetName());
 
    // Extra code so that we can communicate with the parent page
    window.addEventListener("message", function(event){
      if (event.source == parent) {
        includeGadget(getGadgetName());
      }
    }, false);
 
    </script>
  </head>
 
  <body id="level6">
    <img src="/static/logos/level6.png">
    <img id="cube" src="/static/level6_cube.png">
    <div id="log">Loading gadget...</div>
  </body>
</html>

index.html

class MainPage(webapp.RequestHandler):
  def render_template(self, filename, context={}):
    path = os.path.join(os.path.dirname(__file__), filename)
    self.response.out.write(template.render(path, context))
 
  def get(self):
    self.render_template('index.html')
 
application = webapp.WSGIApplication([ ('.*', MainPage), ], debug=False)

level.py

 

문제 화면

6번 문제는 URL의 frame#뒤에 넣은 값을 읽어, 해당 주소를 <script> 의 src로 넣고 document.head.appendChild()로 head영역에 더해주게 된다.

즉 src의 값을 alert()를 실행하는 주소의 값으로 넣어주면 된다.

 

내 웹서버에 js파일을 업로드하여 실행해주는 방법도 있지만, 이번엔 Data URL schema방식을 사용했다.

 

Data URL schema문법

data:[<mediatype>][;base64],<data>

 

 

data:text/javascript,alert()를 입력해주어 성공!

'Security > Webhacking' 카테고리의 다른 글

SQL injection 공격  (0) 2024.05.12
CSRF 공격  (0) 2024.05.12
Cookie & Session  (0) 2024.05.08

쿠키와 세션은 무엇인가

쿠키와 세션은 웹 서비스에서 사용자의 상태를 저장하여 사용자가 웹사이트를 더욱 편하게 사용하도록 만들기 위해 만들어진 개념입니다.

왜 이런 개념이 만들어졌을까요?

HTTP 프로토콜의 특징


https://raonctf.com/essential/study/web/cookie_connection

웹 서비스에서 사용하는 HTTP프로토콜은 Connectionless와 Stateless라는 특성을 가집니다.

 

Connectionless
클라이언트가 서버에 요청을 하고 응답을 받으면 바로 연결을 끊어 연결을 유지 하지 않는다.

이를 통해 서버의 자원을 효율적으로 관리하고, 수 많은 클라이언트의 요청에도 대응할 수 있게 한다.
Stateless
Stateless는 서버가 클라이언트의 이전 상태를 보존하지 않는다는 의미이다

쿠키와 세션을 사용하지 않는다면 페이지를 이동할 때마다 로그인을 해주어야 하게 된다.

 

위와 같은 문제점을 보완해주기 위해 생겨난 개념이 쿠키(Cookie)와 세션(Session)입니다.

 

쿠키(Cookie)


https://raonctf.com/essential/study/web/cookie_connection

HTTP 쿠키(HTTP cookie)란 하이퍼 텍스트의 기록서(HTTP)의 일종으로서 인터넷 사용자가 어떠한 웹사이트를 방문할 경우 사용자의 웹 브라우저를 통해 인터넷 사용자의 컴퓨터나 다른 기기에 설치되는 작은 기록 정보 파일을 일컫는다. -wikipedia-

 

쉽게 말해 우리가 웹 사이트를 이용할 때 서버에서 우리 컴퓨터에 있는 웹 브라우저에게 쿠키라는 파일을 하나 보내줍니다. 그 쿠키에는 사용자가 웹 사이트를 편하게 이용할 수 있는 여러정보가 담겨있습니다.

 

쿠키의 구성요소

  • 쿠키의 이름 (name)
  • 쿠키의 값 (value)
  • 쿠키의 만료시간 (Expires)
  • 쿠키를 전송할 도메인 이름 (Domain)
  • 쿠키를 전송할 경로 (Path)
  • 보안 연결 여부 (Secure)
  • HttpOnly 여부 (HttpOnly)

쿠키의 특징

  • 클라이언트는 총 300개의 쿠키를 저장할 수 있다
  • 하나의 도메인 당 20개의 쿠키를 가질 수 있다
  • 하나의 쿠키는 4KB까지 저장 가능하다

쿠키의 동작방식

1. 사용자가 쿠키 없이 request 요청

2. 서버가 쿠키를 생성하여 response와 쿠키를 함께 응답

3. 사용자가 서버에게서 받은 쿠키를 저장하고 다음 request부터 쿠키를 넣어 요청

 

쿠키의 사용 예

  • 방문 사이트에서 로그인 시, "아이디와 비밀번호를 저장하시겠습니까?"
  • 쇼핑몰의 장바구니 기능
  • 자동로그인, 팝업에서 "오늘 더 이상 이 창을 보지 않음" 체크, 쇼핑몰의 장바구니

 

션(Session)


세션이란 일정시간동안 사용자로부터 들어오는 요구를 하나의 상태로 유지하는 기술이다.

 

예를 들어, 로그인을 했을 때 다른 페이지로 이동해도 로그인 상태가 계속 유지되면서 이용할 수 있는것은 세션이 있기 때문입니다.

 

세션의 특징

  • 세션은 서버의 메모리 혹은 DB등에 저장된다.
  • 서버에서는 클라이언트를 구분하기 위해 세션 ID를 부여하며 웹 브라우저가 서버에 접속해서 브라우저를 종료할 때까지 인증상태를 유지한다.
  • 접속 시간에 제한을 두어 일정 시간 응답이 없다면 정보가 유지되지 않게 설정 가능.
  • 사용자에 대한 정보를 서버에 두기 때문에 쿠키보다 보안에 좋지만, 사용자가 많아질수록 서버 메모리를 많이 차지하게 됨
  • 사용자가 Request를 보내면, 해당 서버의 엔진이 클라이언트에게 세션 ID를 부여함.

세션의 동작방식

1. 사용자가 서버에 접속 시 세션 ID를 발급받음

2. 사용자가 request 요청을 보낼 때 쿠키에 세션 ID를 넣어서 보내게 됨

3. 서버는 세션 ID를 통해 세션 ID에 맞는 클라이언트의 정보를 가져옴

4. 가져온 클라이언트 정보를 통해 사용자에게 응답

 

세션의 사용 예

  • 로그인 상태유지

쿠키와 세션의 차이


  쿠키 세션
저장 위치 클라이언트 웹 서버
저장 형식 text Object
만료 시점 쿠키 저장시 설정 브라우저 종료시 삭제
사용하는 자원 클라이언트 리소스 웹 서버 리소스
용량 제한 총 300개
하나의 도메인 당 20개
하나의 쿠키 당 4KB
서버가 설정하게 됨
속도 빠름 느림
보안 안좋음 좋음

 

쿠키 취약점

쿠키와 관련하여 발생할 수 있는 취약점에는 다음과 같은 것들이 있습니다.

 

Session Hijacking

 - XSS나 Sniffing등의 공격을 통해 쿠키를 탈취당하게 되면 공격자가 피해자의 세션 ID를 통해 바로 로그인을 할 수 있게 됩니다.

 

CSRF

 - CSRF공격을 통해 사용자의 세션 ID를 이용하여 공격자가 원하는 작업을 수행할 수 있습니다.

 

 

'Security > Webhacking' 카테고리의 다른 글

SQL injection 공격  (0) 2024.05.12
CSRF 공격  (0) 2024.05.12
XSS문제 실습  (0) 2024.05.10
PE 포맷(Portable Executable)은 윈도우 운영 체제에서 사용되는 실행 파일, DLL, object 코드, FON 폰트 파일등을 위한 파일 형식이다. PE 포맷은 윈도우 로더가 실행 가능한 코드를 관리하는데 필요한 정보를 캡슐화한 데이터 구조체이다. -위키백과-

 

다시 말하자면 PE파일이란 윈도우 운영체제에서 우리가 만든 파일이 다른 윈도우 운영체제의 PC로 옮겨(Portable)져도 실행(Executable)되도록 만들어 놓은 파일을 말합니다.

 

파일 확장자의 종류로는 다음이 있습니다.

.acm, .ax, .cpl, .dll, .drv, .efi, .exe,  .mui, .ocx, .scr, .sys, .tsp

 

PE 파일의 구조


PE파일의 구조-출처:https://rednooby.tistory.com/33

  • DOS header 부터 Section header 까지를 PE Header, 그 밑의 Section 들을 합쳐서 PE Body라고 합니다.

  • 파일에서는 offset으로, 메모리에서는 VA(Virtual Address) 로 위치를 표현합니다.

  • 파일이 메모리에 로딩되면 모양이 달라집니다(Section의 크기, 위치 등)

  • Section header에 각 Section에 대한 파일/메모리에서의 크기, 위치, 속성 등이 정의되어 있습니다.

  • PE header의 끝부분과 각 Section의 끝부분에 있는 NULL padding이라는 영역이 있습니다.
    컴퓨터에서 파일, 메모리, 네트워크 패킷 등을 처리할 때 효율을 높이기 위해 최소기본단위를 사용하는데, PE파일에서도 이러한 개념이 적용된 것입니다.

  • 파일/메모리에서 섹션의 시작위치는 각 파일/메모리의 최소기본단위의 배수에 해당하는 위치여야하고, 빈 공간은 NULL로 채웁니다.

VA와 RVA


VA(Virtual Address) : 가상메모리상의 절대주소

RVA(Relative Virtual Address) : 기준위치(Imagebase)에서부터의 상대주소

 

RVA와 VA의 관계식은 다음과 같습니다.

RVA + Imagebase = VA

 

왜 RVA를 써야할까?

PE파일(주로 DLL)이 프로세스 가상 메모리의 특정 위치에 로딩되는 순간

이미 그 위치에 다른 PE 파일(DLL)이 로딩되어있을 수 있습니다.

 

그럴때 재배치(Relocation) 과정을 통해서 비어 있는 다른 위치에 로딩되어야 하는데,

만약 PE header 정보들이 VA로 되어있다면 정상적인 엑세스가 이루어지지 않을것입니다.

 

PE Header


PE파일의 각 부분에 대한 설명은 너무나도 길어지기에 PE에 대해 정말 잘 정리해주신 분의 블로그를 발견하여 링크올려드립니다.

아래 그림과 함께 읽어보시면 더욱 이해가 잘 될거라고 생각합니다.

DOS Header & DOS Stub

https://reversecore.com/19

 

NT header(IMAGE_FILE_HEADER & IMAGE_OPTIONAL_HEADER32)

아래 그림중 signature~NumberOfRvaAndSizes 부분

https://reversecore.com/20

https://reversecore.com/21

 

Section Header

아래 그림중 Section Table 영역

https://reversecore.com/22

 

IAT(Import Address Table) & EAT(Export Address Table)

https://reversecore.com/23

https://reversecore.com/24

PE Header 32bit Structure-출처:https://commons.wikimedia.org/wiki/File:Portable_Executable_32_bit_Structure.png

 

이번엔 Stack의 구조와 Stack Frame Pointer에 대해 알아보겠습니다.

 

Stack이란?

Stack이란 RAM내의 영역 중 하나로

프로그램에서 함수가 호출될 때 필요한 지역변수와 매개변수가 저장되는 영역입니다.

또 Stack은 후입선출(Last In First Out)구조이기 때문에 데이터 저장시 높은 주소에서 낮은 주소방향으로 데이터를 저장하게 됩니다.


Stack의 구조

Stack은 기본적으로 저장공간이기 때문에 데이터를 담을 수 있는 상자가 쭉 늘어서 있는 창고라고 생각하면 됩니다.

 

그럼 이 Stack에 우리의 컴퓨터는 어떤 방식으로 데이터를 저장하는걸까요?

이해를 위해서 예시를 하나 보도록 하겠습니다.

main(){

  int A = sum(1,2)

  return A

}

sum(x,y){

   return x+y

}

위와 같은 단순한 코드하나를 만들어 봤습니다. 

 

우리가 이 코드로 만든 프로그램을 돌릴때 Stack에선 데이터를 어떻게 처리하는지 보겠습니다.


Stack의 구조

함수가 호출될 때 Stack엔 매개변수, 반환 주소값, 지역변수 이렇게 3가지의 데이터가 들어갑니다.

 

main()함수 실행시

  1. main()함수엔 매개변수가 없어 반환 주소값부터 들어가게 됩니다.
  2. 가장 아래(높은)주소부터 RET(반환 주소값), RBP(main()함수 스택 프레임의 시작점), 변수 c, 버퍼(지역변수) 이렇게 채워 가는걸 볼 수 있습니다.

 

위와 같은 함수의 호출 정보를 스택 프레임(Stack Frame) 이라고 합니다.

 

sum()함수 실행시

  1. sum()함수는 main()함수 안에서 호출되기 때문에
  2. sum()함수를 호출하게 되면 main()함수의 스택 프레임위에 다시 sum()함수의 스택 프레임을 쌓게 됩니다.
  3. sum()함수엔 매개변수가 있어 매개변수 x, y를 먼저 쌓아주는 모습을 볼 수 있습니다.

 


스택 프레임 포인터(Stack Frame Pointer)

이제 Stack이 어떤식으로 데이터를 저장하는지 알게됐습니다.

그럼 저걸 어떻게 사용해서 프로그램을 돌리는 걸까요?

 

CPU내에는 레지스터라고 하는 아주 작은 값만을 담을 수 있는(하지만 처리속도가 매우 빠른)  메모리가 있습니다.

CPU는 이 레지스터와 RAM에 저장되어있는 값들을 이용하여 프로그램을 돌립니다.

Stack의 데이터들을 이용할때도 이 레지스터들을 이용하게됩니다.

 

레지스터는 여러가지 종류가 있지만 Stack에 있는 데이터를 다룰 때 사용하는 레지스터는 SP, FP 레지스터입니다.

 

SP(Stack Pointer) 레지스터 : 다음 데이터가 저장될 스택의 주소를 담고 있는 레지스터

 

FP(Frame Pointer) 레지스터 : SP레지스터가 돌아갈 주소(함수 호출 전)를 담고있는 레지스터

 

SP레지스터는 함수 호출 중 데이터가 저장될 스택의 주소를 가리킵니다. CPU가 SP가 가리키고 있는 스택에 값을 넣고 나면 SP레지스터는 그 위의 주소를 가리키게 변경됩니다.

 

FP레지스터는 함수 호출 이전에 SP레지스터가 가리키고 있던 주소를 담고있게됩니다.

 

함수 호출이 끝난 후 SP레지스터는 FP레지스터에 쓰여져있는 주소를 참고하여 함수를 호출하기 이전의 주소로 돌아가게됩니다.

 

하지만 함수 호출을 여러번 하게 될 경우 FP레지스터의 값이 계속 바뀌기 때문에 스택에 FP레지스터의 값을 저장해 놓음으로써 스택 프레임간의 경계정보를 저장합니다.

'Security > Pwnable' 카테고리의 다른 글

메모리 구조  (1) 2023.03.29

메모리 구조에 대해 이야기하기 전 프로그램의 실행순서를 알아보겠습니다.

프로그램이 실행되는 순서(Free space는&nbsp; heap 또는 stack영역에 데이터가 할당되면 사용되는 곳입니다.)

 

 

메모리는 크게 4가지 영역으로 나눌 수 있습니다.

  • Code/Text 영역
  • Data 영역
  • Heap 영역
  • Stack 영역

Code/Text 영역

프로그램의 소스코드가 저장되는 영역, 기계어 형태로 저장

 

Code영역 또는 Text영역이라고도 부릅니다.

 

CPU는 Code영역에 저장된 명령어들을 하나씩 가져가 실행합니다.

 

Code영역은 프로그램이 시작하고 종료될 때까지 메모리에 계속 남아있습니다.

Data 영역

전역변수와 static변수가 할당되는 영역

 

main함수 전에 선언되어 프로그램 시작과 동시에 할당되고 프로그램이 종료하면 메모리에서 소멸됩니다.

 

Data 영역은 Rodata, BSS, Data 3가지 영역으로 나뉩니다.

 

Rodata(Read Only data)영역은 읽기 전용 data들이 들어갑니다.

주로 상수, 상수형 문자열 등의 값이 들어갑니다.

읽기 전용 영역이기 때문에 쓰는것은 불가능합니다.

 

Data영역과 BSS영역

data영역과 bss영역은 둘다 전역 변수를 저장하는건 동일합니다.

정적변수(static)도 이 영역에 저장됩니다.

data영역과 bss영역의 차이는 값이 초기화 되어있는가 되어있지 않은가의 차이입니다.

data영역은 초기화 된 변수, bss영역은 초기화 하기 전의 변수를 저장합니다.

이 영역들은 읽기 쓰기 모두 가능합니다.

 

Heap 영역

동적으로 선언된 변수가 할당되는 영역

 

메모리 위쪽 주소부터 할당되는 선입선출(FIFO) 구조

 

런타임 시 크기가 결정

 

프로그래머가 원하는 시점에 변수를 할당하고 소멸 가능하도록 하는 영역

 

사용하고 난 후 메모리 해제를 해주지 않으면 memory leak이 발생하기 때문에 반드시 메모리 해제를 해줘야 합니다.

 

 

Stack 영역

함수 호출 시 생성되는 지역변수와 매개변수가 저장되는 영역

 

메모리 아래쪽 주소부터 할당되는 후입선출(LIFO) 구조

 

컴파일 타임에 크기가 결정

 

함수의 호출과 함께 할당되며 함수의 호출이 완료(종료)되면 소멸합니다.

 

stack영역에 저장되는 함수의 호출 정보를 스택 프레임(Stack Frame)이라고 합니다.

 

오버 플로우(Overflow)

오버플로우란, 한정된 메모리 공간이 부족하여 메모리 내의 데이터가 넘쳐 흐르는 현상입니다.

오버플로우

Heap Overflow

Heap이 위에서부터 주소를 채워 내려오다가 Stack영역을 침범하는 경우

Stack Overflow

Stack이 아래에서부터 주소를 채워 올라가다가 Heap영역을 침범하는 경우

'Security > Pwnable' 카테고리의 다른 글

Stack의 구조와 Stack Frame Pointer  (0) 2023.04.01

+ Recent posts