APIMiner - The API Logger for Malwares - The Fast Way To Identifying Malwares
http://www.malware-analysis-and-detection-engineering.com/2020/09/apiminer-api-logger-for-malwares-fast.html
@reverseengine
http://www.malware-analysis-and-detection-engineering.com/2020/09/apiminer-api-logger-for-malwares-fast.html
@reverseengine
Malware-Analysis-And-Detection-Engineering
APIMiner - The API Logger for Malwares - The Fast Way To Identifying Malwares
Direct Download Link for Latest Release of APIMiner: https://github.com/poona/APIMiner/releases/download/1.0.0/release-v1.0.0.zip One of...
❤1
این بخش داخل ریورس بدافزار آنپکینگ تحلیل فانکشن های ++C و Lib ها استفاده میشه
Struct داخل struct
مثال C:
داخل حافظه اینجوری دیده میشه:
در اسمبلی:
نکته
اگر دیدید چند فیلد int پشتسر همن تقریبا همیشه یک struct است نه آرایه
اگر یک offset یهو زیاد شد مثل 16 یعنی وجود double / pointer / align
This section is used in reverse malware unpacking analysis of C++ functions and Libs
Struct inside struct
Example C:
In memory it looks like this:
In assembly:
Tip
If you see multiple int fields in a row, it's almost always a struct, not an array
If an offset suddenly increases, like 16, it means there's a double / pointer / align
@reverseengine
Struct داخل struct
مثال C:
struct B {
int x;
int y;
};
struct A {
int id;
struct B pos;
double score;
};
داخل حافظه اینجوری دیده میشه:
offset 0 id (int)
offset 4 pos.x (int)
offset 8
pos.y (int)
offset 12 padding
(برای align کردن double)
offset 16 score (double)
در اسمبلی:
mov eax, DWORD PTR [rdi] ; id
mov eax, DWORD PTR [rdi + 4] ; pos.x
mov eax, DWORD PTR [rdi + 8] ; pos.y
movsd xmm0, [rdi + 16] ; score
نکته
اگر دیدید چند فیلد int پشتسر همن تقریبا همیشه یک struct است نه آرایه
اگر یک offset یهو زیاد شد مثل 16 یعنی وجود double / pointer / align
This section is used in reverse malware unpacking analysis of C++ functions and Libs
Struct inside struct
Example C:
struct B {
int x;
int y;
};
struct A {
int id;
struct B pos;
double score;
};
In memory it looks like this:
offset 0 id (int)
offset 4 pos.x (int)
offset 8
pos.y (int)
offset 12 padding
(to align double)
offset 16 score (double)
In assembly:
mov eax, DWORD PTR [rdi] ; id
mov eax, DWORD PTR [rdi + 4] ; pos.x
mov eax, DWORD PTR [rdi + 8] ; pos.y
movsd xmm0, [rdi + 16] ; score
Tip
If you see multiple int fields in a row, it's almost always a struct, not an array
If an offset suddenly increases, like 16, it means there's a double / pointer / align
@reverseengine
❤1
بخش سیزدهم بافر اورفلو
مفهوم ret2libc و چطور از توابع libc برای هدایت اجرا استفاده میکنیم
چرا وقتی استک مال ما قابل اجرا نیست NX یا آدرس ها جا به جا میشن به جای گذاشتن شلک د روی استک میریم سراغ توابع آماده libc مثل puts یا printf یا در حالت خطرناک system
وقتی نمیتونم کد بذاریم و اجراش کنیم NX یا آدرسها متغیرن ASLR میایم از کتابخونه سیستم استفاده میکنیم به جای اینکه RIP رو بندازیم روی شل کد خودمون RIP رو میندازیم روی آدرس تابعی تو libc که قبلا هم خود برنامه ازش استفاده کرده puts و آرگومان مناسب رو هم جوری کنار میذاریم که puts یه رشته دلخواه رو چاپ کنه
این ایده دو مرحله اصلی داره
1 نشت آدرس libc یا یک آدرس ثابت پیدا میکنیم
2 از اون آدرس استفاده میکنیم تا آدرس توابع libc را محاسبه کنیم و بعد RIP رو به آن تابع ببریم
Code C:
file9_demo.c
#include <stdio.h>
#include <string.h>
char secret[] = "this is a libc string for demo";
void vuln(char *s) {
char buf[32];
strcpy(buf, s); /* unsafe but دمو */
puts("returned from vuln");
}
int main(int argc, char **argv) {
if (argc < 2) {
printf("usage %s input\n", argv[0]);
return 1;
}
vuln(argv[1]);
puts("program finished");
return 0;
}
ret2libc
یعنی استفاده از توابع آماده libc به جای اجرای شل کد روی استک
معمولا دو قدم لازمه:
نشت آدرس و بعد پر کردن استک جوری که وقتی برگشت تابع libc اجرا بشه با آرگومان مناسب
امنیت: NX و ASLR و PIE ترکیبی هستند که کار رو پیچیده میکنن
Part 13 Buffer Overflow
The concept of ret2libc and how we use libc functions to direct execution
Why when our stack is not executable NX or addresses are moved instead of putting shellcode on the stack we go to ready libc functions like puts or printf or in dangerous mode system
When we can't write code and execute it NX or addresses are variable ASLR we use the system library Instead of putting RIP on our shellcode we put RIP on the address of a function in libc that the program has already used puts and we leave the appropriate argument in such a way that puts prints a desired string
This idea has two main steps
1 We find a libc address leak or a fixed address
2 We use that address to calculate the address of libc functions and then put RIP to that function
Code C:
file9_demo.c
#include <stdio.h>
#include <string.h>
char secret[] = "this is a libc string for demo";
void vuln(char *s) {
char buf[32];
strcpy(buf, s); /* unsafe but demo */
puts("returned from vuln");
}
int main(int argc, char **argv) {
if (argc < 2) {
printf("usage %s input\n", argv[0]);
return 1;
}
vuln(argv[1]);
puts("program finished");
return 0;
}
ret2libc
i.e. using ready-made libc functions instead of executing shellcode on the stack
Usually two steps are required:
Leak the address and then fill the stack so that when the libc function returns it is executed with the appropriate arguments
Security: NX, ASLR and PIE are a combination that complicates the task
@reverseengine
👍2
پاکسازی ردپای پردازشی Process Artifacts
Process Artifact
هر برنامه ای که اجرا میکنید حتی ساده ترین اسکریپت یه سری اثر پردازشی از خودش میذاره:
چه ساعتی اجرا شد
چه Threadهایی ساخت
چه Handle هایی باز کرد
چه Module هایی لود شدن
چه مقدار RAM مصرف کرد
چه Parent داشت
چه Token استفاده کرد
این چیزاست که DFIR و EDR عاشقشن چون با همین ها مسیر حمله رو از اول تا اخر reconstruct میکنن
مهم ترین ردپاهای پردازشی که معمولا جا میمونه
Process Creation Info
مثل یک پرونده:
StartTime CommandLine ParentProcess، IntegrityLevel
Modules / DLLs
لیست DLL هایی که لود شدن معمولا کاملا مشخصه
Thread Artifacts
حتی اگه بعدا پاک بشه،اطلاعات Thread Creation یه مدت زنده میمونه
Handle Table
فایلها pipeها registry ها mutex ها
هر کدوم روی handle اثر میذاره
Memory Layout
حتی اگر inject کرده باشید footprint بخش تزریقی تو Virtual Memory Table مشخصه
Token Artifacts
نوع توکن privilege هایی که borrow شده بودن Owner/Group
چطور باید کاهش شون بدیم
عمر پروسه رو کوتاه نگه داری
بیشتر artifact ها بر اساس زمان بالا بودن پروسه جمع میشن
تا جای ممکن کار های خارجی لود نکنید
هر DLL اضافه = یک trace
Thread نسازید مگر لازم باشه
Thread
کمتر یعنی footprint کمتر
Handle Hygiene
هرچیزی باز شد خیلی زود ببندید
خیلیا کدشون رو handle باز میذارن و همون میشه سند جرم
Memory Hygiene
Buffer
های بزرگ الکی نسازید
Memory section
های عجیب نذارید و حتما free کنید
رفتار Parent-Child منطقی باشه
اگه ParentSpoofing ناقص باشه artifact ش تو توکن و timestamps مشخصه
هرچی زنجیره عجیب تر باشه
لو رفتن بیشتر میشه
Process Artifacts Cleanup
Process Artifact
Every program you run, even the simplest noscript, leaves behind a series of process traces:
What time it was run
What threads it created
What handles it opened
What modules were loaded
How much RAM it consumed
What parent it had
What token it used
This is what DFIR and EDR love because they reconstruct the attack path from start to finish
The most important process traces that are usually left
Process Creation Info
Like a file:
StartTime CommandLine ParentProcess, IntegrityLevel
Modules / DLLs
List of DLLs that were loaded is usually quite specific
Thread Artifacts
Even if it is later cleared, Thread Creation information remains alive for a while
Handle Table
Files, pipes, registries, mutexes
Each of which affects the handle
Memory Layout
Even if you have injected the footprint of the injected part In the Virtual Memory Table, it is specified
Token Artifacts
Type of borrowed privilege tokens Owner/Group
How to reduce them
Keep the process life short
Most artifacts are accumulated based on the time the process is up
Do not load external tasks as much as possible
Each additional DLL = a trace
Do not create threads unless necessary
Fewer threads means less footprint
Handle Hygiene
Close everything that is opened very quickly
Many people leave their code handles open and that is evidence of the crime
Memory Hygiene
Do not create excessively large buffers
Do not leave strange memory sections and be sure to free them
Parent-Child behavior should be logical
If ParentSpoofing is incomplete, the artifact is specified in the token and timestamps
The stranger the chain, the more leakage
@reverseengine
❤1
اولین قدم توی باینری اکسپلویتیشن اینه که بفهمید برنامه چطوری و چرا کرش میکنه
کرش برای بقیه یه باگه ولی برای ما یه فرصت طلاییه با تحلیل کرش میفهمید یا جریان اجرای برنامه واقعا قابل هک شدن هست یا نه
فهمیدن اینکه برنامه چطوری کرش میکنه Crash Analysis
قبل اینکه بریم سراغ ROP و شل کد و این چیزا باید بدونیم برنامه دقیقا چرا کرش میکنه و چطوری میتونیم رفتار کرش رو کنترل کنیم اینجا همون جاییه که اکسپلویت واقعی شکل میگیره
کرش یعنی چی؟
کرش یعنی برنامه یه جایی دیگه نمیتونه ادامه بده و سیستم بهش میگه:
داداش جمع کن بریم گند زدی😂
ولی برای ما این بهترین نقطه ی شروع حمله ست
چون هر کرش یعنی یه چیزی از دست برنامه در رفته
چرا کرش برای ما مهمه؟
چون وقتی برنامه میمیره💀:
یا رجیسترها خراب شدن
یا جریان اجرای برنامه از کنترل خارج شده
یا یه آدرس عجیب شده مقصد اجرای کد
و اینا همون چیزایی هستن که قراره تبدیل بشن به:
کنترل PC Program Counter / RIP EIP
اجرای شلکد
یا ساخت ROP chain
پس اول باید بفهمیم کرش چه شکلیه و چی رو تغییر میده
چطور کرش رو تحلیل کنیم؟
معمولا با یکی از این ابزارها:
gdb لینوکس
gef / pwndbg / peda
WinDbg ویندوز
x64dbg ویندوز
ولی مهم تر از ابزار چیزیه که باید دنبالش بگردیم:
چیزهایی که توی یه کرش باید چک کنیم :
آدرس کرش کجاست؟
مثلا SIGSEGV در آدرس 0x41414141 یعنی احتمالا برنامه با ورودی ما (A = 0x41) ترکیده😁
کدوم رجیسترها با ورودی ما پر شدن؟
مثل EIP/RIP، ESP/RSP، RBP و حتی رجیستر های کمکی مثل RDX و RAX
استک چه شکلی شده؟
آیا data ما روی استک ریخته؟
آیا اندازه ورودی یادداشت شده؟
آیا برنامه قبل از کرش از مرز یه بافر رد شده؟
مثلاً یه رشته بلند باعث شده strcpy یا gets از کنترل خارج بشه؟
این اطلاعات همون چیزیه که بهمون میگه:
آیا قابل اکسپلویت هست؟
یا فقط تکون خورده ولی قابل سواستفاده نیست؟
چرا این مرحله مهمه؟
چون هیچ اکسپلویتی بدون تحلیل کرش نوشته نمیشه وقتی دقیق بفهمیم برنامه کجا و چطور ترکیده میتونی مرحله بعد بریم سراغ:
پیدا کردن Offset
کنترل EIP/RIP
ساخت Payload
و بعد ROP / شلکد
The first step in binary exploitation is to understand how the program crashes and why it crashes
A crash is a bug for others, but it's a golden opportunity for us. By analyzing the crash, you can understand whether the program's execution flow is really hackable or not
Understanding how the program crashes Crash Analysis
Before we go into ROP and shellcode and all that, we need to know exactly why the program crashes and how we can control the crash behavior. This is where the real exploit comes in.
What does a crash mean?
A crash means that the program can't continue anywhere else and the system tells it:
Bro, get out of here, you messed up😂
But for us, this is the best starting point for an attack
Because every crash means something is missing from the program
Why is a crash important to us?
Because when a program dies💀:
Either the registers are corrupted
Or the program execution flow is out of control
Or a strange address is the destination of the code execution
And these are the things that are going to become:
Controlling PC Program Counter / RIP EIP
Executing shellcode
Or building ROP chain
So first we need to understand what the crash looks like and what it changes
How to analyze the crash?
Usually with one of these tools:
gdb Linux
gef / pwndbg / peda
WinDbg Windows
x64dbg Windows
But more important than the tool is what we need to look for:
Things to check in a crash:
Where is the crash address?
For example, SIGSEGV at address 0x41414141 means that the program probably exploded with our input (A = 0x41)😁
Which registers were filled with our input?
Like EIP/RIP, ESP/RSP, RBP and even auxiliary registers like RDX and RAX
What is the stack shape?
Did our data spill onto the stack?
Was the input size noted?
Did the program overflow a buffer before crashing?
For example, did a long string cause strcpy or gets to go out of control?
This information is what tells us:
Is it exploitable?
Or is it just shaken but not exploitable?
Why is this step important?
Because no exploit can be written without crash analysis. Once we know exactly where and how the program crashed, we can move on to the next step:
Finding Offset
EIP/RIP Control
Building Payload
کرش برای بقیه یه باگه ولی برای ما یه فرصت طلاییه با تحلیل کرش میفهمید یا جریان اجرای برنامه واقعا قابل هک شدن هست یا نه
فهمیدن اینکه برنامه چطوری کرش میکنه Crash Analysis
قبل اینکه بریم سراغ ROP و شل کد و این چیزا باید بدونیم برنامه دقیقا چرا کرش میکنه و چطوری میتونیم رفتار کرش رو کنترل کنیم اینجا همون جاییه که اکسپلویت واقعی شکل میگیره
کرش یعنی چی؟
کرش یعنی برنامه یه جایی دیگه نمیتونه ادامه بده و سیستم بهش میگه:
داداش جمع کن بریم گند زدی😂
ولی برای ما این بهترین نقطه ی شروع حمله ست
چون هر کرش یعنی یه چیزی از دست برنامه در رفته
چرا کرش برای ما مهمه؟
چون وقتی برنامه میمیره💀:
یا رجیسترها خراب شدن
یا جریان اجرای برنامه از کنترل خارج شده
یا یه آدرس عجیب شده مقصد اجرای کد
و اینا همون چیزایی هستن که قراره تبدیل بشن به:
کنترل PC Program Counter / RIP EIP
اجرای شلکد
یا ساخت ROP chain
پس اول باید بفهمیم کرش چه شکلیه و چی رو تغییر میده
چطور کرش رو تحلیل کنیم؟
معمولا با یکی از این ابزارها:
gdb لینوکس
gef / pwndbg / peda
WinDbg ویندوز
x64dbg ویندوز
ولی مهم تر از ابزار چیزیه که باید دنبالش بگردیم:
چیزهایی که توی یه کرش باید چک کنیم :
آدرس کرش کجاست؟
مثلا SIGSEGV در آدرس 0x41414141 یعنی احتمالا برنامه با ورودی ما (A = 0x41) ترکیده😁
کدوم رجیسترها با ورودی ما پر شدن؟
مثل EIP/RIP، ESP/RSP، RBP و حتی رجیستر های کمکی مثل RDX و RAX
استک چه شکلی شده؟
آیا data ما روی استک ریخته؟
آیا اندازه ورودی یادداشت شده؟
آیا برنامه قبل از کرش از مرز یه بافر رد شده؟
مثلاً یه رشته بلند باعث شده strcpy یا gets از کنترل خارج بشه؟
این اطلاعات همون چیزیه که بهمون میگه:
آیا قابل اکسپلویت هست؟
یا فقط تکون خورده ولی قابل سواستفاده نیست؟
چرا این مرحله مهمه؟
چون هیچ اکسپلویتی بدون تحلیل کرش نوشته نمیشه وقتی دقیق بفهمیم برنامه کجا و چطور ترکیده میتونی مرحله بعد بریم سراغ:
پیدا کردن Offset
کنترل EIP/RIP
ساخت Payload
و بعد ROP / شلکد
The first step in binary exploitation is to understand how the program crashes and why it crashes
A crash is a bug for others, but it's a golden opportunity for us. By analyzing the crash, you can understand whether the program's execution flow is really hackable or not
Understanding how the program crashes Crash Analysis
Before we go into ROP and shellcode and all that, we need to know exactly why the program crashes and how we can control the crash behavior. This is where the real exploit comes in.
What does a crash mean?
A crash means that the program can't continue anywhere else and the system tells it:
Bro, get out of here, you messed up😂
But for us, this is the best starting point for an attack
Because every crash means something is missing from the program
Why is a crash important to us?
Because when a program dies💀:
Either the registers are corrupted
Or the program execution flow is out of control
Or a strange address is the destination of the code execution
And these are the things that are going to become:
Controlling PC Program Counter / RIP EIP
Executing shellcode
Or building ROP chain
So first we need to understand what the crash looks like and what it changes
How to analyze the crash?
Usually with one of these tools:
gdb Linux
gef / pwndbg / peda
WinDbg Windows
x64dbg Windows
But more important than the tool is what we need to look for:
Things to check in a crash:
Where is the crash address?
For example, SIGSEGV at address 0x41414141 means that the program probably exploded with our input (A = 0x41)😁
Which registers were filled with our input?
Like EIP/RIP, ESP/RSP, RBP and even auxiliary registers like RDX and RAX
What is the stack shape?
Did our data spill onto the stack?
Was the input size noted?
Did the program overflow a buffer before crashing?
For example, did a long string cause strcpy or gets to go out of control?
This information is what tells us:
Is it exploitable?
Or is it just shaken but not exploitable?
Why is this step important?
Because no exploit can be written without crash analysis. Once we know exactly where and how the program crashed, we can move on to the next step:
Finding Offset
EIP/RIP Control
Building Payload
❤4
Ransomware Attack Update for the 4th of December
https://darkwebinformer.com/ransomware-attack-update-for-the-4th-of-december-2025
@reverseengine
https://darkwebinformer.com/ransomware-attack-update-for-the-4th-of-december-2025
@reverseengine
Dark Web Informer
Ransomware Attack Update for the 4th of December 2025
❤1
Threat Attack Daily - 4th of December 2025
https://darkwebinformer.com/threat-attack-daily-4th-of-december-2025
@reverseengine
https://darkwebinformer.com/threat-attack-daily-4th-of-december-2025
@reverseengine
Dark Web Informer
Threat Attack Daily - 4th of December 2025
❤1
A Binary Ninja plugin for vulnerability research
https://github.com/Martyx00/VulnFanatic
@reverseengine
https://github.com/Martyx00/VulnFanatic
@reverseengine
GitHub
GitHub - Martyx00/VulnFanatic: A Binary Ninja plugin for vulnerability research.
A Binary Ninja plugin for vulnerability research. Contribute to Martyx00/VulnFanatic development by creating an account on GitHub.
❤1
Reverse-engineering the first FPGA chip the XC2064
http://www.righto.com/2020/09/reverse-engineering-first-fpga-chip.html
@reverseengine
http://www.righto.com/2020/09/reverse-engineering-first-fpga-chip.html
@reverseengine
Righto
Reverse-engineering the first FPGA chip, the XC2064
A Field-Programmable Gate Array (FPGA) can implement arbitrary digital logic, anything from a microprocessor to a video generator or crypt...
❤1
ARM64 Reversing and Exploitation
Part 1 - ARM Instruction Set + Simple Heap Overflow
http://highaltitudehacks.com/2020/09/05/arm64-reversing-and-exploitation-part-1-arm-instruction-set-heap-overflow/
ARM64 Reversing and Exploitation
Part 2 - Use After Free http://highaltitudehacks.com/2020/09/06/arm64-reversing-and-exploitation-part-2-use-after-free
ARM64 Reversing and Exploitation
Part 3 - A Simple ROP Chain http://highaltitudehacks.com/2020/09/06/arm64-reversing-and-exploitation-part-3-a-simple-rop-chain
@reverseengine
Part 1 - ARM Instruction Set + Simple Heap Overflow
http://highaltitudehacks.com/2020/09/05/arm64-reversing-and-exploitation-part-1-arm-instruction-set-heap-overflow/
ARM64 Reversing and Exploitation
Part 2 - Use After Free http://highaltitudehacks.com/2020/09/06/arm64-reversing-and-exploitation-part-2-use-after-free
ARM64 Reversing and Exploitation
Part 3 - A Simple ROP Chain http://highaltitudehacks.com/2020/09/06/arm64-reversing-and-exploitation-part-3-a-simple-rop-chain
@reverseengine
Prateekg147
ARM64 Reversing and Exploitation Part 1 - ARM Instruction Set + Simple Heap Overflow
Hi Everyone ! In this blog series, we will be understanding the ARM instruction set and using that to reverse ARM Binaries followed by writing exploits for them. So let’s start with the basics of ARM64.
👍2
Using Qiling to resolve obfuscated import on windows
https://gist.github.com/y0ug/b83fcf121f80d419c8d5eb342ca31a59
@reverseengine
https://gist.github.com/y0ug/b83fcf121f80d419c8d5eb342ca31a59
@reverseengine
Gist
Using Qiling to resolve obfuscated import on windows
Using Qiling to resolve obfuscated import on windows - _IAT_qiling.py
🔥2
DRAKVUF is a virtualization based agentless black-box binary analysis system
https://github.com/tklengyel/drakvuf
@reverseengine
https://github.com/tklengyel/drakvuf
@reverseengine
GitHub
GitHub - tklengyel/drakvuf: DRAKVUF Black-box Binary Analysis
DRAKVUF Black-box Binary Analysis. Contribute to tklengyel/drakvuf development by creating an account on GitHub.
❤1
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
https://forum.reverse4you.org/t/dealing-with-manipulated-elf-binary-and-manually-resolving-import-functions/11842
@reverseengine
R0 CREW
Dealing with Manipulated ELF Binary and Manually Resolving Import Functions
Source: github.com/jeffli678 This is a writeup about solving the BinaryNewbie’s Tr1cky Cr4ckm3. It is created by user BinaryNewbie, who is NOT a newbie for binary reversing. It can be downloaded at: Crackmes 5e727daa33c5d4439bb2decd.zip (6.0 KB) We…
👏2
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
https://blog.lazym.io/2020/09/05/Dive-deeper-Analyze-real-mode-binaries-like-a-Pro-with-Qiling-Framework
@reverseengine
Lazymio's Blog
Dive Deeper -- Analyze real mode binaries like a Pro with Qiling Framework
IntroductionAnalyzing a real mode binary like DOS executables or MBR code is never an easy task. The best approach we have is to utilize Bochs, QEMU or Dosbox to emulate such binaries with some debugg
❤1
Struct داخل آرایه
C:
آدرس:
اسمبلی:
چطور تشخیص بدیم struct هست
وقتی:
ضربدر یک عدد غیر معمول دیدید 12 24 36
offset
های ثابت مثلا 4 8 16
یعنی struct array هست نه 2D array
Struct inside array
C:
Address:
Assembly:
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
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
❤1
مهم ترین بخش برای Exploit + ROP
کامپایلر دقیقا چه چیز هایی رو داخل استک ذخیره میکنه:
متغیر های محلی چجوری روی استک قرار میگیرن؟
کد C:
کامپایل با -O0:
نکته مهم برای اکسپلویت:
لوکالها همیشه از آدرس های:
شروع میشن
این دقیقا جایی که بافر اورفلو اتفاق میوفته
Most important part for Exploit + ROP
What exactly does the compiler store on the stack:
How are local variables placed on the stack?
C code:
Compile with -O0:
Important note for exploit:
Locals always start at:
This is exactly where the buffer overflow occurs
@reverseengine
کامپایلر دقیقا چه چیز هایی رو داخل استک ذخیره میکنه:
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 بازنویسی بشه رو حساب کنید
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
@reverseengine
ساختار استک:
┌──────────────────┐ 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 ساده
اول یه ورودی بلند به برنامه میدید چیزی مثل:
هدف اینه که کرش ایجاد بشه و ببینید آیا ورودی شما وارد رجیسترها شده یا نه
مثلا:
RIP = 0x41414141 عالیه
RIP شده یه چیز رندوم باز هم قابل بررسیه
اصلا ورودی ما اثری نذاشته پس بافر مربوطه جای دیگه ست
وقتی مطمئن شدیم داده ی ما وارد مسیر برنامه شده میریم مرحله بعد
ساخت Pattern یکتا الگو تصادفی
برای اینکه بفهمیم کدوم قسمت دقیقا روی EIP/RIP نشسته از یه الگوی یکتا استفاده میکنیم نه AAAAA….
ابزار هایی مثل:
یک رشته مثلا 3000 کاراکتری میسازن که هیچ بخشش شبیه بخش دیگه نیست
چیزی شبیه:
این رشته رو میفرستید به برنامه برنامه خراب میشه حالا EIP/RIP رو نگاه میکنید
فرض کند توی RIP دیدید:
حالا باید ببینید این بخش از الگو دقیقا چندمین بایت بود؟
پیدا کردن Offset
از ابزار پیدا کردن offset استفاده میکنیم
یا داخل gdb/gef:
بهتون میگه مثلا:
"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:
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:
They create a string of, say, 3000 characters, where no part is the same as another
Something like:
You send this string to the program, the program crashes, now you look at EIP/RIP
Suppose you saw in RIP:
Now you need to see exactly what byte this part of the pattern was?
Finding Offset
We use the offset finder tool
or in gdb/gef:
جایی که میفهمید واقعا میتونید برنامه رو هک کنید یا نه
وقتی فهمیدید برنامه چطوری کرش میکنه قدم بعد اینه که مشخص کنید ورودی شما دقیقا کجای استک یا رجیستر ها میشینه
این یعنی باید بفهمید دقیقا کدوم کاراکتر از ورودی باعث شده 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