en
Feedback
ReverseEngineering

ReverseEngineering

Open in Telegram
1 265
Subscribers
No data24 hours
-37 days
+730 days
Posts Archive
Repost from ARVIN
Malware development trick 46: simple Windows keylogger. Simple C example https://cocomelonc.github.io/malware/2025/05/01/malware-tricks-46.html

IDA Pro Tips to Add to Your Bag of Tricks https://swarm.ptsecurity.com/ida-pro-tips @reverseengine

UAFuzz: Binary-level Directed Fuzzing for Use-After-Free Vulnerabilities https://github.com/strongcourage/uafuzz @reverseengine

Repost from Source Byte
REMOTE WINDOWS CREDENTIAL DUMP WITH SHADOW SNAPSHOTS: EXPLOITATION AND DETECTION https://labs.itresit.es/2025/06/11/remote-windows-credential-dump-with-shadow-snapshots-exploitation-and-detection/

RustHound-CE 2.4.5
ابزار جمع‌آوری BloodHound که به زبان Rust نوشته شده و قابلیت کامپایل متقابل دارده با لینوکس، ویندوز و macOS سازگاره پس تمام فایل‌های JSON قابل تجزیه و تحلیل توسط BloodHound Community Edition رو تولید میکنه
دستورالعمل‌ها: نصب از cargo cargo install rusthound-ce دستورالعمل‌ها: rusthound-ce -i 192.168.1.10 -d domain.local -u user@domain.local -p 'pass' -z RustHound-CE 2.4.5
The BloodHound collection tool, written in Rust and cross-compiled, is compatible with Linux, Windows, and macOS. Therefore, it produces all JSON files that can be parsed by BloodHound Community Edition.
Instructions: install from cargo
cargo install rusthound-ce
Instructions:
rusthound-ce -i 192.168.1.10 -d domain.local -u user@domain.local -p 'pass' -z
@reverseengine

pattern offset 0x39654138
It tells you something like:
"Offset = 524"
That means character number 524 from the input is exactly on the EIP/RIP And this is exactly the basis for all the following work Why is it important? When you have the Offset, it means: You can sit directly on the program execution flow with your input Then You pad anything you want from 0 to Offset From Offset onwards, you put the addresses or ROP chain or your shellcode From this point on, you are in control, not the program After analyzing the crash, you need to figure out exactly how many bytes it takes for your input to reach somewhere like EIP or RIP. This is done by creating a unique pattern and finding the Offset When you find the Offset, it means you have definitely been able to take control of the program execution flow and this is the starting point for exploit writing @reverseengine

گرفتن Offset و کنترل‌ کردن EIP/RIP جایی که میفهمید واقعا میتونید برنامه رو هک کنید یا نه وقتی فهمیدید برنامه چطوری کرش میکنه قدم بعد اینه که مشخص کنید ورودی شما دقیقا کجای استک یا رجیستر ها میشینه این یعنی باید بفهمید دقیقا کدوم کاراکتر از ورودی باعث شده EIP/RIP یا جریان اجرای برنامه از دست بره به این میگن Offset Offset یعنی چی؟ مفهومش ساده‌ست: چندتا کاراکتر از شروع ورودی لازم دارید تا برسید به نقطه‌ای که برنامه کرش میکنه؟ مثلاً اگه با 2000 تا A برنامه خراب شد و توی EIP شده 0x41414141 خب میفهمید A اثر کرده ولی اینکه کدوم A؟ کدوم کاراکتر دقیقا روی EIP نشسته؟ اینجاست که Offset معنی پیدا میکنه فاز گرفتن Fuzzing ساده اول یه ورودی بلند به برنامه میدید چیزی مثل:
python -c "print('A' * 5000)"
هدف اینه که کرش ایجاد بشه و ببینید آیا ورودی شما وارد رجیسترها شده یا نه مثلا: RIP = 0x41414141 عالیه RIP شده یه چیز رندوم باز هم قابل بررسیه اصلا ورودی ما اثری نذاشته پس بافر مربوطه جای دیگه‌ ست وقتی مطمئن شدیم داده‌ ی ما وارد مسیر برنامه شده میریم مرحله بعد ساخت Pattern یکتا الگو تصادفی برای اینکه بفهمیم کدوم قسمت دقیقا روی EIP/RIP نشسته از یه الگوی یکتا استفاده میکنیم نه AAAAA…. ابزار هایی مثل:
msf-pattern_create
gef pattern create
pwndbg pattern create
یک رشته مثلا 3000 کاراکتری میسازن که هیچ بخشش شبیه بخش دیگه نیست چیزی شبیه:
Aa0Aa1Aa2Aa3Bb0Bb1Bb2...
این رشته رو میفرستید به برنامه برنامه خراب میشه حالا EIP/RIP رو نگاه میکنید فرض کند توی RIP دیدید:
0x39654138
حالا باید ببینید این بخش از الگو دقیقا چندمین بایت بود؟ پیدا کردن Offset از ابزار پیدا کردن offset استفاده میکنیم
msf-pattern_offset -q 39654138
یا داخل gdb/gef:
pattern offset 0x39654138
بهتون میگه مثلا: "Offset = 524" یعنی کاراکتر شماره 524 از ورودی دقیقا روی EIP/RIP نشسته و این دقیقا پایه همه‌ ی کارهای بعدیه چرا مهمه؟ وقتی Offset رو دارید یعنی: میتونید با ورودیتون مستقیما روی جریان اجرای برنامه بشینید بعد از 0 تا Offset هرچی میخواید پد میذارید از Offset به بعد آدرس‌ها یا ROP chain یا شل‌کدتون رو قرار میدید از این لحظه به بعد کنترل با شمائه نه با برنامه بعد از تحلیل کرش باید بفهمید دقیقا چند بایت طول میکشه تا ورودیتون برسه به جایی مثل EIP یا RIP این کار با ساختن یه الگو یکتا و پیدا کردن Offset انجام میشه وقتی Offset رو پیدا کنید یعنی حتما تونستید جریان اجرای برنامه رو در اختیار بگیرید و این نقطه شروع اکسپلویت‌نویسیه Getting Offset and Controlling EIP/RIP Where you can really hack your program Once you understand how your program crashes, the next step is to determine exactly where your input sits on the stack or registers This means you need to figure out exactly which character of the input caused the EIP/RIP or program execution flow to be lost This is called Offset What does Offset mean? The concept is simple: How many characters from the start of the input do you need to get to the point where the program crashes? For example, if the program crashes with 2000 A and the EIP is 0x41414141, then you know that A has taken effect But which A? Which character exactly sits on the EIP? This is where Offset comes into play Simple Fuzzing First, you would see a long input to the program, something like:
python -c "print('A' * 5000)"
The goal is to create a crash and see if your input has entered the registers or not For example: RIP = 0x41414141 is great RIP is a random thing that can still be checked Our input has not left any trace at all, so the corresponding buffer is somewhere else Once we are sure that our data has entered the program path, we move on to the next step Create a unique random pattern To find out which part exactly sits on EIP/RIP, we use a unique pattern, not AAAAA…. Tools like:
msf-pattern_create
gef pattern create
pwndbg pattern create
They create a string of, say, 3000 characters, where no part is the same as another Something like:
Aa0Aa1Aa2Aa3Bb0Bb1Bb2...
You send this string to the program, the program crashes, now you look at EIP/RIP Suppose you saw in RIP:
0x39654138
Now you need to see exactly what byte this part of the pattern was? Finding Offset We use the offset finder tool
msf-pattern_offset -q 39654138
or in gdb/gef:

