Introduction
This tutorial teaches you some handy tricks when creating shellcode, such as how to load libraries, dynamically locate Windows functions, define and locate string constants, and call Windows functions. This sets you up to start creating your own shellcode.
Some of this tutorial was based on information pulled fromhttp://www.vividmachines.com/shellcode/shellcode.html.
Our aim
The aim of our shellcode will be to display a Windows dialog box containing a custom message.
What function do we need to call?
From programming experience (or at least by Googling), we know that to generate a message box on Windows we need to make a call to the MessageBoxA function. Also via Googling we could determine that the MessageBoxA function exists within User32.dll.
If we used the technique from the previous tutorial we could use "findFunctionInDLL.sh" to determine that this function exists in user32.dll, and this would also give us the address of this function. This would be done in the following fashion:
# ./findFunctionInDLL.sh MessageBoxA
user32.dll
MessageBoxA is located at 0x7e45058a in user32.dll
user32.dll
MessageBoxA is located at 0x7e45058a in user32.dll
So we would now know the address of the MessageBoxA function and we would know that it is located in user32.dll. Unfortunately, if we hardcode this memory address into our shellcode, it would only work on your current operating system. In my case Windows XP SP2.
Instead we are going to use a technique that allows us to find the MessageBoxA function dynamically, without hardcoding the memory address.
So is user32.dll loaded?
In Windows the only library that we know for sure is loaded is Kernel32.dll, but we don't necessarily know if user32.dll is loaded. We generally have to assume that it isn't, unless you are creating theshellcode for a specific exploit.
To load a library on Windows we can call the "LoadLibraryA" function, which is located in Kernel32.dll. So we need to locate the address of LoadLibraryA. This can either be done using findFunctionInDLL.sh, as above; however, a quicker way would be to use arwin directly since we know the function and library already. This is shown below:
# ./arwin Kernel32.dll LoadLibraryA
arwin - win32 address resolution program - by steve hanna - v.01
LoadLibraryA is located at 0x7c801d77 in Kernel32.dll
arwin - win32 address resolution program - by steve hanna - v.01
LoadLibraryA is located at 0x7c801d77 in Kernel32.dll
It should be noted that we are only trying to dynamically find the MessageBoxA function address dynamically. We are not trying to remove all hardcoded memory addresses altogether. This will be covered in later tutorials, which will allow you to create shellcode that runs on a range of Windows platforms.
So how do we locate the MessageBoxA function?
So at this stage we know how to load the user32.dll library, which we know contains the MessageBoxA function that we want to call. But we still don't know the address of where MessageBoxA is located.
We can use the "GetProcAddress" function, which is located in Kernel32.dll. We can pass our function name to GetProcAddress and it will return the address of our function. So first off, we need to locate GetProcAddress using arwin:
# ./arwin Kernel32.dll GetProcAddress
arwin - win32 address resolution program - by steve hanna - v.01
GetProcAddress is located at 0x7c80adc0 in Kernel32.dll
arwin - win32 address resolution program - by steve hanna - v.01
GetProcAddress is located at 0x7c80adc0 in Kernel32.dll
How do we prevent crashing the parent process?
In the last tutorial, the process crashes causing a core dump. To exit cleanly we need to call the ExitProcess fuction. For simplicity, we are just going to enumerate the memory address of this function within Kernel32.dll by using arwin. This can be done as follows:
# ./arwin Kernel32.dll ExitProcess
arwin - win32 address resolution program - by steve hanna - v.01
ExitProcess is located at 0x7c81ca82 in Kernel32.dll
arwin - win32 address resolution program - by steve hanna - v.01
ExitProcess is located at 0x7c81ca82 in Kernel32.dll
At this point we now have all of the information required to create our shellcode. So that you are easily able to understand the assembly below, I want to just point out one more technique that is used.
Defining and locating string constants
From the above information, there are three strings that we want to define in our shellcode. These are:
'user32.dll'
'MessageBoxA'
'Hey'
'MessageBoxA'
'Hey'
We will use the "user32.dll" string to pass as a parameter to LoadLibraryA. We will use the "MessageBoxA" string to pass as a parammeter to GetProcAddress. We will use the "Hey" string as a parameter to "MessageBoxA" so that our dialog box displays the message "Hey".
The following snippet of code demonstrates how we define a string at the end of our code, and locate the string at the top;
+--------------- [snip] ---------------+
;Retrieve the address of the library name string set below.
jmp short GetLibrary ;Jump to where our library string is located ("GetLibrary" label below)
GetLibraryReturn:;Create a label we can call to return here.
pop ecx ;the "call" operation has pushed the return address onto the stack, which we have designed to point to our string - so pop the address of the library name string off the stack and into ecx.
;At this point, ecx points to our string.
;Retrieve the address of the library name string set below.
jmp short GetLibrary ;Jump to where our library string is located ("GetLibrary" label below)
GetLibraryReturn:;Create a label we can call to return here.
pop ecx ;the "call" operation has pushed the return address onto the stack, which we have designed to point to our string - so pop the address of the library name string off the stack and into ecx.
;At this point, ecx points to our string.
+--------------- [snip] ---------------+
GetLibrary: ;Create the "GetLibrary" label where our library name string is located
call GetLibraryReturn ;"call" is like jump, but also pushes the next instruction address onto the stack. Since our string is defined immediately after this instruction, this is the address of our string.
db 'user32.dll' ;Write the raw bytes into the shellcode that represent our string.
db 0x00 ;Terminate our string with a null character.
call GetLibraryReturn ;"call" is like jump, but also pushes the next instruction address onto the stack. Since our string is defined immediately after this instruction, this is the address of our string.
db 'user32.dll' ;Write the raw bytes into the shellcode that represent our string.
db 0x00 ;Terminate our string with a null character.
+--------------- [snip] ---------------+
The Shellcode
The following is the code for msgbox.asm, which was originally pulled fromhttp://www.vividmachines.com/shellcode/shellcode.html, with very slight modifications and comments.
Create msgbox.asm on your local system within your Cygwin shellcode directory using the following code. Make sure you read the comments throughout the code since they explain what action each line performs, and gives handy tips for later shellcode development. Remember to replace the address of each function with the addresses that you enumerated above with arwin.
+--------------- Start msgbox.asm --------------+
;msgbox.asm
[SECTION .text]
[SECTION .text]
BITS 32
global _start
_start:
;zero out the registers
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
;Retrieve the address of the library name string set below.
jmp short GetLibrary
GetLibraryReturn:
pop ecx ;pop address of the Library string
jmp short GetLibrary
GetLibraryReturn:
pop ecx ;pop address of the Library string
;Pass library string as parameter to LoadLibraryA, and call LoadLibraryA
mov ebx, 0x7c801d77 ;LoadLibraryA(libraryname)
push ecx ;push parameter to LoadLibraryA
call ebx ;call LoadLibraryA - eax holds return value
mov ebx, 0x7c801d77 ;LoadLibraryA(libraryname)
push ecx ;push parameter to LoadLibraryA
call ebx ;call LoadLibraryA - eax holds return value
;Retrieve the address of the function name string set below.
jmp short FunctionName
FunctionReturn:
pop ecx ;pop address of the function string
jmp short FunctionName
FunctionReturn:
pop ecx ;pop address of the function string
;Pass function string as parameter to LoadLibraryA, and call LoadLibraryA
push ecx ;push string as the second parameter
push eax ;pass first parameter
mov ebx, 0x7c80adc0 ;GetProcAddress(hmodule,functionname)
call ebx ;eax now holds address of MessageBoxA
push ecx ;push string as the second parameter
push eax ;pass first parameter
mov ebx, 0x7c80adc0 ;GetProcAddress(hmodule,functionname)
call ebx ;eax now holds address of MessageBoxA
jmp short Message
MessageReturn:
pop ecx ;get the message string
xor edx,edx ;clear edx value
;Push the parameters onto the stack:
push edx ;MB_OK
push ecx ;title
push ecx ;message
push edx ;NULL window handle
call eax ;MessageBoxA(windowhandle,msg,title,type)
MessageReturn:
pop ecx ;get the message string
xor edx,edx ;clear edx value
;Push the parameters onto the stack:
push edx ;MB_OK
push ecx ;title
push ecx ;message
push edx ;NULL window handle
call eax ;MessageBoxA(windowhandle,msg,title,type)
ender:
xor edx,edx ;empty edx out
push eax ;move address of MessageBoxA onto stack
mov eax, 0x7c81ca82 ;ExitProcess(exitcode);
call eax ;exit cleanly so we don't crash parent
xor edx,edx ;empty edx out
push eax ;move address of MessageBoxA onto stack
mov eax, 0x7c81ca82 ;ExitProcess(exitcode);
call eax ;exit cleanly so we don't crash parent
GetLibrary: ;Define location and string constant "user32.dll"
call GetLibraryReturn ;push address of next byte onto stack, and return to GetLibraryReturn
db 'user32.dll';string constant
db 0x00;terminate string with null
call GetLibraryReturn ;push address of next byte onto stack, and return to GetLibraryReturn
db 'user32.dll';string constant
db 0x00;terminate string with null
FunctionName:;Define location and string constant "MessageBoxA"
call FunctionReturn;push address of next byte onto stack, and return to FunctionReturn
db 'MessageBoxA';string constant
db 0x00;terminate string with null
call FunctionReturn;push address of next byte onto stack, and return to FunctionReturn
db 'MessageBoxA';string constant
db 0x00;terminate string with null
Message:;Define location and string constant "Hey"
call MessageReturn;push address of next byte onto stack, and return to MessageReturn
db 'Hey';string constant
db 0x00;terminate string with null
call MessageReturn;push address of next byte onto stack, and return to MessageReturn
db 'Hey';string constant
db 0x00;terminate string with null
+--------------- End msgbox.asm --------------+
Compiling the Assembly Code
So now that we have our shellcode written in assembly, we need to compile it. This can be done using the nasm assembly compiler, using the following command where msgbox.asm is your assembly source code file, and msgbox.bin is the compiled binary output file:
# nasm -f bin -o msgbox.bin msgbox.asm
Obtaining the shellcode
Now that we have a compiled binary file we can use the xxd tool to generate the shellcode for us. This can be done using the following xxd command, which will generate the following output:
# xxd -i msgbox.bin
unsigned char msgbox_bin[] = {
0x31, 0xc0, 0x31, 0xdb, 0x31, 0xc9, 0x31, 0xd2, 0xeb, 0x2a, 0x59, 0xbb,
0x77, 0x1d, 0x80, 0x7c, 0x51, 0xff, 0xd3, 0xeb, 0x2f, 0x59, 0x51, 0x50,
0xbb, 0xc0, 0xad, 0x80, 0x7c, 0xff, 0xd3, 0xeb, 0x34, 0x59, 0x31, 0xd2,
0x52, 0x51, 0x51, 0x52, 0xff, 0xd0, 0x31, 0xd2, 0x50, 0xb8, 0x82, 0xca,
0x81, 0x7c, 0xff, 0xd0, 0xe8, 0xd1, 0xff, 0xff, 0xff, 0x75, 0x73, 0x65,
0x72, 0x33, 0x32, 0x2e, 0x64, 0x6c, 0x6c, 0x00, 0xe8, 0xcc, 0xff, 0xff,
0xff, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6f, 0x78, 0x41,
0x00, 0xe8, 0xc7, 0xff, 0xff, 0xff, 0x48, 0x65, 0x79, 0x00
};
unsigned int msgbox_bin_len = 94;
unsigned char msgbox_bin[] = {
0x31, 0xc0, 0x31, 0xdb, 0x31, 0xc9, 0x31, 0xd2, 0xeb, 0x2a, 0x59, 0xbb,
0x77, 0x1d, 0x80, 0x7c, 0x51, 0xff, 0xd3, 0xeb, 0x2f, 0x59, 0x51, 0x50,
0xbb, 0xc0, 0xad, 0x80, 0x7c, 0xff, 0xd3, 0xeb, 0x34, 0x59, 0x31, 0xd2,
0x52, 0x51, 0x51, 0x52, 0xff, 0xd0, 0x31, 0xd2, 0x50, 0xb8, 0x82, 0xca,
0x81, 0x7c, 0xff, 0xd0, 0xe8, 0xd1, 0xff, 0xff, 0xff, 0x75, 0x73, 0x65,
0x72, 0x33, 0x32, 0x2e, 0x64, 0x6c, 0x6c, 0x00, 0xe8, 0xcc, 0xff, 0xff,
0xff, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6f, 0x78, 0x41,
0x00, 0xe8, 0xc7, 0xff, 0xff, 0xff, 0x48, 0x65, 0x79, 0x00
};
unsigned int msgbox_bin_len = 94;
This creates an array of characters that can be used within a C program. Each of the hexadecimal numbers (0xXX) in the output represent a byte within the shellcode.
So we want to do with this output to create the shellcode? We are going to use the xxd-shellcode.sh script from the previous tutorial to strip out the raw shellcode that we can put directly into our "shellcodetest.c" program.
This program takes the input file "msgbox.bin", so run the following command to produce the following output. This output will automatically be saved to "msgbox.shellcode". This shellcode may vary slightly if you are using a different OS or service pack due to the differing address of the functions we call on your system.
# ./xxd-shellcode.sh msgbox.bin
\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xeb\x2a\x59\xbb\x77\x1d\x80\x7c\x51\xff\xd3\xeb\x2f\x59\x51\x50\xbb\xc0\xad\x80\x7c\xff\xd3\xeb\x34\x59\x31\xd2\x52\x51\x51\x52\xff\xd0\x31\xd2\x50\xb8\x82\xca\x81\x7c\xff\xd0\xe8\xd1\xff\xff\xff\x75\x73\x65\x72\x33\x32\x2e\x64\x6c\x6c\x00\xe8\xcc\xff\xff\xff\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x41\x00\xe8\xc7\xff\xff\xff\x48\x65\x79\x00
\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xeb\x2a\x59\xbb\x77\x1d\x80\x7c\x51\xff\xd3\xeb\x2f\x59\x51\x50\xbb\xc0\xad\x80\x7c\xff\xd3\xeb\x34\x59\x31\xd2\x52\x51\x51\x52\xff\xd0\x31\xd2\x50\xb8\x82\xca\x81\x7c\xff\xd0\xe8\xd1\xff\xff\xff\x75\x73\x65\x72\x33\x32\x2e\x64\x6c\x6c\x00\xe8\xcc\xff\xff\xff\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x41\x00\xe8\xc7\xff\xff\xff\x48\x65\x79\x00
Testing the shellcode
We will be using the "shellcodetest.c" program to test our shellcode. The aim of this step is to insert our shellcode into a C program, which we can then compile and execute. This program is designed to then execute our shellcode.
Before we can do this you need to insert your shellcode that was generated from the last step into this program. You place it between the quotes of the "code[]" array. It should end up looking something like the following:
+----------------- Start updated shellcodetest.c -----------------+
/*shellcodetest.c*/
char code[] = "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xeb\x2a\x59\xbb\x77\x1d\x80\x7c\x51\xff\xd3\xeb\x2f\x59\x51\x50\xbb\xc0\xad\x80\x7c\xff\xd3\xeb\x34\x59\x31\xd2\x52\x51\x51\x52\xff\xd0\x31\xd2\x50\xb8\x82\xca\x81\x7c\xff\xd0\xe8\xd1\xff\xff\xff\x75\x73\x65\x72\x33\x32\x2e\x64\x6c\x6c\x00\xe8\xcc\xff\xff\xff\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x41\x00\xe8\xc7\xff\xff\xff\x48\x65\x79\x00";
int main(int argc, char **argv)
{
int (*func)();
func = (int (*)()) code;
(int)(*func)();
}
char code[] = "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xeb\x2a\x59\xbb\x77\x1d\x80\x7c\x51\xff\xd3\xeb\x2f\x59\x51\x50\xbb\xc0\xad\x80\x7c\xff\xd3\xeb\x34\x59\x31\xd2\x52\x51\x51\x52\xff\xd0\x31\xd2\x50\xb8\x82\xca\x81\x7c\xff\xd0\xe8\xd1\xff\xff\xff\x75\x73\x65\x72\x33\x32\x2e\x64\x6c\x6c\x00\xe8\xcc\xff\xff\xff\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x41\x00\xe8\xc7\xff\xff\xff\x48\x65\x79\x00";
int main(int argc, char **argv)
{
int (*func)();
func = (int (*)()) code;
(int)(*func)();
}
+----------------- End updated shellcodetest.c -----------------+
We now need to compile the updated shellcodetest.c program so that it can kick off our shellcode. This can be done with the following command:
# gcc -o shellcodetest shellcodetest.c
This should create the executable program "shellcodetest.exe".
You should now be able to execute this program, which will then kick off your shellcode. Remember this shellcode is designed to trigger a message box containing the message 'Hey', and then it should exit cleanly without triggering a core dump. If you do get a core dump, then your hardcoded function addresses are probably wrong and you need to check your arwin output for each of the functions above.
# ./shellcodetest.exe
(message box produced saying "Hey")
(click "Ok" and it should exit cleanly)
(message box produced saying "Hey")
(click "Ok" and it should exit cleanly)
Congratulations!
You have just created some shellcode that loads Windows libraries, dynamically locate a Windows function, defines and locates string constants, and calls Windows functions.
This places you in a good position to start creating your own shellcode; however, we still have some hardcoded addresses in the code above. The following tutorial will show you how to remove these hardcoded addresses by dynamically locating Kernel32.dll and the GetProcAddress function. It also shows you how to create functions in assembly so that you can reuse your code.
Do you need to increase your credit score?
ReplyDeleteDo you intend to upgrade your school grade?
Do you want to hack your cheating spouse Email, whatsapp, Facebook, instagram or any social network?
Do you need any information concerning any database.
Do you need to retrieve deleted files?
Do you need to clear your criminal records or DMV?
Do you want to remove any site or link from any blog?
you should contact this hacker, he is reliable and good at the hack jobs..
contact : cybergoldenhacker at gmail dot com
I just couldn't leave your website before telling you that I truly enjoyed the top quality info you present to your visitors? Will be back again frequently to check up on new posts. fascia alta visibilità
ReplyDeleteShellcode Tutorial 4: Message Box Shellcode - Elite Hacks >>>>> Download Now
ReplyDelete>>>>> Download Full
Shellcode Tutorial 4: Message Box Shellcode - Elite Hacks >>>>> Download LINK
>>>>> Download Now
Shellcode Tutorial 4: Message Box Shellcode - Elite Hacks >>>>> Download Full
>>>>> Download LINK
Shellcode Tutorial 4: Message Box Shellcode - Elite Hacks >>>>> Download Now
ReplyDelete>>>>> Download Full
Shellcode Tutorial 4: Message Box Shellcode - Elite Hacks >>>>> Download LINK
>>>>> Download Now
Shellcode Tutorial 4: Message Box Shellcode - Elite Hacks >>>>> Download Full
>>>>> Download LINK qF
SSN DOB DL FULLZ
ReplyDeleteDUMPS WITH PINS 101 & 202
CC WITH CVV
DL SCAN FRONT & BACK
HIGH CREDIT SCORES PROS
BUSINESS WIN FULLZ
OFFICE365 EMAILS & LOGINS
CPANELS
SHELLS
SMTPS
RDPS
-Fresh stuff available
-Legit & Verified
-Fullz are freshly spammed from good resources
-Spamming Complete tools & tutorials package available
Feel Free to hit me up
ICQ 752822040 / @killhacks
Telegram @killhacks / @leadsupplier
Email hacksp007 @ dnmx.org
Skype/Wickr @peeterhacks