The binary appears to be a “DOS/MBR boot sector” with a valid signature according to classical layout, see figure “Structure of a classical generic MBR”1.

00000000: bc00 9c31 c0b0 03cd 1031 d2b9 0d00 b40e  ...1.....1......
00000010: b3c8 be64 7cac 30d8 cd10 fecb e2f7 b400  ...d|.0.........
00000020: cd16 aab4 0e3c 0d75 2fcd 10b0 0acd 10be  .....<.u/.......
00000030: 717c b91d 00ac cd10 e2fb be8e 7cb9 0900  q|..........|...
00000040: c1c2 0781 c237 13ad 31d0 88e3 b40e cd10  .....7..1.......
00000050: 88d8 cd10 e2ea ebfe 00c2 86d6 b02a cd10  .............*..
00000060: ebbc ebfe 89a4 a5a0 b7b0 e2a2 afdb db87  ................
00000070: 9c53 6b69 636b 6120 6c6f 6573 6e69 6e67  .Skicka loesning
00000080: 206f 6368 2043 5620 7469 6c6c 3a20 29ba   och CV till: ).
00000090: 43d7 70cc 666f aa64 b1b5 d786 5042 9e4e  C.p.fo.d....PB.N
...
000001f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.

The MBRs use Intel 8086 architecture with the x86-16 instruction set, where the MBR boot sector code expects to be loaded at physical address 0000:7c001.

I began disassemble with radare2 disassembler: r2 -AA -b16 -m 0x7c00 fra and executed it using qemu-system-i386 -fda fra.

When executed, the BIOS asks the user for an access key that it uses to derivate a “key” used for the deobfuscation process of the actual e-mail. I noticed several BIOS interrupt calls int 0x10 with teletype output (ah = 0x0e)2 and one int 0x16 for obtaining keystrokes from the keyboard3.

0000:7c25 checks for carriage return in al after the int 0x16 interrupt. If not, goto 0000:7c58 to truncate (“hash”) the input in al with dx, and store in register dx.

The dx register is then used as the input key for deobfuscation, starting at address 0000:7c40. The deobfuscation part overlays the input with a 18-byte found at address 0000:7c8e.

