stack5 - 쉘 코드

oogu ㅣ 2022. 9. 7. 19:59

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
  char buffer[64];

  gets(buffer);
}

코드가 너무 깔끔하다.. gets 함수를 이용해 ret 값을 shellcode가 존재하는 곳으로 변조시키자

stack5 부터는 32bit 이다.

[그림 1-1]

gdb-peda pattern 이용해 ret 위치를 구한다.

[그림 1-2]
[그림 1-3]

[그림 1-2] 를 통해 나온 문자열을 main+22 에 브레이크 포인트로 걸고 run 한 후 삽입한다.

이 때 ret 실행전 스택을 보면 삽입된 문자열인걸 알 수 있다. 스택에 들어간 문자열 위치를 구하면된다. 문자열 위치로 점프를 하기 때문이다.

[그림 1-4]

offset 이 76이다. 즉 buffer 변수에서 부터 ret 전 까지 76byte 거리가 존재한다는 걸 알았다.

[그림 1-5]

stack5 문제는 이전 문제 처럼 win 함수가 존재하지 않는다. 따라서 직접 shellcode 를 넣고 ret에서 shellcode 위치로 점프해야한다. gets 함수는 한 번 밖에 없으므로 payload 작성시 shellcode도 입력되어야 한다. 

따라서 shellcode는 argc, argc .. 를 덮어씌울 것이다. 근데 ret 에서 argc 로 이동하면 shellcode가 존재하기 때문에 shellcode가 실행된다.

[그림 1-6]

[그림 1-6] 보고 payload 작성하면 "A"*72 + shellcode 위치 + shellcode 이다.

그렇다면 shellcode가 어디에 삽입되는지 찾아야한다.

[그림 2-1]

shellcode는 32bit shellcode 구글링하면 찾을 수 있다.

shell_addr는 아직 위치를 모르기 때문에 dummy 값으로 넣는다.

[그림 2-2]

스택을 확인하면 shell_addr 값(0xffffffff)을 확인할 수 있고 바로 밑(0xffffd080)에 shellcode가 들어간 걸 알 수 있다.

따라서 0xffffffff 를 0xffffd080 으로 변경하면 된다.

shell_addr 값을 수정 후 실행하면 shell을 딸 수 있다. ㅎㅎ

'protostar' 카테고리의 다른 글

stack6  (0) 2022.09.09
stack5 - Return to libc(RTL)  (0) 2022.09.07
stack4  (0) 2022.09.07
stack3  (0) 2022.09.07
stack2  (0) 2022.09.06