1 265
Subscribers
No data24 hours
-37 days
+730 days
Posts Archive
1 265
From Support Ticket to Zero Day
https://horizon3.ai/attack-research/attack-blogs/from-support-ticket-to-zero-day
@reverseengine
1 265
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
1 265
Reverse-engineering and analysis of SanDisk High Endurance microSDXC card
https://ripitapart.com/2020/07/16/reverse-engineering-and-analysis-of-sandisk-high-endurance-microsdxc-card
@reverseengine
1 265
Attack Secure Boot of SEP
https://github.com/windknown/presentations/raw/master/Attack_Secure_Boot_of_SEP.pdf
@reverseengine
1 265
Fuzzing the Windows API for AV Evasion
https://winternl.com/fuzzing-the-windows-api-for-av-evasion
@reverseengine
1 265
IDA Pro Tips to Add to Your Bag of Tricks
https://swarm.ptsecurity.com/ida-pro-tips
@reverseengine
1 265
UAFuzz: Binary-level Directed Fuzzing for Use-After-Free Vulnerabilities
https://github.com/strongcourage/uafuzz
@reverseengine
1 265
Repost from N/a
1 265
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/
1 265
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-ceInstructions:
rusthound-ce -i 192.168.1.10 -d domain.local -u user@domain.local -p 'pass' -z@reverseengine
1 265
pattern offset 0x39654138It 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
1 265
گرفتن 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 createThey 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:
0x39654138Now 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 39654138or in gdb/gef:
1 265
محل دقیق 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
1 265
مهم ترین بخش برای 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 registersHow 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 retImportant note for exploit: Locals always start at:
rbp - 4 rbp - 8 rbp - 0x10This is exactly where the buffer overflow occurs @reverseengine
1 265
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 = 4How 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
1 265
Dive Deeper -- Analyze real mode binaries like a Pro with Qiling Framework
https://blog.lazym.io/2020/09/05/Dive-deeper-Analyze-real-mode-binaries-like-a-Pro-with-Qiling-Framework
@reverseengine
1 265
Dealing with Manipulated ELF Binary and Manually Resolving Import Functions
https://forum.reverse4you.org/t/dealing-with-manipulated-elf-binary-and-manually-resolving-import-functions/11842
@reverseengine
