用户
搜索
  • TA的每日心情
    开心
    2017-6-11 12:52
  • 签到天数: 243 天

    连续签到: 1 天

    [LV.8]以坛为家I

    管理员

    Security Personnel

    Rank: 9Rank: 9Rank: 9

    150

    主题

    1377

    帖子

    4947

    魔法币
    收听
    0
    粉丝
    95
    注册时间
    2015-11-4

    幽默灌水王突出贡献春秋文阁春秋巡逻热心助人奖

    zusheng 管理员 Security Personnel 幽默灌水王 突出贡献 春秋文阁 春秋巡逻 热心助人奖 楼主
    发表于 2017-6-14 18:19:36 23024
    0x01 前言

    本文的目的不是为了介绍如何进行恶意的破坏性活动,而是为了教会你如何去防御此类破坏性活动,以帮助你扩大知识范围,完善自己的技能,如有读者运用本文所学技术从事破坏性活动,本人概不负责。

    0x02 什么是Shellcode

    shellcode是用作利用软件漏洞的有效载荷的一小段代码,因为它通常启动一个命令shell,攻击者可以从中控制受攻击的机器,所以称他为shellcode。但是任何执行类似任务的代码都可以称为shellcode。 因为有效载荷的功能不仅限于一个shell。
    shellcode基本的编写方式有以下三种

    • 直接编写十六进制操作码。
    • 使用c语言编写程序,然后进行编译,最后进行反汇编来获取汇编指令和十六进制操作码。
    • 编写汇编程序,将该程序汇编,然后从二进制中提取十六进制操作码。


    第一种方法很极端,直接编写十六进制操作码是一件非常难得事情。下面我将带大家一步步去编写自己的shellcode。

    0x03 execve系统调用

    在Linux系统上执行程序的方式有多种,但是其中使用最广泛的一种方式就是通过借助execve系统调用。我们首先来看看execve的使用方法。

    1.png

    说明看起来很复杂,其实很简单。我们先使用c语言来实现它。

    c语言实现execve系统调用创建shell

    我们首先来新建一个文件:

    2.png

    我们使用vim来编写代码:

    看完上面的介绍,使用c语言来实现就很简单了。

    [AppleScript] 纯文本查看 复制代码
    #include <unistd.h>
    
    int main()
    {
        char * shell[2];
        shell[0]="/bin/sh";
        shell[1]=NULL;
        execve(shell[0],shell,NULL);
    }

    然后我们使用gcc编译器来编译一下:

    gcc test.c -o test.o

    运行看看:

    3.png

    成功执行创建一个shell。

    转向汇编语言

    前面我们已经使用c语言来实现了,现在我们就需要用汇编语言来重写execve系统调用,其实很简单。我们先来查看一下execve系统调用号:11
    4.png
    汇编代码重写:

    首先我们将寄存器eax清零。

    xor eax,eax

    然后我们将寄存器eax进行入栈操作,其实就是将字符串末尾的空字符值入栈:

    push eax

    然后将//sh入栈(由于需要对齐,因此这里用了四个字节)

    push 0x68732f2f

    最后将/bin入栈。

    push 0x6e69622f

    现在栈上已经有了全部所需数据,现在就是设置execve系统调用了。

    [AppleScript] 纯文本查看 复制代码
    mov ebx,esp
    push eax
    push ebx
    mov ecx,esp
    xor edx,edx
    mov al,0xb  ;0xb表示其系统调用号的十六进制,execve的系统调用号为11
    int 0x80


    完整代码如下:

    [AppleScript] 纯文本查看 复制代码
    section .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@kali:~/demo# ld -o test test.o

    运行测试看看
    root@kali:~/demo# ./test
    #

    5.png

    0x04 提取十六进制操作码并测试Shellcode

    获得十六进制操作码很简单,我们只需要使用objdump工具的-d选项来进行反汇编即可:

    6.png

    最后我们检查一下有没有出现空字符(\x00)。

    测试shellcode

    首先我们将十六进制操作码放入一个名为shellcode[]的缓冲区中。

    [AppleScript] 纯文本查看 复制代码
    #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[]的起始地址。最后我们执行这个函数。
    现在我们编译一下,这里注意一下,编译成功后我们还是不能成功执行的,会出现段错误的提示,这是因为系统本身有数据区执行保护机制,导致在全局数据段的shellcode不能被运行,即出现段错误。

    7.png

    这里我们先安装一下execstack。

    sudo apt-get install execstack

    然后针对编译后的程序使用execstack

    execstack -s 程序名

    之后执行就OK了

    8.png

    总结

    现在我们已经知道一个shellcode编写流程了,别走开,这只是基础篇,我们实现的这个shellcode缺乏实战,下一篇教程我们继续完善这个shellcode。

    参考:
    《汇编语言(第3版) 》王爽
    《[科普]浅入浅出Liunx Shellcode》pr0cess

    Hacking the earth
    yyyxy 管理员 六国战旗移动展示平台! 秦 楚 燕 魏 齐 赵
    来自 3#
    发表于 2017-6-15 10:21:24
    文章奖励介绍及评分标准:http://bbs.ichunqiu.com/thread-7869-1-1.html,如有疑问请加QQ:286894635!
    奖金
    点评
    100
    比较基础  可以看出刚开始学习的一门技术,但写的有教育性,有逻辑性

    使用道具 举报 回复
    感谢楼主分享
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册