▶ SSTI(Server-Side Template Injection)

 

- 공격자가 서버에서 임의의 코드를 실행할 수 있는 사용자 입력으로 템플릿 지시문을 주입할 때 발생하는 취약점

- 종류 : Ruby, Java, Twig, Smarty, Freemarker, Jade/Codepen, Velocity, Mako, Jinja2

 

- 정적 웹페이지 : 간단한 html을 사용해 페이지를 만들고 서버에 저장해 불러온 그대로의 모습을 보여주는 방식

- 동적 웹페이지 : 사용자가 작성하거나 선택한 이벤트에 따라 웹페이지의 구성과 내용이 달라지는 방식

- 템플릿 언어 : 언어의 변수 및 문법을 html 안에서 쓸 수 있도록 제공해주는 언어로 템플릿을 이용하면

                       구성하기 간단하면서 동적인 페이지를 만들 수 있음

 

- RCE(Remote Code Execution)가 템플릿에 들어가면 악의적인 행동 발생 가능

- RCE(원격 코드 실행) : 사용자와 동적으로 작동하는 템플릿의 방식에 나타나는 취약점으로 임의의 코드를 실행하도록

                                   하여 공격자가 프로세스를 제어할 수 있도록 만듦

 

→ 템플릿 주입은 웹 서버의 내부를 직접 공격하고 종종 RCE를 획득하여 취약점을 발생시킴

 

- Server-Side Template Injection 하는 방법

1. 구문을 입력하는 곳에 {{config}}나 주어진 단서를 활용하여 File.open('/etc/passwd')를 인젝션하여 디렉토리 확인

2. cat flag.txt 같은 코드를 rce하여 flag 값 뽑아오기

 

- SSTI 예제

?content={{7*7}}  → 49 출력

?content={{config.items()}}  → 딕셔너리 형태로 현재 설정되어 있는 config 출력

?content={{config.from_object('os')}}*  → os 라이브러리에 설정되어 있는 config 추가
?content={{''.__class__.__mro__}}  → root에 접근

슬라이싱 기법 이용하여 원하는 클래스 찾아보기

ex) {{''.__class__.__mro__[1]__subclasses__()[408]('ls',shell=True,stdout=-1).communicate()}} → 디렉토리 목록 출력

 

 

- SSTI 연습하기 좋은 ctf 문제

www.root-me.org/en/Challenges/Web-Server/ 

(Java - Server-side Template Injection)

 

 

 

 

▶ 코드 분석 

 

from urllib.parse import urlparse // URL 구문 분석 함수

URL6개의 구성 요소로 구문 분석하여 6개 항목 네임드 튜플 반환

 

from wordlists import ssti // ssti 취약점

 

from core.libs import alert_bug, insert_to_params_urls // ssti 경고창, url 주입

 

 

 

def __init__(self,opts,r):

     self.opts = opts

     self.http = r

     __init__함수로 opts와 r을 받아서 초기화 해줌

 

 

 

