Rating:

# Challenge Zero

## Task

We are presented with a animted gif of a fireplace with a hint which depends on the browser used.
```
Did you know: Plain text goes best with a text browser.

Hint: $ target remote localhost:1234
```
So lets use lynx as a text browser and we get:

```
D0NT PU5H M3 C0Z 1M C1053 T0 T3H 3DG3

Hint: If only the flames wouldn't move that much...
```
Doing the same with wget results in:
```
Is that a curling iron in your pocket or are you just happy to see me?
```

Doing the same with curl we finally get:
```
#########################################################################
###############################I##########################################
###############################UY#########################################
###############################j#Xl#######################################
###############################8#iQ#######################################
###############################C#M7#######################################
#############################J#z8p#UV#####################################
#############################h#cNj#gv#####################################
#############################W#1wk#WF#####################################
#############################8#nMC#c5##########Q##########################
#############################FxYVy1#DSw#########p#########################
#############################NU#0Y4#Ly4#########t############Vz###########
##############################hQW#zAu#S########yM#############x###########
#############Ij#############1gO#FFW#XFQ#########wWl###########8###########
#############vI#############z##NUQDU#pVi#######hXL#EI########0#UC#########
#############h#############SOE###cpR#ihE#######LCJ#UT########z#hB#########
#############Y#CE######9###Rih#WCk#0qQ#kxRO##EN#MRy#h########TI#U#########
###########Mw#RF0#######o##JE#IsU#S####wz#N##E0#sIj###########lYO#E#######
###########Qp#LzJ#####gJE#############0rU#j##1CKCI###########sQS##########
###########o2K#FU####q#Uz############h#KO####E#ItQ#########itS############
###########VEY#KT##S#lTY#Ew##########4#QCQ###yJV#Yp#######################
###########W#CREK##So#4RE#k##########iR#C##ki#MEQ#p#######################
###########Ij#######BUK#C9L#Q########lF#eIU#9aL#FAs#######################
####################ITE#5RV#lIV#####SQhUSI#wXj#BeK########################
###################z84#PQp#NTE#dZ##W#ics#S18#iND#4n#######################
#################K#05f#VUs###mPU#########Et####R###js#####################
#################qJ##UN###cJV###############w9P#S##gv#M###################
#######################0t#U##########################YF###################
################o##sM#l############################o5###SCM###############
##########################################################################
##############################iIi###chI#T####he###########################
##########################UiR###ANz#t##dQ#i1YCk##0########################
###################sI##U#####lC######I###V4w###R1####5####################
##########################################################################
```

So it looks like a base64 encoded changing string sorrounded by #'s.

## Step 1 getting the binary

I used `curl https://advent2019.overthewire.org/challenge-zero -O` to save the animated text into a file.
The I just removed the "formatting" with sed using `cat challenge-zero| sed 's/\x1b\[[0-9;]*m//g' >challenge_zero.txt`.
Checking the resulting .txt file and searching for == (the end of the base64 encoded string) it looks like the
animation has 5 frames.

