Radare 2: reversing framework

William Khepri
10 min readJan 3, 2019

--

Radare 2 es un potente framework de reversing.

Radare logo

El reversing o ingeniería inversa, en castellano, es el proceso que se lleva acabo con el objetivo de obtener información de un diseño a partir de un producto final, para determinar cuales son sus componentes, de que forma interactúan entre si, y cuál fue el proceso de fabricación.

Historia:

Radare2 surge, gracias a Sergi Àlvarez (pancake) que trabajando como analista forense, decidió crear una pequeña herramienta, un editor hexadecimal, con características muy básicas:

  • Ser extremadamente portatil (compatible con Unix, línea de comando, c, pequeño)
  • Buscar una cadena o hexpair
  • Revisar y volcar los resultados en un disco.

El editor fue diseñado principalmente para recuperar archivos borrados de una partición HFS+.

Después de dicho proceso pancake decició ampliar la herramienta para que tuviera un i/o pluggeable para poder implementar funcionalidades de depuración, soporte para múltiples arquitecturas y análisis de código.

Desde entonces, el proyecto ha ido evolucionando para proporcionar un marco completo para el análisis de binarios, al tiempo que utiliza conceptos básicos de UNIX. Dichos conceptos incluyen el famoso “todo es un archivo” , “pequeños programas que interactúan usando stdin/stdout”, y paradigmas de “mantenerlo simple”.

Mas adelante, la necesidad de scripting mostró la fragilidad del diseño inicial (radare1): una herramienta monolítica hizo que la API fuera dificil de utilizar, por lo que fue necesaria una refactorización profunda. En 2009 radare2 (r2) surgió como un Fork de radare1. La refactorización añadió flexibilidad y características dinámicas, lo que permitió una mejor integración, facilitando la utilización de r2 desde diferentes lenguajes de programación. Mas tarde, la API de r2pipe permitió el acceso a radare2 a través de pipes desde cualquier lenguaje.

Lo que comenzó como un proyecto de una sola persona, con algunas contribuciones eventuales, se fue convirtiendo gradualmente en un gran proyecto basado en la comunidad alrededor de 2014. Los usuarios fueron creciendo rápidamente, y el autor y el desarrollador principal tuvieron que cambiar los roles de programador a administrador para integrar el trabajo de los diferentes desarrolladores que se unieron al proyecto.

El proyecto de GitHub sigue activo a día de hoy, y desde el año 2016, tiene lugar en Barcelona el congreso r2con donde se reúne la comunidad una vez al año.

Pero dejémonos de historia y hablemos un poco sobre las utilidades de las que dispone radare2:

Utilidades:

  • rax2: Es un conversor de base, o evaluador de expresiones, que resulta útil para realizar conversiones de base entre valores, hexadecimales, decimales, enteros, cadenas de caracteres, ascii, soporta Endiannes y puede ser utilizado como Shell si no se le dan argumentos. Éste es el menú de ayuda en el cual se ofrecen también algunos ejemplos:
root@kali:~# rax2 -h
Usage: rax2 [options] [expression]
int -> hex ; rax2 10
hex -> int ; rax2 0xa
-int -> hex ; rax2 -77
-hex -> int ; rax2 0xffffffb3
int -> bin ; rax2 b30
bin -> int ; rax2 1010d
float -> hex ; rax2 3.33f
hex -> float ; rax2 Fx40551ed8
oct -> hex ; rax2 35o
hex -> oct ; rax2 Ox12 (O is a letter)
bin -> hex ; rax2 1100011b
hex -> bin ; rax2 Bx63
-e swap endianness ; rax2 -e 0x33
-b binstr -> bin ; rax2 -b 01000101 01110110
-s hexstr -> bin ; rax2 -s 43 4a 50
-S bin -> hexstr ; rax2 -S C J P
-v version ; rax2 -V
-x hash string ; rax2 -x linux osx
-k keep base ; rax2 -k 33+3 -> 36
-h help ; rax2 -h
  • rabin2: Poderosa herramienta para manejar archivos binarios, para obtener información sobre importaciones, secciones, encabezados, etc. Es capaz de entender varios tipos de archivos como Java Class, ELF, PE, Match-O, etc, y es capaz de obtener importaciones / exportaciones de símbolos, dependencias de bibliotecas, secciones de cadenas de datos, xrefs, direcciones de punto de entrada, secciones, tipos de arquitectura, etc.