def scan(self,url,methods=['GET','POST']): 해당 url과 method 방식 불러옴

     for method in methods:

          for payload,match in ssti.items(): items() 함수 이용

          item() 함수 이용하여 payload와 match 쌍을 한꺼번에 출력

 

               nurl = insert_to_params_urls(url,payload) 해당 url과 payload 받아옴

            ※ def insert_to_params_urls(url,text,single=True,debug=False):

                    u = list()

                    try:

                         if len(url.split('?')) >= 1: url에서 '?'라는 문자로 나눈 개수가 1보다 크거나 같으면

                              for param in url.split('?')[1].split('&'): 위에서 나눈 값에서 '&'라는 문자로 문자열 나누기

                                   u.append(url.replace(param,param + text))

                                   param 값을 param에 text를 더해준 값으로 바꿔준 후 list에 요소 추가

                         return remove_dups(u) 리스트 반환

                     except Exception as e: 예외처리 오류가 발생하면 해당 블록 수행

                          if debug:

                               print(f'[insert_to_params_urls] {e}')

                          return list()

 

               for n in nurl:

                    if method == 'GET': 만약 method가 GET 방식이라면 해당 method 값 반환

                                               load() 함수로 이어지고 agent.txt 읽기 파일로 생성되는 듯(?)

                         r = self.http.send(method,n)

                        ※ send() 함수

                        def send(self,method='GET',url=None,body={},headers={},redirect=False,org=True):

                        try:

                             a = Agent()

                             if self.ragent:

                                  a.load()

                             if 'User-agent' not in headers.keys():

                                  headers['User-agent'] = a.random

                             if self.headers:

                                  for h,v in self.headers.items():

                                        headers[h] = v

                             if self.redirect:

                                  redirect = True

                             else:

                                  redirect = False

                             if self.timeout:

                                  timeout = self.timeout

                             else:

                                  timeout = 10

                             if type(self.proxy) == dict:

                                  proxy = self.proxy

                             else:

                                  proxy = {}

                             if org:

                                  if body:

                                       body = post_data(body)

                            else:

                                  body = {}

                            if method != 'GET':

                                  if body:

                                      pass

                                  else:

                                      body = post_data(urlparse(url).query)

                                      url = url.split('?')[0]

                            time.sleep(self.delay)

                            req = request(method, url, data=body, headers=headers, allow_redirects=redirect, verify=False,

                                                  timeout=timeout, proxies=proxy)

                            self.count += 1

                            if self.debug:

                                  print(f'--- [#{self.count}] Request ---')

                                  print(dump_request(req).decode())

                                  print('\n---- RESPONSE ----')

                                  print(dump_response(req).decode())

                                  print('--------------------\n\n')

                            return req

                      except Exception as e:

                            if self.debug:

                                  print(e)

                            return 0

 

                    else: 아니면 url에서 '?' 문자로 나눠주고 n쿼리의 URL 항목 튜플 형태로 분석하여 반환

                         r = self.http.send(method,url.split('?')[0],body=urlparse(n).query)

                    if r != 0: # 0 = Connection error: r이 0이면 connection error, 0이 아니면 각각 해당하는 값을 반환

                         if match in r.content.decode('utf-8'):

                              return {

                                           'http':r,

                                           'target':n,

                                           'match':match,

                                           'payload':payload,

                                        }

 

 

 

def main(opts,r):

s = Scan(opts,r)

v = s.scan(opts['url'],methods=opts['methods'])

if v:

alert_bug('SSTI',**v)

s라는 객체를 만들어 opts와 r을 전달해줌

v라는 객체에 해당 url과 methods(GET or POST)를 전달받고 만약 v가 존재한다면 SSTI 취약점 경고창 띄움

 

'2021-1 STUDY > Web Programming Study' 카테고리의 다른 글

scant3r_SQLI  (0) 2021.05.05
Web Scanner  (0) 2021.04.11
Python  (0) 2021.03.27

1. Pwntools

1) CTF 프레임워크이자 익스플로잇을 쉽게 짤 수 있게 해주는 라이브러리

2) 설치방법

- apt-get update 
- apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential 
- python3 -m pip install --upgrade pip
- python3 -m pip install --upgrade pwntools

 

2. Pwntools 사용법

1) pwn 모듈 import

→ from pwn import *

2) 파일 연결

- 원격인 경우 : remote(IP, PORT)

- 로컬인 경우 : process(PATH)

    → 해당 프로그램을 실행시킨 후 입력을 대기한다.

    → process()로 실행시킨 프로그램은 입출력을 화면에 직접 할 수 없고 변수를 통해 함수를 호출하는 방법을 이용해야 한다.

- ssh인 경우 : ssh(USERNAME,IP,PORT,PASSWORD)

3) 데이터 받아오기 

- 한 줄 받아오기 : recvline()

- str까지 받아오기 : recvuntil(str)

- int만큼 받아오기 : recv(int)

4) 데이터 보내기

- value 값 보내기 : send(value)

- 데이터 한 줄 보내기 : sendline(value)

