PHP: Analizar las annotations de propiedades mediante reflection

18 mayo, 2013 a las 15:20

A veces puede sernos útil utilizar los annotations sobre una propiedad:

/**
 * @tabla   Cualquiera
 * @columna Otra
 */
public $nombre;

Y luego analizar estas anotaciones en el código para completar su valor, etc (Tipico caso de un ORM).

$class = new ReflectionClass(new TuClase());
$properties = $class->getProperties();
foreach($properties as $property)
{
    $doc_block = $property->getDocComment();
    $annotations = parseDocBlock($doc_block);
}

function parseDocBlock($doc_block)
{
    $annotations = array();
    $doc_block = substr($doc_block, 3, -2);

    if (preg_match_all('/@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?[ \t]*\r?$/m', $doc_block, $matches)) {
        $numMatches = count($matches[0]);

        for ($i = 0; $i < $numMatches; ++$i) {
            $annotations[$matches['name'][$i]][] = $matches['value'][$i];
        }
    }
    return $annotations;
}

Crear aplicación multi-plataforma nativa para Android con PhoneGap

12 mayo, 2013 a las 13:39

Apache Cordova (PhoneGap) es una plataforma para crear aplicaciones nativas para dispositivos móviles, utilizando únicamente HTML, CSS y JavaScript (Estos se alojarán localmente en la aplicación, y podremos servirle contenido dinámico mediante AJAX con nuestro servidor web),
De este modo, utilizando HTML, CSS y Javascript, conseguimos desprendernos de la necesidad de emplear código nativo del SO del dispositivo (Java para Android, Objective-C para iPhone, etc), lo que nos permitirá portar nuestra aplicación a cualquier plataforma (Actualmente soporta iOS, Android, Blackberry, Windows Phone, Palm WebOS, Bada, y Symbian) sin ningún (o casi ningún) cambio.

Aún así el conjunto de APIs de Apache Cordova (PhoneGap) nos permitirá utilizar funcionalidades nativas del dispositivo, como puede ser por ejemplo utilizar la cámara, el acelerometro, etc.

Para portar nuestra aplicación hecha en HTML, CSS y JavaScript, a Android, primero necesitaremos:

  • Descargar e instalar Android SDK.
  • Descargar la última versión de PhoneGap y extraer los ficheros contenidos.

Ahora ya podremos crear un nuevo proyecto con PhoneGap.
Para esto abrimos una Shell y nos posicionaremos en el directorio de PhoneGap, una vez aquí nos dirigiremos al subdirectorio lib/android/bin

Y ejecutaremos:

user@host:~$ ./create <project_path> <package_name> <project_name>

<project_path> es el directorio donde queremos generar nuestro Proyecto de Android Cordova
<package_name> es el nombre del package, por ejemplo: com.YourCompany.YourAppName (debe contener los tres nombres de espacio)
<project_name> es el nombre del proyecto, por ejemplo: YourApp (No debe contener espacios ni guiones)

Ahora ya tenemos nuestro proyecto creado, y podemos dirigirnos al directorio donde lo hayamos generado.
Una vez aquí, podemos ver que hay un directorio llamado assets que contiene un subdirectorio llamado www. Es en este último donde deberemos incluir todos los ficheros HTML, CSS y JavaScript de nuestra aplicación. Al arrancarse la aplicación en el dispositivo se cargará el fichero index.html.

apphtmlphonegap Con nuestro Java IDE favorito con Android SDK configurado (Al descargar Android SDK, viene incluida una versión de Eclipse con Android SDK ya configurado), podemos compilar nuestro proyecto, y empaquetar nuestra aplicación.
De este modo podremos ejecutarla en una Maquina Virtual Android o directamente en nuestro dispositivo conectado por USB.

LWOTP (Login With One-Time Password)

9 mayo, 2013 a las 20:53

