pwnable 9번 문제인 BOF_PIE 이다.

 

보아하니 매번 실행할 때마다 출력해주는 주소의 위치는 바뀌고, 우리한테 무언가 값을 입력받는다.

 

32bit elf 파일, NX-bit와 PIE가 걸려있다.

 

main문에서는 welcome 함수를 실행 후 Nah를 출력한다.

 

welcome 함수에서는 welcome의 주소를 출력하고, v1에 scanf로 입력을 받는다.

 

그리고 함수들 중 j0n9hyun이라는 함수가 있는데, 보아하니 flag를 출력해주는 함수이다.

PIE가 걸려있는것을 고려해보았을 때, 매 함수는 실행 할때마다 주소가 바뀌지만, 각 함수들의 offset은 동일할 것이다.

우리는 프로그램을 실행하면서 welcome의 주소를 알 수 있다.

따라서 현재 바이너리에서 j0n9hyun의 주소가 welcome의 주소로부터 얼마나 차이가 나는지를 통해 offset 크기를 알 수 있다.

 

0x909 - 0x890 = 0x79, 즉 offset 크기는 0x79이다.

자 그러면 우리가 입력을 받는 v1은 ebp-12h에 있으니, v1(18) + sfp(4) = 22, 22개의 더미데이터를 입력하고, 주어진 welcome 함수 - 0x79를 한 값을 ret에 써주면 j0n9hyun이 실행될 것이다.

익스코드를 짜보자.

 

성공적으로 익스플로잇이 된다.

Load of the BOF 문제를 풀어보기로 했다.

1번 문제인 gremlin 이다.

 

보아하니 argv에 입력받은 내용을 strcpy로 buffer에 복사하는 코드이다.

strcpy로 값을 복사하니 bof가 일어날 것이다.

buffer에 쉘코드를 넣고 ret 주소를 다시 buffer의 주소로 가리키면 될 것이다.

buffer의 사이즈는 256, sfp(4)를 더해 260칸이므로 쉘코드를 제외한 나머지 칸들을 NOP sled로 채워주면 될 것이다.

 

strcpy가 실행된 부분인 main+59에 bp를 걸고, A를 넣어서 어디서부터 buffer가 입력이 되는지 확인해보자.

 

보다시피 0xbffff918 부터 입력이 된다.

 

따라서 쉘코드가 깨지지 않게 적당히 NOP sled를 넣고, 쉘코드를 넣고, NOP sled를 다시 넣고 ret 주소를 0xbffff918로 적어주면 쉘코드가 실행될 것이다.

 

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80

 

쉘코드는 24바이트 쉘 코드를 사용할 것이다.

즉, 260 - 24 = 236 만큼 앞 뒤로 NOP sled를 써주자.

그리고 그 뒤의 ret 주소에 0xbffff918를 리틀엔디안 형식으로 넣어주면 될 것이다.

 

성공적으로 쉘을 땄다.

hello bof world

'Hacking > Pwnable' 카테고리의 다른 글

[LOB] 3번 - goblin  (0) 2020.08.16
[LOB] 2번 - cobolt  (0) 2020.08.16
Hackerschool FTZ - level9 write up  (0) 2019.09.21
Hackerschool FTZ - level8 write up  (0) 2019.09.18
Hackerschool FTZ - level7 write up  (0) 2019.09.18

pwnable 8번 문제인 Offset 이다.

 

이런식으로 실행이 되는데, 입력을 받는 다는 것 빼고는 잘 모르겠으니 바이너리를 한 번 보자.

 

32비트 elf파일, NX-bit가 걸려있으니 shell코드를 못 쓰고, PIE가 걸려있으니 매 타임 실행할 때마다 변수, 함수들의 오프셋 위치가 달라질 것이다. FULL RELRO라 GOT Overwrite도 못한다.

 

s에 입력을 받고, select_func라는 함수에 s를 넘겨준다.

 

select_func에서는 v3라는 함수포인터에 two라는 값을 넣어주고, dest에 넘겨받은 우리가 입력해준 값을 받고, 그 값이 one이면 v3를 one으로 바꿔준다.

 

두 함수는 정말 별거 없다.

 

함수 포인터에 값을 넣어서 실행하는 방식이니 v3를 뭔가로 덮어야한다고 생각했다.

그래서 함수들을 보니, 함수 중에 print_flag라는 함수가 있다.

 

flag를 출력해준다.

그말은 즉 v3의 값을 print_flag함수의 주소로 덮어쓴다면 flag가 출력될 것이다.

main에서 s는 gets로 입력을 받으니 BOF가 일어날 것이다.

select_func에서의 dest는 ebp-2Ah, v3는 ebp-Ch에 있으니, 0x2A - 0xC = 0x1E = 30(10) 이 된다.

즉, 우리는 더미값을 30칸 채워주고, print_flag의 주소를 쓰면 될 것이다.

익스코드를 짜보자.

 

성공적으로 익스플로잇이 된다.

+ Recent posts