BOF of 2.6 Kernel ! 박수완 / Su-Wan, PARK [ L1nkC] 숭실대학교 정보보호동아리 ACK E-mail : Skyhwen@naver.com
Index 1.What is BOF? ----------------------------------------3 2.Initial of BOF------------------------------------------4 3. The elementary of BOF ---------------------------5 4.BOF Defensive Mechanism 4-1 BOF in RedHat 9 [2.4kernel] -------------------------------------10 4-2 RTL [Return To Libc]------------------------------------------------17 4-3 BOF in 2.6 kernel 4-3.1 Fake EBP-----------------------------------------------32 4-3.2 Ret Execl Overflow-----------------------------------39
What is BOF? Buffer Over Flow 의 줄임말 즉 메모리에 할당된 버퍼의 양을 초과하는 데이터를 입력하여 프로그 램의 복귀 주소(return address)를 조작, 궁극적으로 해커가 원하는 코드를 실행하는 것. ◀그림1: 일반적 bof 전후의 메모리 모습
Initial Of BOF 1988년 Morris Worm 사건에서 의 finger daemon을 이용한 공 격이 시초 1997년 Phrack 잡지 49호에 실 린 Aleph의 “Smashing the Stack for Fun and Profit” 이라 는 기사에서 이 버퍼 오버플로우 에 대한 자세한 원리와 제작 방 법이 소개되면서 널리 알려짐
보통 읽을 수 있는 부분이 있으나, 변조될 경우 Segfault 발생 The elementary of BOF 메모리의 구성 요소 중에서 사용자가 입력한 부분이 들어가는 곳은 stack 이다. Bof 는 크게 stack 을 이용하느냐 heap 을 이용하느냐에 따라 stack overflow와 heap overflow 로 나뉜다. 변수 정보가 들어가는 Data 부분은 변동폭이 작으며 주소값이 고정되어 있어 인자 전달에 자주 쓰이는 영역이다. ◀표1: 메모리 구조 상위 메모리 주소 Env/Argv Strings 환경 변수와 명령 창의 데이터가 저장된다. Env/Argv Poiners Argc Stack 로컬 인자와 프로세스 상태 저장 Heap 동적으로 할당된 데이터가 저장된다. Data(.bss) 초기화되지 않은 변수 Date(.data) 초기화된 변수 Code(.text) 보통 읽을 수 있는 부분이 있으나, 변조될 경우 Segfault 발생
The elementary of BOF#2 Bof를 하기 위해서는 메모리 구조를 파악해야 한다. 이때 메모리 구조 파악을 도와 주는 것이 GDB [ Gnu DeBuger ] 이다. 간단하게 GDB로 메모리를 확인해보자. ▲그림1:GDB의 대상이 된 파일의 원본 소스 GDB로 열어본 파일의 구조 그림2:▶
The elementary of BOF#3 간단한 어셈블리어 명령어 몇 개와 인자를 확인해보자. push A : A를 스택에 넣는다 sub A B : A를 B에서 뺀다 add A B : A를 B에 더한다 mov A B : A의 값을 B에 저장한다. call A : A 함수를 호출한다 leave,ret : 함수 호출을 마무리 짓는데 쓰인다. 간단한 어셈블리어 명령어 몇 개와 인자를 확인해보자. EBP: Extended Base Pointer 어셈블리어 연산의 기준이 되는 pointer 함수 호출시마다 새로 생성되어 기준이 된다. ESP: Extended Stack Pointer 현재 스택의 위치를 알려주는 pointer 그밖에.. 인자 전달을 담당하는 것이 대부분
The elementary of BOF#4 Shell: 운영체제상에서 다양한 운영체제 기능과 서비스를 구현하는 인터페이스를 제공하는 프로그램 프로그램의 인자 전달 방식은 다음과 같다 ./file [인자1] [인자2] [인자3] ▲그림 1: Vul1은 받은 인자를 출력해주는 파일. 우리는 BOF를 함에 있어 16진수 값을 많이 이용하게 될 것이다. 하지만 1번 그림을 보면 16진수로 인식하지 않고 문자로 인식하는 것을 볼 수 있다.
The elementary of BOF#5 이때 사용하는 것이 perl [ 리눅스 기능을 포함하는 프로그래밍 언어] Print [ 16진수 인자를 올바르게 인식하게 할 수 있는 명령어] 이다. 보통 인자는 `perl –e ‘print “인자” ‘` 식으로 표현해서 넣는다. ▲그림 1: perl 과 print 를 이용해 인자를 전달해 준 모습. 그림1에서 확인할수 있다시피 인자를 입력해줄때 조심할 점은 1바이트씩 끊어서 입력해주어야 한다는 점이 있고 이외에도 메모리에 적재될때는 리눅스는 Little endian 방식을 사용하므로 거꾸로 넣어주어야 한다는 것이다. 예를 들어 0x12345678 을 입력해줄때는 \x78\x56\x34\x12 식으로 입력해주어야 한다.
Bof in RedHat 9 실험 시스템 : Red Hat 9 Random Stack 이 적용된 실험 대상 파일 사용자에게 입력 받은 값의 크기를 체크하지 않는 취약함수 strcpy를 사용했다. Random Stack 이 적용된 Red Hat 9 에서의 Bof를 실시한다. 실행 스택을 보여주는 bug 프로그램으로 실행시마다 stack의 주소가 바뀌는것을 확인할 수 있다.
Bof in Redhat#2 변하지 않는 부분[환경변수]에 특정 프로그램을 이용하여 [EGG shell] 쉘을 실행시키는 코드 삽입 환경변수 : shell의 실행 프로그램이나 쉘 상에서 쓰이는 언어 등을 정의한다. 환경적인 부분을 담당하고 있는 변수라 하여 이름 붙여졌다. ▲EGG shell을 실행한 후 EGG 라는 새로운 변수가 적재된것을 확인 할 수 있다. 특정 변수에 할당된 Buffer를 Overflow 시켜 Main 함수의 RET(Return Address) 가 공격코드가 포함된 주소를 가리키도록 변경
SFP(Saved Frame Pointer ; ebp) Bof in Redhat#3 GDB를 이용해 변수에 할당된 공간 계산 Sub $0x18, %esp -스택의 현재 위치를 가리키는 esp 에서 0x18만큼 빼준다는 것은 그만큼 메모리를 할당한다는 것이다. 정상적인 코드를 넣었을때의 실행결과 메모리 구조를 나타내었다. SFP 라는 영역에는 앞서 언급했던 EBP[기준이 되는 Base Pointer] RET에는 돌아갈 주소를 포함하고 있다. 0x18 = 24byte 정상 종료 코드 … RET(Return Address) SFP(Saved Frame Pointer ; ebp) buf [ 사용자가 선언한 변수]
조작된 RET(Return Address) Bof in RedHat 9#4 28byte 공격에 성공하여 root의 권한을 얻었다. 0xbffff1c9 [공격 코드] … 조작된 RET(Return Address) 우리의 궁극적인 목표는 RET가 공격 코드 값을 지닌 곳으로 귀환하게 하는것이다. 할당된 버퍼 24byte EBP 4byte 24+4= 28 byte Return 할 주소에 공격 코드가 담긴 곳을 넣어 공격 코드가 실행되도록 한다. aaaa …
Defencive Mechamism 2.6 kernel 에서는 앞선 BOF 공격을 방어하기 위해 여러 가지 기술들이 적용. Random Stack+@ 환경변수 적재돼는 부분도 변경 Non – executable stack 기존의 스택에 쉘코드를 넣는 overflow 를 막기 위한 기술 Stack Guard Stack의 일정주소번지에 프로그래머가 유도하는 값을 심어두고 후에 유도된 값을 체크하는 방법 Stack Shield 함수의 리턴주소를 복사하여 실제 리턴주소를 참조하지 않고 함 수를 리턴해주는 방식이다 함수 인자 참조 형식 변경 Etc...
Defencive Mechamism#Random Stack 기존 RedHat9 에 쓰인 기법보다 강력해졌다. ∆RedHat9(2.4 kernel) 에서의 EGG 쉘 사용 ∆ CentOs(2.6 kernel) 에서의 EGG쉘 사용 [ 환경 변수 영역도 변경된다 ]
Defencive Mechamism#Non-Exe.. Non – executable stack 스택 영역의 코드를 실행 할 수 없게 만듬 쉘코드를 스택 영역에 넣어서 공격하는 방법을 방지 [Egg shell 사용불가] RTL (Return Into Libc) 기법으로 파훼 Return Into Libc Return Address 의 주소를 공유라이브러리 주소로 바꾼 다음 원하는 인자까지 구성시켜 주어 shell을 실행하는 기법
RTL(Return to Libc)#1 Q. 스택에 실행코드를 넣지 않고 공격해야 한다. 다른 방법은 무엇이 있는가? A. Random 한 위치를 지니게 된 스택 대신 정적인 위치를 가진 공유라이브러리를 사용한다. 동적 라이브러리 라고도 불리며 , 실행시 메모리에 적재된다. Q. 라이브러리란? 소프트웨어를 만들 때 쓰이는 클래스나 서브루틴들의 모임을 가리키는 말이다. C표준 라이브러리 같은 경우 , 우리가 흔히 쓰는 stdio.h 나 stdlib.h 등의 헤더파일을 포함하고 있다. 윈도에서 .dll 리눅스에서는 .so 형식을 띤다. 즉 , 메모리 어딘가에 위치한 미리 정의된 함수를 이용하는 것이 RTL의 핵심.
RTL#2 버퍼를 overflow 시켜 RET를 조작하되 실행의 흐름을 스택 대신 libc 영역으로 돌려 원하는 함수를 수행하게 하는 것 ▲그림 1: RTL 기법을 도식화한 모습
1. 실행할 함수의 선택 2. 선택 함수의 메모리 주소 확인 함수선택 및 주소확인_RTL#3 쉘을 실행시킬 수 있는 함수 system, execve, execl …. 인자의 형식이 다를뿐 모두 비슷한 함수이며, 우리는 여기서 execl 함수 사용 2. 선택 함수의 메모리 주소 확인 GDB로 파일을 열고 정보를 출력해주는 명령어 print 를 사용해 execl 의 주소를 얻자.
3. execl 함수의 인자 전달 execl 의 인자 참조방식_RTL#4 int execl( const char *path, const char *arg, ...); Ex) execl(“/bin/ls”,”/bin/ls”,”-al”,”/tmp”,0); 마지막 인자는 0이 되어야 함을 유의해두자. 이때 execl 이 인자를 참조하는 방식을 살펴보자. ▲EBP를 기준으로 +8 ,+12,+16 한 값을 인자로 받는다. Main EBP &P2 /bin/bash &P1 Sh RET execl EBP
Q1.함수는 공유라이브러리에서 호출한다. 그렇다면 인자는 어떻게 집어넣어줘야할까? 함수의 인자전달_RTL#5 Q1.함수는 공유라이브러리에서 호출한다. 그렇다면 인자는 어떻게 집어넣어줘야할까? A1.애초에 인자가 완성된 함수를 포함한 파일을 따로 만들어 실행시키자. Q2. 완성한 파일을 구동중인 프로그램과 연결해서 어떻게 실행시키지? A2. execl 함수의 인자에 변하지 않는 특정 값을 넣어 그 값을 실행 시킬수 있다. 하지만 그 값은 이미 존재하는 것을 가져다 써야 하므로 매우 한정적이다. 고로 프로그램 이름과 같은 값을 찾는 것은 불가능하다. 만약.. 이 값과 쉘을 실행시키는 프로그램과 연결 할 수 있다면…
특정 값을 실행시키면 그 값 대신 프로그램이 실행되는 것..? Symbolic Link_RTL#6 특정 값을 실행시키면 그 값 대신 프로그램이 실행되는 것..? Symbolic Link! ln –s [ file1 ] [ file2 ] File1 을 실행할때는 걸기 전과 변화가 없지만 file2의 경우 연결한 후에 실행시키면 file1이 실행된다. window 의 단축아이콘의 개념과 비슷하다. 즉, 공유라이브러리를 통해 execl 을 실행하고 그 인자로 변하지 않는 특정 값을 준다. 그 값에 Symbolic Link 를 걸어 공격자가 실행하고자 하는 파일을 실행시킨다 Q.그렇다면 그 변하지 않는 특정 값은 메모리 어디에 위치할까? A. 메모리 구조를 다시 한번 살펴보자.
인자선택과 Symbolic Link 설정_RTL#8 execl 의 인자는 변하지 않는 DataSegment 중에서도 NULL 바이트 앞의 값을 선택한다. 0을 마지막 인자로 인식하는 execl 의 특성을 기억하자 \x01 의 값을 지닌 주소 0x8049014를 인자로 주도록 하자. 이를 인자로 execl 을 실행하면 쉘 상에서 명령어 창에서 ./ `perl –e ‘print “\x01”’` 라고 한것과 동일한 효과를 얻게 된다. Symbolic Link 로 우리가 \x01이 실행될때 쉘을 얻을 수 있는 파일이 실행되도록 하자 ▲ Symbolic Link 를 걸어주자 ▲ 걸어준 Symbolic Link 의 확인
Buffer 크기계산_RTL#9 구체적인 코드를 짜기 앞서 취약한 프로그램 코드 분석하자. 배열에 할당된 공간은 dummy byte를 포함해 24바이트이다. 우리가 변경하고자 하는 값은 ret이므로 ebp 값까지 덮어써주자. +4바이트를 더해 28바이트를 더하면 된다.
공격 전후의 메모리 구조_RTL#10 ▲평소 main함수의 구조 일반적인 execl 함수의 메모리 구조▶ ▲ 공격 후의 변조된 main 구조 execl의 ebp가 된다. buffer dummy ebp Return Address argc argv Execl 이전의 base pointer Return Address Execl 첫번째 인자 Execl 두번째 인자 Buffer-Dummy Data Execl `s Address dummy Execl 첫번째인자 Execl 두번째인자 Execl 세번째인자
Buffer-dummy data의 크기는 28 byte 공격 코드 내용_RTL#11 Buffer-dummy data의 크기는 28 byte execl`s address 는 공유라이브러리에 있는 주소 0x420aca0을 집어넣는다 Dummy는 4바이트 execl의 인자는 변하지 않는 Data Segment 의 주소 값을 넣어준다. Buffer-Dummy Data Execl `s Address dummy Execl 첫번째인자 Execl 두번째인자 Execl 세번째인자
./vul `perl –e ‘print “a”x28, //buffer 영역 + ebp 공격 코드 작성_RTL#12 Code#1 ./vul `perl –e ‘print “a”x28, //buffer 영역 + ebp ”\xa0\xac\x20\x04”, //execl 함수 주소 ”aaaa”, //인자는 ebp+8한 값에서 찾으므로 4바이트가 무시된다. ”\x14\x90\x04\x08”x3’` //Data Segment 영역 ▲그림1:우리가 원한 값은 0x0420aca0 이었는데 0x4200aca0이라는 엉뚱한 값이 들어갔다. A*28 0x420aca0 AAAA 0x08049014
Q. 0x0420 대신 0x4200 이 들어간 것을 확인할 수 있다. 왜 그럴까? Exploit_RTL#13 Q. 0x0420 대신 0x4200 이 들어간 것을 확인할 수 있다. 왜 그럴까? A.\x20 은 공백을 의미한다. 이를 아스키값 그대로 입력하게 해야 할것이다. 올바른 입력을 하기 위해 “ “ 를 사용하자. Final Code! ./vul “`perl –e ‘print “a”x28,”\xa0\xac\x20\x04”,”aaaa”,”\x14\x90\x04\x08”x3’`” 공격이 성공하여 root의 권한을 얻어낸 모습이다.
Defencive Mechanism of F.C Fedora Core 의 출시.. Q. Fedora Core란? A. Red Hat 社가 9을 기준으로 무료 배포를 그만두었다. 이에 따라 출시된 배포판 리눅스가 Fedora core이다. Fedora는 Red Hat 社 의 후원을 받고 있으며, 대표적인 배포판 리눅스로 자리매김하고 있다. Fedora Core의 Defensive Mechanism 운영체제 Red Hat 9 Fedora Core Non-execute stack X O Non-execute heap Random stack Random heap Random libc Libc address의 크기 16M이상 16M미만
Defencive Mechanism of F.C Random Stack. Heap : stack과 heap 의 위치가 임의로 변하게 하여 특정 값 지정을 방지 Stack, Heap 의 변하지 않는 부분에 쉘코드를 넣어 파훼 Non –Excute stack . Heap : 쉘코드를 메모리에 직접 적재하여 실행 하는 것을 방지 stack, heap 등을 사용하지 않고 Libc 에 있는 함수 주소를 가져다 쓰는 RTL 공격으로 파훼 Random Libc : Libc 주소가 임의로 변하여 RTL 방지 변동폭이 크지 않고 주소가 순환적이며, 한번 깨져버릴경우 주소 고정 Libc 주소 크기 조정: RTL 기법 사용시 반드시 \x00 바이트가 들어가도록 하여 인자 참조 방지 Ebp 로 인자를 참조하는 방식을 이용. EBP 변조 하여 파훼
Defencive Mechamism of F.C3 실습대상: Fedora Core 3 -2.6kernel Q.RTL 기법이 가능할까? LibC의 주소가 16MB 이하이므로 Execl 함수의 주소가 0x00972720에 위치한 것을 알수 있다. 0x00은 NULL 바이트를 의미한다. 이는 Terminate –canary 로서 인자 참조와 다음 함수의 호출을 방해한다. 이 방어기법을 ASCll –Armor 방법이라고 한다. 0x00 때문에 execl 을 호출하고 그 위에 인자 값을 넣어주는 방법은 불가능하게 되었다.
Q. ASCll –Armor 때문에 execl 함수의 인자전달이 어려워졌다. 어떻게 전달해줘야 할까? 인자전달의 방식 이해_Fake EBP#1 Q. ASCll –Armor 때문에 execl 함수의 인자전달이 어려워졌다. 어떻게 전달해줘야 할까? A.인자 참조 방식이 ebp를 기준으로 한다는 것을 생각해 볼때 , ebp 를 변조하면 인자를 넘겨줄수 있다. ebp의 기존 인자 참조방식을 살펴볼때 변조할 ebp에는 인자가 위치한 값 -8 을 넣어줘야한다. 인자의 위치는 ASCll – Armor 때문에 단순 Data Segment 영역의 참조로는 공격이 불가능하게 되었다.
GOT의 발견_Fake EBP#2 GOT [ Global Offset Table ] : 전역 데이터에 대한 포인터 테이블 Data Segment 영역 중에서도 특별한 구역 ELF [리눅스에서 쓰는 파일 포맷] 가 라이브러리 내의 심볼을 찾기 위해 GOT를 만들어 사용한다 Data Segment 영역에서 순차적으로 확인을 해보자 ………. 0x8049570 = GOT +12 이므로 GOT는 0x8049564
1. GOT 의 주소에서 -8 한 값으로 ebp 를 변조한다 2. Return Address 에는 execl 함수를 넣어준다. 공격시나리오 정리_Fake EBP#3 공격 순서는 다음과 같다 1. GOT 의 주소에서 -8 한 값으로 ebp 를 변조한다 2. Return Address 에는 execl 함수를 넣어준다. 3. GOT의 값 중 Symbolic Link를 걸어줄 적절한 것을 찾아 연결한다 이렇게 코드를 짜면 다음과 같은 메모리 구조를 이룬다 Buf 변조된 ebp Execl 함수 Argc argv Ebp AAAA Execl 인자 Shell 프로그램 실행
공격코드 생성_Fake EBP#4 그렇다면 공격 코드를 작성해보자 먼저 buffer의 값을 채우고… GOT 의 값은 0x08049564 여기서 -8 하면 0x804955c, 이는 변조된 ebp 에 들어갈 값이다. execl 의 주소는 0x972720 Symbolic Link를 건다. ln –s shell `perl –e ‘print “\x01”’` ./vul “`perl –e ‘print “a”x24 ,”\x5c\x95\x04\x08”, ”\x20\x27\x97”’`”
ebp 의 값은 함수가 호출될때마다 바뀌는 것을 기억하는가? 코드 실패 원인 분석_Fake EBP#5 공격이 성공하지 않는다. 어떻게 된걸까? ▲그림1: 모든 값이 올바르게 되었는데 실패했다. ebp 의 값은 함수가 호출될때마다 바뀌는 것을 기억하는가? ▲ 그림2: 함수 호출시마다 이런 현상이 일어나는데 이를 함수 프롤로그 과정이라고 한다. 기껏 변경한 ebp 의 값이 함수가 호출되면서 다시 변경되어버리는 것이다. 이러한 과정을 거치지 않기 위해서는 프롤로그 과정을 넘긴 후의 주소를 넘기면 될 것이다. 고로 execl 의 함수의 주소는 0x009720 이 아니라 프롤로그 과정을 마친 +3을 한 0x009723을 넣어주어야 할 것이다.
./vul `perl –e ‘print “a”x24, “\x5c\x95\x04\x08”, “\x23\x27\x97”’` Exploit_Fake EBP#6 Final Code! ./vul `perl –e ‘print “a”x24, “\x5c\x95\x04\x08”, “\x23\x27\x97”’` ln –s shell `perl –e ‘print “\x01”’` ▲그림1: 공격에 성공하여 root 쉘을 얻어냈다. shell dummy 변조된 ebp Execl 함수+3 GOT-8 GOT-4 GOT … 0x01
Ret Execl Overflow#1 Fedora Core 4 FC4에서는 3에서의 Fake EBP를 알아채고 인자 참조 형식을 바꿨다. ebp 대신 esp 를 기준으로 인자를 참조하는 것을 볼 수 있다. 첫번째 인자는 esp에서 12 값을 더한 값이 된다. 유동적인 ESP를 변조시키는 것이 관건
Q. ESP를 변경시키는 가장 좋은 방법이 무엇일까? A. 어셈블리 명령어 중 ret 를 이용한다. ESP의 변경_REO#2 Q. ESP를 변경시키는 가장 좋은 방법이 무엇일까? A. 어셈블리 명령어 중 ret 를 이용한다. ret 는 pop %eip 를 실행시키는 어셈블리어로 eip를 이용해 esp 를 변조시킬수 있다. ▲공격전 main함수 메모리 구조 ▲공격후 main함수 메모리 구조 Buf SPF RET Argc Argv Buf- dummy data ret Execl 함수 ... Execl 인자 shell
적절한 인자의 탐색_REO#3 ▲그림1:먼저 ret 주소를 확인한다 ▲ 그림2:Execl 함수의 주소를 얻자. execl 함수의 인자로 적절한 값을 찾아야 한다. 스택의 값은 매번 변하므로 적절하지 않고 애용해왔던 Data Segment 영역에 속한 값을 이용하도록 하자. ebp ret 1 2 3 4 5 6 7 8 9
ebp까지 dummy data로 덮어씌우고 RET영역부터 main 함수의 ret 값을 집어 넣는다. 인자 전달을 위한 계산_REO#4 Execl 의 esp 를 기준으로 12바이트 앞의 data 를 첫번째 인자로 받아들인다. 기존의 여기서 우리가 채워넣어야 할 ret 수를 계산해야 한다. ebp까지 dummy data로 덮어씌우고 RET영역부터 main 함수의 ret 값을 집어 넣는다. 같은 이름을 지니고 있지만, 역할은 틀리다는 것을 유의하자. RET 영역의 값은 Return 주소값이고 , ret 은 어셈블리 명령어다. 총 10번 pop을 시켜서 esp를 앞으로 당기자. 그리고 execl 의 함수 값을 집어넣으면 12바이트 앞의 data를 인자로 참조해 execl 의 주소를 향한다. 2 6 7 8 9
./vul `perl –e ‘print “a”x8, ”\xb1\x83\x04\x08”x10, ”\x5c\x04\xdb”’` 공격 시나리오 작성_REO#5 코드를 생성해보자. EBP영역 까지 다른 data로 덮는다. [ Buffer 영역 + 4 ] ret 로 Data segment 영역의 12바이트전까지 채운다. [0x80483b1] esp를 기준으로 12바이트 뒤가 첫번째 인자가 된다. ret 는 esp 를 한칸씩 앞으로 당기는 역할을 한다. execl 함수의 주소를 집어 넣는다. [0x19e1ac] ./vul `perl –e ‘print “a”x8, ”\xb1\x83\x04\x08”x10, ”\x5c\x04\xdb”’` ret 1 2 3
Data Segment 영역에 있는 값을 확인하자. Symbolic Link 작성_REO#6 Data Segment 영역에 있는 값을 확인하자. ▲NULL byte 전까지의 값들이 실행될것이다. 그 값에 쉘을 실행하는 파일을 Symbolic Link로 연결하자. ▲ 공격에 앞서 올바르게 연결되었는지 확인하자. ret 1 2 3
./vul `perl –e ‘print “a”x8, ”\xb1\x83\x04\x08”x10, ”\x5c\x04\xdb”’` Exploit_REO#5 Final Code! ./vul `perl –e ‘print “a”x8, ”\xb1\x83\x04\x08”x10, ”\x5c\x04\xdb”’` ln –s shell `perl –e ‘print “\x55\x89\xe5\x57\x56\x53\x83\xec\x0c\x28”’` AAAA ret … execl …. 인자 ret 1 2 3 shell
Exploit_REO#7 ▲ Root 권한의 쉘을 얻어냈다 Segmentation Fault 가 출력되는건 Random Libc 때문이다. ret 1 2 3
Random Libc_REO#etc.. 간혹 코드는 정확한데 쉘이 안떨어지는 경우가 있다. 이는 Random Libc 때문이다. 즉 execl 의 함수 위치가 변경됀다는 것이다. 하지만 걱정할것은 없다. Random Libc 라고 해도 그 변동폭은 크지 않아 몇번 시도 하다보면 이내 쉘을 얻을 수 있다. ▲ 다음은 Random Libc가 깨져 execl 의 주소가 바뀌지 않고 출력돼는 것 -Random Libc는 깨지기 매우 쉬운 Defensive Mechanism이다. 고정된 execl 함수의 주소로 여러 번의 시도 없이 바로 root권한의 쉘을 얻어냈다. ret 1 2 3
Summary 2.6 이전 kernel 에서의 BOF ReTurn into Libc Fake EBP 스택의 실행을 막는 방법을 파훼하기 위해 출현 기존 스택에 함수를 적재하던 방식을 탈피. 미리 인자를 구성시켜 두고 공유라이브러리에서 함수를 호출하는 방식. Fake EBP 16MB 이하의 주소를 가진 Libc의 ASCll-Armor 때문에 출현 ebp를 변조하여 정상적인 함수의 호출을 가능케함 Ret execl Overflow ebp 대신 esp를 기준으로 한 함수 인자 전달 방식 채택 ret를 통해 esp를 변경하여 인자 전달 후 함수 호출
참고자료 달고나 – buffer_overflow_foundation_pub Hardsoju – history_of_bufferoverflow_vol1 randomkid – fedora_core_3,4,5_stack_bufferoverflow 원재아빠 - Return_to_lib 의 이해와 적용 원재아빠 – Stack Guard 의 이해 양대일 – 정보 보안 개론과 실습- 시스템해킹과 보안 [2004. 한빛미디어]
THANK YOU !