mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/generic-methodologies-and-resources/basic-forensic-meth
This commit is contained in:
parent
f196254ef2
commit
cd8df7d496
@ -2,11 +2,11 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Hojas de Trucos de Forense
|
||||
## CheatSheets de Forense
|
||||
|
||||
[https://www.jaiminton.com/cheatsheet/DFIR/#](https://www.jaiminton.com/cheatsheet/DFIR/)
|
||||
|
||||
## Servicios en Línea
|
||||
## Servicios en línea
|
||||
|
||||
- [VirusTotal](https://www.virustotal.com/gui/home/upload)
|
||||
- [HybridAnalysis](https://www.hybrid-analysis.com)
|
||||
@ -14,42 +14,42 @@
|
||||
- [Intezer](https://analyze.intezer.com)
|
||||
- [Any.Run](https://any.run/)
|
||||
|
||||
## Herramientas de Antivirus y Detección Offline
|
||||
## Herramientas de antivirus y detección sin conexión
|
||||
|
||||
### Yara
|
||||
|
||||
#### Instalar
|
||||
#### Instalación
|
||||
```bash
|
||||
sudo apt-get install -y yara
|
||||
```
|
||||
#### Preparar reglas
|
||||
|
||||
Usa este script para descargar y fusionar todas las reglas de malware yara de github: [https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9](https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9)\
|
||||
Usa este script para descargar y fusionar todas las reglas yara de malware desde github: [https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9](https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9)\
|
||||
Crea el directorio _**rules**_ y ejecútalo. Esto creará un archivo llamado _**malware_rules.yar**_ que contiene todas las reglas yara para malware.
|
||||
```bash
|
||||
wget https://gist.githubusercontent.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9/raw/4ec711d37f1b428b63bed1f786b26a0654aa2f31/malware_yara_rules.py
|
||||
mkdir rules
|
||||
python malware_yara_rules.py
|
||||
```
|
||||
#### Escanear
|
||||
#### Escaneo
|
||||
```bash
|
||||
yara -w malware_rules.yar image #Scan 1 file
|
||||
yara -w malware_rules.yar folder #Scan the whole folder
|
||||
```
|
||||
#### YaraGen: Verificar malware y crear reglas
|
||||
#### YaraGen: Detectar malware y crear reglas
|
||||
|
||||
Puedes usar la herramienta [**YaraGen**](https://github.com/Neo23x0/yarGen) para generar reglas yara a partir de un binario. Consulta estos tutoriales: [**Parte 1**](https://www.nextron-systems.com/2015/02/16/write-simple-sound-yara-rules/), [**Parte 2**](https://www.nextron-systems.com/2015/10/17/how-to-write-simple-but-sound-yara-rules-part-2/), [**Parte 3**](https://www.nextron-systems.com/2016/04/15/how-to-write-simple-but-sound-yara-rules-part-3/)
|
||||
Puedes usar la herramienta [**YaraGen**](https://github.com/Neo23x0/yarGen) para generar yara rules a partir de un binario. Consulta estos tutoriales: [**Part 1**](https://www.nextron-systems.com/2015/02/16/write-simple-sound-yara-rules/), [**Part 2**](https://www.nextron-systems.com/2015/10/17/how-to-write-simple-but-sound-yara-rules-part-2/), [**Part 3**](https://www.nextron-systems.com/2016/04/15/how-to-write-simple-but-sound-yara-rules-part-3/)
|
||||
```bash
|
||||
python3 yarGen.py --update
|
||||
python3.exe yarGen.py --excludegood -m ../../mals/
|
||||
```
|
||||
### ClamAV
|
||||
|
||||
#### Instalar
|
||||
#### Instalación
|
||||
```
|
||||
sudo apt-get install -y clamav
|
||||
```
|
||||
#### Escanear
|
||||
#### Escaneo
|
||||
```bash
|
||||
sudo freshclam #Update rules
|
||||
clamscan filepath #Scan 1 file
|
||||
@ -57,25 +57,25 @@ clamscan folderpath #Scan the whole folder
|
||||
```
|
||||
### [Capa](https://github.com/mandiant/capa)
|
||||
|
||||
**Capa** detecta **capacidades** potencialmente maliciosas en ejecutables: PE, ELF, .NET. Así que encontrará cosas como tácticas de Att\&ck, o capacidades sospechosas como:
|
||||
**Capa** detecta potencialmente maliciosas **capabilities** en ejecutables: PE, ELF, .NET. Así que encontrará cosas como Att\&ck tactics, o capacidades sospechosas como:
|
||||
|
||||
- verificar el error de OutputDebugString
|
||||
- ejecutarse como un servicio
|
||||
- crear proceso
|
||||
- check for OutputDebugString error
|
||||
- run as a service
|
||||
- create process
|
||||
|
||||
Consíguelo en el [**repositorio de Github**](https://github.com/mandiant/capa).
|
||||
Consíguelo en el [**Github repo**](https://github.com/mandiant/capa).
|
||||
|
||||
### IOCs
|
||||
|
||||
IOC significa Indicador de Compromiso. Un IOC es un conjunto de **condiciones que identifican** algún software potencialmente no deseado o **malware** confirmado. Los Blue Teams utilizan este tipo de definición para **buscar este tipo de archivos maliciosos** en sus **sistemas** y **redes**.\
|
||||
Compartir estas definiciones es muy útil, ya que cuando se identifica malware en una computadora y se crea un IOC para ese malware, otros Blue Teams pueden usarlo para identificar el malware más rápido.
|
||||
IOC means Indicator Of Compromise. Un IOC es un conjunto de **condiciones que identifican** algún software potencialmente no deseado o confirmado **malware**. Blue Teams usan este tipo de definiciones para **buscar este tipo de archivos maliciosos** en sus **sistemas** y **redes**.\
|
||||
Compartir estas definiciones es muy útil, ya que cuando se identifica malware en un equipo y se crea un IOC para ese malware, otros Blue Teams pueden usarlo para identificar el malware más rápido.
|
||||
|
||||
Una herramienta para crear o modificar IOCs es [**IOC Editor**](https://www.fireeye.com/services/freeware/ioc-editor.html)**.**\
|
||||
A tool to create or modify IOCs is [**IOC Editor**](https://www.fireeye.com/services/freeware/ioc-editor.html)**.**\
|
||||
Puedes usar herramientas como [**Redline**](https://www.fireeye.com/services/freeware/redline.html) para **buscar IOCs definidos en un dispositivo**.
|
||||
|
||||
### Loki
|
||||
|
||||
[**Loki**](https://github.com/Neo23x0/Loki) es un escáner para Indicadores Simples de Compromiso.\
|
||||
[**Loki**](https://github.com/Neo23x0/Loki) es un scanner para Simple Indicators of Compromise.\
|
||||
La detección se basa en cuatro métodos de detección:
|
||||
```
|
||||
1. File Name IOC
|
||||
@ -92,41 +92,41 @@ Compares process connection endpoints with C2 IOCs (new since version v.10)
|
||||
```
|
||||
### Linux Malware Detect
|
||||
|
||||
[**Linux Malware Detect (LMD)**](https://www.rfxn.com/projects/linux-malware-detect/) es un escáner de malware para Linux lanzado bajo la licencia GNU GPLv2, que está diseñado en torno a las amenazas que enfrentan los entornos de alojamiento compartido. Utiliza datos de amenazas de sistemas de detección de intrusiones en el borde de la red para extraer malware que se está utilizando activamente en ataques y genera firmas para la detección. Además, los datos de amenazas también se derivan de las presentaciones de los usuarios con la función de pago de LMD y recursos de la comunidad de malware.
|
||||
[**Linux Malware Detect (LMD)**](https://www.rfxn.com/projects/linux-malware-detect/) es un escáner de malware para Linux publicado bajo la licencia GNU GPLv2, diseñado en torno a las amenazas que se enfrentan en entornos de hosting compartido. Utiliza datos de amenazas de sistemas de detección de intrusiones en el perímetro de la red para extraer malware que se está usando activamente en ataques y genera firmas para su detección. Además, los datos de amenazas también se derivan de envíos de usuarios mediante la LMD checkout feature y de recursos comunitarios de malware.
|
||||
|
||||
### rkhunter
|
||||
|
||||
Herramientas como [**rkhunter**](http://rkhunter.sourceforge.net) se pueden utilizar para verificar el sistema de archivos en busca de posibles **rootkits** y malware.
|
||||
Herramientas como [**rkhunter**](http://rkhunter.sourceforge.net) pueden usarse para comprobar el filesystem en busca de posibles **rootkits** y malware.
|
||||
```bash
|
||||
sudo ./rkhunter --check -r / -l /tmp/rkhunter.log [--report-warnings-only] [--skip-keypress]
|
||||
```
|
||||
### FLOSS
|
||||
|
||||
[**FLOSS**](https://github.com/mandiant/flare-floss) es una herramienta que intentará encontrar cadenas ofuscadas dentro de ejecutables utilizando diferentes técnicas.
|
||||
[**FLOSS**](https://github.com/mandiant/flare-floss) es una herramienta que intentará encontrar obfuscated strings dentro de executables utilizando diferentes técnicas.
|
||||
|
||||
### PEpper
|
||||
|
||||
[PEpper](https://github.com/Th3Hurrican3/PEpper) verifica algunas cosas básicas dentro del ejecutable (datos binarios, entropía, URLs e IPs, algunas reglas de yara).
|
||||
[PEpper ](https://github.com/Th3Hurrican3/PEpper) comprueba algunas cosas básicas dentro del executable (binary data, entropy, URLs and IPs, algunas yara rules).
|
||||
|
||||
### PEstudio
|
||||
|
||||
[PEstudio](https://www.winitor.com/download) es una herramienta que permite obtener información de ejecutables de Windows como importaciones, exportaciones, encabezados, pero también verificará virus total y encontrará técnicas potenciales de Att\&ck.
|
||||
[PEstudio](https://www.winitor.com/download) es una herramienta que permite obtener información de Windows executables como imports, exports y headers, pero también consultará virus total y encontrará posibles Att\&ck techniques.
|
||||
|
||||
### Detect It Easy(DiE)
|
||||
|
||||
[**DiE**](https://github.com/horsicq/Detect-It-Easy/) es una herramienta para detectar si un archivo está **encriptado** y también encontrar **empaquetadores**.
|
||||
[**DiE**](https://github.com/horsicq/Detect-It-Easy/) es una herramienta para detectar si un archivo está **encrypted** y también encontrar **packers**.
|
||||
|
||||
### NeoPI
|
||||
|
||||
[**NeoPI**](https://github.com/CiscoCXSecurity/NeoPI) es un script de Python que utiliza una variedad de **métodos estadísticos** para detectar contenido **ofuscado** y **encriptado** dentro de archivos de texto/script. El propósito de NeoPI es ayudar en la **detección de código de shell web oculto**.
|
||||
[**NeoPI** ](https://github.com/CiscoCXSecurity/NeoPI) es un script Python que utiliza una variedad de **statistical methods** para detectar contenido **obfuscated** y **encrypted** dentro de text/script files. El propósito de NeoPI es ayudar en la **detection of hidden web shell code**.
|
||||
|
||||
### **php-malware-finder**
|
||||
|
||||
[**PHP-malware-finder**](https://github.com/nbs-system/php-malware-finder) hace su mejor esfuerzo para detectar **código ofuscado**/**sospechoso** así como archivos que utilizan funciones de **PHP** a menudo usadas en **malwares**/webshells.
|
||||
[**PHP-malware-finder**](https://github.com/nbs-system/php-malware-finder) hace todo lo posible para detectar **obfuscated**/**dodgy code** así como archivos que usan **PHP** functions frecuentemente usadas en **malwares**/webshells.
|
||||
|
||||
### Apple Binary Signatures
|
||||
|
||||
Al revisar alguna **muestra de malware** siempre debes **verificar la firma** del binario ya que el **desarrollador** que lo firmó puede estar ya **relacionado** con **malware.**
|
||||
Al revisar alguna **malware sample** siempre deberías **check the signature** del binary, ya que el **developer** que lo firmó puede ya estar **related** con **malware.**
|
||||
```bash
|
||||
#Get signer
|
||||
codesign -vv -d /bin/ls 2>&1 | grep -E "Authority|TeamIdentifier"
|
||||
@ -137,18 +137,113 @@ codesign --verify --verbose /Applications/Safari.app
|
||||
#Check if the signature is valid
|
||||
spctl --assess --verbose /Applications/Safari.app
|
||||
```
|
||||
## Técnicas de Detección
|
||||
## Técnicas de detección
|
||||
|
||||
### Apilamiento de Archivos
|
||||
### File Stacking
|
||||
|
||||
Si sabes que alguna carpeta que contiene los **archivos** de un servidor web fue **actualizada por última vez en alguna fecha**. **Verifica** la **fecha** en que todos los **archivos** en el **servidor web** fueron creados y modificados, y si alguna fecha es **sospechosa**, revisa ese archivo.
|
||||
Si sabes que una carpeta que contiene los **archivos** de un servidor web fue **actualizada por última vez en una fecha determinada**. **Comprueba** la **fecha** en que todos los **archivos** del **servidor web** fueron creados y modificados y si alguna fecha es **sospechosa**, revisa ese archivo.
|
||||
|
||||
### Líneas Base
|
||||
### Baselines
|
||||
|
||||
Si los archivos de una carpeta **no deberían haber sido modificados**, puedes calcular el **hash** de los **archivos originales** de la carpeta y **compararlos** con los **actuales**. Cualquier cosa modificada será **sospechosa**.
|
||||
|
||||
### Análisis Estadístico
|
||||
### Statistical Analysis
|
||||
|
||||
Cuando la información se guarda en registros, puedes **verificar estadísticas como cuántas veces se accedió a cada archivo de un servidor web, ya que un shell web podría ser uno de los más**.
|
||||
Cuando la información se guarda en logs puedes **comprobar estadísticas como cuántas veces se accedió a cada archivo del servidor web**, ya que un web shell podría ser uno de los más accedidos.
|
||||
|
||||
---
|
||||
|
||||
### Android in-app native telemetry (no root)
|
||||
|
||||
En Android, puedes instrumentar código nativo dentro del proceso de la app objetivo precargando una pequeña librería logger antes de que otras libs JNI se inicialicen. Esto proporciona visibilidad temprana del comportamiento nativo sin hooks a nivel de sistema ni root. Un enfoque popular es SoTap: coloca libsotap.so para el ABI adecuado dentro del APK e inyecta una llamada System.loadLibrary("sotap") de forma temprana (p. ej., en un inicializador estático o en Application.onCreate), luego recoge logs desde rutas internas/externas o, como fallback, desde Logcat.
|
||||
|
||||
Consulta la página de reversing nativo para Android para detalles de configuración y rutas de logs:
|
||||
|
||||
{{#ref}}
|
||||
../../../mobile-pentesting/android-app-pentesting/reversing-native-libraries.md
|
||||
{{#endref}}
|
||||
|
||||
---
|
||||
|
||||
## Desofuscación del flujo de control dinámico (JMP/CALL RAX Dispatchers)
|
||||
|
||||
Las familias de malware modernas abusan intensamente de la ofuscación del Control-Flow Graph (CFG): en lugar de un salto/llamada directo calculan el destino en tiempo de ejecución y ejecutan un `jmp rax` o `call rax`. Un pequeño *dispatcher* (típicamente nueve instrucciones) establece el objetivo final dependiendo de las banderas `ZF`/`CF` de la CPU, rompiendo por completo la recuperación estática del CFG.
|
||||
|
||||
La técnica —demostrada por el loader SLOW#TEMPEST— puede ser derrotada con un flujo de trabajo de tres pasos que sólo requiere IDAPython y el emulador CPU Unicorn.
|
||||
|
||||
### 1. Localizar cada salto/llamada indirecta
|
||||
```python
|
||||
import idautils, idc
|
||||
|
||||
for ea in idautils.FunctionItems(idc.here()):
|
||||
mnem = idc.print_insn_mnem(ea)
|
||||
if mnem in ("jmp", "call") and idc.print_operand(ea, 0) == "rax":
|
||||
print(f"[+] Dispatcher found @ {ea:X}")
|
||||
```
|
||||
### 2. Extraer el byte-code del dispatcher
|
||||
```python
|
||||
import idc
|
||||
|
||||
def get_dispatcher_start(jmp_ea, count=9):
|
||||
s = jmp_ea
|
||||
for _ in range(count):
|
||||
s = idc.prev_head(s, 0)
|
||||
return s
|
||||
|
||||
start = get_dispatcher_start(jmp_ea)
|
||||
size = jmp_ea + idc.get_item_size(jmp_ea) - start
|
||||
code = idc.get_bytes(start, size)
|
||||
open(f"{start:X}.bin", "wb").write(code)
|
||||
```
|
||||
### 3. Emularlo dos veces con Unicorn
|
||||
```python
|
||||
from unicorn import *
|
||||
from unicorn.x86_const import *
|
||||
import struct
|
||||
|
||||
def run(code, zf=0, cf=0):
|
||||
BASE = 0x1000
|
||||
mu = Uc(UC_ARCH_X86, UC_MODE_64)
|
||||
mu.mem_map(BASE, 0x1000)
|
||||
mu.mem_write(BASE, code)
|
||||
mu.reg_write(UC_X86_REG_RFLAGS, (zf << 6) | cf)
|
||||
mu.reg_write(UC_X86_REG_RAX, 0)
|
||||
mu.emu_start(BASE, BASE+len(code))
|
||||
return mu.reg_read(UC_X86_REG_RAX)
|
||||
```
|
||||
Ejecute `run(code,0,0)` y `run(code,1,1)` para obtener los objetivos de las ramas *false* y *true*.
|
||||
|
||||
### 4. Parchear de nuevo un jump / call directo
|
||||
```python
|
||||
import struct, ida_bytes
|
||||
|
||||
def patch_direct(ea, target, is_call=False):
|
||||
op = 0xE8 if is_call else 0xE9 # CALL rel32 or JMP rel32
|
||||
disp = target - (ea + 5) & 0xFFFFFFFF
|
||||
ida_bytes.patch_bytes(ea, bytes([op]) + struct.pack('<I', disp))
|
||||
```
|
||||
Después de parchear, fuerza a IDA a reanalizar la función para que se restauren el CFG completo y la salida de Hex-Rays:
|
||||
```python
|
||||
import ida_auto, idaapi
|
||||
idaapi.reanalyze_function(idc.get_func_attr(ea, idc.FUNCATTR_START))
|
||||
```
|
||||
### 5. Etiquetar llamadas indirectas a la API
|
||||
|
||||
Una vez que se conoce el destino real de cada `call rax`, puedes indicarle a IDA cuál es para que los tipos de parámetros y los nombres de variables se recuperen automáticamente:
|
||||
```python
|
||||
idc.set_callee_name(call_ea, resolved_addr, 0) # IDA 8.3+
|
||||
```
|
||||
### Beneficios prácticos
|
||||
|
||||
* Restaura el CFG real → la decompilación pasa de *10* líneas a miles.
|
||||
* Permite string-cross-reference & xrefs, haciendo trivial la reconstrucción del comportamiento.
|
||||
* Scripts son reutilizables: insértalos en cualquier loader protegido por el mismo truco.
|
||||
|
||||
---
|
||||
|
||||
## Referencias
|
||||
|
||||
- [Unit42 – Evolving Tactics of SLOW#TEMPEST: A Deep Dive Into Advanced Malware Techniques](https://unit42.paloaltonetworks.com/slow-tempest-malware-obfuscation/)
|
||||
- SoTap: Lightweight in-app JNI (.so) behavior logger – [github.com/RezaArbabBot/SoTap](https://github.com/RezaArbabBot/SoTap)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,44 +1,136 @@
|
||||
# Reversing Native Libraries
|
||||
# Ingeniería inversa de bibliotecas nativas
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
**Para más información, consulta:** [**https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html**](https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html)
|
||||
|
||||
Las aplicaciones de Android pueden utilizar bibliotecas nativas, típicamente escritas en C o C++, para tareas críticas de rendimiento. Los creadores de malware también utilizan estas bibliotecas, ya que son más difíciles de descompilar que el bytecode DEX. La sección enfatiza las habilidades de ingeniería inversa adaptadas a Android, en lugar de enseñar lenguajes de ensamblaje. Se proporcionan versiones ARM y x86 de las bibliotecas para compatibilidad.
|
||||
**Para más información consulta:** [**https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html**](https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html)
|
||||
|
||||
### Puntos Clave:
|
||||
Las apps Android pueden usar bibliotecas nativas, típicamente escritas en C o C++, para tareas críticas de rendimiento. Los creadores de malware también abusan de estas bibliotecas porque los objetos compartidos ELF siguen siendo más difíciles de decompilar que el byte-code DEX/OAT.
|
||||
Esta página se centra en flujos de trabajo *prácticos* y en mejoras recientes de herramientas (2023-2025) que facilitan la ingeniería inversa de archivos `.so` de Android.
|
||||
|
||||
- **Bibliotecas Nativas en Aplicaciones de Android:**
|
||||
- Utilizadas para tareas intensivas en rendimiento.
|
||||
- Escritas en C o C++, lo que hace que la ingeniería inversa sea un desafío.
|
||||
- Se encuentran en formato `.so` (objeto compartido), similar a los binarios de Linux.
|
||||
- Los creadores de malware prefieren el código nativo para dificultar el análisis.
|
||||
- **Interfaz Nativa de Java (JNI) y NDK de Android:**
|
||||
- JNI permite que los métodos de Java se implementen en código nativo.
|
||||
- NDK es un conjunto de herramientas específico de Android para escribir código nativo.
|
||||
- JNI y NDK conectan el código de Java (o Kotlin) con bibliotecas nativas.
|
||||
- **Carga y Ejecución de Bibliotecas:**
|
||||
- Las bibliotecas se cargan en memoria usando `System.loadLibrary` o `System.load`.
|
||||
- JNI_OnLoad se ejecuta al cargar la biblioteca.
|
||||
- Los métodos nativos declarados en Java se vinculan a funciones nativas, permitiendo la ejecución.
|
||||
- **Vinculación de Métodos de Java a Funciones Nativas:**
|
||||
- **Vinculación Dinámica:** Los nombres de las funciones en las bibliotecas nativas coinciden con un patrón específico, permitiendo la vinculación automática.
|
||||
- **Vinculación Estática:** Utiliza `RegisterNatives` para la vinculación, proporcionando flexibilidad en la nomenclatura y estructura de funciones.
|
||||
- **Herramientas y Técnicas de Ingeniería Inversa:**
|
||||
- Herramientas como Ghidra e IDA Pro ayudan a analizar bibliotecas nativas.
|
||||
- `JNIEnv` es crucial para entender las funciones e interacciones de JNI.
|
||||
- Se proporcionan ejercicios para practicar la carga de bibliotecas, la vinculación de métodos y la identificación de funciones nativas.
|
||||
---
|
||||
|
||||
### Recursos:
|
||||
### Flujo rápido de triaje para un `libfoo.so` recién extraído
|
||||
|
||||
- **Aprendiendo Ensamblador ARM:**
|
||||
- Sugerido para una comprensión más profunda de la arquitectura subyacente.
|
||||
- [Fundamentos de Ensamblador ARM](https://azeria-labs.com/writing-arm-assembly-part-1/) de Azeria Labs es recomendado.
|
||||
- **Documentación de JNI y NDK:**
|
||||
- [Especificación JNI de Oracle](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html)
|
||||
- [Consejos de JNI de Android](https://developer.android.com/training/articles/perf-jni)
|
||||
- [Introducción al NDK](https://developer.android.com/ndk/guides/)
|
||||
- **Depuración de Bibliotecas Nativas:**
|
||||
- [Depurar Bibliotecas Nativas de Android Usando JEB Decompiler](https://medium.com/@shubhamsonani/how-to-debug-android-native-libraries-using-jeb-decompiler-eec681a22cf3)
|
||||
1. **Extraer la biblioteca**
|
||||
```bash
|
||||
# From an installed application
|
||||
adb shell "run-as <pkg> cat lib/arm64-v8a/libfoo.so" > libfoo.so
|
||||
# Or from the APK (zip)
|
||||
unzip -j target.apk "lib/*/libfoo.so" -d extracted_libs/
|
||||
```
|
||||
2. **Identificar arquitectura y protecciones**
|
||||
```bash
|
||||
file libfoo.so # arm64 or arm32 / x86
|
||||
readelf -h libfoo.so # OS ABI, PIE, NX, RELRO, etc.
|
||||
checksec --file libfoo.so # (peda/pwntools)
|
||||
```
|
||||
3. **Listar símbolos exportados y vínculos JNI**
|
||||
```bash
|
||||
readelf -s libfoo.so | grep ' Java_' # dynamic-linked JNI
|
||||
strings libfoo.so | grep -i "RegisterNatives" -n # static-registered JNI
|
||||
```
|
||||
4. **Cargar en un decompilador** (Ghidra ≥ 11.0, IDA Pro, Binary Ninja, Hopper or Cutter/Rizin) y ejecutar análisis automático.
|
||||
Las versiones recientes de Ghidra introdujeron un decompilador AArch64 que reconoce stubs PAC/BTI y etiquetas MTE, mejorando considerablemente el análisis de bibliotecas compiladas con el NDK de Android 14.
|
||||
5. **Decidir entre reversing estático o dinámico:** el código sin símbolos (stripped) u ofuscado a menudo necesita *instrumentación* (Frida, ptrace/gdbserver, LLDB).
|
||||
|
||||
---
|
||||
|
||||
### Instrumentación dinámica (Frida ≥ 16)
|
||||
|
||||
La serie 16 de Frida introdujo varias mejoras específicas para Android que ayudan cuando el objetivo usa optimizaciones modernas de Clang/LLD:
|
||||
|
||||
* `thumb-relocator` ahora puede *hook tiny ARM/Thumb functions* generadas por el alineamiento agresivo de LLD (`--icf=all`).
|
||||
* La enumeración y re-enlace de *ELF import slots* funciona en Android, permitiendo parchear por módulo con `dlopen()`/`dlsym()` cuando los inline hooks son rechazados.
|
||||
* Se corrigió Java hooking para el nuevo **ART quick-entrypoint** usado cuando las apps se compilan con `--enable-optimizations` en Android 14.
|
||||
|
||||
Ejemplo: enumerando todas las funciones registradas a través de `RegisterNatives` y volcando sus direcciones en tiempo de ejecución:
|
||||
```javascript
|
||||
Java.perform(function () {
|
||||
var Runtime = Java.use('java.lang.Runtime');
|
||||
var register = Module.findExportByName(null, 'RegisterNatives');
|
||||
Interceptor.attach(register, {
|
||||
onEnter(args) {
|
||||
var envPtr = args[0];
|
||||
var clazz = Java.cast(args[1], Java.use('java.lang.Class'));
|
||||
var methods = args[2];
|
||||
var count = args[3].toInt32();
|
||||
console.log('[+] RegisterNatives on ' + clazz.getName() + ' -> ' + count + ' methods');
|
||||
// iterate & dump (JNI nativeMethod struct: name, sig, fnPtr)
|
||||
}
|
||||
});
|
||||
});
|
||||
```
|
||||
Frida funcionará sin configuración adicional en dispositivos con PAC/BTI (Pixel 8/Android 14+) siempre que uses frida-server 16.2 o posterior – versiones anteriores no conseguían localizar el padding para inline hooks.
|
||||
|
||||
### Telemetría JNI local al proceso mediante .so precargado (SoTap)
|
||||
|
||||
Cuando la instrumentación completa es excesiva o está bloqueada, aún puedes obtener visibilidad a nivel nativo precargando un pequeño logger dentro del proceso objetivo. SoTap es una biblioteca nativa ligera de Android (.so) que registra el comportamiento en tiempo de ejecución de otras bibliotecas JNI (.so) dentro del mismo proceso de la app (no se requiere root).
|
||||
|
||||
Key properties:
|
||||
- Se inicializa temprano y observa las interacciones JNI/nativas dentro del proceso que la carga.
|
||||
- Persiste logs usando múltiples rutas escribibles con graceful fallback a Logcat cuando el almacenamiento está restringido.
|
||||
- Source-customizable: edita sotap.c para ampliar/ajustar lo que se registra y recompila por ABI.
|
||||
|
||||
Setup (repack the APK):
|
||||
1) Drop the proper ABI build into the APK so the loader can resolve libsotap.so:
|
||||
- lib/arm64-v8a/libsotap.so (for arm64)
|
||||
- lib/armeabi-v7a/libsotap.so (for arm32)
|
||||
2) Ensure SoTap loads before other JNI libs. Inject a call early (e.g., Application subclass static initializer or onCreate) so the logger is initialized first. Smali snippet example:
|
||||
```smali
|
||||
const-string v0, "sotap"
|
||||
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
|
||||
```
|
||||
3) Rebuild/sign/install, run the app, then collect logs.
|
||||
|
||||
Log paths (checked in order):
|
||||
```
|
||||
/data/user/0/%s/files/sotap.log
|
||||
/data/data/%s/files/sotap.log
|
||||
/sdcard/Android/data/%s/files/sotap.log
|
||||
/sdcard/Download/sotap-%s.log
|
||||
# If all fail: fallback to Logcat only
|
||||
```
|
||||
Notas y solución de problemas:
|
||||
- ABI alignment is mandatory. A mismatch will raise UnsatisfiedLinkError and the logger won’t load.
|
||||
- Storage constraints are common on modern Android; if file writes fail, SoTap will still emit via Logcat.
|
||||
- Behavior/verbosity is intended to be customized; rebuild from source after editing sotap.c.
|
||||
|
||||
This approach is useful for triage de malware and JNI debugging where observing native call flows from process start is critical but root/system-wide hooks aren’t available.
|
||||
|
||||
---
|
||||
|
||||
### Vulnerabilidades recientes que vale la pena buscar en APKs
|
||||
|
||||
| Año | CVE | Librería afectada | Notas |
|
||||
|------|-----|------------------|-------|
|
||||
|2023|CVE-2023-4863|`libwebp` ≤ 1.3.1|Desbordamiento de búfer en el heap accesible desde código nativo que decodifica imágenes WebP. Varias apps Android incluyen versiones vulnerables. Cuando veas un `libwebp.so` dentro de un APK, comprueba su versión e intenta explotarlo o parchearlo.| |
|
||||
|2024|Multiple|OpenSSL 3.x series|Varios problemas de seguridad de memoria y padding-oracle. Muchos bundles de Flutter & ReactNative incluyen su propio `libcrypto.so`.|
|
||||
|
||||
Cuando detectes archivos `.so` de *terceros* dentro de un APK, siempre verifica su hash contra los avisos upstream. SCA (Software Composition Analysis) es poco común en móvil, por lo que las compilaciones vulnerables y desactualizadas son frecuentes.
|
||||
|
||||
---
|
||||
|
||||
### Tendencias de Anti-Reversing y Hardening (Android 13-15)
|
||||
|
||||
* **Pointer Authentication (PAC) & Branch Target Identification (BTI):** Android 14 habilita PAC/BTI en las bibliotecas del sistema en silicio ARMv8.3+ compatible. Los decompiladores ahora muestran pseudo-instrucciones relacionadas con PAC; para análisis dinámico Frida inyecta trampolines *after* stripping PAC, pero tus trampolines personalizados deben llamar a `pacda`/`autibsp` cuando sea necesario.
|
||||
* **MTE & Scudo hardened allocator:** memory-tagging is opt-in but many Play-Integrity aware apps build with `-fsanitize=memtag`; use `setprop arm64.memtag.dump 1` plus `adb shell am start ...` to capture tag faults.
|
||||
* **LLVM Obfuscator (opaque predicates, control-flow flattening):** los packers comerciales (p. ej., Bangcle, SecNeo) protegen cada vez más código *nativo*, no solo Java; espera bogus control-flow y blobs de strings encriptados en `.rodata`.
|
||||
|
||||
---
|
||||
|
||||
### Recursos
|
||||
|
||||
- **Aprender ARM Assembly:** [Azeria Labs – ARM Assembly Basics](https://azeria-labs.com/writing-arm-assembly-part-1/)
|
||||
- **Documentación JNI & NDK:** [Oracle JNI Spec](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html) · [Android JNI Tips](https://developer.android.com/training/articles/perf-jni) · [NDK Guides](https://developer.android.com/ndk/guides/)
|
||||
- **Depuración de librerías nativas:** [Debug Android Native Libraries Using JEB Decompiler](https://medium.com/@shubhamsonani/how-to-debug-android-native-libraries-using-jeb-decompiler-eec681a22cf3)
|
||||
|
||||
### Referencias
|
||||
|
||||
- Registro de cambios de Frida 16.x (Android hooking, tiny-function relocation) – [frida.re/news](https://frida.re/news/)
|
||||
- Aviso NVD para el overflow de `libwebp` CVE-2023-4863 – [nvd.nist.gov](https://nvd.nist.gov/vuln/detail/CVE-2023-4863)
|
||||
- SoTap: Logger ligero in-app de comportamiento JNI (.so) – [github.com/RezaArbabBot/SoTap](https://github.com/RezaArbabBot/SoTap)
|
||||
- Lanzamientos de SoTap – [github.com/RezaArbabBot/SoTap/releases](https://github.com/RezaArbabBot/SoTap/releases)
|
||||
- ¿Cómo trabajar con SoTap? – [t.me/ForYouTillEnd/13](https://t.me/ForYouTillEnd/13)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,56 +1,57 @@
|
||||
# Smali - Decompiling/\[Modifying]/Compiling
|
||||
# Smali - Descompilando/[Modificando]/Compilando
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
A veces es interesante modificar el código de la aplicación para acceder a información oculta para ti (quizás contraseñas o flags bien ofuscados). Entonces, podría ser interesante decompilar el apk, modificar el código y recompilarlo.
|
||||
|
||||
**Referencia de Opcodes:** [http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html](http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html)
|
||||
A veces es interesante modificar el código de la aplicación para acceder a información oculta para ti (quizá contraseñas bien ofuscadas o flags). Entonces, puede ser interesante descompilar el apk, modificar el código y recompilarlo.
|
||||
|
||||
## Forma Rápida
|
||||
**Referencia de opcodes:** [http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html](http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html)
|
||||
|
||||
Usando **Visual Studio Code** y la extensión [APKLab](https://github.com/APKLab/APKLab), puedes **decompilar automáticamente**, modificar, **recompilar**, firmar e instalar la aplicación sin ejecutar ningún comando.
|
||||
## Forma rápida
|
||||
|
||||
Usando **Visual Studio Code** y la extensión [APKLab](https://github.com/APKLab/APKLab), puedes **descompilar automáticamente**, modificar, **recompilar**, firmar e instalar la aplicación sin ejecutar ningún comando.
|
||||
|
||||
Otro **script** que facilita mucho esta tarea es [**https://github.com/ax/apk.sh**](https://github.com/ax/apk.sh)
|
||||
|
||||
## Decompilar el APK
|
||||
## Descompilar el APK
|
||||
|
||||
Usando APKTool puedes acceder al **código smali y recursos**:
|
||||
Usando APKTool puedes acceder al **código smali y a los recursos**:
|
||||
```bash
|
||||
apktool d APP.apk
|
||||
```
|
||||
Si **apktool** te da algún error, intenta [instalar la **última versión**](https://ibotpeaches.github.io/Apktool/install/)
|
||||
Si **apktool** te da algún error, prueba [installing the **latest version**](https://ibotpeaches.github.io/Apktool/install/)
|
||||
|
||||
Algunos **archivos interesantes que deberías revisar son**:
|
||||
|
||||
- _res/values/strings.xml_ (y todos los xml dentro de res/values/\*)
|
||||
- _res/values/strings.xml_ (y todos los xml dentro de res/values/*)
|
||||
- _AndroidManifest.xml_
|
||||
- Cualquier archivo con extensión _.sqlite_ o _.db_
|
||||
|
||||
Si `apktool` tiene **problemas decodificando la aplicación**, echa un vistazo a [https://ibotpeaches.github.io/Apktool/documentation/#framework-files](https://ibotpeaches.github.io/Apktool/documentation/#framework-files) o intenta usar el argumento **`-r`** (No decodificar recursos). Entonces, si el problema estaba en un recurso y no en el código fuente, no tendrás el problema (tampoco descompilarás los recursos).
|
||||
Si `apktool` tiene **problemas decodificando la aplicación** echa un vistazo a [https://ibotpeaches.github.io/Apktool/documentation/#framework-files](https://ibotpeaches.github.io/Apktool/documentation/#framework-files) o prueba usando el argumento **`-r`** (No decodificar recursos). Entonces, si el problema estaba en un recurso y no en el código fuente, no tendrás el problema (tampoco decompilarás los recursos).
|
||||
|
||||
## Cambiar código smali
|
||||
|
||||
Puedes **cambiar** **instrucciones**, cambiar el **valor** de algunas variables o **agregar** nuevas instrucciones. Yo cambio el código Smali usando [**VS Code**](https://code.visualstudio.com), luego instalas la **extensión smalise** y el editor te dirá si alguna **instrucción es incorrecta**.\
|
||||
Puedes **cambiar** **instrucciones**, modificar el **valor** de algunas variables o **añadir** nuevas instrucciones. Yo modifico el código Smali usando [**VS Code**](https://code.visualstudio.com), luego instalas la **smalise extension** y el editor te dirá si alguna **instrucción es incorrecta**.\
|
||||
Algunos **ejemplos** se pueden encontrar aquí:
|
||||
|
||||
- [Ejemplos de cambios Smali](smali-changes.md)
|
||||
- [Smali changes examples](smali-changes.md)
|
||||
- [Google CTF 2018 - Shall We Play a Game?](google-ctf-2018-shall-we-play-a-game.md)
|
||||
|
||||
O puedes [**ver a continuación algunos cambios Smali explicados**](smali-changes.md#modifying-smali).
|
||||
O puedes [**check below some Smali changes explained**](smali-changes.md#modifying-smali).
|
||||
|
||||
## Recompilar el APK
|
||||
|
||||
Después de modificar el código, puedes **recompilar** el código usando:
|
||||
Después de modificar el código puedes **recompilar** el código usando:
|
||||
```bash
|
||||
apktool b . #In the folder generated when you decompiled the application
|
||||
```
|
||||
Compilará el nuevo APK dentro de la carpeta _**dist**_.
|
||||
Esto va a **compilar** el nuevo APK **dentro** de la carpeta _**dist**_.
|
||||
|
||||
Si **apktool** lanza un **error**, intenta[ instalar la **última versión**](https://ibotpeaches.github.io/Apktool/install/)
|
||||
|
||||
### **Firma el nuevo APK**
|
||||
### **Firmar el nuevo APK**
|
||||
|
||||
Luego, necesitas **generar una clave** (se te pedirá una contraseña y algo de información que puedes llenar aleatoriamente):
|
||||
Luego, necesitas **generar una clave** (se te pedirá una contraseña y cierta información que puedes completar aleatoriamente):
|
||||
```bash
|
||||
keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias <your-alias>
|
||||
```
|
||||
@ -58,22 +59,22 @@ Finalmente, **firma** el nuevo APK:
|
||||
```bash
|
||||
jarsigner -keystore key.jks path/to/dist/* <your-alias>
|
||||
```
|
||||
### Optimizar nueva aplicación
|
||||
### Optimizar la nueva aplicación
|
||||
|
||||
**zipalign** es una herramienta de alineación de archivos que proporciona una optimización importante a los archivos de aplicación de Android (APK). [More information here](https://developer.android.com/studio/command-line/zipalign).
|
||||
**zipalign** es una herramienta de alineación de archivos que proporciona una optimización importante a los archivos APK de las aplicaciones Android. [Más información aquí](https://developer.android.com/studio/command-line/zipalign).
|
||||
```bash
|
||||
zipalign [-f] [-v] <alignment> infile.apk outfile.apk
|
||||
zipalign -v 4 infile.apk
|
||||
```
|
||||
### **Firma el nuevo APK (¿de nuevo?)**
|
||||
### **Firmar el nuevo APK (¿otra vez?)**
|
||||
|
||||
Si **prefieres** usar [**apksigner**](https://developer.android.com/studio/command-line/) en lugar de jarsigner, **debes firmar el apk** después de aplicar **la optimización con** zipalign. PERO TEN EN CUENTA QUE SOLO TIENES QUE **FIRMAR LA APLICACIÓN UNA VEZ** CON jarsigner (antes de zipalign) O CON apksigner (después de zipalign).
|
||||
Si **prefieres** usar [**apksigner**](https://developer.android.com/studio/command-line/) en lugar de jarsigner, **deberías firmar el apk** después de aplicar **la optimización con** zipaling. PERO TEN EN CUENTA QUE SOLO TIENES QUE **FIRMAR LA APLICACIÓN UNA VEZ** CON jarsigner (antes de zipalign) O CON aspsigner (después de zipaling).
|
||||
```bash
|
||||
apksigner sign --ks key.jks ./dist/mycompiled.apk
|
||||
```
|
||||
## Modificando Smali
|
||||
|
||||
Para el siguiente código Java Hello World:
|
||||
Para el siguiente código Java de Hello World:
|
||||
```java
|
||||
public static void printHelloWorld() {
|
||||
System.out.println("Hello World")
|
||||
@ -89,13 +90,13 @@ invoke-virtual {v0,v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
|
||||
return-void
|
||||
.end method
|
||||
```
|
||||
El conjunto de instrucciones Smali está disponible [aquí](https://source.android.com/devices/tech/dalvik/dalvik-bytecode#instructions).
|
||||
The Smali instruction set is available [here](https://source.android.com/devices/tech/dalvik/dalvik-bytecode#instructions).
|
||||
|
||||
### Cambios ligeros
|
||||
|
||||
### Modificar valores iniciales de una variable dentro de una función
|
||||
### Modificar los valores iniciales de una variable dentro de una función
|
||||
|
||||
Algunas variables se definen al principio de la función utilizando el opcode _const_, puedes modificar sus valores, o puedes definir nuevos:
|
||||
Algunas variables se definen al comienzo de la función usando el opcode _const_, puedes modificar sus valores, o puedes definir nuevas:
|
||||
```bash
|
||||
#Number
|
||||
const v9, 0xf4240
|
||||
@ -103,7 +104,7 @@ const/4 v8, 0x1
|
||||
#Strings
|
||||
const-string v5, "wins"
|
||||
```
|
||||
### Operaciones Básicas
|
||||
### Operaciones básicas
|
||||
```bash
|
||||
#Math
|
||||
add-int/lit8 v0, v2, 0x1 #v2 + 0x1 and save it in v0
|
||||
@ -126,7 +127,7 @@ iput v0, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Save v0 inside
|
||||
if-ne v0, v9, :goto_6 #If not equals, go to: :goto_6
|
||||
goto :goto_6 #Always go to: :goto_6
|
||||
```
|
||||
### Cambios Mayores
|
||||
### Cambios mayores
|
||||
|
||||
### Registro
|
||||
```bash
|
||||
@ -139,17 +140,17 @@ invoke-static {v5, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/Strin
|
||||
```
|
||||
Recomendaciones:
|
||||
|
||||
- Si vas a usar variables declaradas dentro de la función (declaradas v0,v1,v2...) coloca estas líneas entre el _.local \<número>_ y las declaraciones de las variables (_const v0, 0x1_)
|
||||
- Si quieres poner el código de registro en medio del código de una función:
|
||||
- Agrega 2 al número de variables declaradas: Ej: de _.locals 10_ a _.locals 12_
|
||||
- Las nuevas variables deben ser los siguientes números de las variables ya declaradas (en este ejemplo deberían ser _v10_ y _v11_, recuerda que comienza en v0).
|
||||
- Cambia el código de la función de registro y usa _v10_ y _v11_ en lugar de _v5_ y _v1_.
|
||||
- Si vas a usar variables declaradas dentro de la función (declaradas v0,v1,v2...) coloca estas líneas entre la _.local <number>_ y las declaraciones de las variables (_const v0, 0x1_)
|
||||
- Si quieres poner el código de logging en medio del código de una función:
|
||||
- Suma 2 al número de variables declaradas: Ex: de _.locals 10_ a _.locals 12_
|
||||
- Las nuevas variables deben ser los números siguientes de las variables ya declaradas (en este ejemplo deben ser _v10_ y _v11_, recuerda que empieza en v0).
|
||||
- Cambia el código de la función de logging y usa _v10_ y _v11_ en lugar de _v5_ y _v1_.
|
||||
|
||||
### Toasting
|
||||
|
||||
Recuerda agregar 3 al número de _.locals_ al principio de la función.
|
||||
Recuerda añadir 3 al número de _.locals_ al principio de la función.
|
||||
|
||||
Este código está preparado para ser insertado en el **medio de una función** (**cambia** el número de las **variables** según sea necesario). Tomará el **valor de this.o**, **lo transformará** a **String** y luego **hará** un **toast** con su valor.
|
||||
Este código está preparado para insertarse en el **medio de una función** (**cambia** el número de las **variables** según sea necesario). Tomará el **valor de this.o**, lo **transformará** a **String** y luego **hará** un **toast** con su valor.
|
||||
```bash
|
||||
const/4 v10, 0x1
|
||||
const/4 v11, 0x1
|
||||
@ -161,4 +162,38 @@ invoke-static {p0, v11, v12}, Landroid/widget/Toast;->makeText(Landroid/content/
|
||||
move-result-object v12
|
||||
invoke-virtual {v12}, Landroid/widget/Toast;->show()V
|
||||
```
|
||||
### Cargar una biblioteca nativa al inicio (System.loadLibrary)
|
||||
|
||||
A veces necesitas precargar una biblioteca nativa para que se inicialice antes que otras libs JNI (p. ej., para habilitar process-local telemetry/logging). Puedes inyectar una llamada a System.loadLibrary() en un inicializador estático o temprano en Application.onCreate(). Ejemplo smali para un inicializador estático de clase (<clinit>):
|
||||
```smali
|
||||
.class public Lcom/example/App;
|
||||
.super Landroid/app/Application;
|
||||
|
||||
.method static constructor <clinit>()V
|
||||
.registers 1
|
||||
const-string v0, "sotap" # library name without lib...so prefix
|
||||
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
|
||||
return-void
|
||||
.end method
|
||||
```
|
||||
Alternativamente, coloca las mismas dos instrucciones al inicio de tu Application.onCreate() para asegurarte de que la librería se cargue lo antes posible:
|
||||
```smali
|
||||
.method public onCreate()V
|
||||
.locals 1
|
||||
|
||||
const-string v0, "sotap"
|
||||
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
|
||||
|
||||
invoke-super {p0}, Landroid/app/Application;->onCreate()V
|
||||
return-void
|
||||
.end method
|
||||
```
|
||||
Notas:
|
||||
- Asegúrate de que la variante ABI correcta de la biblioteca exista bajo lib/<abi>/ (p. ej., arm64-v8a/armeabi-v7a) para evitar UnsatisfiedLinkError.
|
||||
- Cargarla muy temprano (class static initializer) garantiza que el logger nativo pueda observar la actividad JNI posterior.
|
||||
|
||||
## Referencias
|
||||
|
||||
- SoTap: Logger ligero in-app de comportamiento de JNI (.so) – [github.com/RezaArbabBot/SoTap](https://github.com/RezaArbabBot/SoTap)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user