This program allows you to get information about ELF/PE/MZ and CLASS files in a simple way.

-A List archs

-a arch Set arch (x86, arm, .. accepts underscore for bits x86_32)

-b bits Set bits (32, 64, ...)

-B addr Override baddr

-c [fmt:C[:D]]
Create [elf,mach0,pe] for arm and x86-32/64 tiny binaries where 'C' is an
hexpair list of the code bytes and ':D' is an optional concatenation to describe
the bytes for the data section.

-C List classes

-e Show entrypoints for disk and on-memory

-f subbin Select sub-binary architecture. Useful for fat-mach0 binaries

-g Same as -SMRevsiz (Show all possible information). See -r

-i Show imports (symbols imported from libraries)

-s Show exported symbols

-S Show sections

-M Show address of 'main' symbol

-z Show strings inside .data section (like gnu strings does)

-I Show binary info

-H Show header fields

-l List linked libraries to the binary

-R Show realocations

-O str Write/extract operations (-O help)

-o str Output file/folder for write operations (out by default)

-r Show output in radare format

-v Display virtual addressing offsets

-m addr Show source line reference from a given address

-L List supported bin plugins

-@ addr Show information (symbol, section, import) of the given address

-n str Show information (symbol, section, import) at string offset

-x Extract all sub binaries from a fat binary (f.ex: fatmach0)

-V Show version information

-h Show usage help message.
  • rasm2: Ésta herramienta ensamblador / desensamblador inicialmente fue diseñada para parchear binarios, su función principal es conseguir que los bytes correspondan a la instrucción opcode dada por la máquina.

con él podemos emsamblar:

$ rasm2 -d 89d85d90 
mov eax, ebx;pop ebp;nop

y desensamblar:

$ rasm2 'mov eax, ebx;pop ebp;nop' 
89d85d90

No solo x86, sino también registros mips.

$ rasm2 -a mips  'addiu a1, a2, 8' 
0800c524
$ rasm2 -a mips -d 0800c524
addiu a1, a2, 8
  • radiff2: Ésta herramienta nos permite visualizar gráficamente las diferencias entre dos binarios. Para utilizarla debemos tener configurada la herramienta Xdot (Visor interactivo para gráficos escritos en lenguaje de gráficos Graphviz) para instalarlo debemos ejecutar el comando sudo apt install xdot. La sintaxis de raddif2 es de la siguiente forma:

radiff2 -g function_name binary1 binary | xdot -

En cuanto a los colores que observamos gráficamente:

radiff2.
  • amarillo: significa que algunas compensaciones no coinciden.
  • gris: indica que la coincidencia es perfecta.
  • rojo: indica que existen muchas diferencias entre un binario y el otro.

en el manual de la herramienta podemos acceder a todas las funcionalidades que la herramienta nos proporciona:

RADIFF2(1)                                   BSD General Commands Manual                                   RADIFF2(1)  
NAME RADIFF2 — unified binary diffing utility
SYNOPSIS
radiff2 [-AabcCdDhOrspxvz] [-t 0-100] [-g sym] [-S algo] file1 file2
DESCRIPTION
radiff2 implements many binary diffing algorithms for data and code. -A Analyze binary after loading it with RCore (see -C) and use -AA to run aaaa instead of aaa.
-a Specify architecture (x86, arm, ..)
-b Select register size bits for given arch
-B Binary output (GDIFF format)
-c Count number of differences.
-e -[k=v] Specify eval config vars for all RCore instances created.
-C Code diffing using graphdiff algorithm.
Output columns are: file-a-address, percentage of most similar function in B file | file-b-address.
(Use with -A to analyze the binaries to find more func‐ tions)
-d Use delta diffing (slower).
-D Show disasm instead of hexpairs (honors -a arch and -b bits)
-g sym | off1,off2 Graph diff output of given symbol, or between two functions, at given offsets: one for each binary.
-h Show usage help message.
-i Compare the list of imports
-n Suppress address names (show only addresses) when code diffing.
-O Do code diffing with all bytes instead of just the fixed opcode bytes
-p Use physical addressing (io.va=0)
-q Quiet mode: disable colors and reduce output
-r Output in radare commands as a binary patch.
-x Show two column hexdump diffing.
-s Calculate text distance from two files.
-ss Same as before but using the Levenstein algorithm (faster but sometimes buggy)
-S [name, namelen, dist, size, ...] Specify which column of the code diffing algo use for diffing
-t 0-100 Choose matching threshold for binary code diffing -u Unified diff output
-U Unified diff output using system´s diff program
-v Show version information.
-V Be verbose sometimes
-z Perform diff on extracted strings SEE ALSO radare2(1), rafind2(1), rahash2(1), rabin2(1), rasm2(1), ragg2(1), rarun2(1), rax2(1),
AUTHORS pancake <pancake@nopcode.org> Feb 10, 2018
  • rafind2: Es un editor hexadecimal de línea de comando avanzado, que nos permite buscar patrones de bytes en un fichero binario. Puede buscar filtrando por varias opciones, como cadenas que finalicen en cero, o definir el tamaño del bloque, para acceder a todas las opciones posibles consultaremos la ayuda que facilito a continuación:
