viernes, 17 de octubre de 2008

Bios, passwords y otras hierbas

Bueno aqui publico como se resetean los bios , no exactamente es todo código sino mas bien metodos, si bien tambien posteare algunos codigos implementados en c, Pascal, Delphi, Ensamblador y otros lenguajes.

Bueno aqui va:
Cómo desactivar la contraseña de una BIOS

Hay tres formas de desactivar una contraseña. Dos de estas formas son relativamente sencillas de llevar a cabo:

La primera consiste en abrir la CPU y quitar la pila de la placa base, esperar de 3 a 5 segundos y volverla a colocar. Al quitar la pila los datos de la CMOS se pierden, incluida la contraseña. La mayoría de las placas base incluyen unos jumpers que permiten resetear la CMOS sin necesidad de extraer la pila.

La segunda forma consiste en eliminar la contraseña provocando un error en la BIOS del sistema. Cuando se guarda la configuración de una BIOS, esta (casi todas las versiones lo hacen) genera un CRC en la que intervienen los parámetros de dicha configuración. Cuando se accede a la BIOS, dicho programa realiza de nuevo la operación del CRC y lo compara con el resultado que tenía previamente almacenado. De esta forma verifica que no se ha cambiado ningún dato de manera intencionada o por error. Si así sucediera, la BIOS reinicia los datos de la CMOS y con ellos el password, el cual deja de estar activo y permite el acceso a la BIOS.

El problema de estas dos formas de desactivación de un password reside en que en los dos casos se pierde la configuración del sistema.

La tercera forma es específica, mediante programación.


Codificación de un password de la BIOS Award

El algoritmo en cuestión es bastante deficiente y el resultado de dicho algoritmo es un dato de tipo word sin signo (2 bytes) que se guarda en una posición de la CMOS que puede variar con respecto a la versión de esta. Algunas versiones de esta BIOS guardan dos passwords pero usan el mismo método de codificación.

La codificación es bien simple. Consiste en sumar el código ASCII de cada una de las letras que forman el password, pero antes de pasar a sumar la siguiente letra, multiplica el resultado por 4. Es decir, coge una letra, lo multiplica por 4, le suma la segunda, multiplica este resultado por 4 y así hasta sumar la última letra del password (máximo 8 caracteres). Como he dicho, el resultado se almacena en 2 bytes, el número entero sin signo más alto que se puede representar en 2 bytes es 65535. Si el resultado del algoritmo es mayor a 65535, se divide ese resultado entre 65536. Toma el resultado entero obtenido de esa división y lo suma al resto de dicha división. Ese dato obtenido será el entero sin signo (2 bytes) que se almacenará en la CMOS.

La verdad es que a nivel de código de máquina es más sencillo. Trabaja sobre un registro de tipo word, tamaño de dos bytes. Realiza la suma del ASCII de cada letra y hace un desplazamiento de bits dos posiciones hacia la izquierda. Al final, si el flag de acarreo está activado, es decir, si en cualquiera de los desplazamientos a la izquierda, se escapa algún bit, le suma al resultado un 1.

Por ejemplo... Si el password en cuestión es Dragon
El código ASCII de estas letras es: D = 68 r =114 a = 97 g =103 o = 111 n =110
Teniendo el cuenta que inicialmente el resultado = 0, sumamos y multiplicamos por 4 cada resultado:
(4 * 68) + 114 = 386
(4 * 386) + 97 = 1641
(4 * 1641) + 103 = 6667
(4 * 6667) + 111 = 26779
(4 * 26779) + 110 = 107226

Lo que hay que hacer en este caso es dividir 107226 entre 65536, quedarnos con el resto, y al resto sumarle el nº de múltiplos de 65536 obtenido:
107226 / 65536 = 1 , resto = 41690 >> 41690 + 1 = 41691.

Para no complicarse la existencia, como las operaciones de suma y multiplicación no van a dar un resultado cuyo tamaño en memoria sea superior a 3 bytes, no sería necesario hacer divisiones. Bastaría con restar al nº obtenido 65535, va a dar lo mismo 107226 - 65535 = 41691. En definitiva, es truncar el resultado si es mayor de 65535.

El resultado es 41691 que separado en 2 bytes es 162 y 219 ((162 * 256) + 219).

Este algoritmo es deficiente porque este resultado se puede obtener con mas de una (mas de 200000) combinaciones de caracteres diferentes.

Sabiendo esto, es fácil implementar un programa que codifique o descodifique dicho password para poder acceder así a cualquier BIOS. De todas formas también se puede implementar un programa que descodifique el password por fuerza bruta, pero eso... es otra historia ^_^.



Cómo acceder a la CMOS

A la CMOS de cualquier placa base (PC) se accede mediante 2 puertos físicos:

