El fichero omgdos es un ejecutable ELF 32bit Linux
$ file omgdos
omgdos: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]= 0x9b85ac423ba72581a5c483f8a1ed 077004bde96e, stripped
El traceado revela llamadas de sistema a vm86, se usa el modo 8086 virtual :
# strace ./omgdos
...
execve("./omgdos", ["./omgdos"], [/* 21 vars */]) = 0
[ Process PID=7405 runs in 32 bit mode. ]
mmap2(NULL, 1048576, PROT_READ|PROT_WRITE|PROT_ EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ ANONYMOUS, -1, 0) = 0
...
vm86(0x1, 0x804a780, 0x8048db2, 0, 0xfffc) = -1 ENOSYS (Function not implemented)
Para la ejecución en el modo virtual 8086 el programa host tiene que mmap-ear todo el código y los datos usados a la memoria y configurar handlers para los callbacks. La memoria esta en :
if ( alloc_mem(1048576u) == -1 )
{
v2 = __errno_location();
v3 = strerror(*v2);
fprintf(stderr, "%s: cannot mmap: %s\n", *(_DWORD *)a2, v3);
exit(1);
}
sub_8048E3C(0, 31744u);
sub_8048EDB(105u);
v4 = sub_8048940(0, 0x7C00u);
emulate((int)code, 671, v4, "C:\\WINDOWS\\RUNDLL32.EXE");
Para la interacción con el programa host se usa la interrupción 105 (0x69), el handler se implementa en
.text:08049016 handler proc near ; CODE XREF: sub_8048BFF+114#p
.text:08049016
Funciones:
0 – exit
1 – imprimir a stdout
2 – leer de stdin
El modo real se puede obtener interrumpiendo en la llamada de sistema VM86_INIT y volcando la reserva de memoria con la función alloc_mem():
# gdb -q ./omgdos
Reading symbols from /home/user/coruna/omg/omgdos.. .(no debugging symbols found)...done.
gdb-peda$ catch syscall vm86
Catchpoint 1 (syscall 'vm86' [166])
gdb-peda$ r
Catchpoint 1 (call to syscall vm86), 0xf7fdf430 in __kernel_vsyscall ()
gdb-peda$ generate-core-file core
Saved corefile core
Después se puede extraer el core:
$ cat extract_core
#!/usr/bin/python
f = open('core').read()
open('dmp', 'w').write(f[1600:1600+ 1000000])
Code is loaded on address 0x7C00 (like MBR):
seg000:7C00 mov sp, offset stack
seg000:7C03 mov ax, offset aDimeQuICenIElP ; "Dime, -+qu+¬ cen+¬ el pen+¦ltimo d+¡a e"...
seg000:7C06 call print
seg000:7C09 mov ax, 2
seg000:7C0C mov bx, offset input
seg000:7C0F mov cx, 100
seg000:7C12 int 69h
seg000:7C14 mov ax, offset input
seg000:7C17 call near ptr decrypt_compare+1
seg000:7C1A test ax, ax
seg000:7C1C jnz short loc_7C23
seg000:7C1E mov ax, offset winner ; "\x1B[1m-íS+¡!\x1B[0m -+C+¦mo lo has sab"...
seg000:7C21 jmp short loc_7C26
seg000:7C23 loc_7C23: ; CODE XREF: seg000:7C1C#j
seg000:7C23 mov ax, offset nope ; "Pffff pero qu+¬ me est+ís contando.\n"
seg000:7C26
seg000:7C26 loc_7C26: ; CODE XREF: seg000:7C21#j
seg000:7C26 call print
seg000:7C29 mov ax, 0
seg000:7C2C int 69h
Imprime la cadena
Dime, ¿qué cené el penúltimo día en el festival de Ortigueira?
comprueba la entrada de usuario, y si acierta imprime
¿Cómo lo has sabido? Venga, pon la solución en la web y luego búscame para explicarme cómo demonios lo has hecho.
y en error
Pffff pero qué me estás contando.
Rutina de descifrado:
seg000:7C2E aLgimijhflyUMns db 'Lgimijhfly+u-mnsp}' ; DATA XREF: seg000:7C47#o
seg000:7C40 db 7Fh ;
seg000:7C41 ; ------------------------------ ------------------------------ ---------------
seg000:7C41 jnz short near ptr aDimeQuICenIElP+24h
seg000:7C43
seg000:7C43 decrypt_compare: ; CODE XREF: seg000:7C17#p
seg000:7C43 cmp [bp+57h], dl
seg000:7C46 push cx
seg000:7C47 mov si, offset aLgimijhflyUMns ; "Lgimijhfly+u-mnsp}"
seg000:7C4A mov di, ax
seg000:7C4C xor cx, cx
seg000:7C4E
seg000:7C4E loc_7C4E: ; CODE XREF: seg000:7C60#j
seg000:7C4E inc cx
seg000:7C4F cmp cx, 16h
seg000:7C52 jz short loc_7C67
seg000:7C54 mov al, [di]
seg000:7C56 xor al, cl
seg000:7C58 mov ah, [si]
seg000:7C5A cmp al, ah
seg000:7C5C jnz short loc_7C62
seg000:7C5E inc si
seg000:7C5F inc di
seg000:7C60 jmp short loc_7C4E
Hace un XOR con la posición de cada caracter y lo compara con un string prefijado. La entrada se puede calcular:
t=' 4C67696D696A68666C792B752D6D6E 73707D7F756138'.decode('hex')
s=''
for i in xrange(len(t)):
s += chr(ord(t[i])^(i+1))
print s
Así que la respuesta correcta es “Mejillones y cacaolat.”
No hay comentarios:
Publicar un comentario