jam 블로그

[bof 원정대] golem -> darkknight (sfp or fpo) 본문

해킹/시스템

[bof 원정대] golem -> darkknight (sfp or fpo)

kid1412 2012. 3. 22. 18:30
728x90
다음은 문제 소스입니다.

 [그림 1] darkknight.c

소스분석
1. 인자값이 적어도 하나이상
2. problem_child 함수 안에 buffer의 크기는 40
3. problem_child 함수 안에 buffer에 src 복사시의 길이는 41

 
 문제 푸는 과정입니다.

힌트가 있다시피 stack frame point를 사용해서 푸는 문제입니다.
0. bash2
1. problem_child에서 buffer의 주소값 찾기
2. stack frame point을 이용한 bof 공격 

 
1. problem_child에서의 buffer의 주소값을 찾기

buffer의 주소값 구하는건 쉽습니다. gdb를 사용하여 찾아봅시다. (어셈블리어 쪽에 빨간상 위치에 브레이크 포인트 걸려있는 곳입니다.)

 [그림 2] gdb 화면

1. 먼저 브레이크 포인트를 problem_child 함수 안에 buffer에 걸었습니다.
2. 그 다음 r(run) `perl -e 'print "A"x41'` 실행하였습니다. (인자값에 A 41개를 넣는겁니다. 41보다 큰수 해봐야 41길이 만큼 buffer에 넣기 때문에 41로 하였습니다.) 
3. r 로 넣었다면 브레이크포인트에 걸립니다. 그곳이 buffer가 만들어지려는 곳(아직 만들기 직전 상태입니다.)
4. ni(nexti)로 어셈블리 한줄 실행 시키면 buffer가 만들어집니다.
5. i(info) reg ebp esp 로 확인하면 esp(stack point)가 buffer의 첫번째 주소를 가리킵니다. 
6. 따라서 buffer의 주소값은 0xbffffac4입니다. (복사한 소스로 만들어진것이 때문에 원본과 약간의 주소값 차이가 있을수 있습니다.) 

 
 2.  stack frame point을 이용한 bof 공격 

stack frame point는 리턴값 주소값에서 1byte만 바꾸어서 공격하는 방식입니다.  (어셈블리어 쪽에 빨간상 위치에 브레이크 포인트 걸려있는 곳입니다.)

 [그림 3] 41번째의 A가 buffer의 리턴값 마지막 1byte에 들어간 모습

 [그림 4] main 함수로 넘어오고 나서 ebp esp 값

1. problem_child에서의 buffer의 리턴값을 받은 main함수에서 ebp 값입니다. 이때가 main함수에서 leave 위치입니다.
2. ni하여 main의 ret으로 이동하면 ebp의 위치에 있는 4byte를 읽어 드립니다. (ebp : 0x0f400140)
3. ni하면 0x0f400140값에 위치한 것을 진행합니다. 진행하게되면 아래와 같은 화면이 나옵니다.
 [그림 5] 계속 진행한 화면

4. 위와 같이 메모리에 접근하지 못하여 오류가 나옵니다.
5. 만약 0x0f400140이 shellcode가 있는 부분이라면 shellcode를 실행하게 됩니다. 
6. shellcode를 argv[1]에 넣고 공격합니시다.
7. 그전에 argv[1]의 주소값을 알아봅시다. argv[1]의 주소값은 환경변수 첫번째 앞에 붙어있습니다. 지금은 소스코드가 있으니 소스코드를 변경하여 알아봅시다.

 [그림 6]argv[1] 주소값 알기 위한 코드

 [그림 7] argv[1]의 주소값

8. 위의 정보를 가지고 bof 공격 
 [그림 8] bof 공격

ps. 여기서 argv[1]의 주소는 원래보다 좀더 뒤쪽을 선택해주어아야 \x90을 밟고 shellcode로 넘어갑니다.
ps2. 또한 1byte 넣어주는 것은 약간의 변경이 생길수 있습니다.

Comments