Se trata de una aplicación que he desarrollado para aumentar la seguridad de conexiones ssh desde clientes inseguros, donde no podemos garantizar la inexistencia de ningun keylogger en la maquina, etc. Pese a esto, puede que necesitemos realizar dichas conexiones a nuestro servidor desde una de estas maquinas.
Con LWOTP, al conectarnos mediante SSH a una maquina (no nos preocupa la contraseña, la protección fuerte está detras) lo hariamos de la siguiente manera:

user@host:~$ ssh user@anotherhost

Y automáticamente al entrar nos mostraría un token y nos solicitaría una clave de un solo uso.
Por ejemplo:
Token: VPJcwwoJo5
Introduce la Clave:

Ese token deberá ser introducido en la aplicación generadora de claves (podríamos tener el generador en un smartphone, etc).

Si la clave introducida es correcta nos abriría una shell, si es incorrecta se cerraría la sesión.

Puedes clonarlo desde este reposoitorio de GitHub.
Para compilarlo, necesitaras entre otras cosas las librerías Boost C++.
Puedes instalarlas fácilmente en GNU/Linux Debian based con:

user@host:~$ aptitude install libboost*

Para compilar LWOTP:
user@host:~$ g++ lwotp.cpp -o lwotp

(Para el generador, seria igual, pero con lwotpg.cpp)LWOTP se aplica a usuarios específicos.
Edita el fichero /etc/passwd
felixcarmona:x:1000:1000:felixcarmona,,,:/home/felixcarmona:/bin/bash

Y modifica el /bin/bash por /elpathcorrespondiente/lwotp
De este modo, al iniciar sesión, no se abrirá una shell, si no la aplicación lwotp, que será el responsable de abrirte una shell o no.

Call private methods from outside a class in PHP using reflection

14 febrero, 2013 a las 20:02

Is possible that when you’re doing unit tests, you need to test a private method.
Ideally would test the public method that uses these private methods, but sometimes is not possible test directly the public method because it has too many dependencies, etc.
But you can explicitly test the private methods for greater coverage.

Look this:

class TestClass {
    private function sum($a, $b)
    {
        return $a+$b;
    }
}

$object = new TestClass();
echo $object->sum(2,3); // 5

If we execute, it returns: 

Fatal error: Call to private method TestClass::sum()

But we can change the method visibility using the reflection:

$reflection = new ReflectionClass('TestClass');
$closure = $reflection->getMethod('sum')->getClosure(new TestClass());
echo call_user_func_array($closure, array(3,2)); // 5

it returns: 5

Programar DLL (C++) e inyectarla en los offsets de un binario

28 enero, 2013 a las 21:03

Tengo una aplicación ya compilada, la cual no dispongo del código fuente.
Una forma de añadirle funcionalidades, es inyectandole una biblioteca de enlace dinámico.
Voy a programarla en C++ y a compilarla con Dev-C++.

#include "windows.h";
#include "stdio.h";
#define EXPORT extern "C" __declspec (dllexport)

EXPORT void injection( ){} //Anclaje

EXPORT BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserved)
{
    switch(reason)
    {
        case DLL_PROCESS_ATTACH:
            MessageBox(0,"aplicacion abierta","titulo",MB_OK);
            break;
        case DLL_PROCESS_DETACH:
            MessageBox(0,"aplicacion cerrada","titulo",MB_OK);
            break;
    }

    return true;
}

EXPORT void injection( ){} Es la función exportable que utilizaremos para inyectar la DLL (nos ofrece un anclaje mas solido y limpio que DllMain).

La función DllMain correrá automáticamente en un thread paralelo al instanciar la aplicación que inyecta.

Esta función dispone de varios eventos, de los cuales he utilizado DLL_PROCESS_ATTACH y DLL_PROCESS_DETACH, para mostrar un par de mensajes.
Al abrir la aplicación, aparecerá el mensaje 1, y al cerrar la aplicación, aparecerá el mensaje 2.

Una vez compilada la DLL es el momento de inyectarla en algún offset disponible (buscando un “hueco vacio” suficiente en el binario).
Existen herramientas como StudPE que nos simplifican la tarea (también podríamos hacerlo manualmente con un editor hexadecimal)

