28 feb 2020

Las entrañas de un repo GIT: Objects

Hace un par de días publicamos en el blog un write-up sobre una prueba de un CTF basado en una carpeta .git que podéis ver aquí y hoy me gustaría profundizar un poco más en los entresijos de GIT.

Para los despistados, GIT es una herramienta de control de versiones que permite a los desarrolladores trabajar de manera colaborativa mediante el uso de ramas y referencias concretas a momentos actuales en el código.

Logo de git

Lo primero que tenemos que tener en cuenta es cómo iniciar un repositorio git y de qué se compone, para ello vamos a crear un pequeño repositorio donde hacer pruebas y mostrar el contenido interno.

Contenido de un repositorio GIT

Como se puede apreciar, dentro de esa carpeta .git (oculta para el usuario) es donde sucede la magia de git y está compuesta principalmente por las siguientes carpetas:
  • .git/branches antigua carpeta donde se guardaba información sobre las distintas ramas del repositorio, actualmente se considera deprecada pero se crea por evitar conflictos.
  • .git/hooks almacena pequeños scripts que serán ejecutados en distintos momentos, ideales para hacer comprobaciones antes de subir código al repositorio remoto ;)
  • .git/info contiene información adicional sobre el repositorio.
  • .git/refs actualmente se usa como almacén de referencias dentro del repositorio, esto son tanto las etiquetas de versiones como las distintas ramas de trabajo.
  • .git/objects esta es la carpeta más interesante de todas, aquí se almacena la información del repositorio en sí, es decir, aquí es donde se guarda el contenido de los archivos.

No obstante, cabe destacar estos dos archivos:

  • HEAD hace referencia a la posición actual en el repositorio, es decir a la rama donde está trabajando (p.ej. master)

¿Cómo almacena git el contenido?

Para entenderlo mejor vamos a realizar una pequeña demo centrada en esa carpeta objects que actualmente está vacía, donde almacena supuestamente git los datos de los archivos en el repositorio. Para ello usaremos el comando git hash-object que es de lo que git hace uso internamente cuando se realiza un commit.

Creado objeto de git

Ahora nuestra carpeta .git/objects ya contiene un archivo, en este caso localizado en .git/objects/eb/d770c4ec1aeb9db7d5cc43fd0186bad6edf022. Cabe destacar el uso de una carpeta con los dos primeros caracteres, esto lo realiza para optimizar las búsquedas en los repositorios en los que existen gran cantidad de objetos.

Si con esto ya se entiende más o menos como gestiona git los datos, vamos a realizar una prueba generando un archivo con dos versiones distintas

Creamos un archivo con varias versiones

Tal y como se puede apreciar, se han generado 2 hashes distintos para un mismo archivo y es que a diferencia de lo que pudiera parecer, git genera un blob de datos  (datos binarios) de tipo objeto por cada contenido de modo que un mismo archivos con distintas versiones aparecerá en la carpeta .git/objects como varios archivos de datos distintos.

Si quisiéramos ver el contenido de uno de estos objetos, se puede usar el comando git cat-file que se encargará de devolvernos el contenido de ese objeto, si usásemos el comando cat nos encontraríamos con contenido binario y comprimido ilegible, os recomiendo hacer una pequeña prueba.

Recuperamos el contenido de un objeto de git

Con este sencillo comando, se puede leer el contenido de los distintos blobs pertenecientes a un repositorio, a destacar el uso de -p para indicarle que interprete el tipo de dato del que se trata, pues ya veremos en posteriores post que puede haber varios.

Ahora dominamos un poco más como se almacena la info en git, a lo largo de esta serie os explicaremos como puede seros útil en un pentest o ejercicio de red team.

Sed buenos y 
¡Feliz viernes!

No hay comentarios:

Publicar un comentario