码迷,mamicode.com
首页 > 系统相关 > 详细

我的第一个shell code -- hello world

时间:2015-12-12 23:10:17      阅读:314      评论:0      收藏:0      [点我收藏+]

标签:

尝试了好久,终于成功输出了hello world

实验环境

$uname -a                     
Linux archlinux 4.2.5-1-ARCH #1 SMP PREEMPT Tue Oct 27 08:13:28 CET 2015 x86_64 GNU/Linux

 $gcc --version
  gcc (GCC) 5.2.0
  Copyright (C) 2015 Free Software Foundation, Inc.
  This is free software; see the source for copying conditions. There is NO
  warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

核心代码

hello.s

 1 section     .text
 2 global      _start
 3 
 4 _start:
 5 
 6   jmp msg
 7 
 8 code:
 9   xor rax, rax    ;clean up the registers
10   xor rbx, rbx
11   xor rdx, rdx
12   xor rcx, rcx
13 
14   mov al, 4       ;syscall write
15   mov bl, 1       ;stdout is 1
16   pop rcx         ;save string address
17   mov dl, 12      ;length of the string
18   int 0x80
19 
20   xor rax, rax
21   mov al, 1       ;exit the shellcode
22   xor rbx,rbx
23   int 0x80
24 msg:
25   call code
26   db hello world, 10

 

这里有几个值得注意的地方:

1. 由于c语言中的字符串以‘\0‘为结尾,我们生成的shell code就不能包含00字节,所以能用al就绝不用ax or eax or rax,bl,dl同理。

2. 注意到代码里有个莫名奇妙的pop rcx没有?有没有发现代码的组织很奇怪?为什么要先jmp到msg在call code呢?事实上这也是为了去掉00字节。

call 指令会将返回的地址(这里就是第26行)push到栈上,之后再pop到rcx。

$nasm -f elf64 hello.s -o hello.o                                              
$ld -s -o hello hello.o 
$./hello
hello world                                                 
$objdump -d hello

hello: file format elf64-x86-64



Disassembly of section .text:


0000000000400080 <.text>:
400080: eb 1f            jmp 0x4000a1
400082: 48 31 c0          xor %rax,%rax
400085: 48 31 db          xor %rbx,%rbx
400088: 48 31 d2          xor %rdx,%rdx
40008b: 48 31 c9          xor %rcx,%rcx
40008e: b0 04            mov $0x4,%al
400090: b3 01          mov $0x1,%bl
400092: 59            pop %rcx
400093: b2 0c          mov $0xc,%dl
400095: cd 80          int $0x80
400097: 48 31 c0         xor %rax,%rax
40009a: b0 01          mov $0x1,%al
40009c: 48 31          db xor %rbx,%rbx
40009f: cd 80          int $0x80
4000a1: e8 dc ff ff ff    callq 0x400082
4000a6: 68 65 6c 6c 6f    pushq $0x6f6c6c65
4000ab: 20 77 6f        and %dh,0x6f(%rdi)
4000ae: 72 6c          jb 0x40011c
4000b0: 64 fs
4000b1: 0a            .byte 0xa

可以看到没有00字节

 

可以写个小程序从objdump的输出中得到shellcode

 1 #include <stdio.h>
 2 char code[] = "\xeb\x1f\x48\x31\xc0\x48\x31\xdb\x48\x31\xd2\x48\x31\xc9\xb0\x04\xb3" 3 "\x01\x59\xb2\x0b\xcd\x80\x48\x31\xc0\xb0\x01\x48\x31\xdb\xcd\x80\xe8" 4 "\xdc\xff\xff\xff\x68\x65\x6c\x6c\x6f\x20\x77\x6f\x72\x6c\x64";
 5 
 6 
 7 int main()
 8 {
 9 void (*hello)();
10 hello = (void (*)())code;
11 (*hello)();
12 return 0;}

 

编译选项很重要,现代编译器似乎有保护

$gcc -z execstack hello.c 
$./a.out
hello world

大功告成。

我的第一个shell code -- hello world

标签:

原文地址:http://www.cnblogs.com/cfeitong/p/5041958.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!