内存溢出的危害_漏洞练习之网络编程与堆栈溢出技术

6a23c026a63a4b3e463c20f98b5430b8.png

本文首发于“合天智汇”公众号 作者:萌新

  • 0x00

公众号之前发过Exploit-Exercise之Nebula实践指南,Exploit-Exercise一共有5个镜像可供练习,如下所示

c3c9bf377a2f654a8ddb5d0bcad5098f.png

本系列文章将会介绍第二个镜像Protostar的通关经验。

Protostar涉及栈溢出、堆溢出、格式化字符串漏洞、网络编程、及综合性漏洞。

本文将介绍net,final部分。

关于环境准备,在官网https://exploit-exercises.lains.space/protostar/下载即可。下载后得到iso镜像,使用vmware安装。然后使用user/user即可登录

查看ip

18c267fc32b77bd99f0e7672920e7d6e.png

知道ip后可以在kali中ssh连上

7c0e09211b985580cfbfb546e5a26ea0.png

输入user即可

机器上所有需要分析的程序都在如下路径

845bdc406c28dc3150776eddf8f90a34.png
  • 0x01

第一关,net0

951a7d01c48fd0893ce627026083c573.png

从源码中可以看出,会创建一个在2999端口监听的程序

生成随机数赋给wanted

服务端从标准输入读取输入,将值存在变量i里

i与变量wanted中的值相比较,如果相等则打印thank you sir/madam,我们的目标就是打印这条语句

简单测试下

3853cb0ab223c003cfad5c0c1f9b58de.png

连上2999端口后,程序会打印一条包括随机数串的消息,要求我们以小端32位形式回复就是将string转为integer)

这就很简单的,用python写个程序,包括如下功能:

1.连接到本地2999端口

2.读取服务端发来的信息

3.匹配出程序给出的数字

4.将其转为小端32位格式

5.发回去

6.读取服务端响应

代码如下

cc1ebc16c6c183b66bc752649a1d941f.png

运行后如下所示

525476efe8a1f47998bb0c1474a5cf6c.png
  • 0x02

第二关 net1

3245cca2824ffc3e2132bffb554b22c0.png

和第一关类似,程序在2998端口监听,也会给出要转换的数据,我们按照要求转换后发送回去,只要服务端接收后返回的响应为you correctly sent the data,就说明我们成功了

先简单运行下

ee48ca8ba633c6df992cef823e74f58a.png

这就是要求我们将其转为string

这里同样明确我们的脚本需要具备的功能

1.连接到本地2998端口

2.读取服务端发来的数据

3.unpack数据并将其转为无符号整型,再用str函数处理

4.发给服务端

5.打印服务端的响应

代码如下

2f24474da1e223686960839606a879ca.png

测试如下

dd6112cf24123e22723301ae43dfd69f.png
  • 0x03

第三关,net2

c15ecf124a4bfc692a6f2eab934dba15.png

程序监听在2997端口

简单运行下

44b6470c67f218c54793d884e565d473.png

有无法打印的字符,我们使用hexdump可以看到具体的16进制

224b807e113cbee010a6585c22c426a7.png

结合题目可知,是要求我们将4个无符号整型数相加

流程还是一样的,我们先明确脚本需要实现哪些功能:

1.连接到本地2997端口

2.读取4个数

3.将读取的数转为无符号整数并相加

4.发送给服务端

5.读取响应

代码如下

bf76d60908b39a2a2c7591bdc55e102a.png

测试如下

29b72a923cd25729828b131a377f485b.png
  • 0x04

第四关final0

5bf3882dc6732b612446aae87adb3c90.png

从源码中可以看到,是在本地2995端口进行监听

我们连上去看看

5fce5aab2e66d89fd93e0d39b9f915c2.png

输入test,会返回No such user test

程序在第19行调用get接收我们的输入,分配到buffer为512字节,不过我们可以输入更多,所以此处存在栈溢出漏洞。另外注意到我们输入的test,当程序返回时是TEST,这是因为源码中27到30行将其转为了大写。这样的话,我们直接写入的shellcode就会因此失效。不过仔细看代码,会发现,将字符转为大写的for中用的是strlen(buffer)来计算要转换的字符串的长度,而strlen遇到null就停止了。所以我们可以在null后面加上shellcode,这样我们的shellcode就不会因为被大写转换而失效了。(这一点在后面写payload时需要注意)

我们输入超过buffer大小的内容后,会生成coredump

a172abd73c3b3ffe37f17d7fa421b397.png

其路径如下,我们使用gdb调试,注意到会有权限问题

9bf5866e9478aed9d580b9cd14c8e2fb.png

此时需要切到root,密码为godmode

160300c127eb8f188d4df8d1514c55a4.png

查看寄存器

2e93eb4d8fb49c13fcd63dcc7a261601.png

可以看到eip寄存器被覆盖为0x44444444,也就是DDDD

说明偏移为532

为了拿到shell,我们需要execve函数和字符串/bin/sh的地址

先找execve的

gdb挂上后进行查找

b372d482ae878556fd373edf2669f5e3.png

在下图中找到了execve()的地址0x08048c0c

d0e14771a3464de6b130a43df1a7ca3d.png

然后找/bin/sh字符串的地址

先查找程序依赖的动态链接库文件

cc830c984d62043fbcbf93892f4346f9.png

在其中找/bin/sh

e0a7b7af1542096cadde9c504043bc48.png

1176511是偏移,我们还要找到libc的起始地址

为此需要先找到final的进程id,再查看maps

4d4b1777819d2d8605db58b11ed85bfa.png

