BUUCTF-PWN-[第五空间2019 决赛]PWN5

这题考到 格式化字符串的方法 我之前没有学过 根据wp写完这题去看看原理

下载打开环境

checksec看看

BUUCTF-PWN-[第五空间2019 决赛]PWN5_第1张图片

 发现有三个保护 nx打开 所以无法写入shellcode

现在看看ida32

BUUCTF-PWN-[第五空间2019 决赛]PWN5_第2张图片

 发现/bin/sh

进去看

BUUCTF-PWN-[第五空间2019 决赛]PWN5_第3张图片

发现就在主函数里面

我们进行代码审计 发现输入名字 他会返回名字 然后再输入密码 如果密码和unk_804c044一样 输出shellcode

我们看看这个函数是什么

搜索一下

BUUCTF-PWN-[第五空间2019 决赛]PWN5_第4张图片

 

 发现是随机数 这样我们就无法通过判断得到shellcode

我们现在又两个方法

1. 将atoi的判断变为system 然后手动输入/bin/sh

这样他就会在判断的时候进行执行shellcode

我们开始查找

在这之前我们需要了解 got和plt

BUUCTF-PWN-[第五空间2019 决赛]PWN5_第5张图片

 因为我们需要plt里面的shellcode进行执行 

plt和got是什么

这两个其实就是两个表 我们的函数进行执行

必须要通过这两个表去寻找 函数的真正地址 因为是经过

plt ->got ->plt ->存储函数地址的函数->atoi的真正地址

我们在执行atoi这个函数的前面 他不会给我们函数的地址 只有运行到这个函数了

他才会给函数进行分配地址

在第一次运行该函数的时候 他就会进行上述的操作

第二次就不会了

plt->got->atoi

直接就能找到

类似于中转站

继续做题

我们知道了plt和got

我们要如何构造呢

BUUCTF-PWN-[第五空间2019 决赛]PWN5_第6张图片

我们发现plt中存在system和atoi 

BUUCTF-PWN-[第五空间2019 决赛]PWN5_第7张图片

 而atoi又存在和我们输入的东西进行if判断

那如果我们在执行的时候 把atoi的got指向system的plt呢

atoi.plt->atoi.got->system.plt->函数->system

这样我们就得到system函数

如果我们输入了/bin/sh 那他就会执行

system('/bin/sh')

这样就成功了

但是有一个问题 我们利用这个是通过print函数的漏洞

我们输入的东西会在调用函数前先压入栈内 我们不知道我们该什么时候进行更改

所以我们需要计算出偏移量 这里就可以使用格式化字符串

格式化字符串

因为这个漏洞是通过print函数出现的

因为程序员的偷懒

print("%d",str)
print(str)

 这两种看似是一样的 但是第二种就很容易出现格式化字符串漏洞

因为没有对输出字符串进行规定

我们可以一直构造 %p来查看地址

例如

AAAA -%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p

因为输出没有管理

所以他会把str 直接进行查找

查完AAAA 开始执行%p

%d 用于读取10进制数值

%x 用于读取16进制数值

%s 用于读取字符串值

%n 用于讲当前字符串的长度打印到var中,例 printf("test %hn",&var[其中var为两个字节]) printf("test %n",&var[其中var为一个字节])

%p

输出十六进制数据,区别是有前缀“0x”,实际上就是输出个指针,所以32位输出4字节,64位输出8字节

我们可以进行产生 看看有没有字符串漏洞的产生

 我的理解是这样的BUUCTF-PWN-[第五空间2019 决赛]PWN5_第8张图片

 

我们发现 到4141414 有10个量 就是他从压入栈到执行 需要10个偏移量

所以我们

我们开始写exp

from pwn import *
p=remote('node4.buuoj.cn',25418)
elf=ELF('./pwn')
atoi_got=elf.got['atoi']
system_plf=elf.plt['system']
payload=fmtstr_payload(10,{atoi_got:system_plf})
p.sendline(payload)
p.sendline('/bin/sh')
p.interactive()

你可能感兴趣的:(PWN的学习,安全)