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

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

Я искал утилиту (или даже скрипт 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-битное int и, следовательно, только 32 КБ. Поскольку мне нужно было число, превышающее 900 миллионов, я объединил два значения $RANDOM, поэтому, например, если мои случайные числа равны 22861 и 11 111, я получаю 2 286 111 111, а затем подгоняя его под размер моего блока, я получаю довольно случайное значение в моем диапазоне. У него нет идеальной энтропии, но опять же, что действительно случайно на компьютере?;) 10# существует в случае, если первое случайное число равно 0, оно заставляет bash использовать основание 10, а не основание 8, что и используется, если он считает, что число является восьмеричным (ведущий ноль). Я также записываю случайные числа в файл для последующего анализа, чтобы узнать, каков был спред. Если вам это не нужно, вы можете просто вынуть

echo -e $number >> progress.txt

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

6 ответов

Решение

Вы можете использовать скрипт в сочетании с дд.

например

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

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

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

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

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

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

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

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

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

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

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

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

Затем я записал нули на диск:

pv < /dev/zero > /dev/sdz

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

ТОЛЬКО из-за того, что меня раздражало то, что ни одно решение bash не будет писать случайные числа так быстро, как это делала бы любая из приведенных выше записей, я написал небольшую программу на C, называемую svrandom, для генерации случайных чисел QUICKLY, которую я вызвал из 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/ сд {х}

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

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

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

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

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

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

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

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

Спасибо за решение сверху!
Поскольку мне не разрешено комментировать ответ сценарием, я должен сам добавить крошечное улучшение.
Я просто немного настроил его для большего удобства, чтобы определить устройство. 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

Опция dban является правильным ответом на эту проблему.

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

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

dd if=/dev/zero | openssl des > /dev/hda13
Другие вопросы по тегам