- 쉘에 직접 명령을 전송, 수신하기 : interactive()

    → 프로그램에 직접 입출력 조작이 필요할 때 이 함수를 호출

 

3. Pwntools 자주 쓰이는 모듈, 함수

1) pwnlib.context

- pwntools 설정에 편리

- context.log_level='debug' : exploit에 어려움이 있을 때 세팅

2) remote, listen, ssh, process

- pwnlib.tubes

- CTF에서 가장 일반적으로 쓰이고 편리한 기능

3) log

- pwnlib.log

4) shellcraft

- pwnlib.shellcraft

- shellcode 라이브러리

5) gdb.debug와 gdb.attach

- pwnlib.gdb

- 자동으로 breakpoint 설정하고 exploit에 반복을 만듦

 

4. 연습문제

 

 

먼저 chall.c 코드를 통해 소스코드를 확인할 수 있다.

이 코드는 랜덤으로 결정되는 a와 b를 합한 값을 입력받아 답이 맞다면 correct, 다르다면 wrong을 출력한다.

 

 

따라서 문제를 해결하기 위해 파이썬으로 위와 같은 코드를 작성했다.

먼저 swing_pwn_chall이라는 파일은 로컬 파일이기 때문에 process()함수를 이용하여 연결해주었고

위 코드에서 20번 반복되었기 때문에 반복문을 사용해준 후 

recvuntil()을 사용하여 해당 문자의 앞까지 데이터를 받아올 수 있도록 하고

sendline()을 사용하여 a와 b에 저장된 값을 int형으로 변환해준 데이터를 보낼 수 있도록 한다.

이 값을 recvline()을 사용하여 한 줄을 보내주고 이와 같이 입출력 조작을 해주었으므로 interactive() 함수를 이용한다.

 

 

위와 같이 작성한 코드를 실행시키면 correct와 flag가 잘 출력되는 것을 확인할 수 있다.

'2021-1 STUDY > Pwnable Study' 카테고리의 다른 글

Week05_BOF  (0) 2021.05.19
Week04_GDB 분석  (0) 2021.05.12
Week03_collision  (0) 2021.05.05
Week03_setuid  (0) 2021.05.05
Week01_메모리구조  (0) 2021.03.31

1. 큐란?

 

1) 개념

- 사전적 의미 : 무엇인가를 기다리는 줄

- 자료구조에서의 의미 : 무언가를 처리하기 위해 대기 중인 자료의 줄, 대기행렬이라고도 함

2) 특성

- FIFO(First-In First-Out) : 선입선출, 가장 먼저 들어간 데이터가 가장 먼저 나옴

3) 사용 예

- 선입선출 특성이 필요한 현실 세계의 다양한 시스템들을 나타낼 때 사용

- ex) 운영체제의 프린터 스풀러 (먼저 처리한 것부터 실행)

4) 구조

- 데이터를 차례대로 저장하는 선형 자료구조

- 새로운 데이터를 맨 뒤인 리어에 추가

- 리어(rear) : 큐에서 맨 나중에 추가한 데이터

         - 맨 앞인 프런트에서 자료를 제거하여 반환

- 프런트(front) : 맨 먼저 추가한 데이터

- 인큐(enqueue) : 새로운 데이터를 추가하는 연산

         - 큐의 크기 : 저장할 수 있는 최대 데이터의 개수 → 오버플로우 방지하기 위해 동적 메모리 사용을 권장

- 디큐(dequeue) : 기존 데이터를 반환하는 연산

         - 프런트가 가리키고 있는 데이터 제거

- 피크(peek) : 가장 오래된 데이터 반환 (데이터 제거 X)

 

 

2. 추상 자료형 큐

 

이름

기능

입력

출력

설명

createQueue()

큐 생성

큐의 크기 n

큐 q

빈 큐 q 생성

deleteQueue()

큐 삭제

큐 q

N/A

큐 메모리 해제

isFull()

자료 추가

가능 여부 판단

큐 q

True/False

