Назад | Перейти на главную страницу

Запись случайных данных в случайные сектора жесткого диска

У меня есть жесткий диск, который вышел из строя, и перед тем, как отправить его в RMA, я хочу стереть с него как можно больше данных. Я пробовал использовать утилиты Windows, а также сделал dd of / dev / random. Проблема в том, что я не могу дождаться завершения любого из этих решений, поскольку причина RMA в том, что он пишет с максимальной скоростью 1 МБ / с. На один проход жесткого диска емкостью 500 ГБ потребуется более 140 часов.

Я искал утилиту (или даже сценарий bash в Linux), которая выбирала бы сектора случайным образом и записывала случайные данные (или даже нули) в эти сектора. Я надеюсь, что если я запущу это в течение 24 часов, это сотрет около 80 ГБ данных. Поскольку он будет выбран случайным образом, все большие файлы будет невозможно восстановить, а более мелкие будут либо стерты, либо будут отсутствовать фрагменты, либо, возможно, будут восстановлены. К сожалению, это оптимальное решение для меня на данный момент.

РЕШЕНИЕ

Благодаря "evildead" я смог получить много данных на диске, которые случайным образом заполнялись мусором из / dev / urandom. Сценарий bash на случай, если он кому-то понадобится, приведен ниже:

#!/bin/bash
while (true); do
    randnum=${RANDOM}${RANDOM}
    number=$((10#$randnum%976773168))
    echo -e $number >> progress.txt
    dd if=/dev/urandom of=/dev/sdx1 skip=$number count=1
done

Вам нужно будет заменить 976773168 на количество блоков на вашем диске. Первоначально я пробовал $ RANDOM в bash, но это всего лишь 16-битное целое число и, следовательно, всего 32 КБ. Поскольку мне нужно число, превышающее 900 миллионов, я объединил два значения $ RANDOM, поэтому, например, если мои случайные числа равны 22861 и 11111, я получаю 2286111111, а затем подгоняя его под размер моего блока, я получаю довольно случайное значение в моем диапазоне. У него нет идеальной энтропии, но опять же, что на самом деле случайное на компьютере? ;) 10 # присутствует в случае, если первое случайное число равно 0, оно заставляет bash использовать базу 10, а не базу 8, что он и использует, если считает, что число является восьмеричным (ведущим нулем). Я также записываю случайные числа в файл для последующего анализа, чтобы увидеть, какой был разброс. Если вам это не нужно, вы можете просто вынуть

echo -e $number >> progress.txt

и он будет работать нормально. Также не забудьте заменить sdx1 с фактическим диском или разделом, с которым вы хотите работать. Я надеюсь, что это было полезно для кого-то, я знаю, что это было действительно полезно для меня.

вы можете использовать shellscript в сочетании с dd.

например

 while (true); do
   number=$((($RANDOM * 32768 + $RANDOM)))
   dd if=/dev/urandom of=/dev/sdx1 seek=$number count=1
 done

Вам нужно только изменить число, которое генерируется из $ RANDOM, чтобы оно соответствовало вашим блокам.

РЕДАКТИРОВАТЬ 2016: Обратите внимание, старое решение было неверным. Поскольку мы хотим перезаписать байт в случайной позиции в выходном потоке, мы должны использовать поиск вместо пропуска, как упоминалось в комментариях.

Моя система не сломана и пишет с /dev/random составляет около 650 Кбит / с. Писать из /dev/urandom составляет 7 Кбит / с.

Я работал над этой проблемой для себя, и для чисто bash-решения вы должны быть реалистами в отношении вашей цели, потому что, если ваша цель не состоит в том, чтобы научиться делать это в bash, потому что цель состоит в том, чтобы делать это ВСЕ в bash, цель Безопасную очистку диска лучше выполнять другими способами, хотя в этом решении полезен bash.

Алгоритм evildead bash для случайного выбора, куда dd будет записывать на диск, работает, однако / dev / urandom значительно медленнее, чем / dev / random, и я думаю, что менее безопасно забивать диск кусками случайных данных, и я думаю, что это будет труднее получить данные с очищенного диска, если вы быстро сделаете два прохода, записав на него единицы, а затем нули.

Для себя записал на диск:

tr '\0' '\377' < /dev/zero | pv > /dev/sdz

затем я записал нули на диск с помощью:

pv < /dev/zero > /dev/sdz

Обратите внимание на использование pv. Это отличная программа, хотя вам придется установить ее в большинстве систем. Легко найти, похоже, не имеет справочной страницы, но она есть в сети. Он показывает процесс передачи данных по каналу, а в некоторых программах вы даже можете настроить его останов после передачи определенного количества данных.

ТОЛЬКО потому, что меня раздражало то, что никакое решение bash не будет записывать случайные числа так быстро, как это делают любые из этих записей выше, я написал небольшую программу на C под названием svrandom для БЫСТРОГО генерирования случайных чисел, которую я вызвал из bash следующим образом:

while :; do ./svrandom; done  | pv > /dev/sdz

В моей системе, которая заполняет диск / dev / sdz случайными числами так же быстро, как и запись / dev / zero. Цель очистки диска случайными числами достигнута, и в решении использовался bash.

/* svrandom
a small program from shadowvision.com September 2015 to generate strings of random numbers.
the default setting of 10000000 gives about 453 megs, adjust as 
needed */ 

#include <stdio.h>
#include <stdlib.h>
int main()
{
int r,a,b;
 /* adjust following number as needed to suit your string length */
 for(a=0;a<10000000;a++)
 {
 for(b=0;b<5;b++)
 {
 r=rand();
 printf("%d",r);
 }

 }
 return(0);
}

В источнике я упоминаю, что вы можете контролировать длину строки случайных чисел, регулируя число. Если вы вызываете его из цикла while, вам не придется, хотя в конце каждого цикла может быть возврат каретки, но если вам нужна одна непрерывная строка только из программы, вам придется изменить номер.

отрезать! оглядываясь, я нашел это решение на https://superuser.com/questions/19326/how-to-wipe-free-disk-space-in-linux

openssl enc -aes-256-ctr -pass pass: "$ (dd if = / dev / urandom bs = 128 count = 1 2> / dev / null | base64)" -nosalt </ dev / zero | pv> / dev / SD {x}

и как там парень сказал, я не могу поверить, насколько это быстро. Он пишет на диск быстрее, чем я думал максимальная скорость записи дисков.

Мне кажется, что эта команда использует openssl для шифрования строки нулей из / dev / zero с использованием / dev / urandom в качестве начального числа, но я не уверен на 100%. мое решение с программой C для записи случайных чисел записывает в мою систему со скоростью 82 Мбит / с, это решение openssl пишет со скоростью 100 Мбит / с. Вот Это Да!

Если у вас есть мощный магнит, вы можете протереть его физически.

Я разбираю старые, мертвые жесткие диски и достаю магниты звуковой катушки из узла позиционирования головки. Это редкоземельные магниты, и для типичного 3,5-дюймового накопителя они достаточно мощные, чтобы стереть достаточное количество следящих дорожек на жестком диске, поэтому его нельзя будет использовать.

Так или иначе, возьмите магнит, протрите его взад и вперед по верхней крышке накопителя, и меньше чем через минуту у вас будет мертвый привод. Поскольку это все равно RMA, им все равно.

Лучшее программное обеспечение, которое автоматизирует этот процесс, - это Darik's Boot and Nuke (также известное как DBAN).

Это загрузочный компакт-диск с широким набором механизмов очистки диска, в зависимости от степени агрессивности (и времени, необходимого для очистки диска).

Это доступно из http://www.dban.org/

Спасибо за решение на высоте!
Поскольку мне не разрешено комментировать ответ со сценарием, я должен сам добавить крошечное улучшение.
Я просто немного настроил его для большего удобства, так что нужно только определить устройство. fdisk предоставит количество секторов:

#!/bin/bash
# add device to mangle
# example: 
# disk=/dev/sde
disk=
# get number of sectors
sectors=$(fdisk $disk -l| head -1| awk '{print $7}')
# run
while (true); do
    randnum=${RANDOM}${RANDOM}
    number=$((10#$randnum%$sectors))
    echo -e $number >> progress.txt
    dd if=/dev/urandom of=$disk skip=$number count=1
done

Скрипт Python 3 с:

  • осведомленность о размере блочного устройства
  • проверка размера блочного устройства путем записи байтов на границах
  • гарантия уничтожения первого и последнего байта
  • случайные данные перезаписываются
  • случайное смещение
  • случайные размеры партий

Если вам нужен Python 2, то его будет легко скрыть, используя "" .format () вместо f "" строк.

import subprocess
import random


REPS = 100
CRASH_ON_FIRST_FAILURE = True  # change to False if the device is not reliable

def run(*cmd, assert_returncode=None, print_stderr=False):
    completed = subprocess.run(cmd, capture_output=True)
    if assert_returncode:
        assert completed.returncode == assert_returncode, f"Unexpected return code (got={assert_returncode}, expected={assert_returncode})"
    if print_stderr:
        print(str(completed.stderr))
    return completed.stdout


def part_size(part):
    """
    Partition size in bytes
    """
    return int(run("blockdev", "--getsize64", part))


def destroy_block(part, bs, seek, assert_returncode=None, print_result=False):
    run(
        "dd", f"bs={bs}", "if=/dev/urandom", f"of={part}", f"seek={seek}", "count=1",
        assert_returncode=assert_returncode
    )
    if print_result:
        print(f"Destroyed bs={bs} of={part} seek={seek}")


def destory_random_block(part, part_size, bs):
    """
    bs=1 destroys bytes sized block
    bs=1024 destroys KB sized block
    etc.
    """
    seek_max = int(part_size / bs)
    seek = random.randint(0, seek_max)
    if CRASH_ON_FIRST_FAILURE:
        assert_returncode = 0
    else:
        assert_returncode = None
    destroy_block(part, bs=bs, seek=seek, assert_returncode=assert_returncode)


def destroy(part):
    """
    part - partition to be destroyed
    """
    s = part_size(part)
    destroy_block(part, bs=1, seek=s, assert_returncode=1)  # "test" destroying 1 byte at size boundary, should fail
    destroy_block(part, bs=1, seek=(s - 1), assert_returncode=0, print_result=True)  # "test" destroying 1 bytes before boundary, should pass
    destroy_block(part, bs=1, seek=0, assert_returncode=0, print_result=True)  # "test" destroying first 1 byte
    while True:
        print(f"Destroying {REPS} byte-sized blocks")
        for _ in range(REPS):
            destory_random_block(part, part_size=s, bs=1)
        print(f"Destroying {REPS} KB-sized blocks")
        for _ in range(REPS):
            destory_random_block(part, part_size=s, bs=1024)
        print(f"Destroying {REPS} MB-sized blocks")
        for _ in range(REPS):
            destory_random_block(part, part_size=s, bs=(1024 * 1024))
        rand_size = random.randint(1, 1024 * 1024)
        print(f"Destroying {REPS} {rand_size}-sized blocks")
        for _ in range(REPS):
            destory_random_block(part, part_size=s, bs=rand_size)
        print("\nRise and repeat\n\n")


destroy("/dev/sdb1")



Пример вывода:

# "test" destroying 1 byte at size boundary, should fail
# "test" destroying 1 bytes before boundary, should pass
Destroyed bs=1 of=/dev/sdb1 seek=10736369663
# "test" destroying first 1 byte
Destroyed bs=1 of=/dev/sdb1 seek=0

Destroying 100 byte-sized blocks
Destroying 100 KB-sized blocks
Destroying 100 MB-sized blocks
Destroying 100 875091-sized blocks

Rise and repeat


Destroying 100 byte-sized blocks
Destroying 100 KB-sized blocks
Destroying 100 MB-sized blocks
Destroying 100 1028370-sized blocks

Rise and repeat

Бежать:

  1. Скопируйте исходный код все, кроме последней строки
  2. На хосте жертвы войдите как корень
  3. На хосте жертвы запустите: python3
  4. Вставьте код из шага 1
  5. Тип destroy("/dev/XYZ") и верните ключ дважды
  6. Через несколько часов нажмите Ctrl-c

ПРИМЕЧАНИЕ. «/ Dev / XYZ» - это имя раздела, в котором будут потеряны данные.

ВНИМАНИЕ! Остерегайтесь ошибок типа «жирный палец». Данные исчезнут навсегда, поэтому еще раз проверьте, какой раздел вы вводите.

ПРЕДУПРЕЖДЕНИЕ. Выполнение этого сценария в течение нескольких дней в облачных службах может стоить, если вы платите за IOP записи на диск.

В dban вариант - правильный ответ на эту проблему.

Запись "случайных" данных из / dev / random вызовет проблемы в большинстве систем, потому что вы исчерпаете энтропию в системе и закончите запись данных очень медленно.

Почти так же "случайно", как в / dev / random - это зашифровать строку нулей с помощью случайной парольной фразы. Для этого вы можете использовать dd и openssl, и это позволяет вам уничтожать диски так быстро, как система может записывать на диск (вместо ожидания / dev / random). Вы сможете запустить это 3-5 раз за то же время, что и что-то, что просто dding из / dev / random.

dd if=/dev/zero | openssl des > /dev/hda13