File > Open PE. (y seleccionas el binario de la aplicación)

En la pestaña Functions, hay un cuadro a la izquierda (Imported Functions), pulsando con el botón secundario, seleccionamos la opción Add New Import.

Pulsamos en Dll Select, y seleccionamos la dll, luego pulsamos en Select func. y seleccionamos la función que hemos creado como anclaje (en mi caso, injection), pulsamos OK, luego en Add to list y ADD, luego de nuevo en OK.

Ahora la DLL, ya está inyectada

Ingeniería Inversa y Cracking, modificando el algoritmo de un ejecutable

27 enero, 2013 a las 22:57

Los programas son conjuntos de operaciones aritméticas que se ejecutan sobre la memoria.
A estas operaciones se acceden mediante una serie de saltos (ya sean condicionales o incondicionales).
Si lo que quiero es obtener una salida distinta a la habitual, lo que debo hacer es modificar el algoritmo, forzando una serie de saltos concretos. (Estudiando las operaciones aritméticas y saltos que realiza la aplicación)

Tenemos una aplicación que parece contener una contraseña, pero no está autorizada a mostrarnosla.
a1
Abrimos la aplicación con Ollydbg y buscamos cadenas legibles, con el fin de poder situarnos en el flujo que contiene la condición que nos niega darnos la contraseña.
a2
Podemos ver la parte que devuelve la contraseña, pero esta enmascarada, así que no aparece directamente, si no que en el momento de ejecución cada %c, será sustituido por valores char.
a3
Pulsamos doble click sobre el y nos mandará a esa parte:
a41
Nos situamos sobre el “No puedo darte la clave”, y se desplegará una flecha, que nos indicará desde que salto proviene la instrucción.

Nos posicionamos en el origen y vemos que pone JE, que significa “salta si es equivalente”, entonces entendemos que hay una condición que esta impidiendo que la aplicación nos de la contraseña.
Por lo tanto vamos a modificar JE por su antónimo: JNE, que significa “salta si no es equivalente”.
Hacemos doble click sobre el, lo modificamos y pulsamos Assemble:
a5
Ahora que ya hemos modificado el algoritmo de la aplicación, pasamos a probarlo: Pulsamos en Debug > Run (O directamente pulsamos F9)
a6
Ya está, hemos conseguido que nos muestre la clave.
Código fuente del ejecutable:
#include <stdio.h>
#include <cstdlib>

int main() {
    bool autorizado = false;
    if(autorizado)
        printf("Puedo darte la clave: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",'f','0','6','7','4','3','2','8','d','1','3','5','5','9','c','5','d','c','6','d','9','b','2','b','7','5','c','8','6','2','5','7');
    else
        printf("No puedo darte la clave");

    system("PAUSE");
    return 0;
}

Ingeniería Inversa y Cracking, buscando cadenas

27 enero, 2013 a las 21:20

Estamos frente a una aplicación que nos solicita una contraseña que desconocemos:
p11
Si introducimos una contraseña al azar, nos dirá que es incorrecta. Así que vamos a examinar el binario utilizando la herramienta Ollydbg, para tratar de encontrar la clave escrita en alguna parte:
p2
Abrimos Ollydbg y pulsamos en File > Open (O pulsamos directamente F3)

Pulsamos con el botón secundario sobre cualquier parte del cuadro CPU y seleccionamos Search for > All referenced strings.

Aquí podemos observar las cadenas legibles en el programa, entre estas podemos encontrar la clave: ClAvE1234Af
p3
Esto es porque la aplicación tiene la clave en plano.
p4

Código fuente del ejecutable:

#include <cstdlib>
#include <iostream>

using namespace std;

int main()
{
    char clave[0];
    cout << "Introduce la clave:" << endl;
    cin >> clave;
    if((string)clave == "ClAvE1234Af")
        cout << "La clave introducida es correcta." << endl;
    else
        cout << "La clave introducida es incorrecta" << endl;

    system("PAUSE");
    return 0;
}