큐에 인큐를 수행할 수 있는지 반환, 배열 큐인 경우에만 의미 있음

isEmpty()

빈 큐인지 판단

큐 q

True/False

빈 큐인지 반환

enqueue()

인큐

큐 q

성공/실패 여부

큐의 맨 뒤에 새로운 자료 추가

dequeue()

디큐

데이터 data

데이터

큐의 맨 앞에 있는 자료 제거 후 반환

peek()

피크

큐 q

데이터

큐의 맨 앞에 있는 자료 반환

(큐에서 제거 X)

 

 

 

3. 배열 선형 큐

 

1) 개념

- 배열로 구현한 선형 큐

2) 단점

- 미리 크기를 지정해야 함

- 배열의 앞부분부터 사용할 수 없는 빈 곳이 생김 (메모리 낭비)

         → 배열 원형 큐를 사용하거나 포인터로 구현한 연결 큐를 사용할 것을 권장

3) 구조

 

 

① enqueue()

- 조건식 1 : rear == maxCount – 1 (배열 선형 큐가 가득 찬 상태)

- 조건식 2 : currentCount == maxCount

② isFull()

- 현재 노드 개수 pQueue->currentCount가 최대 노드 개수 pQueue->maxCount와 같다면 배열 선형 큐가 가득 찬 상태

- 조건식 : pQueue->rear == pQueue->maxCount - 1

③ dequeue()

- pReturn->data = pQueue->pData[pQueue->front].data

④ isEmpty()

- 멤버 변수 currentCount의 값이 0이면 현재 큐가 비어 있는 상태

⑤ peek()

- 값을 삭제하지 않는다는 점이 dequeue와 다름

 

 

4. 배열 원형 큐

 

1) 개념

- 빈 노드가 있지만 인큐 연산이 불가능한 배열 선형 큐의 단점 보완

- 조건식 1 : rear = (rear+1) % maxCount

 

 

'2021-1 STUDY > Data Instructure Study' 카테고리의 다른 글

Week02_Stack  (0) 2021.04.07
Week01_ArrayList  (0) 2021.03.30

re 모듈의 주요 메소드

compile(pattern[,flags]) : pattern을 컴파일하여 정규식 객체를 반환

match(pattern,string[,flags]) : string의 시작부분부터 pattern이 존재하는지 검사하여 MatchObject 인스턴스를 반환

search(pattern,string[,flags]) : string의 전체에 대해서 pattern이 존재하는 지 검사하여 MatchObject 인스턴스를 반환

split(pattern, string[,maxplit=0]) : pattern을 구분자로 string을 분리하여 리스트로 반환

findall(pattern, string[,flags]) : string에서 pattern을 만족하는 문자열을 리스트로 반환

finditer(pattern, string[,flags]) : string에서 pattern을 만족하는 문자열을 반복자로 반환

sub(pattern, repl, string[,count=0]) : string에서 pattern과 일치하는 부분에 대하여 repl로 교체하여 결과 문자열을 반환

