字母数字NOP实现

时间:2012-10-14 05:43:52

标签: c assembly x86

以字母数字形式查找NOP替代方案,以便通过IDS测试缓冲区溢出。 IDS将编码非0x90%90等非字母数字值,以满足HTTP RFC标准,因此可以尝试进行字母数字迭代。已创建字母数字有效负载,但利用代码使用memset0x90来填充缓冲区。利用代码here

页面here提供了一些多字节选项,但我不知道如何用x0f\x1f\x00或其他任何可能为sled提供雪橇的东西替换NOP字节(第147行)上面引用的代码中的有效负载。有什么建议吗?

2 个答案:

答案 0 :(得分:6)

这是一个great site,列出了各种ASCII汇编指令(包括ASCII nops),如果你很好奇的话。使用这些指令,您可以构建仅包含ASCII字符的整个程序。在黑帽工作的背景下,这些说明非常便于绕过入侵检测系统和文本过滤器。

例如,序列ABCDEFGIJKLMNO是x86无操作,尽管基本上看起来像字母顺序。此外,如果您不关心丢弃某些寄存器,则可以创建ASCII指令序列,这些指令除了递增或递减这些寄存器之外什么都不做。

如果您正在尝试使用这些多字节nops构建一个nop-sled,请注意(AFAIK)如果不使用可以在任何字节偏移处输入的nop,则无法生成真正的nop-sled并且仍然执行精确的无操作。但是,使用像AIinc ecx; dec ecx)这样的指令比使用多字节NOP序列更安全,因为如果以错误的偏移量输入序列就会删除寄存器(而多字节NOP可能会导致非法的指令异常或做一些意想不到的事情。)

无论如何,通常情况下,您可以通过C中的缓冲区复制任何多字节序列(假设sizeof(buffer)是操作长度的倍数):

/* I find string notation to be more convenient, but it means using `sizeof(op)-1` to get the op length */
static char op[] = "\xaa\xbb\xcc";

char buffer[3072];
int i;

for(i=0; i<sizeof(buffer); i++)
    buffer[i] = op[i%(sizeof(op)-1)];

答案 1 :(得分:1)

如果你的意思是你想要一个多字节的NOP序列(假设0f 1f 00 这样的序列),你需要在一个循环中这样做,比如:

char cycle[] = { '\x0f', '\x1f', '\x00' };
for (int i = 0; i < sizeof(buffer); i++)
    buffer[i] = cycle[i%3];

这可能不会达到您的预期,buffer大小不是三个字节的倍数,但在这种情况下您可以使用最后的1字节NOP:

int i = -1;
char cycle[] = { '\x0f', '\x1f', '\x00' };
while (++i < sizeof(buffer) - (sizeof(buffer) % 3))
    buffer[i] = cycle[i%3];
while (i < sizeof(buffer))
    buffer[i++] = '\x90';

您不能使用memset,因为该功能通过将每个字节设置为特定值来工作,它不允许您将交替字节设置为不同的值。