El puerto 112 (70h) de escritura, en el que se indica la dirección o posición del dato que se va a leer o escribir en la CMOS. El tamaño máximo de una CMOS suele ser de 256 bytes y cada BIOS usa un nº determinado de estos bytes, normalmente hasta 128. Luego el rango de escritura en ese puerto va de 0 a 255.
El puerto 113 (71h) de lectura/escritura en el que se lee o escribe el dato de la posición indicada en el puerto 112.


Códigos de ejemplo para resetear la CMOS ya sea Award, Ami Bios o la que sea

Para causar un error de CRC en la BIOS solo es necesario cambiar uno de los datos que intervienen el la operación de dicho CRC o el resultado en si. Si no se sabe cuál es la posición en la que se encuentra dicho resultado o los datos que intervienen en esa verificación lo más seguro es reescribir toda la CMOS con un dato aleatorio. El siguiente código logra nuestro propósito.

Lenguaje C++

#pragma hdrstop
#include
#include
#include

#pragma argsused
int main(int argc, char **argv)
{
char buffer[83];
char *p;

printf("Programado por Emiliano Traba");
buffer[0] = 1;
p = cgets(buffer);
asm
{
mov dx, 70h
mov al, 00000
out dx, al
int 21h
}
}

Lenguaje Pascal/Delphi

procedure ResetCMOS;
var intPos: integer;
begin
for intPos := 0 to255 do
begin
port[112] := intPos;
port[113] := 1;
end;
end

Lenguaje Ensamblador

MOV CX, 00FFh;
@Bucle:
MOV DX, 70h;
MOV AX, CX;
OUT DX, AX;
MOV DX, 71h;
MOV AX, 1h;
OUT DX, AX;
LOOP @Bucle;

o bien

mov dx, 070h
mov al, 02Eh
out dx, al
inc dx
xor al, al
out dx, al

Con el debug de DOS

* debug
* o 70 2E
* o 71 FF
* Q

o bien

* debug
* o 70 17
* o 71 17
* Q

Con QBasic o Basic

* 10 OUT &H70,17
* 20 OUT &H71,0

o bien

* OUT &H70,&H17 UT &H71,&H17


Una vez ejecutado ese código y reiniciado el ordenador la BIOS presentará un mensaje de error de CRC, reseteará los datos de la CMOS y entrará automáticamente en la BIOS para configurar de nuevo el sistema. En ese momento el sistema ya es nuestro. Podemos reactivar disquetera, anular otros dispositivos etc...



Códigos de ejemplo sobre codificación del pass de una BIOS Award y AmiBios

Con unos mínimos conocimientos en programación, a partir de la descripción dada sobre la codificación de un password en una BIOS Award podemos generar un código que haga dicha función. El propósito de este código sería devolver un entero a partir de un password que nosotros tecleemos. Damos por validado que ese password no es mayor de 8 letras.

Código en Pascal para bios Award:

function EncodePass(strPass: string): integer;
var intPos: integer;
LngRes: longint;
begin
intPos := 1;
lngRes := 0;
while intPos <= ord(strPass[0]) do
begin
lngRes := (lngRes * 4) + ord(strPass[intPos]);
inc(intPos);
end;
if lngRes > 65535 then
lngRes := (lngRes div 65536) + (lngRes mod 65536);
Result := lngRes;
end;

El resultado de esta función es un entero de 2 bytes. Para separar el resultado de la función en 2 bytes no hay mas que dividir ese dato por 256, quedarnos con el número de múltiplos obtenido en esa división y su resto. De tal forma que un entero esta compuesto por (múltiplos*256)+resto)

Nota: Delphi dispone de las funciones Hi() y Lo() para separar ambos bytes.


Una vez resuelta esta función, sólo quedaría saber en qué posición de la CMOS se guarda ese resultado, observar si guarda primero el byte de mayor peso o biceversa y hallar de qué manera afecta ese dato en la operación de CRC para generar un CRC válido. Esta operación es sencilla y no tiene mas complicación que realizar comparaciones de los passwords introducidos en la BIOS con los datos modificados en la CMOS.



Descodificación del pass de una BIOS Award

Hay dos formas de conseguir el password de una Award. Directamente por ingeniería inversa, o por fuerza bruta. A continuación se detallan las dos formas.

Por Fuerza bruta:

Este método consiste en realizar constantemente comparaciones de una cadena literal generada por software y codificada (ver función EncodePass) con el resultado existente en la CMOS, hasta encontrar aquella cadena cuya codificación coincida con dicho resultado. No necesariamente debe terminar cuando encuentre una cadena literal válida. Se puede continuar el escaneo para observar que el número de contraseñas válidas es inmenso, demostrando la deficiencia del algoritmo empleado por estas BIOS. Como contrapunto señalar que este método es bastante lento.

