(writeup) b01lers CTF 2024
- giải này khá dễ nên chỉ wu bài arm thôi nhé
- mấy bài khác làm lai rai nên sẽ để script và idea exploit thôi
shall-we-play-a-game
easy note
bctf{j33z_1_d1dn7_kn0w_h34p_1z_s0_easy}
medium note
- source tương đồng bài easy note nhưng hơi khác chút
- khác luôn libc (2.36) (không dùng hook được)
- thay vào đó ta sẽ ow trên stack để ret2libc
- có thêm vài security check thôi
- script:
bctf{sm4ll_0v3rfl0w_1z_571ll_b4d_0k4y}
seeing-red
- hàm use_ticket() là bịp
- fmt + bof
- ret2libc
- script
bctf{dr1ving_a_n3w_maser@t1_d0wn_@_d3ad_3nd_str33t_eb30c235cde76705}
zero-to-hero
- là shellcode ascii nhưng filter syscall –> brute flag từng bit
arm-and-a-leg


main()

worthyness_tester()

get_address()

feedback()
analyse
- chall cho 2 option, nhưng đọc sơ qua hàm main() thì đ' thấy khác gì =))
- nó sẽ có hàm check để đi tiếp get_address() và feedback() với input chỉ cần là 1337
- trong hàm get_address() có bug FMTSTR –-> leak libc, stack, v.v..
- trong hàm feedback() có BOF cho phép nhập tận 0x100 byte
- note: architecture là aarch64 nên cách khai thác hơi khác arm32 có wu trước đây
leak primitive
- có canary –-> leak canary rồi leak thêm libc
❌ ret2shellcode
- dù checksec thấy NX tắt, cộng thêm gdb vmmap thấy stack là rwxp nên hơi hoang mang ( chắc do qemu ngu ngu )
- shellcode
link: https://shell-storm.org/online/Online-Assembler-and-Disassembler/

- test thử thì local ra đấy, nhưng server thì không

- script tham khảo thôi =))

✅ ret2libc
- đổi qua phương án này
- cái khó là phải kiếm các gadget từ libc
- về libc thì lấy từ docker ra

- để thực thi system('/bin/sh\0') thì thanh ghi x0 (tương đương $rdi) là 1 addr trỏ chuỗi /bin/sh
- thanh ghi return (giống $rip) là x30 cần chứa system
- và cần 1 lệnh call system (ở trường hợp này lấy lệnh
blr
)
- sau khi giành 7749 time để lục gadget thì thu đc 2 gadget có vẻ usefull
mov x0, x19 ; blr x22
search key là mov x0
đưa value x19 vào x0 rồi call x22
ldp x19, x21, [sp, #0x10] ; ldp x22, x23, [sp, #0x20] ; ldp x29, x30, [sp], #0x60 ; ret
search key là ldp
đưa [sp + 0x10] vào x19
đưa [sp + 0x10 + 0x8] vào x21
đưa [sp + 0x20] vào x22
đưa [sp + 0x20 + 0x8] vào x23
đưa [sp] vào x29
đưa [sp + 0x8] vào x30
tăng sp lên 0x60
- vì ta cần /bin/sh ở x0 nên sẽ tìm
mov x0
- và cho ra khá nhiều gadget tương đồng

để nguyên ở đó, sẽ so sánh blr
các thanh ghi với lệnh khác
- vì ta cần x19 chứa /bin/sh, ngoài ra cần liên quan cả
ret
lẫn thanh ghi x30

ngồi đối chiếu 2 lệnh thì thấy lệnh này khả quan
- ok việc chọn gadget xong, ta qua bước ret2libc
- ở mỗi func đều có check canary nên mỗi lần return 1 hàm ta sẽ thêm canary để bypass
- lạ 1 chỗ khi debug thì return ở main() lại không nằm sau main() =))))
- mà nó nằm sau hàm feedback() (nhưng lại có return main rồi check canary ở main() bình thường :v )
- return sau feedback() lại lấy stack pointer (sp) là sau canary của main nên từ sp đó chain payload hợp lí thôi

flow như sau
canary
sp : x29 (junk)
sp + 0x8: x30 ($rip) (gadget_mov)
sp + 0x10: x19 (binsh)
sp + 0x18: x21 (junk)
sp + 0x20: x22 (blr x22) (system)
sp + 0x28: x23 (junk)
get flag

bctf{c0st_y@_@n_ARM_@nd_a_l3g!_a1659d0e634100240e6}