subn(patter, repl, string[,count=0] : sub과 동일하나 결과(결과문자열, 매칭횟수)를 튜플로 반환

escape(string) : 영문자 숫자가 아닌 문자들을 백슬래쉬 처리해서 리턴 (임의의 문자열을 정규식 패턴으로 사용할 경우 유용)

 

 

포트 스캐너

네트워크 소켓(socket)을 사용하여 특정 IP와 Port에 지속적으로 연결 요청을 보내는 작업을 수없이 반복하는 과정이 필요

socket 모듈을 import 한 후 connect() 함수를 호출하여 IP 주소와 포트 번호를 지정해주기

코드를 실행하면 TCP 연결을 수립하여 SYN/SYN-ACK/ACK하게 되고 send() 함수를 사용하여 데이터를 송신하거나 recv() 함수를 사용하여 데이터를 수신

개방되어 있지 않은 port에 대해서는 예외(exception)가 발생하는데, 소켓은 이것을 처리하기 위한 예외처리 루틴 수행(3-way handshake가 수립된 상태)

try~except 구문을 사용하여 닫혀 있는 포트를 무시하고 건너뛰는 형태로 작성할 수도 있음

이때 if문을 사용하여 open된 포트에 대해서만 결과물을 출력하도록 설정하고 조사하고자 하는 포트에 대해 리스트나 배열을 만들어둔 후 해당 값들에 대해서만 루프를 수행하여 조사하게 할 수도 있음

 

 

socket 모듈의 주요 메소드

socket() : 소켓 객체를 생성하는 함수

with as : 파일이나 소켓을 with as 구문으로 생성하면 후에 소멸할 때 close() 메소드를 호출하지 않아도 인터프리터가 자동으로 해줌

bind() : 서버를 만들 때 필요한 메소드로 튜플 형식을 받음

connect() : 클라이언트에서 서버에 접속하기 위해 AF가 인자로 들어가는데, (호스트 주소, 포트번호)로 구성된 튜플을 인자로 전달

listen() : 서버가 데이터 수신을 기다리는 상태로 인자 값으로 들어가는 숫자는 해당 소켓이 몇 개의 동시접속을 허용할 것인지의 의미

accept() : 소켓에 누군가가 접속하여 연결되었을 때 결과 값이 튜플로 return되는 함수로 return 값은 새로운 소켓과 상대방의 AF(Address Family)를 전달, 이 이후부터의 데이터 송수신은 새로운 소켓 이용

sendall()과 recv() : 데이터를 송수신하는 메소드, 클라이언트는 기존의 소켓으로 송수신을 하는 반면 서버는 accept()로 생성된 소켓으로 송수신을 함, 소켓은 턴 바이 턴 형식이기 때문에 데이터를 한 번 송신하면 다음은 수신해야 함

 

 

Nmap Port Scan

nmap을 사용하여 타겟 서버의 포트 개방 여부를 확인하고 어떤 프로세서가 러닝되고 있는지를 확인

 

 

1. os를 import 해줌

2. 첫번째 인자로 options, 두번째 인자로 ip address를 받는 함수 정의, 이때 –F 옵션을 사용하면 빠르고 개략적인 정보만을 보여줌

3. command에 nmap 명령어와 옵선, 스페이스와 IP 할당

4. command를 실행시키기 위해 popen() 메소드를 이용하여 지정

5. 위에서 지정된 process를 읽어들인 후 str() 메소드로 converting하여 results에 넣어주기

6. 저장된 results 반환

 

 

os 모듈의 주요 메소드

getcwd() : 현재 디렉토리 확인하기

chdir() : 디렉토리 변경

listdir() : 현재 디렉토리의 파일 목록 확인하기

read_csv() : csv 파일 호출

walk() : 파일이나 디렉토리의 목로을 얻기 위한 함수, 인수로 디렉토리명을 지저앟여 파일이나 특정 확장자의 목록, 파일 경로 취득 가능

path() : 파일이나 디렉토리의 존재를 확인하거나 지정한 경로의 파일명을 취득하거나 경로나 파일명의 결합 등의 용도로 사용

    exists() : 파일 및 디렉토리의 존재 확인. return값 Bool형

    isdir() : 디렉토리의 존재 여부 확인. return값은 Bool형

    isfile() 파일의 존재 여부를 확인. return값은 Bool형

    basename() : 지정된 경로의 파일명 리턴

    dirname() : 지정된 경로로부터 파일명을 제외한 것 리턴.

    split() : 지정된 경로의 파일명과 그 경로 리턴.

    splitext() : 지정된 파일의 확장자와 확장를 제외한 파일명까지의 경로를 리턴.

    join() : 경로와 파일명 등을 결합

environ() : 환경변수를 취득하거나 읽기 및 쓰기를 위해 사용, 환경변수란 시스템이 참고하고 있는 공통의 변수로 환경에 관련된 데이터나 공통으로 사용하는 파일의 경ㅇ로 등을 저장하기 위해 사용

 

 

robots.txt

웹을 만들 때 검색엔진에서 사이트를 프로그램으로 자동 저장하는 크롤링을 하는데 이때 민감한 페이지나 관리자 페이지 같은 것은 크롤링하지 못하게 텍스트 파일 형태로 작성해둔 것

 

 

1. urllib.request import

2. io import

3. url을 전달 받는 함수 정의

4. url이 ‘/’로 끝난다면 조건문 실행

5. 조건문이 참이면 path에 url 값 그대로 넣어주고 거짓이면 url 값에 ‘/’를 붙여 넣음

6. request 파일 만들기(어떤 사이트든 열어 그 값을 임의로 지정)

7. TextIOWrapper을 이용해서 data에 값 할당

8. return 값으로 위의 결과인 data 값 반환

 

 

sys 모듈 주요 메소드

파이썬 인터프리터를 제어할 수 있는 방법 제공

argv : 명령 행에서 인수 전달, 0번째는 스크립트 이름

exc_info() : 현재 발생한 예외 정보를 튜플로 반환 (예외가 없는 경우 None)

exit() : 강제로 스크립트 종료

path() : 자신이 만든 모듈 불러와서 사용하기

getrefcount(object) : 객체의 참조 카운트 값 반환

modules() : 현재 로딩되어 있는 모듈들을 사전 형태로 나타냄

 

 

파일 사용법

파일객체 = open(‘filename’,‘filemode’)

파일객체.write(‘string’)

파일객체.close()

with~as를 사용하면 자동으로 파일 객체를 닫을 수 있음

ex) with open(‘filename’,‘filemode) as 파일객체: 코드

