2024-01-09 15:03:37 +00:00
< details >
2024-02-09 02:10:17 +00:00
< summary > < strong > Aprenda hacking AWS do zero ao herói com< / strong > < a href = "https://training.hacktricks.xyz/courses/arte" > < strong > htARTE (HackTricks AWS Red Team Expert)< / strong > < / a > < strong > !< / strong > < / summary >
2024-01-09 15:03:37 +00:00
2024-02-09 02:10:17 +00:00
Outras maneiras de apoiar o HackTricks:
2024-01-09 15:03:37 +00:00
2024-02-09 02:10:17 +00:00
* Se você quiser ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Confira os [**PLANOS DE ASSINATURA** ](https://github.com/sponsors/carlospolop )!
* Adquira o [**swag oficial PEASS & HackTricks** ](https://peass.creator-spring.com )
* Descubra [**A Família PEASS** ](https://opensea.io/collection/the-peass-family ), nossa coleção exclusiva de [**NFTs** ](https://opensea.io/collection/the-peass-family )
* **Junte-se ao** 💬 [**grupo Discord** ](https://discord.gg/hRep4RUj7f ) ou ao [**grupo telegram** ](https://t.me/peass ) ou **siga-nos** no **Twitter** 🐦 [**@carlospolopm** ](https://twitter.com/hacktricks_live )**.**
* **Compartilhe seus truques de hacking enviando PRs para os** [**HackTricks** ](https://github.com/carlospolop/hacktricks ) e [**HackTricks Cloud** ](https://github.com/carlospolop/hacktricks-cloud ) repositórios do github.
2024-01-09 15:03:37 +00:00
< / details >
2024-02-09 02:10:17 +00:00
Parte deste guia de referência é baseado na [documentação do angr ](https://docs.angr.io/_/downloads/en/stable/pdf/ ).
2024-01-09 15:03:37 +00:00
2023-06-06 18:56:34 +00:00
# Instalação
```bash
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
```
# Ações Básicas
2021-09-10 15:38:07 +00:00
```python
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'}})
```
2024-02-09 02:10:17 +00:00
# Informações do objeto carregado e principal
2021-09-10 15:38:07 +00:00
2024-01-09 15:03:37 +00:00
## Dados Carregados
2021-09-10 15:38:07 +00:00
```python
#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 ] > ),
2024-01-09 15:03:37 +00:00
('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 ] > )])
2021-09-10 15:38:07 +00:00
"""
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 ] > "
```
2024-01-09 15:03:37 +00:00
## Objeto Principal
2021-09-10 15:38:07 +00:00
```python
#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')
```
2023-06-06 18:56:34 +00:00
## Símbolos e Realocações
2021-09-10 15:38:07 +00:00
```python
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 >
```
2023-06-06 18:56:34 +00:00
## Blocos
2021-09-10 15:38:07 +00:00
```python
#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]"
```
2023-06-06 18:56:34 +00:00
# Análise Dinâmica
2021-09-10 15:38:07 +00:00
2023-06-06 18:56:34 +00:00
## Gerenciador de Simulação, Estados
2021-09-10 15:38:07 +00:00
```python
#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
2021-09-10 16:32:07 +00:00
#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.
2021-09-10 15:38:07 +00:00
#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
```
2023-06-06 18:56:34 +00:00
## Chamando funções
2021-09-10 15:38:07 +00:00
2024-02-09 02:10:17 +00:00
* Você pode passar uma lista de argumentos através de `args` e um dicionário de variáveis de ambiente através de `env` para `entry_state` e `full_init_state` . Os valores nesses estruturas podem ser strings ou bitvectors, e serão serializados no estado como os argumentos e ambiente para a execução simulada. O `args` padrão é uma lista vazia, então se o programa que você está analisando espera encontrar pelo menos um `argv[0]` , você deve sempre fornecê-lo!
* Se você deseja que `argc` seja simbólico, você pode passar um bitvector simbólico como `argc` para os construtores `entry_state` e `full_init_state` . No entanto, tenha cuidado: se fizer isso, você também deve adicionar uma restrição ao estado resultante de que seu valor para argc não pode ser maior do que o número de argumentos que você passou para `args` .
* Para usar o estado de chamada, você deve chamá-lo com `.call_state(addr, arg1, arg2, ...)` , onde `addr` é o endereço da função que você deseja chamar e `argN` é o N-ésimo argumento para essa função, seja como um inteiro, string ou array em Python, ou um bitvector. Se você deseja alocar memória e realmente passar um ponteiro para um objeto, você deve envolvê-lo em um PointerWrapper, ou seja, `angr.PointerWrapper("aponte para mim!")` . Os resultados desta API podem ser um pouco imprevisíveis, mas estamos trabalhando nisso.
2021-09-10 16:32:07 +00:00
2022-05-01 16:32:23 +00:00
## BitVectors
2021-09-10 15:38:07 +00:00
```python
#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
```
2024-02-09 02:10:17 +00:00
## BitVectors Simbólicos e Restrições
2021-09-10 15:38:07 +00:00
```python
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.
```
2024-02-09 02:10:17 +00:00
## Hooking
2022-05-01 16:32:23 +00:00
## Hooking
2021-09-10 15:38:07 +00:00
```python
>>> 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
```
2024-02-09 02:10:17 +00:00
Além disso, você pode usar `proj.hook_symbol(name, hook)` , fornecendo o nome de um símbolo como primeiro argumento, para conectar o endereço onde o símbolo está localizado
2021-09-10 15:38:07 +00:00
2023-06-06 18:56:34 +00:00
# Exemplos