Objective
Challenge
This was an amazing challenge that provided a unique and educational experience. The topic was "Assembly language". We were required to solve several problems that required an understanding of the assembly code blocks provided to us. This challenge started small and slowly built up as we progressed through each level.
Conversation
Welcome to Shellcode Primer (terminal)
Introduction
We will be learning basic x64 shellcode to read a file which of course is quite difficult to outright perform. However, this challenge will guide us through all the learning blocks we need to have a solid foundation and complete the 12th and final challenge.
1. Introduction
; Set up some registers (sorta like variables) with values
; In the debugger, look how these change!
mov rax, 0
mov rbx, 1
mov rcx, 2
mov rdx, 3
mov rsi, 4
mov rdi, 5
mov rbp, 6
; Push and pop - watch how the stack changes!
push 0x12345678
pop rax
push 0x1111
push 0x2222
push 0x3333
pop rax
pop rax
pop rax
; This creates a string and references it in rax - watch the debugger!
call getstring
db "Hello World!",0
getstring:
pop rax
; Finally, return 0x1337
mov rax, 0x1337
ret
2. Loops
; We want to loop 5 times - you can change this if you want!
mov rax, 5
; Top of the loop
top:
; Decrement rax
dec rax
; Jump back to the top until rax is zero
jnz top
; Cleanly return after the loop
ret
3. Getting Started
; This is a comment! We'll use comments to help guide your journey.
; Right now, we just need to RETurn!
;
; Enter a return statement below and hit Execute to see what happens!
ret
4. Returning a Value
; TODO: Set rax to 1337
; Return, just like we did last time
mov rax, 1337
ret
5. System Calls
; TODO: Find the syscall number for sys_exit and put it in rax
; TODO: Put the exit_code we want (99) in rdi
; Perform the actual syscall
mov rax, 60
mov rdi, 99
syscall
6. Calling into the Void
; Push this value to the stack
push 0x12345678
; Try to return
ret
7. Getting RIP
; Remember, this call pushes the return address to the stack
call place_below_the_nop
; This is where the function *thinks* it is supposed to return
nop
; This is a 'label' - as far as the call knows, this is the start of a function
place_below_the_nop:
; TODO: Pop the top of the stack into rax
pop rax
; Return from our code, as in previous levels
ret
8. Hello, World!
; This would be a good place for a call
call boom
; This is the literal string 'Hello World', null terminated, as code. Except
; it'll crash if it actually tries to run, so we'd better jump over it!
db 'Hello World',0
boom:
; This would be a good place for a label and a pop
pop rax
; This would be a good place for a re... oh wait, it's already here. Hooray!
ret
9. Hello, World!!
; TODO: Get a reference to this string into the correct register
call boom
db 'Hello World!',0
; Set up a call to sys_write
; TODO: Set rax to the correct syscall number for sys_write
; TODO: Set rdi to the first argument (the file descriptor, 1)
; TODO Set rsi to the second argument (buf - this is the "Hello World" string)
boom:
mov rax, 1
mov rdi, 1
pop rsi
; TODO Set rdx to the third argument (length of the string, in bytes)
mov rdx, 12
; Perform the syscall
syscall
; Return cleanly
ret
10. Opening a File
; TODO: Get a reference to this string into the correct register
call boom
db '/etc/passwd',0
; Set up a call to sys_open
; TODO: Set rax to the correct syscall number
; TODO: Set rdi to the first argument (the filename)
; TODO: Set rsi to the second argument (flags - 0 is fine)
; TODO: Set rdx to the third argument (mode - 0 is also fine)
; Perform the syscall
boom:
pop rbx
mov rax, 2
mov rdi, rbx
mov rsi, 0
mov rdx, 0
syscall
; syscall sets rax to the file handle, so to return the file handle we don't
; need to do anything else!
ret
11. Reading a File
; TODO: Get a reference to this
call boom
db '/var/northpolesecrets.txt',0
boom:
pop rbx
; TODO: Call sys_open
mov rax, 2
mov rdi, rbx
mov rsi, 0
mov rdx, 0
syscall
; TODO: Call sys_read on the file handle and read it into rsp
mov rbx, rax
mov rax, 0
mov rdi, rbx
mov rsi, rsp
mov rdx, 136
syscall
; TODO: Call sys_write to write the contents from rsp to stdout (1)
mov rax, 1
mov rdi, 1
mov rsi, rsp
mov rdx, 136
syscall
; TODO: Call sys_exit
mov rax, 60
mov rdi, 99
syscall
Comments