学习pwn
前言
目前在0基础学习pwn
记录一下最近学习过程中遇到的一些知识点
pwntools的运用细节
发送 payload
p.send(payload) 发送 payload
p.sendline(payload) 发送 payload,并进行换行(末尾\n)
p.sendafter(some_string, payload) 接收到 some_string 后, 发送你的 payload
p.sendlineafter(some_string, payload) 接收到 some_string 后, 发送你的 payload,加个换行
接收返回内容
p.recv() 一直接收输出
p.recvn(N) 接受 N(数字) 字符
p.recvline() 接收一行输出
p.recvlines(N) 接收 N(数字) 行输出
p.recvuntil(some_string) 接收到 some_string 为止
p.interactive() 直接进行交互,相当于回到shell的模式,一般在取得shell之后使用
生成 shellcode
asm(shellcraft.sh()) |
上面是抄的别人博客的东西
接下来是自己学到的
1
p.recv(n)等价于p.recv(n)
一般与p.recvuntil()连用
假设程序会这样输出:
“aaaaaaaab\x12\x34\x56\x7f”
我们想接收到后面4位,将其当做地址,那么可以这样写脚本
p.recvuntil('b') |
此时imp_addr的值就是0x7f563412
# 2024.4.11 update |
2
另一种情况程序自身打印了一个地址
“0x7f563412”
这时候这个地址是以字符串的形式输出的,我们这时候想要接收数据可以这样
p.recvuntil('\n') ####这里里面填入的字符为0x前面的字符 |
也可以这样
imp_addr=eval(p.recvuntil('\n')[-11:-1])###recvuntil里面填入的字符是想要字符的后面的个字符 |
程序为多行输出的时候,也可以这样
p.recvuntil('gift!\n') |
其中第-1个字符是’\n’,由于python左闭右开的特点,最后写-1刚好能滤掉\n
eval函数可以参考一下python基础语法
3
发送完payload之后想用gdb调试一下,
可以在这样
p=process('./pwn') |
在发送payload前使用gdb.attach语句
第二个参数相当于在gdb里面下断点,一般是输入函数的下一个地址
进入gdb调试后,先按一下c,然后就发现断在了之前写的那个地址
这时候可以用stack 50指令查看一下当前程序里栈的情况
有时上述情况会失败,这里介绍另一种调试方法
在py文件的输入前使用pause函数
pause() |
等程序运行到pause后重新开一个终端输入
gdb attach 4575(pid) |
进入gdb 后在输入后下断点,之后按下c,让程序继续执行
之后转到之前的终端,回车使得脚本继续运行,此时即可以实现调试功能
4
使用cyclic计算偏移量
步骤:
1.首先在终端用cyclic 200指令生成一个序列,这个序列是cyclic特定的序列
然后复制这个序列
2.用gdb pwn指令调试本地程序,一直运行到输入阶段,将刚刚生成的序列复制输入进去,然后回车
3.继续c运行程序,最后程序肯定会断在一个地方,ret 某个错误地址,记住这个地址的低4个字节
4.然后重新开一个终端,输入指令cyclic -l 0xxxxxxxxx (这个就写刚刚的低四个字节),cyclic会返回一个数,这个数就是偏移量,从输入的地址一直到ret的地址

5
在线查找libc库
注意地址写后三位
LibcSeacher联机查找,不需要下辣么多版本的库
python3 install LibcSearcher |
6
*# 给定字节串表示的地址* |
ret2syscall
64位ret2syscall
rax=0x3b |
4.11更新
1
context(log.level='debug') |
别说了,问就是真神
2
puts_plt=elf.sym['puts'] |










