* **Category:** reversing* **Points:** 200* **Description:**
> ## Part 3:>> The final boss!>> Time to pull together your knowledge of Bash, Python, and stupidly-low-level> assembly!!> > This time you have to write some assembly that we're going to run.. You'll see> the output of your code through VNC for 60 seconds.> > Objective: Print the flag.> > What to know:> > Strings need to be alternating between the character you want to print and> '0x1f'.> > To print a string you need to write those alternating bytes to the frame> buffer (starting at 0x00b8000...just do it). Increment your pointer to move> through this buffer.> > If you're having difficulty figuring out where the flag is stored in memory,> this code snippet might help you out:>> ```> get_ip:>   call next_line> next_line:>   pop rax>   ret> ```>> That'll put the address of pop rax into rax.>> Call serves as an alias for push rip (the instruction pointer - where we are> in code) followed by `jmp ______` where whatever is next to the call fills in> the blank.>> And in case this comes up, you shouldn't need to know where you are loaded in> memory if you use that above snippet...>> Happy Reversing!!>> ```sh> nc rev.chal.csaw.io 9004> ```>> -Elyk>> [Makefile](https://ctf.csaw.io/files/b236e0cc11cba5b5fd134436a0c8c811/Makefile)> [part-3-server.py](https://ctf.csaw.io/files/d3e7a84ffb4eeca992c9f458bf4c11ec/part-3-server.py)> [tacOS-base.bin](https://ctf.csaw.io/files/acbf4fe9f0233ce3ed34c55fee34649e/tacOS-base.bin)
## Writeup
This is a challenge in multiple stages, each one having its own flag.(Note: the original link contains all three stages)
The general theme is low-level x86 code and how it behaves after boot.The difficulty is quite low, but it was fun.
### Stage 3
For Stage 3 we get a host and port again, this time we can send them ahex-encoded binary that gets appended to the Stage 2 payload to be executedafter the flag is rendered, we then get a port on which we can observe thebinary over VNC.
The flag seems to be appended after our code, so I just wrote some asm thathexdumps the bytes of our binary and everything after that in an infinite loop:
```as    call nextnext:    pop rbp
    mov edi, 0xb8000
loop:    mov rsi, byte [rbp]    inc rbp    call draw_byte    jmp loop
draw_byte:    /* rdi: framebuffer */    /* rsi: byte */    /* == CLOBBERS == */    /* rsi, rbx, rax */
    mov rbx, rsi
    shr rsi, 4    call draw_nibble
    mov rsi, rbx    call draw_nibble
    ret
draw_nibble:    /* rdi: framebuffer */    /* rsi: nibble */    /* == CLOBBERS == */    /* rax */
    mov rax, rsi    and al, 0x0f    cmp al, 0x09    ja is_char
is_digit:    add al, 0x30    jmp output
is_char:    add al, 0x41 - 0x0a
output:    mov ah, 0x1f
    mov word [rdi], ax    add rdi, 2     ret```
Sending this to the port and connecting via VNC reveals this:
![qemu stage 3 flag](https://losfuzzys.github.io/images/posts/2018-09-20-csawctfquals-tour-of-x86-stage3.png)
Writing this down and decoding this with this:
```pyimport binascii
print(binascii.unhexlify(    "666c61677b53346c31795f53653131535f7461634f5368656c6c5f633064335f62595f7448655f5365345f53683072657d").decode())```
yields the flag:
```flag{S4l1y_Se11S_tacOShell_c0d3_bY_tHe_Se4_Sh0re}```