El siguiente ejemplo muestra una función a la que se le pasa el entero que hay en la CMOS (intCmos) y devuelve solamente una cadena válida, si la hay:


Lenguaje Delphi:

function GetPass(intCmos: integer): string;
var arrCadena: array[0..7] of char;
intPos: byte;
bfound, bOk, bTop: Boolean;
strResultado: string;
begin
bFound := False;
bTop := False;
strResultado := '';
strPCopy(arrCadena, ' '); // Llenamos el buffer con espacios
while (not bFound) and (not bTop) do
begin
intPos := 0;
bOk := False;
repeat // Generamos cadena literal
if ord(arrCadena[intPos]) = 255 then
begin
arrCadena[intPos] := chr(32);
inc(intPos);
if intPos = 8 then bTop := True; // Todas las cadenas evaluadas...
end else
begin
arrCadena[intPos] := chr(ord(arrCadena[intPos]) + 1);
bOK := True;
end;
until bOk or bTop;
if bOK then
begin
bFound := (EncodePass(string(arrCadena)) = intCmos);
if bFound then strResultado := string(arrCadena);
end;
end;
Result := strResultado;
end;



Por ingeniería inversa:

Este método consiste en tratar de conseguir un password válido realizando para ello el proceso contrario a la operación de codificación (y = x + 2 >> x = y - 2). Para ello lo que se trata de hacer es restar del dato de la CMOS un valor, dividirlo entre 4, y así sucesivamente procurando que el ultimo resto sea mayor de 32 y menor de 122, asegurando así que ese password no contiene caracteres especiales. Si el último valor no se encuentra en ese rango hay que retroceder y probar con otro valor. Así hasta encontrar un password válido, que no tiene por qué ser el introducido en un principio (de hecho, es improbable que lo sea). La ventaja del método de ingeniería inversa sobre la fuerza bruta es indudable. El resultado es instantáneo.



En el siguiente código pasamos el entero que contiene la CMOS y la función devolverá un password válido generado por el método de ingeniería inversa. Este código no verifica la existencia de caracteres especiales en el password generado pero no es difícil implementarlo.



function GetPassAward(intCmos:integer): string;
var strTexto: string;
intLetra: integer;
begin
strTexto := '';
while intCmos > 123 do
begin
intLetra := 122;
while ((intCmos - intLetra) mod 4) <> 0 do
dec (intLetra);
strTexto := chr(intLetra) + strTexto;
intCmos := (intCmos - intLetra) div 4;
end;
strTexto := chr(intCmos) + strTexto;
Result := strTexto;
end;



Notas:

Las BIOS AWARD dependiendo de la versión, guardan 1 o 2 contraseñas.

La primera contraseña se encuentra en las posiciones 28 (1Ch) y 29 (1Dh) de la CMOS, siendo 1Ch el byte menos significativo.

El CRC para la primera contraseña consiste en sumar los bytes desde la posición 16 (10h) a la 45 (2Dh) inclusive de la CMOS y el resultado de dos bytes los guarda en las posiciones 46 (2Eh) y 47 (2Fh), siendo 2Fh el byte menos significativo.

El byte de la posición 17 (11h) de la CMOS (concretamente los dos primeros bits) contiene la información que indica que el password está activado (bits a 1) o desactivado (bits a 0). Para ponerlos a 0 solo habría que aplicar la máscara AND 0x11111100 (FCh) a dicho byte.

La segunda contraseña se encuentra en las posiciones 96 (60h) y 97 (61h) de la CMOS, siendo 60h el byte menos significativo. El CRC y los bits de des/activación del password no los he comprobado.

Decodificación del pass de una bios Ami


Lenguaje QBasic:

seed = reg(0) AND &HF0

PRINT "Calculating."
FOR count = 1 TO 6
PRINT ".";
bioschar = reg(count)
decchar = 0
IF bioschar <> 0 THEN
DO
decchar = decchar + 1
pass = 0
FOR bit = 0 TO 7
IF (&HC3 AND 2 ^ bit) = 2 ^ bit AND (seed AND 2 ^ bit) = 2 ^ bit THEN
pass = (pass + 1) MOD 2
END IF
NEXT bit
seed = INT(seed / 2) + pass * 128
LOOP WHILE seed <> bioschar
bpass$ = bpass$ + CHR$(decchar)
ELSE
count = 6
END IF
NEXT count


