Title: Solving game2 from the badge of Black Alps 2017 with radare2
Date: 2017-11-18 17:00

Black Alps was a nice conference where I gave yet another talk about
[Snuffleupagus](https://snuffleupagus.readthedocs.io) (you can get our slides
[here](https://github.com/nbs-system/snuffleupagus/blob/master/slides/blackalps_2017.pdf),
those time including Winnie the Pooh),
and happened to have a pretty amazing badge:

![shitty image of the badge]({static}/images/blackalps_badge.jpg)

The badge was of course full of flag to find, some by "manually fuzzing" the
menus, others by playing with bluetooth, … We spent some time on it, but
apparently, the USB-to-serial thingy was "oddly wired", preventing us from
dumping the firmware with my phone charger cable, and I didn't have anything
fancier, like an
[UART](https://en.wikipedia.org/wiki/Universal_asynchronous_receiver-transmitter)
in my pocket.

So I focused on doing the `game2`, which was about reversing, that you could
play by connecting to the badge with serial-over-usb

```nasm
minicom --device /dev/ttyUSB0
Welcome to minicom 2.7

OPTIONS: I18n 
Compiled on Feb  7 2016, 13:37:27.
Port /dev/ttyUSB0, 14:45:34

Press CTRL-A Z for help on special keys

> help
   show           Show information
   stat           Show cow statistics
   name           Set cow name
   game1          Can you find the password ?
   game2          Reversing challenge
   game3          Can you spot the cheat code ?
   help           Show help on available commands
> game2
Missing argument.
> game2 hunter2
Here is my password checking function. Have fun !
3641008202003c19979859920206a2a061a79954a202073b99979a50a20209920205979a4b2ba8a7994a9202023b8887994692020a82a0788799419202084c8887993d8202014c39979839a202032cd99098309090
Incorrect password :(
> 
```

The chip used is an [ESP-WROOM-32](https://espressif.com/en/producttype/esp-wroom-32),
using the [xtensa](https://ip.cadence.com/ipportfolio/tensilica-ip/xtensa-customizable)
cpu architecture, and of course, radare2 supports it:

```nasm
$ rasm2 -L | grep xtensa
_dAe  32         xtensa      GPL3    XTensa CPU
$
```

I could have done the challenge only with `rasm2`, but it's funnier with
`radare2`:

```nasm
$ r2 -a xtensa -
[0x00000000]> wx 3641008202003c19979859920206a2a061a79954a202073b99979a50a20209920205979a4b2ba8a7994a9202023b8887994692020a82a0788799419202084c8887993d8202014c39979839a202032cd9909830909074979a2f220204fb8887122b0c021df00c021df00c021df00c021df00c021df00c021df00c021df00c021df00c021df00c021df00c021df00c121df0
[0x00000000]> aaaaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze len bytes of instructions for references (aar)
[x] Analyze function calls (aac)
[x] Emulate code to find computed references (aae)
[x] Analyze consecutive function (aat)
[x] Constructing a function name for fcn.* and sym.func.* functions (aan)
[x] Type matching analysis for all functions (afta)
[0x00000000]> VV
                                                                   __0x0__
                                                                     │ │
                                                                     │ └─┐
                                                               ┌─────┘   │
                                                               │         │
                                                             __0xb__  __0x65__
                                                               │ │
                                                         ┌─────┘ └─┐
                                                         │         │
                                                       __0x14__ __0x69__
                                                         │ │
                                                   ┌─────┘ └─┐
                                                   │         │
                                                __0x1c__  __0x6d__
                                                   │ │
                                             ┌─────┘ └─┐ 
                                             │         │
                                           __0x25__  __0x71__
                                             │ │
                                       ┌─────┘ └─┐
                                       │         │
                                    __0x2a__  __0x75__
                                       │ │
                                 ┌─────┘ └─┐ 
                                 │         │
                              __0x32__  __0x79__
                                 │ │
                           ┌─────┘ └─┐  
                           │         │
                        __0x3b__  __0x7d__
                           │ │
                     ┌─────┘ └─┐   
                     │         │
                  __0x43__  __0x81__
                     │ │
               ┌─────┘ └─┐  
               │         │
            __0x4b__  __0x85__
               │ │
         ┌─────┘ └─┐  
         │         │
      __0x59__  __0x89__
         │ │
   ┌─────┘ └─┐
   │         │
__0x61__  __0x8d__
```

It look like a chain of check for each of the eleven characters of the
password.

```nasm
[0x00000065]> pdf
┌ (fcn) fcn.00000000 145
│ 0x00000000      364100         entry a1, 32
│ 0x00000001      410082         l32r a4, 0xfffe0804
│ 0x00000004      02003c         l8ui a0, a0, 60
│ 0x00000007      1997           s32i.n a1, a7, 36
│ 0x00000009      9859           l32i.n a9, a9, 20
│ 0x0000000b      920206         l8ui a9, a2, 6
│ 0x0000000e      a2a061         movi a10, 97
│ 0x00000011      a79954         bne a9, a10, 0x00000069
│ 0x00000014      a20207         l8ui a10, a2, 7
│ 0x00000017      3b99           addi.n a9, a9, 3
│ 0x00000019      979a50         bne a10, a9, 0x0000006d
│ 0x0000001c      a20209         l8ui a10, a2, 9
│ 0x0000001f      920205         l8ui a9, a2, 5
│ 0x00000022      979a4b         bne a10, a9, 0x00000071
│ 0x00000025      2ba8           addi.n a10, a8, 2
│ 0x00000027      a7994a         bne a9, a10, 0x00000075
│ 0x0000002a      920202         l8ui a9, a2, 2
│ 0x0000002d      3b88           addi.n a8, a8, 3
│ 0x0000002f      879946         bne a9, a8, 0x00000079
│ 0x00000032      92020a         l8ui a9, a2, 10
│ 0x00000035      82a078         movi a8, 120
│ 0x00000038      879941         bne a9, a8, 0x0000007d
│ 0x0000003b      920208         l8ui a9, a2, 8
│ 0x0000003e      4c88           movi.n a8, 72
│ 0x00000040      87993d         bne a9, a8, 0x00000081
│ 0x00000043      820201         l8ui a8, a2, 1
│ 0x00000046      4c39           movi.n a9, 67
│ 0x00000048      979839         bne a8, a9, 0x00000085
│ 0x0000004b      a20203         l8ui a10, a2, 3
│ 0x0000004e      2cd9           movi.n a9, 45
│ 0x00000050      909830         xor a9, a8, a9
│ 0x00000053      909074         extui a9, a9, 0, 8
│ 0x00000056      979a2f         bne a10, a9, 0x00000089
│ 0x00000059      220204         l8ui a2, a2, 4
│ 0x0000005c      fb88           addi.n a8, a8, 15
│ 0x0000005e      87122b         beq a2, a8, 0x0000008d
│ 0x00000061      0c02           movi.n a2, 0
│ 0x00000063      1df0           retw.n
│ 0x00000065      0c02           movi.n a2, 0
│ 0x00000067      1df0           retw.n
│ 0x00000069      0c02           movi.n a2, 0
│ 0x0000006b      1df0           retw.n
│ 0x0000006c      f00c02         andb b0, b12, b15
│ 0x0000006f      1df0           retw.n
│ 0x00000071      0c02           movi.n a2, 0
│ 0x00000073      1df0           retw.n
│ 0x00000075      0c02           movi.n a2, 0
│ 0x00000077      1df0           retw.n
│ 0x00000079      0c02           movi.n a2, 0
│ 0x0000007b      1df0           retw.n
│ 0x0000007d      0c02           movi.n a2, 0
│ 0x0000007f      1df0           retw.n
│ 0x00000081      0c02           movi.n a2, 0
│ 0x00000082      021df0         l16ui a0, a13, 0x1e0
│ 0x00000085      0c02           movi.n a2, 0
│ 0x00000087      1df0           retw.n
│ 0x00000089      0c02           movi.n a2, 0
│ 0x0000008b      1df0           retw.n
│ 0x0000008d      0c12           movi.n a2, 1
└ 0x0000008f      1df0           retw.n
```

If you struggle a bit to read the listing, you can set `asm.describe` to
`true`, to get a handy description, but basically, it boils down to `movi`,
`beq` and `l8ui` (as in *load a byte as an unsigned integer*), so it's pretty easy.

I annotated the listing by hand using the `;` command in visual mode,
and `dis` to set the immediate as a string to have a better overview:

```nasm
[0x00000065]> pdf
┌ (fcn) fcn.00000000 145
│ 0x00000000      364100         entry a1, 32             ; subroutine entry, 32 bit stack frame
│  0x00000003      820200         l8ui a8, a2, 0          ; a8 = a2[0]
│  0x00000006      3c19           movi.n a9, '1'          ; a9 = '1'
│  0x00000008      979859         bne a8, a9, 0x00000065  ; if a2[0] != a9; goto 0x65
│ 0x0000000b      920206         l8ui a9, a2, 6           ; a9 = a2[6]
│ 0x0000000e      a2a061         movi a10, 'a'            ; a10 = 'a'
│ 0x00000011      a79954         bne a9, a10, 0x00000069  ; if a2[6] != 'a'; goto end
│ 0x00000014      a20207         l8ui a10, a2, 7          ; a10 = a2[7]
│ 0x00000017      3b99           addi.n a9, a9, 3         ; a9 = 'd'
│ 0x00000019      979a50         bne a10, a9, 0x0000006d  ; if a2[7] != 'c'; goto end
│ 0x0000001c      a20209         l8ui a10, a2, 9          ; a10 = a2[9]
│ 0x0000001f      920205         l8ui a9, a2, 5           ; a9 = a2[5]
│ 0x00000022      979a4b         bne a10, a9, 0x00000071  ; if a2[9] != a2[5]; goto end
│ 0x00000025      2ba8           addi.n a10, a8, 2        ; a10 = '3'
│ 0x00000027      a7994a         bne a9, a10, 0x00000075  ; if a2[5] != a10; goto end
│ 0x0000002a      920202         l8ui a9, a2, 2           ; a9 = a2[2]
│ 0x0000002d      3b88           addi.n a8, a8, 3         ; a8 = '4'
│ 0x0000002f      879946         bne a9, a8, 0x00000079   ; if a2[2] != '4'; goto end
│ 0x00000032      92020a         l8ui a9, a2, 10          ; a9 = a2[10]
│ 0x00000035      82a078         movi a8, 'x'             ; a8 = 'x'
│ 0x00000038      879941         bne a9, a8, 0x0000007d   ; if a2[10] != 'x'; goto end
│ 0x0000003b      920208         l8ui a9, a2, 8           ; a9 = a2[8]
│ 0x0000003e      4c88           movi.n a8, 'H'           ; a8 = 'H'
│ 0x00000040      87993d         bne a9, a8, 0x00000081   ; if a2[8] != 'H'
│ 0x00000043      820201         l8ui a8, a2, 1           ; a8 = a2[1]
│ 0x00000046      4c39           movi.n a9, 'C'           ; a9 = 'C'
│ 0x00000048      979839         bne a8, a9, 0x00000085   ; if a2[1] 1= 'C'; goto end
│ 0x0000004b      a20203         l8ui a10, a2, 3          ; a10 = a2[3]
│ 0x0000004e      2cd9           movi.n a9, 45            ; a9 = 45
│ 0x00000050      909830         xor a9, a8, a9           ; a9 ^= '67'
│ 0x00000053      909074         extui a9, a9, 0, 8       ; a9 = a9[0:8]
│ 0x00000056      979a2f         bne a10, a9, 0x00000089  ; if a2[3] != 'n'; goto end
│ 0x00000059      220204         l8ui a2, a2, 4           ; a2 = a2[4]
│ 0x0000005c      fb88           addi.n a8, a8, 15        ; a8 = 'R'
│ 0x0000005e      87122b         beq a2, a8, 0x0000008d   ; if a2[4] != 'R'; goto end
│ 0x00000061      0c02           movi.n a2, 0             ; return value = 0
│ 0x00000063      1df0           retw.n                   ; return
│ 0x00000065      0c02           movi.n a2, 0
│ 0x00000067      1df0           retw.n
│ 0x00000069      0c02           movi.n a2, 0
│ 0x0000006b      1df0           retw.n
│ 0x0000006c      f00c02         andb b0, b12, b15
│ 0x0000006f      1df0           retw.n
│ 0x00000071      0c02           movi.n a2, 0
│ 0x00000073      1df0           retw.n
│ 0x00000075      0c02           movi.n a2, 0
│ 0x00000077      1df0           retw.n
│ 0x00000079      0c02           movi.n a2, 0
│ 0x0000007b      1df0           retw.n
│ 0x0000007d      0c02           movi.n a2, 0
│ 0x0000007f      1df0           retw.n
│ 0x00000081      0c02           movi.n a2, 0
│ 0x00000082      021df0         l16ui a0, a13, 0x1e0
│ 0x00000085      0c02           movi.n a2, 0
│ 0x00000087      1df0           retw.n
│ 0x00000089      0c02           movi.n a2, 0
│ 0x0000008b      1df0           retw.n
│ 0x0000008d      0c12           movi.n a2, 1              ; return value = 1
└ 0x0000008f      1df0           retw.n                    ; return
```

Getting the flag is only a matter of validating each condition,
yielding you `1C4nR3adH3x`.

```nasm
> game2 1C4nR3adH3x                                                   
Here is my password checking function. Have fun !                     
3641008202003c19979859920206a2a061a79954a202073b99979a50a20209920205979a4b2ba8a7994a9202023b8887994692020a82a0788799419202084c8887993d8202014c39979839a202032cd9909830909074979a2f220204fb8887122b0c021df00c021df00c021df00c021df00c021df00c021df00c021df00c021df00c021df00c021df00c021df00c121df0
Success : Here is a cheat code 88c909 
```

There are at least 7 other flags to find in the badge, maybe I'll write about
them if/when I take the time to get a dump of the firmware.

A laziest way to do it would be to use ESIL, by initializing the ESIL virtual
machine with `aeim`, running until the first jump with `aecu` (as in Analysis
with ESIL to Continue Until), and to check the corresponding register value:

```nasm
jvoisin@kaa 16:48 ~ r2 -a xtensa -b 32 -
[0x00000000]> wx 3641008202003c19979859920206a2a061a79954a202073b99979a50a20209920205979a4b2ba8a7994a9202023b8887994692020a82a0788799419202084c8887993d8202014c39979839a202032cd9909830909074979a2f220204fb8887122b0c021df00c021df00c021df00c021df00c021df00c021df00c021df00c021df00c021df00c021df00c021df00c121df0
[0x00000000]> pd 8
            0x00000000      364100         entry a1, 32
            0x00000003      820200         l8ui a8, a2, 0
            0x00000006      3c19           movi.n a9, 49
        ┌─< 0x00000008      979859         bne a8, a9, 0x00000065
        │   0x0000000b      920206         l8ui a9, a2, 6
        │   0x0000000e      a2a061         movi a10, 97
       ┌──< 0x00000011      a79954         bne a9, a10, 0x00000069
       ││   0x00000014      a20207         l8ui a10, a2, 7
[0x00000000]> aeim
[0x00000000]> aecu 0x00000008
[0x00000000]> pdi 1 @ 0x00000008
0x00000008               979859  bne a8, a9, 0x00000065
[0x00000000]> ? a9
49 0x31 061 49 0000:0031 49 "1" 00110001 49.0 49.000000f 49.000000
[0x00000000]>
```

So as expected, the first letter is `1`. You can get the other ones by manually
setting registers with `aer pc = 0x1337` or `aer a9 = 0x1338` if you're too
loafer to start over upon each good letter.
