Лекция 2
.pdfПонятие эксплойта и уязвимости |
Переполнение буфера |
Подготовка шеллкода |
|
|
|
Примеры программных ошибок (8)
1985 1987 гг. некорректное функционирование аппарата лучевой терапии Therac-25. Причина наличие состояния гонки в обновленной версии. Последствия передозировка радиацией.
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
15/40 |
Понятие эксплойта и уязвимости |
Переполнение буфера |
Подготовка шеллкода |
|
|
|
Примеры программных ошибок (9)
1988 1996 гг. уязвимость систем на базе аутентификации Kerberos. Причина ошибка в генераторе случайных чисел Kerberos. Последствия возможный взлом систем.
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
16/40 |
Понятие эксплойта и уязвимости |
Переполнение буфера |
Подготовка шеллкода |
|
|
|
Примеры программных ошибок (10)
1995 1996 гг. ping of death. Причина отсутствие проверки размера собираемого ICMP-пакета. Последствия переполнение сетевого стека, отказ в обслуживании.
PoD
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
17/40 |
Понятие эксплойта и уязвимости |
Переполнение буфера |
Подготовка шеллкода |
|
|
|
Переполнение буфера
Âèäû: В стеке
В секции .bss  êó÷å
Последствия:
Непредсказуемое поведение программы
XЗатирание переменных
XАварийное завершение программы
Возможность выполнения произвольного кода
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
18/40 |
Понятие эксплойта и уязвимости |
Переполнение буфера |
Подготовка шеллкода |
|
|
|
buf_over ow.c (./buf_over ow 2)
1 |
# include |
< stdio .h > |
2 |
# include < string .h > |
|
3 |
# include < stdlib .h > |
|
4 |
# include < stdint .h > |
|
5 void test ( int n) { |
||
6 |
printf ("n: %d\n", n); |
|
7 |
# pragma pack ( push ) |
|
8 |
# pragma |
pack (1) |
9 |
struct |
{ |
10uint16_t a;
11uint32_t b;
12} v = {1, 2};
13# pragma pack (pop)
14printf ("&v.b - &v.a: %d\n",
15( char *)&v.b - ( char *)&v.a);
16printf ("val v.a: %d\n", v.a);
17printf ("val v.b: %d\n", v.b);
18memset (&v.a, 0, n);
19printf ("val v.a: %d\n", v.a);
20printf ("val v.b: %d\n", v.b);
21}
22 int |
main (int |
argc , char |
* argv []) { |
23 if |
( argc == |
1) return |
1; |
24test ( atoi ( argv [1]));
25return 0;
26}
0x01 0x00 0x02 0x00 0x00 0x00
ab
memset(&v.a, 0, 2);
0x00 0x00 0x02 0x00 0x00 0x00
ab
$ gcc -g buf_overflow.c -o \ buf_overflow
$./buf_overflow 2
n:2
&v.b - &v.a: 2 val v.a: 1 val v.b: 2 val v.a: 0 val v.b: 2
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
19/40 |
Понятие эксплойта и уязвимости |
Переполнение буфера |
Подготовка шеллкода |
|
|
|
buf_over ow.c (отладка ./buf_over ow 2)
$ gdb -q ./buf_overflow
Reading symbols from ./buf_overflow...done.
(gdb) b 18
Breakpoint 1 at 0x4005ee: file buf_overflow.c, line 18.
(gdb) r 2
Starting program: ...
Breakpoint 1, test (n=2) 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 = 2
(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 = 2
(gdb) p n
$6 = 2
(gdb) x $rbp 0x7fffffffe110: 0xffffe130
(gdb) fin
Run till exit from #0 test (n=2) at buf_overflow.c:19
...
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
20/40 |
Понятие эксплойта и уязвимости |
Переполнение буфера |
Подготовка шеллкода |
|
|
|
buf_over ow.c (./buf_over ow 3)
1 |
# include |
< stdio .h > |
2 |
# include < string .h > |
|
3 |
# include < stdlib .h > |
|
4 |
# include < stdint .h > |
|
5 void test ( int n) { |
||
6 |
printf ("n: %d\n", n); |
|
7 |
# pragma pack ( push ) |
|
8 |
# pragma |
pack (1) |
9 |
struct |
{ |
10uint16_t a;
11uint32_t b;
12} v = {1, 2};
13# pragma pack (pop)
14printf ("&v.b - &v.a: %d\n",
15( char *)&v.b - ( char *)&v.a);
16printf ("val v.a: %d\n", v.a);
17printf ("val v.b: %d\n", v.b);
18memset (&v.a, 0, n);
19printf ("val v.a: %d\n", v.a);
20printf ("val v.b: %d\n", v.b);
21}
22 int |
main (int |
argc , char |
* argv []) { |
23 if |
( argc == |
1) return |
1; |
24test ( atoi ( argv [1]));
25return 0;
26}
0x01 0x00 0x02 0x00 0x00 0x00
ab
memset(&v.a, 0, 3);
0x00 0x00 0x00 0x00 0x00 0x00
ab
$ gcc -g buf_overflow.c -o \ buf_overflow
$./buf_overflow 3
n:3
&v.b - &v.a: 2 val v.a: 1 val v.b: 2 val v.a: 0 val v.b: 0
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
21/40 |
Понятие эксплойта и уязвимости |
Переполнение буфера |
Подготовка шеллкода |
|
|
|
buf_over ow.c (отладка ./buf_over ow 3)
$ 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 3
Starting program: ...
Breakpoint 1, test (n=3) 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 = 3
(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 = 3
(gdb) x $rbp 0x7fffffffe110: 0xffffe130
(gdb) fin
Run till exit from #0 test (n=3) at buf_overflow.c:19
...
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
22/40 |
Понятие эксплойта и уязвимости |
Переполнение буфера |
Подготовка шеллкода |
|
|
|
buf_over ow.c (отладка ./buf_over ow 3)
$ 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 3
Starting program: ...
Breakpoint 1, test (n=3) 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 = 3 |
|
||
(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 = 3 |
|
||
(gdb) |
x $rbp |
|
|
0x7fffffffe110: 0xffffe130 |
|
||
(gdb) |
fin |
|
Run till exit from #0 test (n=3) at buf_overflow.c:19
...
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
22/40 |
Понятие эксплойта и уязвимости |
Переполнение буфера |
Подготовка шеллкода |
|
|
|
buf_over ow.c (./buf_over ow 100)
1 |
# include |
< stdio .h > |
2 |
# include < string .h > |
|
3 |
# include < stdlib .h > |
|
4 |
# include < stdint .h > |
|
5 void test ( int n) { |
||
6 |
printf ("n: %d\n", n); |
|
7 |
# pragma pack ( push ) |
|
8 |
# pragma |
pack (1) |
9 |
struct |
{ |
10uint16_t a;
11uint32_t b;
12} v = {1, 2};
13# pragma pack (pop)
14printf ("&v.b - &v.a: %d\n",
15( char *)&v.b - ( char *)&v.a);
16printf ("val v.a: %d\n", v.a);
17printf ("val v.b: %d\n", v.b);
18memset (&v.a, 0, n);
19printf ("val v.a: %d\n", v.a);
20printf ("val v.b: %d\n", v.b);
21}
22 int |
main (int |
argc , char |
* argv []) { |
23 if |
( argc == |
1) return |
1; |
24test ( atoi ( argv [1]));
25return 0;
26}
0x01 0x00 0x02 0x00 0x00 0x00
ab
memset(&v.a, 0, 100);
0x00 0x00 0x00 0x00 0x00 0x00
ab
$gcc -g buf_overflow.c -o \ buf_overflow
$./buf_overflow 100
n:100
&v.b - &v.a: 2 val v.a: 1 val v.b: 2 val v.a: 0
val v.b: 0
Segmentation fault
Браницкий А.А., СПбГУТ |
Лекция 2, Санкт-Петербург, 2021 |
23/40 |