With further sed magic it was possible to remove teh # and other garbage resulting in following bas64 encoded string.
```
YmVnaW4gNjQ0IGJvb3QuYmluCk1eQydgQ01CLlAoWzBPYCFcMGBeQiNSI2BAXiNbQFxAIiNSK2AjUiNAIzBgJiNSK0BPTzlcWitYYDlAXloKTVgxRVMzO1g4Pz5CUWArXGA/QydgUzE4XCM3MDovYEFVI1gnX2AnWV5bS1kmPz5CNmAkX0tZOkpUI0xUMApNWl1aIV9RIV49PFwvKmA7UD8wXEgnQCFeWiMwYDlAX08nTiFdOUBcWCVdTVQiTk5TT0I1XVomMGBaX1peCk00J1QvKmA4YD9AXEgnLkAvYGBcSScoLyYkKCdeWCdVVVo+Rk1gJjgvW10pRiNeXzhOXjRWTScvIVpgP1YKTVxYQEZPR1FGI1NLP1IkNUYjVyMpX1BfJlQhIUYjXl8iQCM7Jz8pUVhcNjgvW1wkWF8nMCc5QFxYVy1DSwpNU0Y4Ly4tVzhQWzAuSyMxIj1gOFFWXFQwWl8vIzNUQDUpVihXLEI0UChSOEcpRihELCJUTzhBYCE9RihWCk0qQkxROENMRyhTIUMwRF0oJEIsUSwzNE0sIjlYOEQpLzJgJE0rUj1CKCIsQSo2KFUqUzhKOEItQitSVEYKTSlTYEw4QCQyJVYpWCREKSo4REkiRCkiMEQpIjBUKC9LQlFeIU9aLFAsITE5RVlIVSQhUSIwXjBeKz84PQpNTEdZWicsS18iND4nK05fVUsmPUEtRjsqJUNcJVw9PSgvM0tUYFosMlo5SCMiIichITheUiRANztdQi1YCk0sIUlCIV4wR15cIktWSkE7QjNMWltVV0gqWiZOW1wxQz5CST4hKjpdPEsvSCUrMywiO1tCQD47RTcySVYKTT4kWiU/KlE0YEZfUSdCIktEV1guMkJeWUBaOEYtMiQ4LzBNRFYnLl1dX1g6QCM5MS4pIkAtISVNLCVZMgoxNSZVWUArRkUiSTxEIzJXXC1AVjU1OkhgCmAKZW5kCg==YmVnaW4gNjQ0IGJvb3QuYmluCk1eQydgQ01CLlAoWzBPYCFcMGBeQiNSI2BAXiNbQFxAIiNSK2AjUiNAIzBgJiNSK0BPTzlcWitYYDlAXloKTVgxRVMzO1g4Pz5CUWArXGA/QydgUzE4XCM3MDovYEFVI1gnX2AnWV5bS1kmPz5CNmAkX0tZOkpUI0xUMApNWl1aIV9RIV49PFwvKmA7UD8wXEgnQCFeWiMwYDlAX08nTiFdOUBcWCVdTVQiTk5TT0I1XVomMGBaX1peCk00J1QvKmA4YD9AXEgnLkAvYGBcSScoLyYkKCdeWCdVVVo+Rk1gJjgvW10pRiNeXzhOXjRWTScvIVpgP1YKTVxYQEZPR1FGI1NLP1IkNUYjVyMpX1BfJlQhIUYjXl8iQCM7Jz8pUVhcNjgvW1wkWF8nMCc5QFxYVy1DSwpNU0Y4Ly4tVzhQWzAuSyMxIj1gOFFWXFQwWl8vIzNUQDUpVihXLEI0UChSOEcpRihELCJUTzhBYCE9RihWCk0qQkxROENMRyhTIUMwRF0oJEIsUSwzNE0sIjlYOEQpLzJgJE0rUj1CKCIsQSo2KFUqUzhKOEItQitSVEYKTSlTYEw4QCQyJVYpWCREKSo4REkiRCkiMEQpIjBUKC9LQlFeIU9aLFAsITE5RVlIVSQhUSIwXjBeKz84PQpNTEdZWicsS18iND4nK05fVUsmPUEtRjsqJUNcJVw9PSgvM0tUYFosMlo5SCMiIichITheUiRANztdQi1YCk0sIUlCIV4wR15cIktWSkE7QjNMWltVV0gqWiZOW1wxQz5CST4hKjpdPEsvSCUrMywiO1tCQD47RTcySVYKTT4kWiU/KlE0YEZfUSdCIktEV1guMkJeWUBaOEYtMiQ4LzBNRFYnLl1dX1g6QCM5MS4pIkAtISVNLCVZMgoxNSZVWUArRkUiSTxEIzJXXC1AVjU1OkhgCmAKZW5kCg==
```