.--------------------------------------------------------------------------.
|        ; CODE XREF from fcn.00007c00 @ +0x6a                             |
|        0000:7c0e      b40e           mov ah, 0xe                         |
|        0000:7c10      b3c8           mov bl, 0xc8                        |
|        0000:7c12      be647c         mov si, 0x7c64                      |
|        ; CODE XREF from fcn.00007c00 @ 0x7c1c                            |
|    .-> 0000:7c15      ac             lodsb al, byte [si]                 |
|    :   0000:7c16      30d8           xor al, bl                          |
|    :   0000:7c18      cd10           int 0x10                            |
|    :   0000:7c1a      fecb           dec bl                              |
|    `=< 0000:7c1c      e2f7           loop 0x7c15                         |
|        ; CODE XREF from fcn.00007c00 @ 0x7c60                            |
|    .-> 0000:7c1e      b400           mov ah, 0                           |
|    :   0000:7c20      cd16           int 0x16                            |
|    :   0000:7c22      aa             stosb byte es:[di], al              |
|    :   0000:7c23      b40e           mov ah, 0xe                         |
|    :   0000:7c25      3c0d           cmp al, 0xd                         |
|   ,==< 0000:7c27      752f           jne 0x7c58                          |
|   |:   0000:7c29      cd10           int 0x10                            |
|   |:   0000:7c2b      b00a           mov al, 0xa                         |
|   |:   0000:7c2d      cd10           int 0x10                            |
|   |:   0000:7c2f      be717c         mov si, 0x7c71                      |
|   |:   0000:7c32      b91d00         mov cx, 0x1d                        |
|   |:   ; CODE XREF from fcn.00007c00 @ 0x7c38                            |
|  .---> 0000:7c35      ac             lodsb al, byte [si] ; 'Skicka loe..'|
|  :|:   0000:7c36      cd10           int 0x10                            |
|  `===< 0000:7c38      e2fb           loop 0x7c35                         |
|   |:   0000:7c3a      be8e7c         mov si, 0x7c8e      ; Overlay       |
|   |:   0000:7c3d      b90900         mov cx, 9                           |
|   |:   ; CODE XREF from fcn.00007c00 @ 0x7c54                            |
|  .---> 0000:7c40      c1c207         rol dx, 7                           |
|  :|:   0000:7c43      81c23713       add dx, 0x1337                      |
|  :|:   0000:7c47      ad             lodsw ax, word [si]                 |
|  :|:   0000:7c48      31d0           xor ax, dx                          |
|  :|:   0000:7c4a      88e3           mov bl, ah                          |
|  :|:   0000:7c4c      b40e           mov ah, 0xe                         |
|  :|:   0000:7c4e      cd10           int 0x10                            |
|  :|:   0000:7c50      88d8           mov al, bl                          |
|  :|:   0000:7c52      cd10           int 0x10                            |
|  `===< 0000:7c54      e2ea           loop 0x7c40                         |
|  @==-> 0000:7c56      ebfe           jmp 0x7c56                          |
|   ::   ; CODE XREF from fcn.00007c00 @ 0x7c27                            |
|   ::   0000:7c58      00c2           add dl, al                          |
|   ::   0000:7c5a      86d6           xchg dh, dl                         |
|   ::   0000:7c5c      b02a           mov al, 0x2a        ; '*'           |
|   ::   0000:7c5e      cd10           int 0x10                            |
|   |:   ; CODE XREF from fcn.00007c00 @ +0x92                             |
|   `==< 0000:7c60      ebbc           jmp 0x7c1e                          |
|   @=-> 0000:7c62      ebfe           jmp 0x7c62                          |
|    :   ; DATA XREF from fcn.00007c00 @ 0x7c12                            |
|    :   0000:7c64      89a4a5a0       mov word [si - 0x5f5b], sp          |
|    :   0000:7c68      b7b0           mov bh, 0xb0                        |
|    `=< 0000:7c6a      e2a2           loop 0x7c0e                         |
`--------------------------------------------------------------------------´

Due to this I can assume that the e-mail is not longer than 18 bytes.

[0000:7c00]> px 18 @ 0x7c8e
- offset -  0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0000:7c8e  29ba 43d7 70cc 666f aa64 b1b5 d786 5042  ).C.p.fo.d....PB
0000:7c9e  9e4e                                     .N

To find the required 16-bit value in dx for the deobfuscation part to output a “fra.se” e-mail, I implemented the same behavior in python with the overlay from 0x7c8e.

_0x7c8e = unpack('H'*9, unhexlify("29ba43d770cc666faa64b1b5d78650429e4e"))

def deobfuscate_i(dx, ax):
	post_0x7c40_dx = rol(dx, 7, 16)             # 0000:7c40 rol dx,7
	post_0x7c43_dx = post_0x7c40_dx + 0x1337    # 0000:7c43 add dx,1337
	post_0x7c48_ax = post_0x7c43_dx ^ ax        # 0000:7c48 xor ax,dx
	ah = chr((post_0x7c48_ax & 0xff00) >> 8)    # 0000:7c4a mv bl,ah
	al = chr(post_0x7c48_ax & 0xff)             # 0000:7c4e int 0x10
	return post_0x7c43_dx, ah, al

def deobfuscate(dx, byte_array, s = str()):
	for byte in byte_array:
		dx, ah, al = deobfuscate_i(dx, byte)
		s += "%c%c" % (al, ah)
	return s

def solve_obfuscator():
	for dx in range(0xffff):
		s = deobfuscate(dx, _0x7c8e)
		if "@fra.se" in s:
			return dx, s		

I verified my implementation by debugging the binary with qemu-system-i386 -fda fra -s and gdb.

By searching for the string "@fra.se", I found that the register dx needs to be 0x1984 to output the e-mail "jobbahososs@fra.se".

To find valid 5-byte printable input values I implemented the truncation function in python, and in parallel brute-forced possible alpha numeric values.