The options are:
-z Search for zero-terminated strings
-a alignOnly accept aligned hits
-s strSearch for a specific string
-S strSearch for a specific wide string
-e regexSearch for a regular expression string matches
-x hexSearch for an hexpair string
-i Identify filetype (like file, uses r2 -qcpm)
-m Carve for known file-types using the r_magic signatures
-M maskSet binary mask to be applied
-f fromSpecify the source adddress
-t toSpecify the target adddress
-X Display hexdump of search results
-Z Display zero-terminated strings results
-n Do not stop the search when a read error occurs
-r Show output in radare commands
-b sizeDefine block size
-q Quiet mode - do not show headings (filenames) above matching contents (default for searching a single file)
-h Show help message
-v Print version and exit
  • rahash2: Ésta utilidad de hashing basada en bloques, nos permite calcular, verificar y mostrar los valores hash de cada bloque de un archivo destino. El tamaño del bloque es, por defecto, de 32768 bytes. Permite introducir el hash directamente desde stdin utilizando “-” como archivo objetivo. Se puede comparar con un hash conocido y obtener el resultado en el estado de salida, tal y como nos indica su ayuda. Permite calcular todos éstos tipos de hash: md5, sha1, sha256, sha384, sha512, crc16, crc32, md4, xor, xorpair, parity, entropy, hamdist, pcprint, mod255, xxhash, adler32, luhn, crc8smbus, crc15can, crc16hdlc, crc16usb, crc16citt, crc24, crc32c, crc32ecma267. Así como los tres encoders/decoders: base64, base91 y punycode. Respecto a los algoritmos de encriptación, rahash2 soporta: rc2, rc4, rc6, aes-ecb, aes-cbc, ror, rol, rot, blowfish, cps2, des-ecb, xor y serpent-ecb.
RAHASH2(1)                                   BSD General Commands Manual                                       RAHASH2(1)  NAME      rahash2 — block based hashing utility  
SYNOPSIS rahash2 [-BdDehjrkvq] [-a algorithm] [-b size] [-D algo] [-E algo] [-s string] [-i iterations] [-I IV] [-S seed] [-f from] [-x hexstr] [-t to] [-c hash] [[file] ...]
DESCRIPTION
This program is part of the radare project.Rahash2 allows you to calculate, check and show the hash values of each block of a target file. The block size is 32768 bytes by default. It's allowed to hash from stdin using '-' as a target file. You can compare against a known hash and get the result in the exit status. You can hash big files by hashing each block and later determine what part of it has been modified.Useful for filesystem analysis. This command can be used to calculate hashes of a certain part of a file or a command line passed string. This is the command used by the 'ph' command of radare.
-a algo
Select an algorithm for the hashing. Valid values are listed in: rahash2 -L
-b blocksize Define the block size
-c hash Compare the computed hash with this one. Allowed only when a single hash is computed.
-D algo Decrypt instead of hash using the given algorithm (base64, base91, rc4, aes, xor, blowfish, rot, rol, ror, rc2, rc6, punycode)
-e Use little endian to display checksums
-E algo Encrypt instead of hash using the given algorithm (base64, base91, rc4, aes, xor, blowfish, rot, rol, ror, rc2, rc6, punycode)
-i iters Apply the hash Iters times to itself+seed
-I [^]s:string|hexstr
Set initialization vector (IV) for the cryptographic functions.
-j Show output in JSON (see -r)
-B Show per-block hash
-k Show result using OpenSSH's VisualHostKey randomart algorithm
-s string Hash this string instead of using the 'source' and 'hash-file' arguments.
-S [^]s:string|hexstr
Set seed to hash with, use ^to prefix seed, otherwise its suffixed. If the seed is just a dash '-' it will read from stdin, this is useful to provide huge XOR payloads or other crypto keys bigger than few bytes.
-f from Start hashing at given address
-t to Stop hashing at given address
-q Quiet mode (-qq for even quieter!)
-r Show output in radare commands
-x hexstr Hash the given hexpair string instead of using the 'source' and 'hash-file' arguments.
-v Show version information
-h Show usage help message.
DIAGNOSTICS
The rahash2 utility exits 0 on success, and >0 if an error occurs.
When -c is used, exit status 0 indicates a match between the expected and computed hashes. SEE ALSO radare2(1), rafind2(1), rahash2(1), rabin2(1), radiff2(1), rasm2(1), ragg2(1), rarun2(1), rax2(1), AUTHORS pancake <pancake@nopcode.org> Feb 6, 2015
  • radare2: La mayoría de los comandos de radare se derivan de los nombres de acción. Deben ser fáciles de recordar, ya que son cortos. En realidad, todos los comandos son letras individuales. Los subcomandos o comandos relacionados se especifican usando el segundo carácter del nombre del comando. Por ejemplo, /foo es un comando para buscar una cadena simple, mientras que /x 90 90 se usa para buscar pares hexadecimales.

El formato general para un comando válido tiene éste aspecto:

[.][times][cmd][~grep][@[@iter]addr!size][|>pipe] ; ...

Por ejemplo,

> 3s +1024 ; busca tres veces 1024 desde la vista actual.

  • rarun2: Ésta herramienta nos permite configurar el entorno de ejecución específico para nuestro binario, permitiéndonos redefinir stdin / stdout, pipes, cambiar las variables de entorno y otras configuraciones útiles para crear las condiciones que nos permitan depurar correctamente nuestro binario.

La sintaxis es como sigue:

$ rarun2 -h
Usage: rarun2 -v|-t|script.rr2 [directive ..]

Cabe destacar, que rarun2 se puede utilizar tanto como parte de radare2 como herramienta aparte. Para cargar el perfil deseado en radare2, usaremos el operador -r para cargar el perfil desde el archivo o -R para especificar la directiva desde la línea de comandos.

Toma el archivo de texto en formato clave = valor para especificar el entorno de ejecución. El formato del perfil es simple. Hay que tener en cuenta, sobre todo, las claves mas importantes que son: program y arg* .

Uno de los casos de uso más comunes para esta herramienta es redirigir la salida del programa depurado en radare2.

Éste sería un ejemplo de perfil básico:

program=/bin/ls
arg1=/bin
# arg2=hello
# arg3="hello\nworld"
# arg4=:048490184058104849
# arg5=:!ragg2 -p n50 -d 10:0x8048123
# arg6=@arg.txt
# arg7=@300@ABCD # 300 chars filled with ABCD pattern
# system=r2 -
# aslr=no
setenv=FOO=BAR
# unsetenv=FOO
# clearenv=true
# envfile=environ.txt
timeout=3
# timeoutsig=SIGTERM # or 15
# connect=localhost:8080
# listen=8080
# pty=false
# fork=true
# bits=32
# pid=0
# pidfile=/tmp/foo.pid
# #sleep=0
# #maxfd=0
# #execve=false
# #maxproc=0
# #maxstack=0
# #core=false
# #stdio=blah.txt
# #stderr=foo.txt
# stdout=foo.txt
# stdin=input.txt # or !program to redirect input from another program
# input=input.txt
# chdir=/
# chroot=/mnt/chroot
# libpath=$PWD:/tmp/lib
# r2preload=yes
# preload=/lib/libfoo.so
# setuid=2000
# seteuid=2000
# setgid=2001
# setegid=2001
# nice=5

--

--

William Khepri

Desarrollador de Software y Autodidacta de la seguridad informática. Escribo sobre seguridad informática y tecnología.