此期为学习记录第二期:反逆向工程,想看看我的第一期的BYPASS篇可以到我的个人主页里面看看
写在开头,此系列文章全部属于教育和经验交流,请勿用于非法用途!!!
了解沙箱
沙箱是一种按照安全策略限制程序行为的执行环境。早期主要用于测试可疑软件等,比如黑客们为了试用某种病毒或者不安全产品,往往可以将它们在沙箱环境中运行。经典的沙箱系统的实现途径一般是通过拦截系统调用,监视程序行为,然后依据用户定义的策略来控制和限制程序对计算机资源的使用,比如改写注册表,读写磁盘等.
我常用的网络沙箱:微步在线云沙箱、VirusTotal.个人推荐VirusTotal沙箱,因为VirusTotal调用安全厂商对文件检测多达60+,比较严格。微步沙箱就比较符合国内
说白了,如果我们获取到一个未知的程序或者动态链接库等可执行的文件,都要对它进行沙箱调试,看看进程的意图是干嘛的,有没有危害。
我先举一个栗子:
红队A写了一个马,给蓝队分析研究.蓝队拿到样本的时候,肯定不会上机,一定会丢进沙箱看看用了什么Windows API、有没有网络行为和哪个IP进行了通讯。A的马没有做反逆向调式或者做的不到位的话,那可能是这种情况…
蓝队都懒得分析了,直接丢垃圾桶了…
那反过来做了反沙箱呢?
唉,这情况就舒服多了,当然VirusTotal的分数还可以降低点,方法我最后介绍下。蓝队但凡对此文件展开逆向工程,一旦拖进沙箱和OD程序就exit(1)GG了,不给调试机会。
反逆向原理
我这里引用Drunkmars大佬的话来说:最简单的反调试的措施就是检测父进程。一般来说,我们手动点击执行的程序的父进程都是explorer。如果一个程序的父进程不是explorer,那么我们就可以认为他是由沙箱启动的。那么我们就直接exit退出,这样,杀软就无法继续对我们进行行为分析了。
思路明确开始实现:
首先调用CreateToolhelp32Snapshot拍摄进程快照,然后遍历我们当前进程的父进程PID,随后进行查询Explorer的PID,最后进行比较explorer PID和当前程序的PID。若两个值相等就确定程序没有在调试,反之直接exit(1);
C++实现:
查询当前程序的父进程PID
DWORD search_my_processid(DWORD pid)
{
DWORD ParentProcessID = -1;
PROCESSENTRY32 pe;
HANDLE hkz;
HMODULE hModule = LoadLibrary(_T("Kernel32.dll"));
FARPROC Address = GetProcAddress(hModule, "CreateToolhelp32Snapshot");
if (Address == NULL) {
OutputDebugString(_T("GetProc error"));
return(-1);
}
_asm {
push 0
push 2
call Address
mov hkz, eax
}
pe.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hkz, &pe)) {
do {
if (pe.th32ProcessID == pid) {
ParentProcessID = pe.th32ParentProcessID;
break;
}
} while (Process32Next(hkz, &pe));
}
return ParentProcessID;
}
查询Explorer的PID
DWORD search_explorer_processid() {
DWORD explorer_id = -1;
PROCESSENTRY32 pe;
HANDLE hkz;
HMODULE hModule = LoadLibrary(_T("Kernel32.dll"));
if (hModule == NULL) {
OutputDebugString(_T("Loaddll error"));
return(-1);
}
FARPROC Address = GetProcAddress(hModule, "CreateToolhelp32Snapshot");
if (Address == NULL) {
OutputDebugString(_T("GetProc error"));
return(-1);
}
_asm {
push 0
push 2
call Address
mov hkz, eax
}
pe.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hkz, &pe)) {
do {
if (strcmp((const char*)pe.szExeFile, "explorer.exe") == 0)
{
explorer_id = pe.th32ProcessID;
break;
}
} while (Process32Next(hkz, &pe));
}
return explorer_id;
}
比较二者的PID:
int determine() {
DWORD explorer_id = search_explorer_processid();
DWORD my_pid =search_my_processid(GetCurrentProcessId());
if (explorer_id == my_pid)
{
return 1;
}
else
{
return 0;
}
}
main.cpp中
void main(){
int anti_sendbox;
anti_sendbox=sendbox();
if(!anti_sendbox){
exit(1);
}
}
实际效果就是上面发的红队反逆向处理.
VirusTotal的分数是10/67如果追求完美的朋友可以试试用指针去调用Windows API函数,这样相对安全点.还有此篇写的是反逆向工程和沙箱,虽然说用AV的时候不会报毒,但是程序中有shellcode(像CS的那种)不做混淆出来也是不行的,一些危险行为等等都会破坏文件是否为正常程序的判定。
-END-