前言

目前在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())

上面是抄的别人博客的东西

https://www.yuque.com/hxfqg9/bin/yxegb6

接下来是自己学到的

1

p.recv(n)等价于p.recv(n)

一般与p.recvuntil()连用

假设程序会这样输出:

“aaaaaaaab\x12\x34\x56\x7f”

我们想接收到后面4位,将其当做地址,那么可以这样写脚本

p.recvuntil('b')
imp_addr=u32(p.recv(3))

此时imp_addr的值就是0x7f563412

# 2024.4.11 update
r=p.recv(6)
puts_addr=u64(r.ljust(8,b'\x00'))

2

另一种情况程序自身打印了一个地址

“0x7f563412”

这时候这个地址是以字符串的形式输出的,我们这时候想要接收数据可以这样

p.recvuntil('\n')  ####这里里面填入的字符为0x前面的字符
imp_addr=eval(p.recv(10))

也可以这样

imp_addr=eval(p.recvuntil('\n')[-11:-1])###recvuntil里面填入的字符是想要字符的后面的个字符

程序为多行输出的时候,也可以这样

p.recvuntil('gift!\n')
addr=eval(p.recvuntil('\n')[-11:-1])
###程序输出是这样的:
'''
OHHH!,give you a gift!
0x565af770
Input:
'''

其中第-1个字符是’\n’,由于python左闭右开的特点,最后写-1刚好能滤掉\n

eval函数可以参考一下python基础语法

3

发送完payload之后想用gdb调试一下,

可以在这样

p=process('./pwn')
······
gdb.attach(p,'b *0x080485E5')
p.sendline(payload2)

在发送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的地址

image-20230711225109422

5

在线查找libc库

https://libc.rip/

注意地址写后三位

LibcSeacher联机查找,不需要下辣么多版本的库

python3 install LibcSearcher

https://blog.csdn.net/MDong1344/article/details/120277351

6

*# 给定字节串表示的地址* 
address_bytes =b'P\x0e\xc8\x9d\x12\x7f\n'
# 将字节串转换为整数(假设是小端序)*
address_int = int.from_bytes(address_bytes, byteorder='little')

ret2syscall

64位ret2syscall

rax=0x3b
rdi=bin_sh_addr
rdx=0
rsi=0
syscall

4.11更新

1

context(log.level='debug')

别说了,问就是真神

2

puts_plt=elf.sym['puts']
puts_got=elf.got['puts']
atoi_got=elf.got['atoi']
free_got=elf.got['free']