$ ./fra.py
Solved! dx = 0x1984 -> jobbahososs@fra.se
b'30306f547a'[00oTz]
b'3030705479'[00pTy]
b'3030715478'[00qTx]
b'3030725477'[00rTw]
b'3030735476'[00sTv]
b'3030745475'[00tTu]
b'3030755474'[00uTt]
b'3030765473'[00vTs]
b'3030775472'[00wTr]
b'3030785471'[00xTq]
b'3030795470'[00yTp]
b'30307a546f'[00zTo]
b'30316f537a'[01oSz]
...

See python code below for complete solution.

#!/usr/bin/env python3

from itertools import chain, product
from multiprocessing import Process,Queue,cpu_count
from binascii import unhexlify,hexlify
from struct import unpack

MIN_LENGTH = 5
MAX_LENGTH = 5

# - offset -  0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
# 0000:7c8e  29ba 43d7 70cc 666f aa64 b1b5 d786 5042  ).C.p.fo.d....PB
# 0000:7c9e  9e4e                                     .N
_0x7c8e = unpack('H'*9, unhexlify("29ba43d770cc666faa64b1b5d78650429e4e"))

rol = lambda val, r_bits, max_bits: \
    (val << r_bits%max_bits) & (2**max_bits-1) | \
    ((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits)))

hash_i = lambda dx, al: \
	((((dx & 0xff00) | (dx + al) & 0xff) & 0x00ff) << 8) | \
	((((dx & 0xff00) | (dx + al) & 0xff) & 0xff00) >> 8)

def deobfuscate_i(dx, ax):
	post_0x7c40_dx = rol(dx, 7, 16)             # 0000:7c40 rol dx,7
	post_0x7c43_dx = post_0x7c40_dx + 0x1337    # 0000:7c43 add dx,1337
	post_0x7c48_ax = post_0x7c43_dx ^ ax        # 0000:7c48 xor ax,dx
	ah = chr((post_0x7c48_ax & 0xff00) >> 8)    # 0000:7c4a mv bl,ah
	al = chr(post_0x7c48_ax & 0xff)				
	return post_0x7c43_dx, ah, al 				

def deobfuscate(dx, b: bytes):
	s = str()
	for byte in b:
		dx, ah, al = deobfuscate_i(dx, byte)
		s += "%c%c" % (al, ah)                 # 0000:7c4e int 0x10 (putchar)
	return s

def solve_obfuscator():
	for dx in range(0xffff):
		s = deobfuscate(dx, _0x7c8e)
		if "@fra.se" in s:
			return dx, s

def hash_bytes(b: bytes, dx = 0):
	for byte in unpack('B' * len(b), b):
		dx = hash_i(dx, byte)
	return dx

def hash_worker(dx, queue):
	while True:
		t = bytes(ord(c) for c in list(queue.get()))
		if hash_bytes(t) == dx:
			print('%s[%s]' % (hexlify(t), ''.join(chr(c) for c in t)))

def test():
	assert(hash_bytes(b'z3MQR') == 0x1984)
	assert(deobfuscate(0x1984, _0x7c8e) == "jobbahososs@fra.se")

if __name__ == "__main__":
	test()

	dx, s = solve_obfuscator()
	print("Solved! Register dx = 0x%04x -> %s" % (dx, s))

	pattern = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
	generator = chain.from_iterable(product(pattern, repeat=i)
					for i in range(MIN_LENGTH, MAX_LENGTH + 1))

	try:
		queue = Queue()

		processes = []
		for i in range(cpu_count()):
		    p = Process(target=hash_worker, args=(dx, queue))
		    p.start()
		    processes.append(p)

		for test in generator:
			queue.put(test)

		queue.join()
	except (KeyboardInterrupt, SystemExit):
		pass

One of many solutions is 00oTz.

References
  1. https://en.wikipedia.org/wiki/Master_boot_record  2

  2. https://en.wikipedia.org/wiki/INT_10H 

  3. https://en.wikipedia.org/wiki/INT_16H