Created
April 11, 2017 01:25
-
-
Save MDFL64/df6842a399dae3f4ad6f1f3708f16795 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; Adam Coggehsall | |
; Writeup for Dakotacon CTF 2017: Postfix Shellcode | |
; Problem Description: | |
; There is a service listening on 138.247.115.12:9994. | |
; This service takes and executes exactly 80 bytes of x86 shellcode. | |
; There is a char pointer to a postfix expression in ebx. | |
; Your are to compute the value of that expression and store the result in eax. | |
; Possible numbers are 0-9 and possible operators are +,-,*,/. | |
; Every token is one char/byte. | |
; Not much of an actual writeup, but I tried to annotate the code I used. | |
; Built with flat assembler, uses 53 bytes. | |
; Pretty sure I just piped the resulting binary into netcat. | |
; This is a macro I stole from another project of mine, | |
; based on a macro I stole off a forum. | |
macro display_num num | |
{ | |
value = num | |
pos=1 | |
if value<0 | |
value = -value | |
display '-' | |
end if | |
while pos*10<=value | |
pos=pos*10 | |
end while | |
while pos>=1 | |
digit=value/pos | |
value=value-(digit*pos) | |
pos=pos/10 | |
display ('0'+digit) | |
end while | |
} | |
use32 | |
top: | |
; Grab a character and increment our pointer. | |
movzx eax, byte [ebx] | |
inc ebx | |
; Figure out what character we're dealing with. | |
; We can check for two characters with each cmp. | |
; If character is greater than /, it must be a number. | |
cmp al,'/' | |
ja num | |
; At this point, the character must be either an operator or null. | |
; Pop two values from the stack. | |
; For operators, these are arguments. | |
; For null, they are the result and the return address. | |
pop ecx | |
pop edx | |
; Finally, jump to the handler for division if the previous comparison was equal. | |
je op_div | |
; Handle + and - | |
cmp al, '+' | |
ja op_sub | |
je op_add | |
; Handle * | |
cmp al, '*' | |
je op_mul | |
; If we end up here, save the result and return. | |
mov eax, ecx | |
jmp edx | |
op_sub: | |
; Negate second parameter and fall through. | |
neg ecx | |
op_add: | |
; Add two numbers. | |
add ecx, edx | |
push ecx | |
jmp top | |
op_mul: | |
; Multiply two numbers. | |
imul ecx, edx | |
push ecx | |
jmp top | |
op_div: | |
; From some x86 docs website: | |
; Signed divide EDX:EAX by r/m32, with result stored in EAX = Quotient, EDX = Remainder. | |
; :) | |
mov eax, edx | |
xor edx, edx | |
idiv ecx | |
push eax | |
jmp top | |
num: | |
; Subtract ASCII '0' to get the actual numeric value. | |
; Push the result. | |
sub al, '0' | |
push eax | |
jmp top | |
; Get size of code up to this point. | |
len = $-$$ | |
display_num len | |
; Fill with nops up to 80 bytes | |
repeat 80-len | |
nop | |
end repeat |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment