Лекция 2
.pdfПонятие эксплойта и уязвимости |
Переполнение буфера |
Подготовка шеллкода |
|
|
|
buf_over ow.c (отладка ./buf_over ow 100)
$ gdb -q ./buf_overflow
Reading symbols from ./buf_overflow...done.
(gdb) b 18
Breakpoint 1 at 0x400602: file buf_overflow.c, line 18.
(gdb) r 100
Starting program: ...
Breakpoint 1, test (n=100) at buf_overflow.c:18
12 memset(&v.a, 0, n);
(gdb) p v.a
$1 = 1
(gdb) p v.b
$2 = 2
(gdb) p n
$3 = 100
(gdb) x $rbp 0x7fffffffe110: 0xffffe130
(gdb) n
19 printf("val v.a: %d\n", v.a);
(gdb) p v.a
$4 = 0
(gdb) p v.b
$5 = 0
(gdb) p n
$6 = 100
(gdb) x $rbp 0x7fffffffe110: 0x00000000
(gdb) fin
Run till exit from #0 test (n=100) at buf_overflow.c:19
...
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
24/40 |
Понятие эксплойта и уязвимости |
Переполнение буфера |
Подготовка шеллкода |
|
|
|
buf_over ow.c (отладка ./buf_over ow 100)
$ gdb -q ./buf_overflow
Reading symbols from ./buf_overflow...done.
(gdb) b 18
Breakpoint 1 at 0x400602: file buf_overflow.c, line 18.
(gdb) r 100
Starting program: ...
Breakpoint 1, test (n=100) at buf_overflow.c:18
12 memset(&v.a, 0, n);
(gdb) p v.a
$1 = 1 |
|
|
||
(gdb) |
p |
v.b |
|
|
$2 = 2 |
|
|
||
(gdb) |
p |
n |
|
|
$3 = 100 |
|
|||
(gdb) |
x |
$rbp |
|
|
0x7fffffffe110: 0xffffe130 |
|
|||
(gdb) |
n |
|
|
|
19 printf("val v.a: %d\n", v.a); |
|
|||
(gdb) p |
v.a |
|
||
$4 = 0 |
|
|
||
(gdb) |
p |
v.b |
|
|
$5 = 0 |
|
Перезатерлось значение переменной v.b |
||
(gdb) |
p |
n |
||
|
||||
$6 = 100 |
|
|||
(gdb) |
x |
$rbp |
Изменилось значение в ячейке стека, |
|
0x7fffffffe110: 0x00000000 |
расположенной по адресу 0x7 fe110 |
|||
(gdb) |
fin |
|
Run till exit from #0 test (n=100) at buf_overflow.c:19
...
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
24/40 |
|
Понятие эксплойта и уязвимости |
Переполнение буфера |
|
Подготовка шеллкода |
|||||
|
|
stack_over ow.c |
|
|
|
||||
1 |
# include < stdio .h > |
|
./stack_overflow \ |
||||||
|
|||||||||
2 |
# include < string .h > |
|
`python -c 'print("a"*8)'` |
||||||
3 |
# include < stdlib .h > |
|
addr &a: 7FFDD99B5608 |
||||||
|
4 void |
overflow ( const |
char *c) |
addr b: 7FFDD99B5600 |
|||||
5 |
{ |
|
|
|
|
val a: 1 |
|
||
6 |
const unsigned long long a = 1; |
val b: '' |
|
||||||
7 |
char b [8] = ""; |
|
addr &a: 7FFDD99B5608 |
||||||
8 |
printf (" addr &a: %lX\n", &a); |
addr b: 7FFDD99B5600 |
|||||||
9 |
printf (" addr b: %lX\n", b); |
val a: 0 |
|
||||||
10 |
printf ("val a: %lu\n", a); |
val b: 'aaaaaaaa' |
|||||||
11 |
printf ("val b: '%s '\n", b); |
|
|
|
|||||
12 |
strcpy (b, c); |
|
./stack_overflow \ |
||||||
13 |
printf (" addr &a: %lX\n", &a); |
`python -c 'print("a"*16)'` |
|||||||
14 |
printf (" addr b: %lX\n", b); |
addr &a: 7FFC580D0428 |
|||||||
15 |
printf ("val a: %lu\n", a); |
addr b: 7FFC580D0420 |
|||||||
16 |
printf ("val b: '%s '\n", b); |
val a: 1 |
|
||||||
17 |
} |
|
|
|
|
val b: '' |
|
||
|
18 int |
main (int |
argc , |
char * argv []) |
addr &a: 7FFC580D0428 |
||||
19 |
{ |
|
|
|
|
addr b: 7FFC580D0420 |
|||
20 |
if |
( argc != |
2) exit (1); |
val a: 7016996765293437281 |
|||||
21 |
overflow ( argv [1]); |
|
val b: 'aaaaaaaaaaaaaaaa' |
||||||
22 |
return 0; |
|
|
|
Segmentation fault |
||||
|
23 |
} |
|
|
|
|
|
||
|
Браницкий А.А., СПбГУТ |
|
Лекция 2, Санкт-Петербург, 2021 |
|
25/40 |
||||
|
|
|
|
|
|
|
|
|
|
Понятие эксплойта и уязвимости Переполнение буфера Подготовка шеллкода
stack_over ow.c (отладка)
$ gcc -g stack_overflow.c -o stack_overflow
$ gdb ./stack_overflow
(gdb) b 12
Breakpoint 1 at 0x40060a: file stack_overflow.c, line 12. (gdb) r $(python -c 'print("a"*16+"b"*8)')
Starting program: ...
Breakpoint 1, overflow (c=0x7fffffffe8fb 'a' <repeats 16 times>, "bbbbbbbb") at stack_overflow.c:12
12 strcpy(b, c);
(gdb) x $rbp 0x7fffffffe4a0: 0xffffe4c0
(gdb) n
13 printf("addr &a: %lX\n &a);
(gdb) x $rbp 0x7fffffffe4a0: 0x62626262
(gdb) fin
Run till exit from #0 overflow ...
0x0000000000400600 in overflow (c=<error reading variable: Cannot access memory at address 0x626262626262624a>, c@entry=<error reading variable: Cannot access memory at address 0x626262626262626a>) at stack_overflow.c:11
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
26/40 |
Понятие эксплойта и уязвимости |
Переполнение буфера |
Подготовка шеллкода |
||||
|
bss_over ow.c |
|
|
|||
1 |
# include < stdio .h > |
|
|
|
||
2 |
# include < string .h > |
|
./bss_overflow abcdefgh |
|||
3 |
# include < stdlib .h > |
|
addr &a: 600AC8 |
|||
4 unsigned long |
long |
a; |
addr b: 600AC0 |
|||
5 char |
b [8]; |
|
|
val a: 1 |
|
|
6 int |
main ( int |
argc , |
char * argv []) |
val b: '' |
|
|
7 |
{ |
|
|
|
addr &a: 600AC8 |
|
8 |
if ( argc != 2) |
|
addr b: 600AC0 |
|||
9 |
exit (1); |
|
|
val a: 0 |
|
|
10 |
a = |
1; |
|
|
val b: 'abcdefgh' |
|
11 |
printf (" addr &a: %lX\n", &a); |
|
|
|||
12 |
printf (" addr b: %lX\n", b); |
./bss_overflow \ |
||||
13 |
printf ("val a: %lu\n", a); |
`python -c 'print("a"*1344)' |
||||
14 |
printf ("val b: '%s '\n", b); |
addr &a: 600AC8 |
||||
15 |
strcpy (b, argv [1]); |
addr b: 600AC0 |
||||
16 |
printf (" addr &a: %lX\n", &a); |
val a: 1 |
|
|||
17 |
printf (" addr b: %lX\n", b); |
val b: '' |
|
|||
18 |
printf ("val a: %lu\n", a); |
Segmentation fault |
||||
19 |
printf ("val b: '%s '\n", b); |
|
|
|||
20 |
return 0; |
|
|
|
|
|
21 |
} |
|
|
|
|
|
|
|
|
|
|
|
|
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
27/40 |
Понятие эксплойта и уязвимости |
Переполнение буфера |
Подготовка шеллкода |
bss_over ow.c (отладка) |
|
$ gcc -g bss_overflow.c -o bss_overflow
$ gdb ./bss_overflow
(gdb) b 15
Breakpoint 1 at 0x400615: file bss_overflow.c, line 15. (gdb) r $(python -c 'print("a"*1344)')
Starting program: ...
Breakpoint 1, main (argc=2, argv=0x7fffffffe088) at bss_overflow.c:15
15 strcpy(b, argv[1]); (gdb) info symbol b
b in section .bss of bss_overflow
(gdb) x $rbp 0x7fffffffdfa0: 0x00000000
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
28/40 |
Понятие эксплойта и уязвимости |
Переполнение буфера |
|
Подготовка шеллкода |
||||||
|
heap_over ow.c |
|
|
|
|
||||
1 |
# include < stdio .h > |
|
./heap_overflow \ |
||||||
|
|||||||||
2 |
# include < string .h > |
|
`python -c 'print("a"*24)'` |
||||||
3 |
# include < stdlib .h > |
|
addr a: 1646010 |
||||||
4 int main ( int argc , char * argv []) |
addr b: 1646030 |
||||||||
5 |
{ |
|
|
|
|
|
a - b: 32 |
|
|
6 |
if ( argc != 2) |
|
val a: 'aaaaaaaaaaaaaaaaaaaaaaaa ' |
||||||
7 |
exit (1); |
|
|
|
val b: '' |
|
|||
8 |
char |
*a |
= |
malloc (24); |
|
len a: 24 |
|
||
9 |
char |
*b |
= |
malloc (8); |
|
len b: 0 |
|
||
10 |
printf (" addr a: %lX\n", |
a); |
*** Error in `./heap_overflow ': free() |
||||||
11 |
printf (" addr b: %lX\n", |
b); |
Aborted |
|
|||||
12 |
printf ("a - b: %d\n", b - a); |
|
|
|
|||||
13 |
strcpy (a, |
argv [1]); |
|
./heap_overflow \ |
|||||
14 |
printf ("val a: '%s '\n", |
a); |
`python -c 'print("a"*33)'` |
||||||
15 |
printf ("val b: '%s '\n", |
b); |
addr a: DC9010 |
||||||
16 |
printf ("len a: %zu\n", |
|
addr b: DC9030 |
||||||
17 |
|
|
strlen (a)); |
|
a - b: 32 |
|
|||
18 |
printf ("len b: %zu\n", |
|
val a: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ' |
||||||
19 |
|
|
strlen (b)); |
|
val b: 'a' |
|
|||
20 |
free (a); |
|
|
|
len a: 33 |
|
|||
21 |
free (b); |
|
|
|
len b: 1 |
|
|||
22 |
return |
0; |
|
|
|
*** Error in `./heap_overflow ': free() ... |
|||
23 |
} |
|
|
|
|
|
Aborted |
|
|
|
|
|
|
|
|
|
|
|
|
Понятие эксплойта и уязвимости |
Переполнение буфера |
Подготовка шеллкода |
|
heap_over ow.c (отладка) |
|
||
$ |
gcc -g heap_overflow.c -o heap_overflow |
|
|
$ |
gdb --args ./heap_overflow `python -c 'print("a"*33)'` |
(gdb) r
Starting program: heap_overflow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
*** Error in `heap_overflow': free(): invalid next size (fast): 0x0000000000601010 ***
Program received signal SIGABRT, Aborted.
(gdb) bt #0 ...
...
#4 0x00007ffff7aaa696 in _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3840
#5 0x000000000040077b in main (argc=2, argv=0x7fffffffe5a8) at heap_overflow.c:20
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
30/40 |
Понятие эксплойта и уязвимости |
Переполнение буфера |
Подготовка шеллкода |
||||
|
vuln_stack.c (уязвимая программа) |
|||||
1 |
# include < stdio .h > |
|
./vuln_stack \ |
|||
2 |
# include < string .h > |
|
`python -c 'print "a"*110'` |
|||
3 |
# include < stdlib .h > |
|
addr buf: 0xffffd5dc |
|||
4 void |
foo ( const char *v) |
|
addr &v: 0xffffd650 |
|||
5 |
{ |
|
|
|
buf: aaa... |
|
6 |
char buf [100]; |
|
Segmentation fault |
|||
7 |
printf (" addr buf: %p\n", buf ); |
|
|
|||
8 |
printf (" addr &v: %p\n", |
&v); |
Разница между адресами |
|||
9 |
strcpy (buf , |
v); |
|
переменных &v и buf: |
||
10 |
printf ("buf: %s\n", buf ); |
0xffffd650-0xffffd5dc=116 |
||||
11 |
} |
|
|
|
|
|
12 int |
main (int |
argc , char |
* argv []) |
|
|
|
13 |
{ |
|
|
|
|
|
14 |
if |
( argc != |
2) exit (1); |
|
|
|
15foo( argv [1]);
16return 0;
17}
Отключение механизма ASLR
sudo sh -c 'echo 0 > /proc/sys/kernel/randomize_va_space '
Компиляция с отключенной опцией защиты стека
gcc -g -m32 -fno-stack-protector \
-z execstack vuln_stack.c -o vuln_stack
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
31/40 |
Понятие эксплойта и уязвимости |
Переполнение буфера |
Подготовка шеллкода |
|
|
|
objdump vuln_stack
objdump -d -M intel vuln_stack | grep -A 5 '<foo>:'
0804845b <foo>: |
mov |
ebp,esp |
3 |
|
||
804845c: |
89 |
e5 |
функции |
|||
804845b: |
55 |
|
push |
ebp |
7 |
|
8048461: |
83 |
ec 08 |
sub |
esp,0x8 |
Пролог |
|
804845e: |
83 |
ec 78 |
sub |
esp,0x78 |
7 |
|
8048464: |
8d 45 94 |
|
eax,[ebp-5 |
|
||
|
|
|
lea |
|
0x6c] |
|
... |
|
|
|
|
|
|
80484b1: |
c3 |
|
ret |
Эпилог функции |
||
|
ret |
|
|
|||
80484b0: |
c9 |
|
leave |
mov esp, ebp |
|
|
|
|
|
|
pop ebp |
|
|
0x6c=108 байт размер массива buf в стеке 0x d5dc адрес массива в стеке
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
32/40 |