Doing a `echo "YmVnaW4gNjQ0IG..kcg==" | base64 -d >c0.dat" and a
```
$ file c0.dat
c0.dat: uuencoded or xxencoded, ASCII text
```
shows that we need to do a uudecode.

```
$ cat challenge_zero.txt | base64 -d | uudecode
$ file boot.bin
boot.bin: DOS/MBR boot sector
```

We end up with a Master Boot Record which we can now start with qemu.

## Step 2 ...Running and disassasmbling the binary

Now the hint from the start page makes sense (target remote localhost:1234). Thats the command needed to connect with gdb to qemu.

The first attempt to boot failed.

![Screenshot_1](https://github.com/zero815/aotw2019/blob/master/day0_image1.png)

So I disassembled the MBR. Here you can find the code dumped with objdump [ASM](https://github.com/zero815/aotw2019/blob/master/day0.asm). It is using aes instructions so we need to start qemu with the right options.
And we end up with this status:

![Screenshot_2](https://github.com/zero815/aotw2019/blob/master/day0_image3.png)

We are prompted for a password. So now its time to understand the code better.

## Step 3 understanding the code

I ended up dowloading a demo version of IDA.
The executable expects a password to be entered. The password is encrypted with a stored key and compared against an expected result.

Following fragment seems to encrypt the password and compare it to an expected result:

```nasm
seg000:005C loc_5C: ; CODE XREF: seg000:loc_40↑j
seg000:005C cmp di, 7E10h ; 16 byte password password is stored in 7e00-7e10
seg000:0060 jnz short loc_31
seg000:0062 movaps xmm0, xmmword ptr ds:7DF0h ; encryption key stored in 0x7DF0
seg000:0067 movaps xmm3, xmmword ptr ds:7E00h ;entered password stored in 0x7E00
seg000:006C call sub_A3 ; encrypt entered password
seg000:006F pxor xmm3, xmmword ptr ds:7DE0h ; expected encryption result is in 0x7DE0
seg000:0075 ptest xmm3, xmm3
seg000:007A jz short loc_86 ; if the compare is OK jump to code decryption
seg000:007C jmp short loc_31 ; jump to password enter again if result is wrong
```
The key for the encryption is stored in 0x7DF0. The password is encrypted with this key. Since symetric encryption is used (AES) it would be easy to just take the value from 0x7DE0 and decrypt it with the key from 0x7DF0 and have the password.

If the encrypted password matches an expected value at 0x7DE0 the fragment below is executed to decrypt and execute code.

Following segment seems to decrypt the code at offset 150 (0x7c00 + 0x150 = 0x7d50) and executed it.
0x7c00 is the address where bootsectors are loaded to,

```nasm
seg000:0086 ; ---------------------------------------------------------------------------
seg000:0086
seg000:0086 loc_86: ; CODE XREF: seg000:007A↑j
seg000:0086 mov si, 7D50h
seg000:0089
seg000:0089 loc_89: ; CODE XREF: seg000:009E↓j
seg000:0089 movaps xmm0, xmmword ptr ds:7E00h ; decrypt and execute code
seg000:008E movaps xmm3, xmmword ptr [si]
seg000:0091 call sub_A3 ; call dencryption function
seg000:0094 movaps xmmword ptr [si], xmm3
seg000:0097 add si, 10h
seg000:009A cmp si, 7DE0h
seg000:009E jnz short loc_89
seg000:00A0 jmp near ptr unk_150 ; execute decrypted code at offset 150
seg000:00A3
```

Following screenshot shows the encryption part of the code
quite nicely.More details can be found in the assembly dump linked above.

![Encryption](https://github.com/zero815/aotw2019/blob/master/day0_image2.png)

Intel aes instructions are used.
I went through this paper to understand how they work in more detail (https://software.intel.com/sites/default/files/article/165683/aes-wp-2012-09-22-v01.pdf).
There are lot of good sources which explain AES and roundkeys etc. in great detail. One could easily start from here https://en.wikipedia.org/wiki/Advanced_Encryption_Standard.

I just put a breakpoint at the `aesenc` and `aesenclast` instruction and dumped the each roundkey used from the `xmm0` register with `i r xmm0` in gdb.

So I had 10 round keys.

## Step 4 getting the password

I decided writing a small piece of assembly code using the round keys I recovered.

```nasm

global _start

section .text
_start:
; load encrypted password
movaps xmm3,[pw]
call dosomething ; decrypt it
jmp end

dosomething:
pxor xmm2,xmm2
; use round keys in reverse order from key j to key a
movaps xmm0,[kj]
pxor xmm3,xmm0
movaps xmm0,[ki]
aesimc xmm0,xmm0
aesdec xmm3,xmm0
movaps xmm0,[kh]
aesimc xmm0,xmm0
aesdec xmm3,xmm0
movaps xmm0,[kg]
aesimc xmm0,xmm0
aesdec xmm3,xmm0
movaps xmm0,[kf]
aesimc xmm0,xmm0
aesdec xmm3,xmm0
movaps xmm0,[ke]
aesimc xmm0,xmm0
aesdec xmm3,xmm0
movaps xmm0,[kd]
aesimc xmm0,xmm0
aesdec xmm3,xmm0
movaps xmm0,[kc]
aesimc xmm0,xmm0
aesdec xmm3,xmm0
movaps xmm0,[kb]
aesimc xmm0,xmm0
aesdec xmm3,xmm0
movaps xmm0,[ka]
aesimc xmm0,xmm0
aesdec xmm3,xmm0

movaps xmm0,[key]
aesdeclast xmm3,xmm0

end:
section .data
align 16
msg: db 0x19, 0xcb, 0xe9, 0xe7, 0xbb, 0x17, 0x89, 0x26, 0x86, 0xb7, 0xea, 0xe4, 0xb2, 0x2d, 0xe5, 0xa3

