环境准备
我现在用的是kali
现阶段工具:checkesc、IDA、比较完善的python环境
下载工具的话,我这里不提供了
buuctf——test_your_nc1
参考wp:
BUUCTF PWN-----第1题:test_your_nc_buuctf test_your_nc-CSDN博客
查看的资料:
checksec安装和简单介绍 - LuoSpider - 博客园 (cnblogs.com)
因为啥也不会,先按大佬思路来
checeksec
前期先学这几个参数
1.Relro:Full Relro(重定位表只读)
Relocation Read Only, 重定位表只读。重定位表即.got 和 .plt 两个表。
2.Stack:No Canary found(能栈溢出)
Canary, 金丝雀。金丝雀原来是石油工人用来判断气体是否有毒。而应用于在栈保护上则是在初始化一个栈帧时在栈底(stack overflow 发生的高位区域的尾部)设置一个随机的 canary 值,当函数返回之时检测 canary 的值是否经过了改变,以此来判断 stack/buffer overflow 是否发生,若改变则说明栈溢出发生,程序走另一个流程结束,以免漏洞利用成功。 因此我们需要获取 Canary 的值,或者防止触发 stack_chk_fail 函数,或是利用此函数。
3.NX: NX enable(不可执行内存)
Non-Executable Memory,不可执行内存。了解 Linux 的都知道其文件有三种属性,即 rwx,而 NX 即没有 x 属性。如果没有 w 属性,我们就不能向内存单元中写入数据,如果没有 x 属性,写入的 shellcode 就无法执行。所以,我们此时应该使用其他方法来 pwn 掉程序,其中最常见的方法为 ROP (Return-Oriented Programming 返回导向编程),利用栈溢出在栈上布置地址,每个内存地址对应一个 gadget,利用 ret 等指令进行衔接来执行某项功能,最终达到 pwn 掉程序的目的。
4.PIE: PIE enable(开启ASLR 地址随机化)
Address space layout randomization,地址空间布局随机化。通过将数据随机放置来防止攻击。
对了,还能看出是64位的
我简单理解就是No Canary found(可以使用栈溢出)这个关闭,就用栈溢出思路解题
NX: NX enable(不可执行内存)开了NX防护(堆栈不可执行),简单解释就是存入的数据不能被执行
PIE: PIE enable(开启ASLR 地址随机化)这个就说明能不能可以随意调用地址(可以是函数的地址)来解题
这一题就是
64位。能用栈溢出。不能执行内存,就是里面已经有的缓存数据。不能随意地址转换
64位IDA打开后就是这样,可以看见/bin/sh,双击
找到函数所在地址(位置),main函数,我们进行查看
双击main函数,按f5
就是system()的执行漏洞,用linux直接nc就行
nc node4.buuoj.cn 29096
问题
问:为什么直接nc buuctf的域名+端口就可以进行命令执行?
nc 192.168.10.1 8080,这就相当于进行正向反弹shell
对方主机开放了8080端口,你(攻击机)主动去连接他,他(目标靶机)执行shell,生成一个简单的交互环境
我们来看一下这个system('/bin/sh')的作用(我少加了一个分号,修改之后就好了)
问:什么是正向反弹shell?和(反向)反弹shell的区别?
正向反弹shell(Reverse Shell): 在正向反弹shell攻击中,受害者的系统会连接到攻击者控制的系统上。简单来说,受害者的系统会发起对攻击者系统的连接,并将一个交互式shell或命令执行权限转移给攻击者,这样攻击者就能够远程控制受害者的系统。
反向反弹shell(Bind Shell): 与正向反弹shell相反,在反向反弹shell攻击中,攻击者的系统会连接到受害者的系统上。攻击者会在自己的系统上启动一个监听程序,然后等待受害者系统主动连接过来。一旦连接建立,攻击者就可以远程控制受害者的系统。
给你的pwn文件就是靶机的漏洞利用点
buuctf——rip
参考wp:
”BUUCTF之pwn题解(一些栈题+程序分析)_buuctf pwn-CSDN博客
CTF buuoj pwn-----第2题:rip_buuoj rip-CSDN博客
初学pwn-BUUCTF(rip)_buuctf rip-CSDN博客
按思路来,第一步checksec一下
tip:可以直接checksec文件夹哦,更方便。
命令是checksec --dir=pwn题目
结论:64位。有栈溢出。可以执行内存。可以地址转换。
嘶~真杂,打开看看,按f5
代码大概意思:
定义了一个变量数组s,大小15
接着,程序通过
gets
函数从你的(标准)输入中读取一行字符串,并将其存储在s
数组中输出s
结论:只要是变量,就可以栈溢出
问:什么是栈溢出?
ai回答:
栈溢出是指向栈中写入了超出限定长度的数据,溢出的数据会覆盖栈中其它数据,从而影响程序的运行。栈溢出是一种常见的安全漏洞,攻击者可以利用栈溢出漏洞来执行恶意代码。攻击者通常会向程序中输入超出预期的数据,从而导致栈溢出。为了防止栈溢出,可以使用一些技术,例如堆栈保护、地址随机化等。
下面是一个栈溢出的例子,假设有一个函数,它接收一个字符串作为参数,并将其复制到一个缓冲区中:
void copy_string(char *dest, char *src) { char buffer[10]; strcpy(buffer, src); strcpy(dest, buffer); }
如果传递给该函数的字符串长度超过了10个字符,那么就会发生栈溢出。攻击者可以利用这个漏洞来执行恶意代码,例如覆盖函数返回地址,从而控制程序的执行流程。
双击箭头指的s
可以发现是15个空间大小,也可以从下面的0x000000000F看出是15个空间大小
我们再去查一下漏洞利用的点,就是栈溢出后,执行什么东西来得到flag
shift+f12查看string window
tip:在IDA中使用Shift+F12快捷键可以打开字符串窗口,该窗口用于显示程序中包含的所有字符串。字符串窗口可以帮助你查看和分析程序中的字符串常量。
双击进入
结论:使用栈溢出,填充s数组,使其导致栈溢出的漏洞,溢出的执行的东西就是fun函数,也就是需要我们溢出后指向fun函数的地址,这个最后的地址也叫返回地址
0x401186就是地址
或者
构造exp
from pwn import *
nc=remote("node4.buuoj.cn",29857)
# 第一种写法
# payload = 'a' * 23 + p64(0x401185).decode("iso-8859-1") + p64(0x401186).decode("iso-8859-1")#A和a都是随意的
# 第二种写法
payload = b'a'*23+p64(0x40118A) #输入payload来进行操作以拿到程序的shell
# 其中 b是bytes的缩写,是bytes类型,p64是打包函数,把地址转换为b类型的二进制形式
nc.sendline(payload)
nc.interactive()
- 0x40118A的由来
在IDA中,打开fun函数, 可看到fun()函数开始的地址为0x401186, "/bin/sh"指令执行的地址为0x40118A
两种方法:
1.标红的
2.右键悬着text view
- p64()函数是将字符串转二进制流
两种方法都可以,已经尝试
第一个方法很有意思,可以研究研究
第二个方法是直接指向了system函数
第一个方法是指向了fun这个函数
但是那个博主没成功,修改后,给出了这样的解释,
执行脚本之后,发现并没有获得shell权限。遇到这个问题,就很奇怪,明明是没有什么问题,很简单的一个练习。只能求助于百度。搜索之后发现64位系统中,需要地址对齐之后才可以执行system。这里需要在fun函数的地址之前加一个retn的地址,在IDA-view里随便找一个retn的指针都可以。具体的原理还没理解,不过这样可以解决地址对齐的问题。
意思就是401186不动,再加一个就行,但是经过我的尝试,这个两个地址必须符合几个条件
401186必须在最后,401185修改的区间在40118[5-8|A-B],因为只有
问题
问:什么是偏移量?
偏移量(Offset):偏移量是指变量或数据相对于某个基地址的位置偏移量。它表示了变量或数据在内存中的位置
问:为什么15个空间大小后还要+8个?代码片段中多出的8个大小的空间是哪一部分?
在main函数中,双击s,s占据了15个db,再加上"s"[saved registers]的8个db,一共23个db.根据代码片段中的表示方式,我们可以看到
+0000000000000000 s
后面的db 8 dup(?)
定义了一个名为r
的字符数组,并且分配了8个未初始化的元素。所以,这8个大小的空间是属于字符数组r
的。
warmup_csaw_2016
wp参考:
[BUUCTF-pwn]——warmup_csaw_2016-CSDN博客
buuctf|warmup_csaw_2016 1_嚚_瘖的博客-CSDN博客
[BUUCTF]PWN------warmup_csaw_2016_pwn warmup_csaw_2016_HAIANAWEI的博客-CSDN博客
Buuctf——warmup_csaw_2016 - mu'a - 博客园 (cnblogs.com)
从题海中入门(三)warmup_csaw_2016 - FreeBuf网络安全行业门户
checksec一下
没有说明位数,但是用32位打开报错提示用64位打开.有栈溢出
分析main代码
看最后的return,发现最后可以被溢出的是变量v5,且该参数没有没做处理。
双击查看v5,得出偏移量40+8
我敲,感谢大佬,我陈哥,pwn神教我认识偏移量
我来回答你为什么要加8,首先v5的总偏移量是0x40,这是ida算好的
然后请看图
tip:
64位的pwn文件rbp是0x8,也就是8
32位的是0x4,也就是4
v5为了溢出,要先填满0x40,然后加上rbp的这个8,就到了ret,ret就是用来指向返回的地址,然后你就指向system的哪个函数地址就行了
tip:
RBP
寄存器的值指向当前函数的栈帧底部。不好理解,就按上面我写的理解就行。RET 是指令中的缩写,代表函数返回(return)指令。当函数执行完毕时,执行 RET 指令将控制权返回给调用该函数的代码。
shift+f12看到cat flag.txt
意思就是说,不在有执行环境,变成了直接找到flag,刚好也能栈溢出,那我们直接只想这个地址就行
双击cat flag.txt他找到所存在的函数
双击进入函数按f5
和上一题一样
发现0x400611是压参数的地方,将其作为返回地址
tip:压参数
我的理解是:将参数压入栈,栈是一个小的存储空间,用0x400611标识
构造exp
from pwn import *
nc=remote("node4.buuoj.cn",29727)
# 第一种写法
#payload = 'a' * 0x48 + p64(0x400611).decode("iso-8859-1") + p64(0x400611).decode("iso-8859-1")
#payload = 'a' * 0x48 + p64(0x400611).decode("iso-8859-1")#这个也可以
# 第二种写法
payload = b'a'*(0x40+8)+p64(0x400611) #输入payload来进行操作以拿到程序的shell,0x40+8=0x48
# # 其中 b是bytes的缩写,是bytes类型,p64是打包函数,把地址转换为b类型的二进制形式
nc.sendline(payload)
nc.interactive()