Award:
* 01322222
* 1EAAh
* 256256
* 589589
* 589721
* ?award
* admin
* alfarome
* aLLy
* aPAf
* award
* award_?
* award.sw
* AWARD SW
* AWARD_SW
* AWARD_PW
* award_ps
* AWARD?SW
* awkward
* BIOS
* bios*
* biostar
* biosstar
* CONCAT
* CONDO
* condo
* djonet
* efmukl
* g6PJ
* h6BB
* HELGA-S
* HEWITT RAND
* HLT
* j09F
* j256
* j262
* j322
* j64
* lkw peter
* lkwpeter
* PASSWORD
* SER
* setup
* SKY_FOX
* SWITCHES_SW
* Sxyz
* SZYX
* t0ch88
* t0ch20x
* ttptha
* TTPTHA
* TzqF
* wodj
* ZAAADA
* zbaaaca
* zjaaadc
* zjaaade

Ami:
* ami
* amidecod
* amipswd
* AMIPSWD
* AMI
* A.M.I.
* aammii
* AMI~
* amiami
* AMI.KEY
* AMISETUP
* AMI?SW
* AMI!SW
* AMI_SW
* bios310
* BIOSPASS
* CMOSPWD
* KILLCMOS
* 589589
* ami.kez
*ami°
* helgaßs
* HEWITT RAND

Vobis:
* merlin

Advance Integration:
* Advance

ALDI (Medion):
* medion

Amptron:
* Polrty

AST:
* SnuFG5

Biostar:
* Biostar
* Q54arwms

Concord:
* last

CTX International:
* CTX_123

CyberMax:
* Congress

Daytek und Daewoo:
* Daytec
* Daewuu

DELL:
* DELL

Digital Equipment:
* komprie

Enox:
* xo11nE

Epox:
* central

Freetech:
* Posterie

HP Vectra Serie:
* hewlpack

IBM:
* IBM
* MBIUO
* sertafu

Iwill
* iwill

Jet Way:
* spoom1

Joss Technology:
* 57gbz6
* Technolgi

MachSpeed:
* sp99dd

Magic-Pro:
* prost

Megastar:
* Star

Micron:
* sldkj754
* xyzall

Micronics:
* dn_04rjc

M Technology:
* mMmM

Nimble:
* xdfk9874t3

Packard Bell:
* Bell9

QDI:
* QDI

Quantex:
* teX1
* xljlbj

Research:
* Col2ogro2

Shuttle:
* Spacve

Siemens Nixdorf:
* SKY_FOX

Speedeasy:
* lesarot1

SuperMicro:
* ksdjfg934t

TMC:
* BIGO

Toshiba:
* 24Banc81
* Toshiba
* toshy99

Vextrec Technology:
* Vextrec

WIMBIOSnbsp BIOS v2.10:
* Compleri

Zenith:
* 3098z
* Zenith

Zeos:
* zeosx

Compaq:
*compaq

Tinys:
*Tiny

METHOD _____ SYSTEM

* Del during boot _____ AMI, Award
* Esc during boot _____ Toshiba
* F1 during boot _____ Toshiba; Phoenix; Late model PS/1 Value Point and 330s
* F2 during boot _____ NEC
* F10 when square in top RH corner of screen _____ Compaq
* Ins during boot _____ IBM PS/2s w/ Reference Partition
* Reset twice _____ Some Dells
* Alt Enter _____ Dell
* Alt ? _____ Some PS/2s
* Ctrl-Esc _____ General
* Ctrl Ins _____ Some PS/2s when pointer at top right of screen
* Ctrl Alt Esc _____ AST Advantage, Award, Tandon
* Ctrl Alt + _____ General
* Ctrl Alt S _____ Phoenix
* Ctrl Alt Ins _____ Zenith, Phoenix
* Ctrl S _____ Phoenix
* Ctrl Shift Esc _____ Tandon 386
* Shift Ctrl Alt + Num Pad Del _____ Olivetti PC Pro
* Setup disk _____ Old Compaqs, Epson (Gemini), IBM, IBM PS/2, Toshiba, most old 286s

2 comentarios:

JonaMetallica dijo...

Hola tengo una Hp Vectra 500 series (no estoy seguro si alguna vez funcionó, lo unico que sé es que se utilizaba en una fabrica) y me pide una "contraseña de encendido", no se puede entrar al bios ni nada, la contraseña no la sé, y quiero saber si alguien me puede ayudar a conseguir el manual o que me enseñen cómo resetear la contraseña o algun otro metodo para que funcione y pueda llegar a ingresar a el Bios así le instalo algun S.O. Muchas gracias

Emiliano dijo...

Hola disculpa que no halla visto tu comentario a tiempo si te sirve de alguna ayuda aca te dejo el link del manual de referencia de hardware y bios de la HP Vectra 500:

http://h20000.www2.hp.com/bc/docs/support/SupportManual/lpv08247/lpv08247.pdf