.. | ||
angr-examples.md | ||
README.md |
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!
Drugi načini podrške HackTricks-u:
- Ako želite da vidite vašu kompaniju reklamiranu na HackTricks-u ili preuzmete HackTricks u PDF formatu proverite SUBSCRIPTION PLANS!
- Nabavite zvanični PEASS & HackTricks swag
- Otkrijte The PEASS Family, našu kolekciju ekskluzivnih NFT-ova
- Pridružite se 💬 Discord grupi ili telegram grupi ili nas pratite na Twitter-u 🐦 @carlospolopm.
- Podelite svoje trikove hakovanja slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Deo ovog šešira je zasnovan na angr dokumentaciji.
Instalacija
sudo apt-get install python3-dev libffi-dev build-essential
python3 -m pip install --user virtualenv
python3 -m venv ang
source ang/bin/activate
pip install angr
Osnovne radnje
Load Binary
Učitaj binarni fajl
To load a binary file into an Angr project, you can use the angr.Project
class. This class represents the entire binary and provides various methods and attributes to interact with it.
Da biste učitali binarni fajl u Angr projekat, možete koristiti klasu angr.Project
. Ova klasa predstavlja ceo binarni fajl i pruža različite metode i atribute za interakciju sa njim.
import angr
# Load the binary
project = angr.Project("/path/to/binary")
Analyze Functions
Analiziraj funkcije
To analyze the functions in a binary, you can use the project.analyses.CFGFast
class. This class constructs a control flow graph (CFG) of the binary and provides methods to analyze the functions.
Da biste analizirali funkcije u binarnom fajlu, možete koristiti klasu project.analyses.CFGFast
. Ova klasa konstruiše graf toka kontrole (CFG) binarnog fajla i pruža metode za analizu funkcija.
from angrutils import plot_cfg
# Analyze the functions
cfg = project.analyses.CFGFast()
# Plot the CFG
plot_cfg(cfg, "/path/to/output.png")
Find Functions by Name
Pronađi funkcije po imenu
To find functions in a binary by their name, you can use the project.kb.functions
attribute. This attribute is a dictionary that maps function names to their corresponding addresses.
Da biste pronašli funkcije u binarnom fajlu po njihovom imenu, možete koristiti atribut project.kb.functions
. Ovaj atribut je rečnik koji mapira imena funkcija na njihove odgovarajuće adrese.
# Find functions by name
function_address = project.kb.functions["function_name"].addr
Find Functions by Address
Pronađi funkcije po adresi
To find functions in a binary by their address, you can use the project.kb.functions
attribute. This attribute is a dictionary that maps function addresses to their corresponding names.
Da biste pronašli funkcije u binarnom fajlu po njihovoj adresi, možete koristiti atribut project.kb.functions
. Ovaj atribut je rečnik koji mapira adrese funkcija na njihova odgovarajuća imena.
# Find functions by address
function_name = project.kb.functions.function_name.addr
Find Basic Blocks
Pronađi osnovne blokove
To find basic blocks in a function, you can use the function.blocks
attribute. This attribute is a dictionary that maps block addresses to their corresponding basic block objects.
Da biste pronašli osnovne blokove u funkciji, možete koristiti atribut function.blocks
. Ovaj atribut je rečnik koji mapira adrese blokova na njihove odgovarajuće objekte osnovnih blokova.
# Find basic blocks
basic_block = function.blocks[block_address]
Analyze Basic Blocks
Analiziraj osnovne blokove
To analyze the basic blocks in a function, you can use the project.analyses.CFGFast
class. This class constructs a control flow graph (CFG) of the function and provides methods to analyze the basic blocks.
Da biste analizirali osnovne blokove u funkciji, možete koristiti klasu project.analyses.CFGFast
. Ova klasa konstruiše graf toka kontrole (CFG) funkcije i pruža metode za analizu osnovnih blokova.
from angrutils import plot_cfg
# Analyze the basic blocks
cfg = project.analyses.CFGFast(function)
# Plot the CFG
plot_cfg(cfg, "/path/to/output.png")
Find Instructions
Pronađi instrukcije
To find instructions in a basic block, you can use the block.capstone.insns
attribute. This attribute is a list of Capstone instruction objects representing the instructions in the basic block.
Da biste pronašli instrukcije u osnovnom bloku, možete koristiti atribut block.capstone.insns
. Ovaj atribut je lista objekata instrukcija Capstone koji predstavljaju instrukcije u osnovnom bloku.
# Find instructions
instructions = block.capstone.insns
Analyze Instructions
Analiziraj instrukcije
To analyze the instructions in a basic block, you can use the block.capstone.insns
attribute. This attribute is a list of Capstone instruction objects representing the instructions in the basic block.
Da biste analizirali instrukcije u osnovnom bloku, možete koristiti atribut block.capstone.insns
. Ovaj atribut je lista objekata instrukcija Capstone koji predstavljaju instrukcije u osnovnom bloku.
# Analyze the instructions
for instruction in block.capstone.insns:
# Perform analysis on each instruction
pass
import angr
import monkeyhex # this will format numerical results in hexadecimal
#Load binary
proj = angr.Project('/bin/true')
#BASIC BINARY DATA
proj.arch #Get arch "<Arch AMD64 (LE)>"
proj.arch.name #'AMD64'
proj.arch.memory_endness #'Iend_LE'
proj.entry #Get entrypoint "0x4023c0"
proj.filename #Get filename "/bin/true"
#There are specific options to load binaries
#Usually you won't need to use them but you could
angr.Project('examples/fauxware/fauxware', main_opts={'backend': 'blob', 'arch': 'i386'}, lib_opts={'libc.so.6': {'backend': 'elf'}})
Učitani podaci
Overview
Pregled
The loaded data section provides information about the data that has been loaded into the program during its execution. This can include files, libraries, and other resources that are necessary for the program to run.
Odeljak o učitanim podacima pruža informacije o podacima koji su učitani u program tokom njegovog izvršavanja. To može uključivati datoteke, biblioteke i druge resurse koji su neophodni za pokretanje programa.
Loaded Files
Učitane datoteke
This subsection lists the files that have been loaded into the program. It provides information such as the file name, its base address in memory, and its size.
Ovaj pododeljak navodi datoteke koje su učitane u program. Pruža informacije kao što su naziv datoteke, njen bazni adresni prostor u memoriji i njena veličina.
Loaded Libraries
Učitane biblioteke
This subsection lists the libraries that have been loaded into the program. It provides information such as the library name, its base address in memory, and its size.
Ovaj pododeljak navodi biblioteke koje su učitane u program. Pruža informacije kao što su naziv biblioteke, njen bazni adresni prostor u memoriji i njena veličina.
Loaded Resources
Učitani resursi
This subsection lists any additional resources that have been loaded into the program. This can include things like images, sound files, or configuration files.
Ovaj pododeljak navodi sve dodatne resurse koji su učitani u program. To može uključivati slike, zvučne datoteke ili konfiguracione datoteke.
Main Object Information
Informacije o glavnom objektu
The main object information section provides details about the main object of the program. This can include information such as the entry point of the program, its base address in memory, and its size.
Odeljak sa informacijama o glavnom objektu pruža detalje o glavnom objektu programa. To može uključivati informacije kao što su tačka ulaska u program, njegov bazni adresni prostor u memoriji i njegova veličina.
#LOADED DATA
proj.loader #<Loaded true, maps [0x400000:0x5004000]>
proj.loader.min_addr #0x400000
proj.loader.max_addr #0x5004000
proj.loader.all_objects #All loaded
proj.loader.shared_objects #Loaded binaries
"""
OrderedDict([('true', <ELF Object true, maps [0x400000:0x40a377]>),
('libc.so.6',
<ELF Object libc-2.31.so, maps [0x500000:0x6c4507]>),
('ld-linux-x86-64.so.2',
<ELF Object ld-2.31.so, maps [0x700000:0x72c177]>),
('extern-address space',
<ExternObject Object cle##externs, maps [0x800000:0x87ffff]>),
('cle##tls',
<ELFTLSObjectV2 Object cle##tls, maps [0x900000:0x91500f]>)])
"""
proj.loader.all_elf_objects #Get all ELF objects loaded (Linux)
proj.loader.all_pe_objects #Get all binaries loaded (Windows)
proj.loader.find_object_containing(0x400000)#Get object loaded in an address "<ELF Object fauxware, maps [0x400000:0x60105f]>"
Glavni cilj
The main objective of the angr framework is to provide a powerful and flexible platform for analyzing binary programs. It is designed to assist in reverse engineering, vulnerability discovery, and exploit development. The framework offers a wide range of features and tools that can be used to automate various tasks in the analysis process.
Glavni cilj angr okvira je da pruži moćnu i fleksibilnu platformu za analizu binarnih programa. Dizajniran je da pomogne u obrnutom inženjeringu, otkrivanju ranjivosti i razvoju eksploatacija. Okvir nudi širok spektar funkcionalnosti i alata koji se mogu koristiti za automatizaciju različitih zadataka u procesu analize.
#Main Object (main binary loaded)
obj = proj.loader.main_object #<ELF Object true, maps [0x400000:0x60721f]>
obj.execstack #"False" Check for executable stack
obj.pic #"True" Check PIC
obj.imports #Get imports
obj.segments #<Regions: [<ELFSegment flags=0x5, relro=0x0, vaddr=0x400000, memsize=0xa74, filesize=0xa74, offset=0x0>, <ELFSegment flags=0x4, relro=0x1, vaddr=0x600e28, memsize=0x1d8, filesize=0x1d8, offset=0xe28>, <ELFSegment flags=0x6, relro=0x0, vaddr=0x601000, memsize=0x60, filesize=0x50, offset=0x1000>]>
obj.find_segment_containing(obj.entry) #Get segment by address
obj.sections #<Regions: [<Unnamed | offset 0x0, vaddr 0x0, size 0x0>, <.interp | offset 0x238, vaddr 0x400238, size 0x1c>, <.note.ABI-tag | offset 0x254, vaddr 0x400254, size 0x20>, <.note.gnu.build-id ...
obj.find_section_containing(obj.entry) #Get section by address
obj.plt['strcmp'] #Get plt address of a funcion (0x400550)
obj.reverse_plt[0x400550] #Get function from plt address ('strcmp')
Simboli i Relokacije
Simboli i relokacije su ključni koncepti u statičkoj analizi i reverznom inženjeringu. Oni nam pomažu da razumemo kako se programi sastoje od različitih delova i kako se ti delovi međusobno povezuju.
Simboli
Simboli su identifikatori koji se koriste za predstavljanje različitih delova programa, kao što su funkcije, promenljive ili konstante. Svaki simbol ima svoje ime i adrese u memoriji gde se nalazi. Oni nam omogućavaju da pristupimo određenim delovima programa i manipulišemo njima.
Relokacije
Relokacije su informacije koje nam govore kako se delovi programa povezuju i kako se adrese simbola prilagođavaju tokom izvršavanja. Kada se program kompajlira, adrese simbola se često ne mogu odrediti unapred, pa se koriste relokacije kako bi se te adrese prilagodile prilikom izvršavanja programa.
Relokacije su posebno važne u dinamički povezanim programima, gde se delovi programa učitavaju u memoriju tokom izvršavanja. One nam omogućavaju da pravilno povežemo simbole i izvršimo program bez grešaka.
Analiza simbola i relokacija
Analiza simbola i relokacija je važan korak u reverznom inženjeringu. Ona nam omogućava da razumemo strukturu programa, identifikujemo ključne delove i prilagodimo ih našim potrebama.
Postoje različiti alati i tehnike koje se koriste za analizu simbola i relokacija, kao što je Angr. Ovi alati nam omogućavaju da vizualizujemo simbole i relokacije, pristupimo njihovim adresama i manipulišemo njima kako bismo bolje razumeli program i izvršili odgovarajuće promene.
Ukratko, simboli i relokacije su ključni koncepti u statičkoj analizi i reverznom inženjeringu. Razumevanje njihove uloge i primene nam pomaže da efikasno analiziramo i manipulišemo programima.
strcmp = proj.loader.find_symbol('strcmp') #<Symbol "strcmp" in libc.so.6 at 0x1089cd0>
strcmp.name #'strcmp'
strcmp.owne #<ELF Object libc-2.23.so, maps [0x1000000:0x13c999f]>
strcmp.rebased_addr #0x1089cd0
strcmp.linked_addr #0x89cd0
strcmp.relative_addr #0x89cd0
strcmp.is_export #True, as 'strcmp' is a function exported by libc
#Get strcmp from the main object
main_strcmp = proj.loader.main_object.get_symbol('strcmp')
main_strcmp.is_export #False
main_strcmp.is_import #True
main_strcmp.resolvedby #<Symbol "strcmp" in libc.so.6 at 0x1089cd0>
Blokovi
Basic Block
Osnovni blok
A basic block is a sequence of instructions with a single entry point and a single exit point. It is a fundamental unit of analysis in reverse engineering and program analysis.
Osnovni blok je sekvenca instrukcija sa jednim ulaznim i jednim izlaznim tačkom. To je osnovna jedinica analize u reverznom inženjeringu i analizi programa.
Super Block
Super blok
A super block is a collection of basic blocks that are executed together as a single unit. It is formed by merging multiple basic blocks that have a common execution path.
Super blok je kolekcija osnovnih blokova koji se izvršavaju zajedno kao jedna jedinica. Formira se spajanjem više osnovnih blokova koji imaju zajednički put izvršavanja.
Function
Funkcija
A function is a sequence of instructions that performs a specific task within a program. It has a defined entry point and may have multiple exit points.
Funkcija je sekvenca instrukcija koja obavlja određeni zadatak unutar programa. Ima definisanu ulaznu tačku i može imati više izlaznih tačaka.
Procedure
Procedura
A procedure is a collection of functions that are related and perform a specific task together. It is often used to organize and modularize code.
Procedura je kolekcija funkcija koje su povezane i zajedno obavljaju određeni zadatak. Često se koristi za organizaciju i modularizaciju koda.
Module
Modul
A module is a self-contained unit of code that can be independently compiled and executed. It typically consists of multiple procedures and functions.
Modul je samostalna jedinica koda koja se može nezavisno kompajlirati i izvršavati. Obično se sastoji od više procedura i funkcija.
Program
Program
A program is a collection of modules that work together to perform a specific task. It is the highest level of abstraction in software development.
Program je kolekcija modula koji zajedno rade kako bi obavili određeni zadatak. To je najviši nivo apstrakcije u razvoju softvera.
#Blocks
block = proj.factory.block(proj.entry) #Get the block of the entrypoint fo the binary
block.pp() #Print disassembly of the block
block.instructions #"0xb" Get number of instructions
block.instruction_addrs #Get instructions addresses "[0x401670, 0x401672, 0x401675, 0x401676, 0x401679, 0x40167d, 0x40167e, 0x40167f, 0x401686, 0x40168d, 0x401694]"
Dinamička analiza
Upravljanje simulacijom, stanja
#Live States
#This is useful to modify content in a live analysis
state = proj.factory.entry_state()
state.regs.rip #Get the RIP
state.mem[proj.entry].int.resolved #Resolve as a C int (BV)
state.mem[proj.entry].int.concreteved #Resolve as python int
state.regs.rsi = state.solver.BVV(3, 64) #Modify RIP
state.mem[0x1000].long = 4 #Modify mem
#Other States
project.factory.entry_state()
project.factory.blank_state() #Most of its data left uninitialized
project.factory.full_init_statetate() #Execute through any initializers that need to be run before the main binary's entry point
project.factory.call_state() #Ready to execute a given function.
#Simulation manager
#The simulation manager stores all the states across the execution of the binary
simgr = proj.factory.simulation_manager(state) #Start
simgr.step() #Execute one step
simgr.active[0].regs.rip #Get RIP from the last state
Pozivanje funkcija
- Možete proslediti listu argumenata kroz
args
i rečnik okruženja krozenv
uentry_state
ifull_init_state
. Vrednosti u ovim strukturama mogu biti stringovi ili bitvektori, i biće serijalizovane u stanje kao argumenti i okruženje za simuliranu izvršnu datoteku. Podrazumevaniargs
je prazna lista, pa ako program koji analizirate očekuje da pronađe baremargv[0]
, uvek ga treba obezbediti! - Ako želite da
argc
bude simboličan, možete proslediti simbolički bitvektor kaoargc
konstruktorimaentry_state
ifull_init_state
. Budite oprezni, međutim: ako to uradite, trebali biste dodati i ograničenje na rezultujuće stanje da vaša vrednost za argc ne može biti veća od broja argumenata koje ste prosledili uargs
. - Da biste koristili pozivno stanje, trebali biste ga pozvati sa
.call_state(addr, arg1, arg2, ...)
, gde jeaddr
adresa funkcije koju želite pozvati, aargN
je N-ti argument te funkcije, ili kao python celobrojni broj, string ili niz, ili kao bitvektor. Ako želite da se alocira memorija i da zapravo prosledite pokazivač na objekat, trebali biste ga umotati u PointerWrapper, tj.angr.PointerWrapper("point to me!")
. Rezultati ove API mogu biti malo nepredvidivi, ali radimo na tome.
BitVektori
#BitVectors
state = proj.factory.entry_state()
bv = state.solver.BVV(0x1234, 32) #Create BV of 32bits with the value "0x1234"
state.solver.eval(bv) #Convert BV to python int
bv.zero_extend(30) #Will add 30 zeros on the left of the bitvector
bv.sign_extend(30) #Will add 30 zeros or ones on the left of the BV extending the sign
Simbolički BitVectors i Ograničenja
Simbolički BitVectors su ključni koncept u angr alatu. Oni predstavljaju simboličke vrijednosti koje se koriste za modeliranje i analizu programa. Simbolički BitVectors se sastoje od bitova koji mogu biti simbolički ili konkretne vrijednosti.
Ograničenja su izrazi koji se primjenjuju na simboličke BitVectors kako bi se postavile određene uvjete ili ograničenja na njihove vrijednosti. Ograničenja se koriste za definiranje uvjeta koje program mora zadovoljiti kako bi se postigao određeni rezultat.
Korištenje simboličkih BitVectors i ograničenja omogućava angr alatu da analizira program na simboličkoj razini, što omogućava pronalaženje ranjivosti, generiranje testnih slučajeva i rješavanje problema vezanih uz programsku logiku.
U angr alatu, simbolički BitVectors i ograničenja se koriste za izgradnju simboličkog izvršavanja programa, što omogućava analizu programa bez stvarnog izvršavanja koda. Ovo je korisno za pronalaženje ranjivosti i generiranje testnih slučajeva bez potrebe za stvarnim pokretanjem programa.
Kroz simboličko izvršavanje, angr alat može generirati putove izvršavanja programa i analizirati njihove uvjete. Ovo omogućava pronalaženje ranjivosti, kao što su prekoračenje bafera ili neispravna provjera korisničkog unosa.
Korištenje simboličkih BitVectors i ograničenja u angr alatu zahtijeva razumijevanje njihovih osnovnih metoda i funkcionalnosti. Ova dokumentacija pruža detaljan pregled ove teme i objašnjava kako koristiti simboličke BitVectors i ograničenja u angr alatu za analizu programa.
x = state.solver.BVS("x", 64) #Symbolic variable BV of length 64
y = state.solver.BVS("y", 64)
#Symbolic oprations
tree = (x + 1) / (y + 2)
tree #<BV64 (x_9_64 + 0x1) / (y_10_64 + 0x2)>
tree.op #'__floordiv__' Access last operation
tree.args #(<BV64 x_9_64 + 0x1>, <BV64 y_10_64 + 0x2>)
tree.args[0].op #'__add__' Access of dirst arg
tree.args[0].args #(<BV64 x_9_64>, <BV64 0x1>)
tree.args[0].args[1].op #'BVV'
tree.args[0].args[1].args #(1, 64)
#Symbolic constraints solver
state = proj.factory.entry_state() #Get a fresh state without constraints
input = state.solver.BVS('input', 64)
operation = (((input + 4) * 3) >> 1) + input
output = 200
state.solver.add(operation == output)
state.solver.eval(input) #0x3333333333333381
state.solver.add(input < 2**32)
state.satisfiable() #False
#Solver solutions
solver.eval(expression) #one possible solution
solver.eval_one(expression) #solution to the given expression, or throw an error if more than one solution is possible.
solver.eval_upto(expression, n) #n solutions to the given expression, returning fewer than n if fewer than n are possible.
solver.eval_atleast(expression, n) #n solutions to the given expression, throwing an error if fewer than n are possible.
solver.eval_exact(expression, n) #n solutions to the given expression, throwing an error if fewer or more than are possible.
solver.min(expression) #minimum possible solution to the given expression.
solver.max(expression) #maximum possible solution to the given expression.
Hookovanje
Hookovanje je tehnika koja omogućava da se izvršavanje programa preusmeri na drugu funkciju ili deo koda. Ovo se može koristiti u cilju nadgledanja ili modifikacije ponašanja programa. Postoje različite vrste hookovanja, uključujući funkcionalno hookovanje, sistemsko hookovanje i mrežno hookovanje.
Funkcionalno hookovanje
Funkcionalno hookovanje se koristi za preusmeravanje izvršavanja programa na drugu funkciju. Ovo se može koristiti za nadgledanje ili modifikaciju ulaznih i izlaznih podataka programa. Primeri funkcionalnog hookovanja uključuju hookovanje funkcija za čitanje i pisanje fajlova ili hookovanje funkcija za mrežnu komunikaciju.
Sistemsko hookovanje
Sistemsko hookovanje se koristi za preusmeravanje izvršavanja programa na sistemski nivo. Ovo se može koristiti za nadgledanje ili modifikaciju sistemskih poziva ili događaja. Primeri sistemskog hookovanja uključuju hookovanje sistemskih poziva za praćenje aktivnosti fajl sistema ili hookovanje događaja za nadgledanje promena u registru.
Mrežno hookovanje
Mrežno hookovanje se koristi za preusmeravanje mrežnog saobraćaja na drugu destinaciju. Ovo se može koristiti za nadgledanje ili modifikaciju mrežnih paketa. Primeri mrežnog hookovanja uključuju hookovanje mrežnih protokola za analizu ili modifikaciju podataka koji se prenose preko mreže.
Implementacija hookovanja
Postoji nekoliko načina za implementaciju hookovanja, uključujući upotrebu posebnih biblioteka ili alata. Jedan od popularnih alata za hookovanje je Angr, koji omogućava analizu i manipulaciju binarnih fajlova. Angr pruža mogućnost hookovanja funkcija i sistemskih poziva, kao i nadgledanje i modifikaciju izvršavanja programa.
>>> stub_func = angr.SIM_PROCEDURES['stubs']['ReturnUnconstrained'] # this is a CLASS
>>> proj.hook(0x10000, stub_func()) # hook with an instance of the class
>>> proj.is_hooked(0x10000) # these functions should be pretty self-explanitory
True
>>> proj.hooked_by(0x10000)
<ReturnUnconstrained>
>>> proj.unhook(0x10000)
>>> @proj.hook(0x20000, length=5)
... def my_hook(state):
... state.regs.rax = 1
>>> proj.is_hooked(0x20000)
True
Osim toga, možete koristiti proj.hook_symbol(name, hook)
pružajući ime simbola kao prvi argument kako biste povezali adresu na kojoj se simbol nalazi.
Primeri
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!
Drugi načini podrške HackTricks-u:
- Ako želite videti oglašavanje vaše kompanije u HackTricks-u ili preuzeti HackTricks u PDF formatu, proverite SUBSCRIPTION PLANS!
- Nabavite zvanični PEASS & HackTricks swag
- Otkrijte The PEASS Family, našu kolekciju ekskluzivnih NFT-ova
- Pridružite se 💬 Discord grupi ili telegram grupi ili nas pratite na Twitter-u 🐦 @carlospolopm.
- Podelite svoje hakovanje trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.