shellcode编写(基础篇)

  1. Starting

昨天看资讯的时候看到fb一篇写shellcode的。最近也学了汇编试了一下整出来了,做个记录虽然实战不靠谱,还要自动化找函数地址…

Starting

环境:

Windows XP
VC++ 6.0

此方法只适用于测试或者学习,无法动态执行shellcode。也就是说shellcode只能在XP上使用,因为从win7开始有了aslr
ASLR说明:https://blog.morphisec.com/aslr-what-it-is-and-what-it-isnt/

弹框测试:

#include<windows.h>
int main(int argc,char** argv){
    MessageBox(NULL,"You are hacked by Migraine!","Pwned",MB_OK);
}

Alt+8调出反汇编模式可以观察是如何实现调用win API的

通过参阅文章发现不能直接提取机器码,必须用汇编在写一遍。然后在提取字节码

通过参阅文章明白汇编执行shellcode是如何执行的

//转自安全客文章
#include<windows.h>
void main()
{
    LoadLibrary("user32.dll");//Load DLL
    __asm
    {    
        push 0x00656e;ne
        push 0x69617267;grai
        push 0x694d2079;y Mi
        push 0x62206565;ed b
        push 0x6b636168;hack
        push 0x20657261;Are
        push 0x20756F59;You
        mov ebx,esp
        push 0x0
        push 0x656e6961;aine
        push 0x7267694d;Migr
        mov ecx,esp


        //int MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption,UINT uType );
        xor eax,eax
        push eax//uTyoe->0
        push ecx//lpCaption->Migraine
        push ebx//lpText->You are hacked by Migraine
        push eax//hWnd->0
        mov esi,0x77D3ADD7//User32.dll->MessageBoxA
        call esi


    }
}
  • 将需要用到的字符串转成十六进制,由于是X86,一次可最多存放8个字节
  • 将字符串转换的十六进制入栈
  • push 0x0后然后重复将需要的东西入栈,在次保存到另外个寄存器
  • 然后从右到左设置win API的值(注意:从右到左)
  • 最后将windows API的地址给esi
  • call 将当前执行指令地址入栈,然后无条件转移到由标签指示的指令

通过OD给对应的API下断点,可以取得地址

(注:每个系统的地址都有差异)

Examlpe:

然后使用C内嵌asm,调试提取机器码

整个asm范围的机器码提取出来:

"\x68\x6E\x65\x00\x00\x68\x67\x72\x61\x69\x68\x79\x20\x4D\x69\x68\x65\x65\x20\x62"
"\x68\x68\x61\x63\x6B\x68\x61\x72\x65\x20\x68\x61\x62\x63\x00\x8B\xDC\x6A\x00\x68"
"\x61\x69\x6E\x65\x68\x4D\x69\x67\x72\x8B\xCC\x33\xC0\x50\x68\x61\x69\x6E\x65\x68"
"\x4D\x69\x67\x72\x8B\xCC\x33\xC0\x50\x51\x53\x50\xBE\xEA\x07\xD5\x77\xFF\xD6"

执行即可:

用WinExec弹个calc

//WinExec address-7C86250D
//ExitProcess address-7C81CB12
#include<windows.h>
int main()
{
    LoadLibrary("kernel32.dll");
    __asm
        {
        push 0x636C6163;calc
        mov eax,esp
        push 0x0
        push 0x5
        mov ebx,esp


        push ebx
        push eax
        mov esi,0x7C86250D
        call esi
        xor ecx,ecx
        mov esi,0x7C81CB12
        call esi
    }
    return 0;
}

shellcode为

"\x68\x63\x61\x6C\x63\x8B\xC4\x6A\x05\x8B\xDC\x53\x50\xBE\x0D\x25\x86\x7C"
"\xFF\xD6\x33\xC9\xBE\x12\xCB\x81\x7C\xFF\xD6"

注意:如果你不知道calc变成十六进制怎么整,汇编整一个就好

参考链接:
随笔之提取Shellcode简单利用本地缓冲区溢出 - FreeBuf互联网安全新媒体平台
一步步学写Windows下的Shellcode - 安全客,安全资讯平台


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。

文章标题:shellcode编写(基础篇)

本文作者:九世

发布时间:2020-05-20, 17:50:51

最后更新:2020-05-20, 18:15:56

原始链接:http://422926799.github.io/posts/c5435d4d.html

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录