파일객체.writelines(리스트) : 문자열로 된 리스트를 사용하여 파일에 한 번에 내용 작성

변수 = 파일객체.readline() or readlines() : 파일 내용 불러오기

pickle 모듈의 dump를 사용하여 객체들을 파일에 저장 가능

 

 

 

'2021-1 STUDY > Web Programming Study' 카테고리의 다른 글

scant3r_SQLI  (0) 2021.05.05
scant3r_SSTI  (0) 2021.05.05
Python  (0) 2021.03.27

1. 스택이란?

 

1) 개념

- 선형구조

- 사전적 의미 : 물건이 쌓여 있는 더미

 

2) 구조

- top : 스택의 가장 윗부분

- bottom : 스택의 가장 아랫부분

- element : 스택에 저장되는 것

- 입출력은 맨 위에서만 일어나고 중간에서는 데이터를 삭제할 수 없음

 

3) 특징

- 후입선출 : LIFO(Last-In First-Out)

→ 가장 최근에 들어온 입력이 가장 먼저 나가게 됨

      ex) ① PUSH 연산 : 새로운 자료를 스택에 추가하는 과정

           ② POP 연산 : 스택에 저장된 자료를 가져오는 과정

                    → 자료 제거 및 가져오기 연산이 동시에 수행

 

 

2. 추상 자료형 스택

 

- 스택(s)

① 객체 : 0개 이상의 원소를 가지는 유한 선형 리스트

② 연산

 

create(size) ::= 최대 크기가 size인 공백 스택 생성

is_full(s) ::= if(스택의 원소 수 == SIZE) return TRUE;

                   else return FALSE;

is_empty(s) ::= if(스택의 원소 수 == 0) return TRUE;

                      else return FALSE;

push(s, item) ::= if(is_full(s)) return ERROR_STACKFULL;

                         else 스택의 맨 위에 item 추가

pop(s) ::= if(is_empty(s)) return ERROR_STACKEMPTY;

                 else 스택의 맨 위의 원소를 제거해서 반환

peek(s) ::= if(is_empty(s)) return ERROR_STACKEMPTY;

                  else 스택의 맨 위의 원소를 제거하지 않고 반환

 

 

3. 스택 구현

 

- 전역 변수로 구현하는 방법

 

#define MAX_STACK_SIZE 100 // 스택의 최대 크기

typedef int element; // 데이터의 자료형

element stack[MAX_STACK_SIZE]; // 1차원 배열

int top = -1;