权限不够,切到root

7154addf499343b8a8e37360cfe27539.png

看到地址为0xb7e97000

所以字符串/bin/sh的地址为0xb7e97000+1176511

于是就可以写攻击脚本了

代码如下

c2da6b629bc437e0bcd6ed6ee716919c.png

注意

1.pad里的’x00’就是为了防止shellcode失效而特地添加的null(见前面的解释)

2.exp中的AAAA是返回地址,这里不重要,也可以随意填

3.ifconfig就是我们想执行的命令,可以替换成任意命令

执行后如图所示

997e0690b4a87e1f4130ca0b574c1277.png
  • 0x05

第五关final1

8d3676e89a8bdd3c0dcd2da41d4ac696.png

题目的提示告诉我们这是一个和格式化字符串有关的漏洞

经过代码审计,发现漏洞点位于第17行的snprintf和19行的syslog

e8862c8df3712f625382651796b7d086.png

这里是用syslog输出,那么我们可以考虑把syslog的地址改为shellcode的地址

我们先简单看看程序跑起来是怎样的,程序在2994端口监听,所以用nc连上2994

c6adc575b7730054caa25fd2b6a2f9d4.png

%n格式化字符会将已输出的字符数写入到对应参数的内存中,我们可以考虑先用%x打印出栈上的数据

f6a76ac2063891a446075d7760044c31.png

然后去查看syslog

2748c10bcbb4b8d467bd6b74d5f72c18.png

看最近的一条,没有看到aaaaaaa被打印出来,我们可以继续测试

ef993fd847f84f6e343ca757ccdb0a84.png

再次查看syslog

cd054d285508bd9b662205d4d1fbad6a.png

看到aaaa被打印出来了,那么我们接下来的任务就是让其对齐,并准备在其中写入地址

输入如下时

8339255e1b05010cd57a436d6ef32b65.png

此时在syslog看到

358acf1c5dee9a9b9b4b756aef9a79a5.png

输入的AAAA对齐了

接下来就是要找到syslog函数的地址,并用shellcode的地址进行替换

寻找syslog的地址

94d217d34898c7c097939937d79a5944.png

接下来使用msfvenom生成监听4444端口的shellcode,如下

shellcode = "x31xdbxf7xe3x53x43x53x6ax02x89xe1xb0x66xcdx80"  
                    "x5bx5ex52x68xffx02x11x5cx6ax10x51x50x89xe1x6a"  
                    "x66x58xcdx80x89x41x04xb3x04xb0x66xcdx80x43xb0" 
                    "x66xcdx80x93x59x6ax3fx58xcdx80x49x79xf8x68x2f"  
                    "x2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1xb0"  
                    "x0bxcdx80"

0c5d451e4ea6c6876500913b4e052b63.png

运行脚本

c15b29411e3bb7852e9020f3a8e120b1.png

然后使用nc监听本地4444端口

下图使用了id,whoami,ls命令进行了测试

bd93605393e1cbfc9b16b0203302517d.png

说明我们成功进行了漏洞利用

  • 0x06

第六关 final2

e35d120dd14a5535b2b1b5097cde3ec9.png

从下图中我们可以看到,程序希望我们的输入以FSRD开头,然后寻找最后出现的”/”字符,从那里开始搜索单词“ROOT”,它使用memove替换了从单词“ / ROOT”开始直到最后一个斜杠“ /”的所有内容

4c8131a594e21386ffbc1546a47af6fe.png

我们可以来试一下

6daf945316820bbc02ddd7c136512a54.png

此时会生成coredump,在gdb中分析

967d048be4d61919b5cb8f7723dcd84e.png

可以看到是在调用free()的时候crash的

接下来就是需要找到我们可以在GOT中覆写的对象,先找write

ffc72f051889370dbafbb77b88a68bb2.png

找到write的地址为0x0804d41c,待会儿会有用到

继续测试

d546f66a7fec9f59b29a0eaf8ebeae92.png

gdb调试

57189fac09ce54d32e90db2fd4d03504.png

可以看到eax,edx被覆盖为了bbbb

我们来进一步分清楚eax,ebx是被哪一部分payload写入的

fd946864e2bcb8cbef8d7a81fd8ffd2b.png

gdb调试

7aa4236a13089771c3f9159f69d68487.png

可以看到eax,edx分别被控制覆盖为了aaaa,bbbb

接下来就可以使用前面找到的write的地址0x0804d41c来测试

a6bb4b0b414fa3310e3b194714d8976d.png

gdb调试

78e101931a8512f6c8c573afa6e3d3dd.png

看到可以成功将61616161(即aaaa)写入了

于是就可以写我们的脚本了

79f8fb8e3259640e6e1bcd24e5fb3792.png

执行脚本

a937f712421faeb272ae1ed62e2764a5.png

nc监听本地4444端口,然后使用whoami,ls命令进行测试

e401366709709bd57e8eca2e1e66dc16.png

说明成功实现了漏洞的利用

  • 0x07

参考:
1.https://exploit-exercises.lains.space/protostar/
2.https://medium.com/bugbounty/
3.https://medium.com/@airman604/
4.https://medium.com/@coturnix97/exploit-exercises-protostar/

实验推荐

格式化(字符串)溢出实验

https://www.hetianlab.com/expc.do?ec=2a2450e9-563e-4d99-b0ab-089d65ba7d4d

(通过本实验,了解格式化字符串漏洞产生原理,并掌握其利用方法

声明:笔者初衷用于分享与普及网络知识,若读者因此作出任何危害网络安全行为后果自负,与合天智汇及原作者无关!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值