محل دقیق Return Address ساختار استک: ┌──────────────────┐ rbp+16 = arg1 │ Argument 1 │ ├──────────────────┤ │ Return Address │ rbp+8 ├──────────────────┤ │ Saved RBP │ rbp ├──────────────────┤ │ Local variable b │ rbp-8 ├──────────────────┤ │ Local variable a │ rbp-4 └──────────────────┘ برای اکسپلویت: باید مقدار بایت‌ هایی که لازمه تا return address بازنویسی بشه رو حساب کنید
Offset = distance(local buffer saved RBP return address)
Exact location Return Address Stack structure: ┌──────────────────┐       rbp+16   = arg1 │    Argument 1     │  ├──────────────────┤  │  Return Address   │   rbp+8 ├──────────────────┤  │     Saved RBP     │   rbp ├──────────────────┤  │  Local variable b │   rbp-8 ├──────────────────┤  │  Local variable a │   rbp-4 └──────────────────┘ To exploit: You need to calculate the number of bytes needed to rewrite the return address
Offset = distance(local buffer saved RBP return address)
@reverseengine

مهم ترین بخش برای Exploit + ROP کامپایلر دقیقا چه چیز هایی رو داخل استک ذخیره میکنه:
Saved RBP
Return Address
Local Variables
Padding / Alignment
Call-preserved registers
متغیر های محلی چجوری روی استک قرار میگیرن؟ کد C:
int func(int x) { int a = 5; int b = x + 3; return a + b; }
کامپایل با -O0:
push rbp mov rbp, rsp sub rsp, 16 ; allocate space for a, b mov DWORD PTR [rbp-4], 5 mov eax, DWORD PTR [rbp+16] ; x add eax, 3 mov DWORD PTR [rbp-8], eax mov eax, DWORD PTR [rbp-4] add eax, DWORD PTR [rbp-8] leave ret
نکته مهم برای اکسپلویت: لوکال‌ها همیشه از آدرس‌ های:
rbp - 4 rbp - 8 rbp - 0x10
شروع میشن این دقیقا جایی که بافر اورفلو اتفاق میوفته Most important part for Exploit + ROP What exactly does the compiler store on the stack:
Saved RBP
Return Address
Local Variables
Padding / Alignment
Call-preserved registers
How are local variables placed on the stack? C code:
int func(int x) { int a = 5; int b = x + 3; return a + b; }
Compile with -O0:
push rbp mov rbp, rsp sub rsp, 16 ; allocate space for a, b mov DWORD PTR [rbp-4], 5 mov eax, DWORD PTR [rbp+16] ; x add eax, 3 mov DWORD PTR [rbp-8], eax mov eax, DWORD PTR [rbp-4] add eax, DWORD PTR [rbp-8] leave ret
Important note for exploit: Locals always start at:
rbp - 4 rbp - 8 rbp - 0x10
This is exactly where the buffer overflow occurs @reverseengine

Struct داخل آرایه C:
struct Item { int a; int b; int c; };
Item arr[100]; return arr[i].b;
آدرس:
arr + i * sizeof(Item)
اسمبلی:
mov eax, DWORD PTR [rdi + rsi*12 + 4] چون sizeof (Item) = 12 offset b = 4
چطور تشخیص بدیم struct هست وقتی: ضربدر یک عدد غیر معمول دیدید 12 24 36 offset های ثابت مثلا 4 8 16 یعنی struct array هست نه 2D array Struct inside array C:
struct Item { int a; int b; int c; };
Item arr[100]; return arr[i].b;
Address:
arr + i * sizeof(Item)
Assembly:
mov eax, DWORD PTR [rdi + rsi*12 + 4] Because sizeof (Item) = 12 offset b = 4
How to tell if it is a struct When: You see an unusual number 12 24 36 Fixed offsets, such as 4 8 16 That means it is a struct array, not a 2D array @reverseengine