→ 배열, top 변수를 함수의 매개변수로 전달할 필요 없음

→ 단점 : 하나의 프로그램에서 여러 개의 스택을 동시에 사용하기 어려움

 

- 스택의 요소 : 구조체로 정의

 

typedef struct {

int student_no;

char name[MAX_STRING];

char address[MAX_STRING];

} element;

 

- 동적 메모리 할당으로 스택 생성

 

int main(void)

{

StackType *s;

s = (StackType *)malloc(sizeof(StackType));

...

}

 

 

4. 스택의 응용 – 괄호 검사 문제

 

1) 문제

- 프로그램에서 사용되는 괄호가 올바르게 사용되었는지를 스택을 사용하여 검사하는 프로그램

 

2) 검사 조건

- 왼쪽 괄호의 개수와 오른쪽 괄호의 개수가 같음

- 같은 종류의 괄호에서 왼쪽 괄호는 오른쪽 괄호보다 먼저 나와야 함

- 서로 다른 종류의 왼쪽 괄호와 오른쪽 괄호 쌍은 서로를 교차하면 안됨

 

3) 괄호 검사 알고리즘

 

check_matching(expr):

while(입력 expr의 끝이 아니면)

      ch <- expr의 다음 글자

      switch(ch)

      case ‘(’ : case ‘[’ : case ‘(’ :

            ch를 스택에 삽입

            break;

      case ‘}’ : case ‘]’ : case ‘)’ :

            if (스택이 비어 있으면)

                  then 오류

            else 스택에서 open_ch를 꺼내기

      if (ch와 open_ch가 ᄍᆞᆨ이 아니면)

            then 오류 보고

            break;

if(스택이 비어있지 않으면)

      then 오류

 

 

 

 

'2021-1 STUDY > Data Instructure Study' 카테고리의 다른 글

Week03_Queue  (0) 2021.04.13
Week01_ArrayList  (0) 2021.03.30

 

 

 

1. TEXT (CODE) 영역

 

- 유저가 작성한 소스코드가 들어가는 영역

 

- 실행할 프로그램의 코드가 저장되는 영역으로 바이너리화되어 저장

 

- 실행 파일을 구성하는 명령어들이 올라가는 메모리 영역으로 함수, 제어문, 상수 등이 지정

 

 

 

2. DATA 영역

 

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

 

- 프로그램의 시작과 동시에 할당되며 프로그램이 종료되어야 메모리가 소멸

 

 

 

3. BSS 영역

 

- 프로그램에서 사용될 변수들이 실제로 위치하는 공간

 

- 변수 선언 순서에 따라 주소값이 커지는 구조

 

 

 

4. HEAP 영역

 

- 동적으로 할당되는 변수의 데이터들이 위치하는 공간

 

- malloc 등의 함수 이용

 

- 프로그래머가 할당 및 해제하는 메모리 공간

 

- 장점 : 프로그램에 필요한 개체의 개수나 크기를 미리 알 수 없는 경우 사용 가능

 

- 단점 : 할당 작업이나 해제 작업으로 인한 속도 저하

 

 

 

5. STACK 영역

 

- 함수에 대한 정보를 포함

 

- 함수 안에 포함되어 있는 지역 변수의 내용들을 포함

 

- 프로그램이 자동으로 사용하는 임시 메모리 영역

 

- 함수 호출 완료 시 사라짐

 

- 장점 : 낭비되는 공간이 없고 하나의 명령만으로 조작 가능

 

- 단점 : 한계를 초과하도록 삽입할 수 없음 ( 유연성 부족 )

 

 

※ HEAP과 STACK 영역은 사실 같은 공간을 공유하는데, HEAP은 메모리 위쪽, STACK은 메모리 아래쪽부터 할당되는 방식

 

→ 각 영역이 상대 공간을 침범하는 일이 발생할 수 있고, 이를 각각 HEAP OVERFLOW, STACK OVERFLOW라고 한다.

 

 

 

 

'2021-1 STUDY > Pwnable Study' 카테고리의 다른 글

