Linux 下 Shellcode 编写入门

  • A+
所属分类:安全博客

##0x00
由于某些原因,突然对shellcode有了些兴趣。从Google翻到了这篇文章Shellcoding for Linux and Windows Tutorial,给予了我很大的帮助。

在这里我就简单地介绍下简单shellcode的编写

##0x01
第一步大概就是是用汇编写源程序。当然,使用C也可以,但是会更复杂些。
这里就大致演示下Hello World的shellcode的编写。
x86环境下。

global _start

_start:
    jmp MESSAGE

    CALLBACK:
    xor eax, eax
    xor ebx, ebx
    xor ecx, ecx
    xor edx, edx
    ;使用xor来将寄存器置零,防止出现00字节

    mov al, 4
    ;通过访问eax的al位来防止赋值的时候出现多余的00字节
    ;这里的4代表着Linux的syscall的write
    mov bl, 1
    ;这里的1指stdout
    pop ecx
    ;从堆栈中得到MESSAGE块的地址(即字符串的地址)
    mov dl, 12
    ;12指字符串的长度
    int 0x80
    ;特权指令

    xor eax, eax
    mov al, 1
    ;1指exit syscall
    xor ebx, ebx
    int 0x80

    MESSAGE:
    call CALLBACK
    ;这里的call调用callback函数,使得MESSAGE的地址被放在堆栈顶,从而可以在接下来被ecx取得。
    db 'Hello world.'

编译运行

nasm -f elf 1.asm
ld -o 1 1.asm
./1

#0x02
当可以正常运行之后,我们使用objdump可以得到机器码。

objdump -d -M intel -S 1

从这里我们可以看到,没有一个00字节(可以防止在注入payload的时候被截断)。

Disassembly of section .text:

08048060 <_start>:
 8048060:       eb 19                   jmp    804807b <MESSAGE>

08048062 <CALLBACK>:
 8048062:       31 c0                   xor    eax,eax
 8048064:       31 db                   xor    ebx,ebx
 8048066:       31 c9                   xor    ecx,ecx
 8048068:       31 d2                   xor    edx,edx
 804806a:       b0 04                   mov    al,0x4
 804806c:       b3 01                   mov    bl,0x1
 804806e:       59                      pop    ecx
 804806f:       b2 0c                   mov    dl,0xc
 8048071:       cd 80                   int    0x80
 8048073:       31 c0                   xor    eax,eax
 8048075:       b0 01                   mov    al,0x1
 8048077:       31 db                   xor    ebx,ebx
 8048079:       cd 80                   int    0x80

0804807b <MESSAGE>:
 804807b:       e8 e2 ff ff ff          call   8048062 <CALLBACK>
 8048080:       48                      dec    eax
 8048081:       65 6c                   gs ins BYTE PTR es:[edi],dx
 8048083:       6c                      ins    BYTE PTR es:[edi],dx
 8048084:       6f                      outs   dx,DWORD PTR ds:[esi]
 8048085:       20 77 6f                and    BYTE PTR [edi+0x6f],dh
 8048088:       72 6c                   jb     80480f6 <MESSAGE+0x7b>
 804808a:       64                      fs
 804808b:       2e                      cs

我们将其中的机器码提取处理下即可。

xebx19x31xc0x31xdbx31xc9x31xd2xb0x04xb3x01x59
xb2x0cxcdx80x31xc0xb0x01x31xdbxcdx80xe8xe2xff
xffxffx48x65x6cx6cx6fx20x77x6fx72x6cx64x2e

#0x03
我们可以通过简单地C程序来测试我们的ShellCode

char code[]="shellcode";
void main()
{
        (*(void(*)())code)();
}

将上面生成的shellcode放入code之后,编译运行就可以了。

gcc -g -z execstack -o code code.c

记得开启堆栈执行。

#0x04
这里作者提到了一种“可打印字符”形式的payload。主要因为很多安全软件都会查杀shellcode,因为大部分shellcode存在大量的不可打印字符。在这里我们使用一种技巧来将shellcode全部转化为可打印的形式。
首先,有下面几种指令可以被打印出来

sub eax, 0xHEXINRANGE
push eax
pop eax
push esp
pop esp
and eax, 0xHEXINRANGE

也许你认为光靠这几个指令是写不出shellcode的。实际上我们可以精心构造这几个指令,让其等效于我们需要的指令。
如:

and eax, 0x454e4f4a ;将eax清零
and eax, 0x3a313035


push esp
pop eax
sub eax, 0x39393333 ;在栈上创建860byte的空间
sub eax, 0x72727550
sub eax, 0x54545421

push eax        ; 保存到esp
pop esp

FROM :rickyhao.com | rickyhao.com

相关推荐: NCTF2019-官方writeup

NCTF2019-官方writeup Table of Contents   NCTF2019-官方writeup WEB Fake XML cookbook[52pt 184solvers] True XML cookbook[294pt 25so…

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: