知道了怎么通过自己写一个完整的ShellCode之后,现在我们就要实现一些在我看来比较高级的操作了,首先,在我学习以来,ShellCode被理解成了栈溢出漏洞利用的锋利武器。
那么,在进行漏洞利用的同时,很有可能你的ShellCode就会因为00截断而不能正常运行,本次内容讲的就是如何让自己的ShellCode一个(0x00,0x0A,0x0D)也没有!!!
当然,你可能会想,我在编写的时候遇到0x00我就想方设法换成没有0x00的代码就行了。答案是:当然不行,在一些固定的参数必须含0的情况下,你这种骚操作无疑让自己秃头秃的更快。
在这里,我们就要用到加密解密的操作了,在源代码不能预防的情况下,我们就给它加密。
加密的操作有很多,在这里,因为我们仅仅是不想它出现(0x00,0x0A,0x0D),所以就没必要整那么复杂的加密操作了。直接整个异或就ok了
直接上代码
ok,在这里我们就拿到了能够让我们的ShellCode不出现(0x00,0x0A,0x0D)的对称秘钥(我这里生成的是0x1b)。
接下来我们要用这个秘钥对ShellCode进行加密,然后将加密后的内容保存至一个新建的txt中。
上代码:
到这里,我们加密的ShellCode已经搞定一半了,但是另一半在我看来才是尤为关键的。
理所当然,这段加密过的ShellCode想要直接通过
是不可能的,为什么呢,当然是没有对其进行解密操作
所以在加密的ShellCode前面,我们还得再加一段用于解密的ShellCode(注:这一段用于解密的ShellCode也不能含有任何0x00,0x0A,0x0D)
因此,解密代码的编写尤为重要:
注:[eax+0x20]是指你的解密代码中的ShellCode距离你的pop eax的偏移(因为你的ShellCode代码是紧跟在你的解密代码的后面的)
先对这段解密代码进行生成二进制ShellCode(判断是否有坏字符)
一样的操作进行二进制CShellCode复制(没有0x00,0x0A,0x0D坏字符):
那说明可以使用这段解密ShellCode,接下来进行ShellCode拼接,将解密ShellCode与要解密的ShellCode拼接在一起:
对其进行调试再次解释一下[eax+20]为什么是加密ShellCode的首地址:
ok,ShellCode编写完毕,试一试能否运行:
/
/
加密函数
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)));
}
/
/
加密函数
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)));
}
/
/
密钥
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);
/
/
密钥
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);
lea eax EnCodeShellCode
push eax
ret
lea eax EnCodeShellCode
push eax
ret
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)