Week05_BOF  (0) 2021.05.19
Week04_GDB 분석  (0) 2021.05.12
Week03_collision  (0) 2021.05.05
Week03_setuid  (0) 2021.05.05
Week02_Pwntools  (0) 2021.04.28

 1. 리스트란? 

 

1) 정의

- 자료를 순서대로 저장하는 자료구조

- 여러 개의 자료가 일직선으로 연결된 선형 구조

- 배열 리스트 : 배열을 이용하여 구현된 리스트

 

2) 주의점

- 리스트는 한 줄로 저장

- 줄을 세울 때 앞 항목과 뒤 항목이 1개로 연결되는 구조

 

3) 배열과 배열리스트

- 배열 : 같은 자료형의 데이터가 메모리 상에 연속적으로 저장

- 배열 리스트 : 자료가 일직선으로 서로 연결

 

 

 

 2. 자료형 

 

1) 정의

- 기초적인 자료형 : 정수, 실수, 문자열 등

- 새로운 자료형 : 스택, 큐, 리스트, 트리 등

 

2) int 자료형

- INT_MIN : 컴퓨터가 나타낼 수 있는 가장 작은 정수

- INT_MAX : 컴퓨터가 나타낼 수 있는 가장 큰 정수

- 복잡한 자료형 구현 시 연산자가 아닌 함수로 작성

 

3) 추상 자료형 (Abstract Data Type, ADT)

- 추상적, 수학적으로 자료형을 정의한 것

- 자료구조는 추상 자료형을 프로그래밍 언어로 구현한 것

- 자연수를 나타내는 추상 자료형 : Nat_Number

① 객체 : 0~INT_MAX까지의 순서화된 정수의 부분 범위

② 함수

Nat_number zero()::= 0

Nat_number successor(x) ::= if(x == INT_MAX) return x

                                           else return x + 1

Boolean is_zero(x) ::= if(x) return FALSE

                                     else return TRUE

Boolean equal(x,y) ::= if(x == y) return FALSE

                                     else return FALSE

Nat_number add(x,y) ::= if((x + y) <= INT_MAX)

                                      else return INT_MAX

Nat_number sub(x,y) ::= if (x < y) return 0

                                        else return x – y;

 

 

 

 3. 리스트 ADT 

 

1) 정의

- 리스트는 자료를 정리하는 방법 중의 하나

 

2) 리스트 ADT

- 리스트를 추상 데이터 타입으로 정의한 것

① 객체 : n형으로, element형으로 구성된 순서 있는 모임

② 함수

insert(list, pos, item) ::= pos 위치에 요소 추가

insert_last(list, item) ::= 맨 끝에 요소 추가

insert_first(list, item) ::= 맨 처음에 요소 추가

delete(list, pos) ::= pos 위치의 요소 제거

clear(list) ::= 리스트의 모든 요소 제거

get_entry(list, pos) ::= pos 위치의 요소 반환

get_length(list) ::= 리스트의 길이

is_empty(list) ::= 리스트가 비었는지 검사

is_full(list) ::= 리스트가 꽉 찼는지 검사

print_list(list) ::= 리스트의 모든 요소 표시

 

3) 리스트 구현

- 배열을 이용한 구현

① 장점 : 리스트 ADT를 가장 간단하게 구현 가능

② 단점 : 크기 고정 → 메모리 낭비

- 연결 리스트를 이용한 구현

① 장점 : 크기 제한 X, 포인터를 이용한 유연한 진행 가능

② 단점 : 구현이 복잡

 

 

 

 4. 배열 리스트  

 

1) 정의

- 순차적 표현(sequential representation) : 배열을 이용한 리스트 구현은 순차적인 메모리 공간 할당

- 배열 사용 시 리스트의 항목을 자연스럽게 저장 가능

 

2) 실습

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'2021-1 STUDY > Data Instructure Study' 카테고리의 다른 글

Week03_Queue  (0) 2021.04.13
Week02_Stack  (0) 2021.04.07

+ Recent posts