ipwn
[SCTF] noleak 본문
Mitigation
[*] '/home/agh04140/pwn/SCTF/noleak/noleak'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
기본적으로 canary랑 nx랑 partial relro만 걸려있다.
바로 분석을 해보자.
Analyzing
|
일단 가장 먼저 system으로 echo flag하는 건 아무 쓸모가 없다. 이 루틴을 넣어 준 이유는 system함수를 자연스럽게? 주기 위한 의도가 아닐까 생각해본다.
그 다음으로 canary_leak함수가 있는데 canary_leak부분은 사실상 쓰레기 함수니까 보지 않도록 하겠다.
leak_memory
|
이 부분은 heap에 값들을 담아주고 바로 free를 해주는 부분이다.
사실 이 부분에서 어떻게 저 청크를 unsorted bin으로 보내서 libc leak을 하고 libc 내부의 가젯들을 잘 섞어써서 쉘 따는 문제인가 했는데 어떻게 해도 unsorted bin으로 보내지지가 않아서 그건 아니라 판단을 했다.
일단은 heap에 값들을 담는다는 부분에서 킵
bof
|
이 부분에서 stdout, stderr을 닫고 힙에 stdin으로 값을 담는다.
중요한 부분은 아까 위에 있었던 memory_leak함수에서 할당한 size보다 작은 사이즈를 할당을 하므로 UAF가 발생하게 된다.
그리고 아래의 while문을 돌면서 스택에 힙에 있던 값을 담아주는데 이 함수에서 할당한 0x64 size보다 더 많은양인 0xc7만큼 입력을 받게 되어서 0x27만큼 overflow가 발생하게 된다.
이제 익스 시나리오를 작성해보자.
Scenario
시나리오를 작성하기 전에 얻은 정보들을 확인해보자.
1. bof 함수에서 overflow가 나는데, loop를 돌 때 idx를 체크하는 변수를 덮을 수 있으므로 canary 우회 가능
2. uaf로 원하는 값을 ret 이후에 자유자재로 덮을 수 있음
3. system함수가 있긴 하지만, 힙 릭도 못하고 data영역에 ed, vi, sh같은 명령어들이 쓰여져 있는 것도 아니므로 가젯을 바로 넣어줄 수가 없음.
4. 하지만 fgets함수의 특성상 rsi에 힙 주소가 담기긴 하므로 /bin/sh를 인자에 담을수는 있다.
이렇게 얻은 정보들로 이제 쉘을 획득하면 되는데, 언듯보면 mov rdi, rsi와 유사한 가젯들이 있어야 가능할 것 같지만 사실 바로 가능한 방법이 하나 있다.
바로 __libc_start_main함수를 이용하는 것이다. (사실 이 방법은 이전에 몇 번 생각은 해 봤었는데, 몇 달전 임준오형이 학교에 와서 강연해 준 정보로 사용 방법을 확실히 알았다.)
위 사진을 보면 __libc_start_main함수는 rdi에 main함수를 넣고 rsi에 argc를 넣어주게 된다.
이 말은 즉 rdi에 있는 함수를 rsi, rdx ....~ 라는 인자들로 실행시킨다는 의미가 되는데, 이 점을 통해서 익스를 할 수 있다.
|
위와 같은 형식으로 함수를 실행시켜주면 sysetm("/bin/sh;")가 실행되게 된다는 의미이다.
이 점을 통해서 솔브를 작성하면 될 듯 하다.
다시 시나리오를 짜보자
1. memory_leak함수에서 아다리 잘 맞추고 값 잘 넣어서 페이로드 작성
2. bof함수에서 작성된 페이로드 기입
3. shell!
Exploit
|
아 익스를 하는게 문제점이 하나 있다면 stdout err을 닫았기 때문에 redirection을 해줘야 한다는 점과 바이너리만 익스를 해서는 IO가 제대로 나오지 않는다는 점이다. (리모트로 열어서 따야 함)
지금 돌아보면 다 쉬운 문제였던듯 하지만 또 막상 대회하면 나오던 것들이랑은 다르게 나오겠지.. 스스로 연구하는 힘을 길러야 할듯.
'CTF's > SCTF' 카테고리의 다른 글
[SCTF] catch_the_bug (exit 내부 루틴으로 exploit 하기) (0) | 2019.03.06 |
---|