Ir al contenido principal

Obteniendo strings de procesos en memoria con ReadProcessMemory().

Ya había estado trabajando con framework y otras herramientas que permiten la lectura de procesos y dump de memoria, hace unos días atrás leí sobre una herramienta de hacking que podía obtener datos del usuario en tiempo de ejecución, esto lo hace a través de la WinAPI y específicamente con la Windows function ReadProcessMemory(), me gusta bastante C y sus derivados como C# porque me permiten poder escarbar en el sistema en sus registro, procesos, files, red(sniffer), etc. Considero que es especial para programar mis propias ideas y descubrimientos hacking/forensic interactuando directamente con el sistema.
Para leer lo que un proceso tiene en memoria he programado las siguientes líneas en C#.
Primero obtengo la lista de procesos para luego identificar el name y ID del proceso que quiero leer en memoria:

/*
# Title: GetProcessId (POC)
# Date: 19/07/2016
# Author: José Alejandro Gago
# Tested on: Windows 7 x64 SP1
*/
using System;
using System.Diagnostics;
using System.ComponentModel;

namespace GetProcessId
{
    class ProcessID{
        void Runningprocesses(){
            // Obteniendo todos los procesos e IDs del Sistema.
            try {
                Process[] localAll = Process.GetProcesses();
                foreach (Process mp in localAll){
                    Console.WriteLine("Process Name : {0}", mp.ProcessName);
                    Console.WriteLine("Process ID   : {0}", mp.Id);
                    Console.WriteLine("Windows Title: {0}\n", mp.MainWindowTitle);
                }
            }
            catch (Exception ex){
                Console.Write("{0}", ex);
            }
            finally {
                Console.ReadKey();
            }
        }
        static void Main(){
            ProcessID myProcess = new ProcessID();
            myProcess.Runningprocesses();
        }
    }
}
Para esta prueba utilizare Visual Studio Code por lo cual ejecutare y escribiré el texto que después quiero identificar en memoria.


Para esto utilizaremos OllyDbg.

OllyDbg es un depurador de código ensamblador para sistemas operativos Microsoft Windows. Pone especial énfasis en el análisis del código binario, Traza registros, reconoce procedimientos, llamadas a las API, swiches, tablas, constantes y strings, así como localiza rutinas de archivos objeto y de bibliotecas. 
OllyDbg es frecuentemente usado para la ingeniería inversa de programas. Es usado por crackers para crackear software hecho por otros desarrolladores. Es a menudo la herramienta primaria para cracking e ingeniería inversa debido a su facilidad de uso y disponibilidad. Fuente: Wikipedia ]
Abrimos OllyDbg
File > Attach y localizamos el proceso, luego abrimos memory map Alt+M y finalmente Binary Search Ctrl+B.
Attach
Memory Map
Binary Search
En este último escribimos el string que estamos buscando y nos mostrara el Dump o volcado de memoria.

0800A478  < Esta es la dirección de memoria a la cual le hare lectura mediante programación.
Panorama Total

Ahora es cuando usamos nuestra tool (El Source code que programe al principio de esta publicación) esta nos dará el nombre del proceso al id y el titulo los cuales usaremos para alimentar el siguiente source code para leer lo que contiene en memoria el proceso.

Para leer el valor de la dirección de memoria 0x0800A478 que capture con OllyDbg importo 2 funciones del kernel32.dll.
  •     OpenProcess ()
  •     ReadProcessMemory ()
Al abrir el proceso, especifico una constante de acceso de lectura de la memoria. 
const int ProcessRead = 0x0010;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
public class MemoryRead{
    /*
    Para leer el valor de la dirección de memoria 0x0800A478
    importo 2 funciones del kernel32.dll.
    1.- OpenProcess ()
    2.- ReadProcessMemory ()
    */
    [DllImport("kernel32.dll")]
    public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);

    [DllImport("kernel32.dll")]
    public static extern bool ReadProcessMemory(int hProcess, int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);

      // Al abrir el proceso, especifico una constante de acceso de lectura de la memoria.
    const int ProcessRead = 0x0010;
    public static void Main(){
        string name = "code";
        int id = 8200;
        Process process = Process.GetProcessesByName(name)[0];
        IntPtr processHandle = OpenProcess(ProcessRead, false, id);
        int bytesRead = 0;
        byte[] buffer = new byte[44]; //'Alejandro was here 3:)' toma 22*2 bytes debido a Unicode
        /* 
           0x0800A478 es la dirección donde encontré la cadena
           Se reemplaza por la dirección que se encuentra en tiempo de ejecución
        */
        ReadProcessMemory((int)processHandle, 0x0800A478, buffer, buffer.Length, ref bytesRead);
        Console.WriteLine(" (" + bytesRead.ToString() + "bytes) - Lectura de memoria : " + Encoding.Unicode.GetString(buffer));
        Console.ReadKey();
    }
}
Ejecutamos nuestra 2da tool a la cual le pasamos los parámetros y esta nos devuelve efectivamente la lectura del proceso code.exe con ID: 8200.
Para finalizar esta prueba de concepto (POC) teórica practica las preguntas son: 

¿Para qué nos sirve?
Nos sirve para múltiples cosas como por ejemplo desarrollar nuestra propia herramienta para análisis de memoria, poder orientar esto a la investigación o forensic. 

¿Dónde se puede implementar esto? 
Como ya antes mencione, se puede implementar en herramientas ahora la forma positiva o negativa dependerá del programador y el usuario, puede implementarse en una herramienta espía que capture datos personales del usuario en tiempo real y luego sacar estos datos remotamente como también una herramienta de investigación para descubrir lo que queramos.


Comentarios

Te sugiero las siguientes publicaciones 🙂🤙

Análisis Forense - Extracción de datos desde un dispositivo móvil Android para análisis lógico.

Análisis Forense - Extrayendo y reconstruyendo imágenes y sesión de usuario desde un volcado de memoria.