ReverseEngineering – Telegram
ReverseEngineering
1.24K subscribers
40 photos
10 videos
55 files
666 links
Download Telegram
مهم ترین بخش برای 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
1
محل دقیق 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
2
گرفتن 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:
1
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
1
RustHound-CE 2.4.5

https://github.com/g0h4n/RustHound-CE

ابزار جمع‌آوری 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

https://github.com/g0h4n/RustHound-CE

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
2
Forwarded 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
The to Reporting for Board.pdf
3.2 MB
The to Reporting for Board

@reverseengine
1