key: db 0x6d,0x79,0x80,0xb9,0xa5,0x0a,0x97,0x24,0x0d,0x2d,0xfc,0x36,0x0d,0x95,0x55,0xaa
; encrypted password
pw: db 0xf7,0xfe,0x1a,0x80,0x36,0x51,0x38,0x90,0xa0,0x34,0x11,0x6d,0x30,0x5e,0x52,0x54
; recovered round keys a-j
ka: db 0x46, 0x85, 0x2c, 0x6e, 0xe3, 0x8f, 0xbb, 0x4a, 0xee, 0xa2, 0x47, 0x7c, 0xe3, 0x37, 0x12, 0xd6
kb: db 0xde, 0x4c, 0xda, 0x7f, 0x3d, 0xc3, 0x61, 0x35, 0xd3, 0x61, 0x26, 0x49, 0x30, 0x56, 0x34, 0x9f
kc: db 0x6b, 0x54, 0x1, 0x7b, 0x56, 0x97, 0x60, 0x4e, 0x85, 0xf6, 0x46, 0x7, 0xb5, 0xa0, 0x72, 0x98
kd: db 0x83, 0x14, 0x47, 0xae, 0xd5, 0x83, 0x27, 0xe0, 0x50, 0x75, 0x61, 0xe7, 0xe5, 0xd5, 0x13, 0x7f
ke: db 0x90, 0x69, 0x95, 0x77, 0x45, 0xea, 0xb2, 0x97, 0x15, 0x9f, 0xd3, 0x70, 0xf0, 0x4a, 0xc0, 0xf
kf: db 0x66, 0xd3, 0xe3, 0xfb, 0x23, 0x39, 0x51, 0x6c, 0x36, 0xa6, 0x82, 0x1c, 0xc6, 0xec, 0x42, 0x13
kg: db 0xe8, 0xff, 0x9e, 0x4f, 0xcb, 0xc6, 0xcf, 0x23, 0xfd, 0x60, 0x4d, 0x3f, 0x3b, 0x8c, 0xf, 0x2c
kh: db 0xc, 0x89, 0xef, 0xad, 0xc7, 0x4f, 0x20, 0x8e, 0x3a, 0x2f, 0x6d, 0xb1, 0x1, 0xa3, 0x62, 0x9d
ki: db 0x1d, 0x23, 0xb1, 0xd1, 0xda, 0x6c, 0x91, 0x5f, 0xe0, 0x43, 0xfc, 0xee,0xe1, 0xe0, 0x9e, 0x73
kj: db 0xca, 0x28, 0x3e, 0x29, 0x10, 0x44, 0xaf, 0x76, 0xf0, 0x7, 0x53, 0x98, 0x11, 0xe7, 0xcd, 0xeb
```

Next step is to compile the code, execute it with gdb and put a breakpoint at the end label and dump xmm3 which contains the decrypted password.

```bash
$ nasm -f elf64 test2.asm
$ ld test2.o
$ gdb a.out
GNU gdb (Ubuntu 8.3-0ubuntu1) 8.3
...
$ (gdb) break end
Breakpoint 1 at 0x4010d1
(gdb) r
Starting program: day0/a.out

Breakpoint 1, 0x00000000004010d1 in ?? ()
(gdb) i r xmm3
xmm3 {v4_float = {0xffffffff, 0xffffffff, 0xffffffff, 0x934cc000}, v2_double = {0x7fffffffffffffff, 0x7fffffffffffffff}, v16_int8 = {0x4d, 0x69, 0x4c, 0x69, 0x54, 0x34, 0x52, 0x79, 0x47, 0x72, 0x34, 0x64, 0x33, 0x4d, 0x62, 0x52}, v8_int16 = {0x694d, 0x694c, 0x3454, 0x7952, 0x7247, 0x6434, 0x4d33, 0x5262}, v4_int32 = {0x694c694d, 0x79523454, 0x64347247, 0x52624d33}, v2_int64 = {0x79523454694c694d, 0x52624d3364347247}, uint128 = 0x52624d336434724779523454694c694d}
(gdb)
```

So the password is `v16_int8 = {0x4d, 0x69, 0x4c, 0x69, 0x54, 0x34, 0x52, 0x79, 0x47, 0x72, 0x34, 0x64, 0x33, 0x4d, 0x62, 0x52}`

Copy pasting that into ipython gives us:
```python
In [6]: res=[0x4d, 0x69, 0x4c, 0x69, 0x54, 0x34, 0x52, 0x79, 0x47, 0x72, 0x34, 0x64, 0x33, 0x4d, 0x62, 0x52]

In [7]: "".join(map(lambda x: chr(x),res))
Out[7]: 'MiLiT4RyGr4d3MbR'

In [8]:

```
## Step 5 getting the flag
All we have to do now is to take the password **MiLiT4RyGr4d3MbR** start the MBR and enter it.
![flag](https://github.com/zero815/aotw2019/blob/master/day0_image4.png)
Now we get a mesage with the flag **AOTW{31oct__1s__25dec}***