Added the morphing problem
Along with all of its generation script stuff...
This commit is contained in:
parent
febcc473f1
commit
23125c60af
27 changed files with 1059 additions and 0 deletions
BIN
self-modifier/b0.bin
Normal file
BIN
self-modifier/b0.bin
Normal file
Binary file not shown.
BIN
self-modifier/b1.bin
Normal file
BIN
self-modifier/b1.bin
Normal file
Binary file not shown.
BIN
self-modifier/b2.bin
Normal file
BIN
self-modifier/b2.bin
Normal file
Binary file not shown.
BIN
self-modifier/b3.bin
Normal file
BIN
self-modifier/b3.bin
Normal file
Binary file not shown.
1
self-modifier/b4.bin
Normal file
1
self-modifier/b4.bin
Normal file
|
@ -0,0 +1 @@
|
|||
¼°wþ;$ân6ßi2*Élu ež5ry ãi<19>åဠriZ?{ hpŽ0ä0$ùæ˜ flêgkß5.NÓâ)ˆW‹ LL$’ræ¶rü]<05> U)xˆŠrLO’üM“\(¬l¯%wØ8trrq"˜j9úM8Þ®89:<3A><=>GGÊGÉiH¬qÿJKL…NOP%Y\â_ÜμZ[\ª¼Öæ„bcd¦®ghi±klmbû<rþX{<7B>}£yz{•}~ý<7F><C3BD>5Á<35>€ÏbBbŒ<62>Ž|<7C>‘’–—˜™š›œ<E280BA>žŸ ›µ£¤¥¦§¨©ª‚±ãÁßÕ<C39F>²Œ´µ¶å¸¹º»½¼¼¼ÄÄÄÄÌÌÌÌÄÄÄÄÜÜÜÜÄÄÄÄÌÌÌÌÄÄÄÄüüüüÄÄÄÄÌÌÌÌÄÄÄÄÜÜÜÜÄÄÄÄÌÌÌÌÄÄÄļ¼¼¼DDDDLLLLDDDD\\\\DDDDLLLLDDDD||||DDDDLLLLDDDD\\\\DDDDLLLLDDDD¼¼¼¼ÄÄÄÄÌÌÌÌÄÄÄÄÜÜÜÜÄÄÄÄÌÌÌÌÄÄÄÄüüüüÄÄÄÄÌÌÌÌÄÄÄÄÜÜÜÜÄÄÄÄÌÌÌÌÄÄÄļ¼¼¼DDDDLLLLDDDD\\\\DDDDLLLLDDDD||||DDDDLLLLDDDD\\\\
|
5
self-modifier/base_block.asm
Normal file
5
self-modifier/base_block.asm
Normal file
|
@ -0,0 +1,5 @@
|
|||
format binary
|
||||
use32
|
||||
include 'std.inc'
|
||||
|
||||
resv_stuff 512-$
|
BIN
self-modifier/base_block.bin
Normal file
BIN
self-modifier/base_block.bin
Normal file
Binary file not shown.
90
self-modifier/build.py
Normal file
90
self-modifier/build.py
Normal file
|
@ -0,0 +1,90 @@
|
|||
import subprocess
|
||||
# Build a self-modifying thinga-ma-jig
|
||||
|
||||
def run_command(cmd):
|
||||
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, stdin=subprocess.PIPE)
|
||||
stdoutput = proc.stdout.read() + proc.stderr.read()
|
||||
return stdoutput
|
||||
|
||||
def build_bin(name):
|
||||
print(run_command('fasm %s.asm' % name))
|
||||
|
||||
def create_xor_block(last_shellcode_block, next_shellcode_block):
|
||||
block = bytearray(b'')
|
||||
for x in range(0, len(last_shellcode_block)): # each shellcode block should be 512 bytes
|
||||
block.append((last_shellcode_block[x]) ^ (next_shellcode_block[x]))
|
||||
return bytes(block)
|
||||
|
||||
def get_shellcode_block(name):
|
||||
build_bin(name)
|
||||
f = open('%s.bin' % name, 'rb')
|
||||
out = f.read()
|
||||
f.close()
|
||||
return out
|
||||
|
||||
shellcode_files = ['first', 'second', 'third', 'fourth', 'last']
|
||||
shellcode_blocks = [get_shellcode_block('base_block')]
|
||||
morpher_file = 'morpher'
|
||||
morpher_template = 'morpher.template.asm'
|
||||
|
||||
xor_blocks = []
|
||||
xor_block_files = []
|
||||
|
||||
def build_shellcode_files():
|
||||
for x in shellcode_files:
|
||||
shellcode_blocks.append(get_shellcode_block(x))
|
||||
|
||||
def gen_xor_blocks():
|
||||
for x in range(0, len(shellcode_files)):
|
||||
xor_block = create_xor_block(shellcode_blocks[x], shellcode_blocks[x+1])
|
||||
xor_blocks.append(xor_block)
|
||||
f = open('b%d.bin' % x, 'wb')
|
||||
f.write(xor_block)
|
||||
f.close()
|
||||
xor_block_files.append('b%d.bin' % x)
|
||||
|
||||
|
||||
def create_morpher_file():
|
||||
_mrph = 'file \'base_block.bin\'\n'
|
||||
_data = ''
|
||||
_block_list = ''
|
||||
|
||||
for x in xor_block_files:
|
||||
_data += '%s: file \'%s\'\n' % (x, x)
|
||||
_block_list += '%s, ' % x
|
||||
|
||||
_data += 'block_ptrs dd %s0' % _block_list
|
||||
|
||||
f = open(morpher_template, 'rb')
|
||||
template = f.read().decode('utf-8')
|
||||
f.close()
|
||||
result = template % (_mrph, _data)
|
||||
f = open('%s.asm' % morpher_file, 'wb')
|
||||
f.write(result.encode('utf-8'))
|
||||
f.close()
|
||||
|
||||
|
||||
# The morpher has 3 sections, modifiable code, static code (morphing), data
|
||||
# Modifiable code will be where each shellcode segment is done
|
||||
# Static code has the morpher that sets up each shellcode segment
|
||||
# Data has the XOR block pointers and indicies for the ones to use in order
|
||||
# Begins by the morpher creating the first shellcode block, setting it up, then running it
|
||||
# continues until the final block that will print the flag
|
||||
# Kinda like a binary bomb but in one binary
|
||||
|
||||
# On entrance to each shellcode segment the ebx register will be a vtable of std funcs
|
||||
# printf
|
||||
# puts
|
||||
# scanf
|
||||
# esi contains the base address of the shellcode segment
|
||||
# edi contains the address of the part of the flag that this segment fills
|
||||
# edx contains the number of the block
|
||||
|
||||
build_shellcode_files()
|
||||
gen_xor_blocks()
|
||||
create_morpher_file()
|
||||
build_bin(morpher_file)
|
||||
|
||||
#print(create_xor_block(b'123', b'321'))
|
||||
#print(get_shellcode_block('shellcode'))
|
84
self-modifier/char.inc
Normal file
84
self-modifier/char.inc
Normal file
|
@ -0,0 +1,84 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Character defines
|
||||
NULL equ 0x00
|
||||
BELL equ 0x07
|
||||
BSPC equ 0x08
|
||||
TAB equ 0x09
|
||||
ENDL equ 0x0A
|
||||
CRET equ 0x0D
|
||||
|
||||
CHAR_0 equ 0x30
|
||||
CHAR_1 equ 0x31
|
||||
CHAR_2 equ 0x32
|
||||
CHAR_3 equ 0x33
|
||||
CHAR_4 equ 0x34
|
||||
CHAR_5 equ 0x35
|
||||
CHAR_6 equ 0x36
|
||||
CHAR_7 equ 0x37
|
||||
CHAR_8 equ 0x38
|
||||
CHAR_9 equ 0x39
|
||||
CHAR_A equ 0x41
|
||||
CHAR_B equ 0x42
|
||||
CHAR_C equ 0x43
|
||||
CHAR_D equ 0x44
|
||||
CHAR_E equ 0x45
|
||||
CHAR_F equ 0x46
|
||||
CHAR_G equ 0x47
|
||||
CHAR_H equ 0x48
|
||||
CHAR_I equ 0x49
|
||||
CHAR_J equ 0x4a
|
||||
CHAR_K equ 0x4b
|
||||
CHAR_L equ 0x4c
|
||||
CHAR_M equ 0x4d
|
||||
CHAR_N equ 0x4e
|
||||
CHAR_O equ 0x4f
|
||||
CHAR_P equ 0x50
|
||||
CHAR_Q equ 0x51
|
||||
CHAR_R equ 0x52
|
||||
CHAR_S equ 0x53
|
||||
CHAR_T equ 0x54
|
||||
CHAR_U equ 0x55
|
||||
CHAR_V equ 0x56
|
||||
CHAR_W equ 0x57
|
||||
CHAR_X equ 0x58
|
||||
CHAR_Y equ 0x59
|
||||
CHAR_Z equ 0x5a
|
||||
CHAR_a equ 0x61
|
||||
CHAR_b equ 0x62
|
||||
CHAR_c equ 0x63
|
||||
CHAR_d equ 0x64
|
||||
CHAR_e equ 0x65
|
||||
CHAR_f equ 0x66
|
||||
CHAR_g equ 0x67
|
||||
CHAR_h equ 0x68
|
||||
CHAR_i equ 0x69
|
||||
CHAR_j equ 0x6a
|
||||
CHAR_k equ 0x6b
|
||||
CHAR_l equ 0x6c
|
||||
CHAR_m equ 0x6d
|
||||
CHAR_n equ 0x6e
|
||||
CHAR_o equ 0x6f
|
||||
CHAR_p equ 0x70
|
||||
CHAR_q equ 0x71
|
||||
CHAR_r equ 0x72
|
||||
CHAR_s equ 0x73
|
||||
CHAR_t equ 0x74
|
||||
CHAR_u equ 0x75
|
||||
CHAR_v equ 0x76
|
||||
CHAR_w equ 0x77
|
||||
CHAR_x equ 0x78
|
||||
CHAR_y equ 0x79
|
||||
CHAR_z equ 0x7a
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
macro resv c_size
|
||||
{
|
||||
db c_size dup (0)
|
||||
}
|
||||
|
||||
macro resv_stuff c_size
|
||||
{
|
||||
repeat c_size
|
||||
db % and 0xff
|
||||
end repeat
|
||||
}
|
2
self-modifier/description.md
Normal file
2
self-modifier/description.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
Welcome to the RE training course, this problem has 4 phases. Solve all four to get the flag.
|
||||
[Download](${morpher_exe})
|
140
self-modifier/first.asm
Normal file
140
self-modifier/first.asm
Normal file
|
@ -0,0 +1,140 @@
|
|||
format binary
|
||||
use32
|
||||
include 'std.inc'
|
||||
|
||||
; On entrance to each shellcode segment the ebx register will be a vtable of std funcs
|
||||
; printf
|
||||
; puts
|
||||
; scanf
|
||||
; sin
|
||||
; cos
|
||||
; tan
|
||||
; asin
|
||||
; acos
|
||||
; atan
|
||||
; malloc
|
||||
; free
|
||||
; esi contains the base address of the shellcode segment
|
||||
; edi contains the address of the part of the flag that this segment fills
|
||||
; edx contains the number of the block
|
||||
|
||||
start:
|
||||
push edx
|
||||
push edi
|
||||
push esi
|
||||
|
||||
mov eax, dword [ebx]
|
||||
lea ecx, [esi + base_txt]
|
||||
push ecx
|
||||
call dword [eax]
|
||||
add esp, 4
|
||||
|
||||
xor eax, eax
|
||||
push eax
|
||||
mov eax, esp
|
||||
push eax
|
||||
|
||||
lea eax, [ebx + 8]
|
||||
mov eax, dword [eax]
|
||||
lea ecx, [esi+scanf_txt]
|
||||
push ecx
|
||||
call dword [eax]
|
||||
add esp, 8
|
||||
|
||||
; inputt'd float is now on top of the stack
|
||||
pop eax
|
||||
mov dword [esi+temp_val], eax
|
||||
|
||||
sub esp, 8
|
||||
cvtss2sd xmm0, dword [esi+temp_val]
|
||||
movsd qword [esp], xmm0
|
||||
|
||||
; call cos
|
||||
lea eax, [ebx + 0x10]
|
||||
mov eax, dword [eax]
|
||||
call dword [eax]
|
||||
|
||||
fstp qword [esp]
|
||||
movsd xmm0, qword [esp]
|
||||
add esp, 8
|
||||
cvtss2sd xmm1, dword [esi+c_val]
|
||||
mulsd xmm0, xmm1
|
||||
push ebp
|
||||
push ebp
|
||||
movsd qword [esp], xmm0
|
||||
|
||||
; call atan
|
||||
lea eax, [ebx + 0x20]
|
||||
mov eax, dword [eax]
|
||||
call dword [eax]
|
||||
|
||||
fstp qword [esp]
|
||||
movsd xmm0, qword [esp]
|
||||
pop eax
|
||||
cvtss2sd xmm1, dword [esi+b_val]
|
||||
pop ecx
|
||||
mulsd xmm0, xmm1
|
||||
push esp
|
||||
push ebp
|
||||
movsd qword [esp], xmm0
|
||||
|
||||
; call sin
|
||||
lea eax, [ebx + 0xc]
|
||||
mov eax, dword [eax]
|
||||
call dword [eax]
|
||||
|
||||
fstp qword [esp]
|
||||
cvtss2sd xmm1, dword [esi+a_val]
|
||||
movsd xmm0, qword [esp]
|
||||
mulsd xmm0, xmm1
|
||||
|
||||
movsd qword [esp], xmm0
|
||||
cvtsd2ss xmm0, qword [esp]
|
||||
pop eax
|
||||
movss dword [esp], xmm0
|
||||
pop eax
|
||||
|
||||
pop esi
|
||||
push esi
|
||||
|
||||
cmp eax, dword [esi+final_val]
|
||||
jnz trash
|
||||
lea ecx, [esi+right_txt]
|
||||
jmp past_trash
|
||||
trash:
|
||||
lea ecx, [esi+wrong_txt]
|
||||
; Make this so it crashes badly
|
||||
inc esp
|
||||
past_trash:
|
||||
push ecx
|
||||
lea eax, [ebx + 0x4]
|
||||
mov eax, dword [eax]
|
||||
call dword [eax]
|
||||
pop ebp
|
||||
|
||||
pop esi
|
||||
pop edi
|
||||
pop edx
|
||||
|
||||
mov eax, dword [esi+temp_val]
|
||||
; 0x61375a7b = little endian of '{Z7a'
|
||||
; 0x61375a7b ^ 0x3fab396d which is the value of the correct input 1.33769
|
||||
; is equal to 0x5e9c6316
|
||||
xor eax, 0x5e9c6316
|
||||
mov dword [edi], eax
|
||||
xor eax, eax
|
||||
mov dword [esi+temp_val], eax
|
||||
|
||||
retn
|
||||
|
||||
b_val dd 0x4039999a
|
||||
base_txt db 'Please enter the best number', ENDL, 0
|
||||
a_val dd 0x40d00000
|
||||
scanf_txt db '%f', 0
|
||||
final_val dd 0xc092e6a0
|
||||
right_txt db 'You got it!', 0
|
||||
c_val dd 0xbf99999a
|
||||
wrong_txt db 'You dumb.', 0
|
||||
temp_val dd 0
|
||||
|
||||
resv_stuff 512-$
|
BIN
self-modifier/first.bin
Normal file
BIN
self-modifier/first.bin
Normal file
Binary file not shown.
167
self-modifier/fourth.asm
Normal file
167
self-modifier/fourth.asm
Normal file
|
@ -0,0 +1,167 @@
|
|||
format binary
|
||||
use32
|
||||
include 'std.inc'
|
||||
|
||||
; On entrance to each shellcode segment the ebx register will be a vtable of std funcs
|
||||
; printf
|
||||
; puts
|
||||
; scanf
|
||||
; sin
|
||||
; cos
|
||||
; tan
|
||||
; asin
|
||||
; acos
|
||||
; atan
|
||||
; malloc
|
||||
; free
|
||||
; esi contains the base address of the shellcode segment
|
||||
; edi contains the address of the part of the flag that this segment fills
|
||||
; edx contains the number of the block
|
||||
|
||||
; 2 - 3,5 - '-'
|
||||
; 3 - 5,7 - '_'
|
||||
; 5 - 7,11 - 'e'
|
||||
; 7 - 11,13 - 'x'
|
||||
; 11 - 13,17 - 't'
|
||||
; 13 - 17,19 - '}'
|
||||
; 17 - 19,23 - '}'
|
||||
; 19 - 23,29 - '}'
|
||||
|
||||
; 3 * 7 * 11 * 17 = 3927
|
||||
; answer "2 4 6 12"
|
||||
; flag _xt}
|
||||
|
||||
start:
|
||||
push edi
|
||||
|
||||
lea eax, [ebx + 0x4]
|
||||
lea ecx, [esi+startup_txt]
|
||||
mov eax, dword [eax]
|
||||
push ecx
|
||||
call dword [eax]
|
||||
pop ebp
|
||||
|
||||
pop edi
|
||||
|
||||
lea ebp, [esi+one]
|
||||
.lp:
|
||||
call process
|
||||
cmp byte [ebp+8], 125
|
||||
jnz .lp
|
||||
|
||||
mov eax, dword [esi+super_val]
|
||||
cmp eax, 3927
|
||||
jnz .bad
|
||||
jmp .finish
|
||||
|
||||
.bad:
|
||||
lea eax, [ebx + 0x4]
|
||||
lea ecx, [esi+wrong_txt]
|
||||
mov eax, dword [eax]
|
||||
push ecx
|
||||
call dword [eax]
|
||||
pop ebp
|
||||
inc esp
|
||||
|
||||
.finish:
|
||||
ret
|
||||
|
||||
two:
|
||||
dd three,five
|
||||
db '-',2
|
||||
|
||||
startup_txt db 'Numberz?', 0
|
||||
|
||||
three:
|
||||
dd five,seven
|
||||
db '_',3
|
||||
|
||||
fmt_txt db '%u',0
|
||||
|
||||
five:
|
||||
dd seven,eleven
|
||||
db 'e',5
|
||||
|
||||
; ebp = current node
|
||||
process:
|
||||
push ebp
|
||||
push ebp
|
||||
mov eax, esp
|
||||
push eax
|
||||
|
||||
lea eax, [ebx + 8]
|
||||
lea ecx, [esi+fmt_txt]
|
||||
mov eax, dword [eax]
|
||||
push ecx
|
||||
call dword [eax]
|
||||
pop ebp
|
||||
pop eax
|
||||
pop ecx
|
||||
pop ebp
|
||||
|
||||
movzx eax, byte [ebp+9]
|
||||
|
||||
cmp eax, ecx
|
||||
jle above_handler
|
||||
jmp below_handler
|
||||
|
||||
seven:
|
||||
dd eleven,thirteen
|
||||
db 'x',7
|
||||
|
||||
above_handler:
|
||||
mov ecx, dword [ebp+4]
|
||||
lea ebp, [esi+ecx]
|
||||
jmp add_next_char
|
||||
|
||||
eleven:
|
||||
dd thirteen,seventeen
|
||||
db 't',11
|
||||
|
||||
mul_handler:
|
||||
movzx eax, byte [ebp+9]
|
||||
mov edx, dword [esi+super_val]
|
||||
mul edx
|
||||
mov dword [esi+super_val], eax
|
||||
ret
|
||||
|
||||
thirteen:
|
||||
dd seventeen, nineteen
|
||||
db '}',13
|
||||
|
||||
below_handler:
|
||||
mov ecx, dword [ebp]
|
||||
lea ebp, [esi+ecx]
|
||||
jmp add_next_char
|
||||
|
||||
seventeen:
|
||||
dd nineteen, twentythree
|
||||
db '}',17
|
||||
|
||||
add_next_char:
|
||||
movzx eax, byte [ebp+8]
|
||||
mov byte [edi], al
|
||||
inc edi
|
||||
jmp mul_handler
|
||||
|
||||
nineteen:
|
||||
dd twentythree, twentynine
|
||||
db '}',19
|
||||
|
||||
super_val dd 1
|
||||
|
||||
twentythree:
|
||||
dd 0, 0
|
||||
db ':',23
|
||||
|
||||
twentynine:
|
||||
dd 0, 0
|
||||
db ')',29
|
||||
|
||||
wrong_txt db 'Nope!',0
|
||||
|
||||
one:
|
||||
dd two, three
|
||||
db 0,1
|
||||
|
||||
resv_stuff 512-$
|
BIN
self-modifier/fourth.bin
Normal file
BIN
self-modifier/fourth.bin
Normal file
Binary file not shown.
13
self-modifier/grader.py
Normal file
13
self-modifier/grader.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
def grade(random, key):
|
||||
if key.find("Z7a_ok_qfme_xt") != -1:
|
||||
return True, "Correct!"
|
||||
incorrect_txt = 'Wrong. '
|
||||
if key.find("Z7a") == -1:
|
||||
incorrect_txt += "Phase 1 failed. "
|
||||
if key.find("_ok_") == -1:
|
||||
incorrect_txt += "Phase 2 failed. "
|
||||
if key.find("qfme") == -1:
|
||||
incorrect_txt += "Phase 3 failed. "
|
||||
if key.find("_xt") == -1:
|
||||
incorrect_txt += "Phase 4 failed. "
|
||||
return False, incorrect_txt
|
37
self-modifier/last.asm
Normal file
37
self-modifier/last.asm
Normal file
|
@ -0,0 +1,37 @@
|
|||
format binary
|
||||
use32
|
||||
include 'std.inc'
|
||||
|
||||
; On entrance to each shellcode segment the ebx register will be a vtable of std funcs
|
||||
; printf
|
||||
; puts
|
||||
; scanf
|
||||
; sin
|
||||
; cos
|
||||
; tan
|
||||
; asin
|
||||
; acos
|
||||
; atan
|
||||
; malloc
|
||||
; free
|
||||
; esi contains the base address of the shellcode segment
|
||||
; edi contains the address of the part of the flag that this segment fills
|
||||
; edx contains the number of the block
|
||||
|
||||
jmp start
|
||||
|
||||
output_text db 'Assuming you got every challenge right here is the flag: %s', ENDL, 0
|
||||
|
||||
start:
|
||||
shl edx, 2
|
||||
sub edi, edx
|
||||
push edi
|
||||
mov eax, dword [ebx]
|
||||
lea ecx, [esi + output_text]
|
||||
push ecx
|
||||
call dword [eax]
|
||||
add esp, 8
|
||||
|
||||
ret
|
||||
|
||||
resv_stuff 512-$
|
BIN
self-modifier/last.bin
Normal file
BIN
self-modifier/last.bin
Normal file
Binary file not shown.
109
self-modifier/morpher.asm
Normal file
109
self-modifier/morpher.asm
Normal file
|
@ -0,0 +1,109 @@
|
|||
format PE console
|
||||
entry start
|
||||
include 'C:\\Projects/asm/INCLUDE/win32a.inc'
|
||||
include 'C:\\Projects/asm/std.inc'
|
||||
|
||||
section '.mrph' code readable executable writeable
|
||||
mrph:
|
||||
|
||||
file 'base_block.bin'
|
||||
|
||||
|
||||
section '.stat' code readable executable
|
||||
|
||||
data import
|
||||
library msvcrt, 'msvcrt.dll'
|
||||
import msvcrt, \
|
||||
printf , 'printf', \
|
||||
puts , 'puts', \
|
||||
scanf , 'scanf', \
|
||||
sin , 'sin', \
|
||||
cos , 'cos', \
|
||||
tan , 'tan', \
|
||||
asin , 'asin', \
|
||||
acos , 'acos', \
|
||||
atan , 'atan', \
|
||||
malloc , 'malloc', \
|
||||
free , 'free', \
|
||||
getchar , 'getchar'
|
||||
end data
|
||||
|
||||
do_morph:
|
||||
push ebp
|
||||
mov eax, 1
|
||||
mov edx, dword [num_block]
|
||||
lea ecx, [block_ptrs + 4*edx]
|
||||
mov ecx, dword [ecx]
|
||||
|
||||
cmp ecx, 0 ; If the block ptr is null return
|
||||
jz .finish
|
||||
|
||||
inc edx
|
||||
mov dword [num_block], edx
|
||||
lea edx, [ecx+512]
|
||||
mov edi, mrph
|
||||
|
||||
.mod:
|
||||
cmp ecx, edx
|
||||
jz .finish
|
||||
movzx eax, byte [ecx]
|
||||
movzx ebp, byte [edi]
|
||||
xor eax, ebp
|
||||
mov byte [edi], al
|
||||
inc edi
|
||||
inc ecx
|
||||
xor eax, eax
|
||||
jmp .mod
|
||||
|
||||
.finish:
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
; No args, flushes input.
|
||||
flush_inp:
|
||||
call [getchar]
|
||||
cmp eax, -1
|
||||
jz .finish
|
||||
cmp eax, ENDL
|
||||
jnz flush_inp
|
||||
.finish:
|
||||
ret
|
||||
|
||||
; On entrance to each shellcode segment the ebx register will be a vtable of std funcs
|
||||
; esi contains the base address of the shellcode segment
|
||||
; edi contains the address of the part of the flag that this segment fills
|
||||
; edx contains the number of the block
|
||||
run_morphed:
|
||||
mov esi, mrph
|
||||
mov edx, dword [num_block]
|
||||
dec edx
|
||||
lea edi, [flag + 4*edx]
|
||||
mov ebx, func_vtable
|
||||
call mrph
|
||||
ret
|
||||
|
||||
start:
|
||||
call do_morph
|
||||
cmp eax, 0
|
||||
jnz .finish
|
||||
call run_morphed
|
||||
call flush_inp
|
||||
jmp start
|
||||
|
||||
.finish:
|
||||
ret
|
||||
|
||||
section '.dat' data readable writeable
|
||||
|
||||
num_block dd 0
|
||||
|
||||
func_vtable dd printf, puts, scanf, sin, cos, tan, asin, acos, atan, malloc, free, 0
|
||||
|
||||
flag db 64 dup (0)
|
||||
|
||||
b0.bin: file 'b0.bin'
|
||||
b1.bin: file 'b1.bin'
|
||||
b2.bin: file 'b2.bin'
|
||||
b3.bin: file 'b3.bin'
|
||||
b4.bin: file 'b4.bin'
|
||||
block_ptrs dd b0.bin, b1.bin, b2.bin, b3.bin, b4.bin, 0
|
BIN
self-modifier/morpher.exe
Normal file
BIN
self-modifier/morpher.exe
Normal file
Binary file not shown.
103
self-modifier/morpher.template.asm
Normal file
103
self-modifier/morpher.template.asm
Normal file
|
@ -0,0 +1,103 @@
|
|||
format PE console
|
||||
entry start
|
||||
include 'C:\\Projects/asm/INCLUDE/win32a.inc'
|
||||
include 'C:\\Projects/asm/std.inc'
|
||||
|
||||
section '.mrph' code readable executable writeable
|
||||
mrph:
|
||||
|
||||
%s
|
||||
|
||||
section '.stat' code readable executable
|
||||
|
||||
data import
|
||||
library msvcrt, 'msvcrt.dll'
|
||||
import msvcrt, \
|
||||
printf , 'printf', \
|
||||
puts , 'puts', \
|
||||
scanf , 'scanf', \
|
||||
sin , 'sin', \
|
||||
cos , 'cos', \
|
||||
tan , 'tan', \
|
||||
asin , 'asin', \
|
||||
acos , 'acos', \
|
||||
atan , 'atan', \
|
||||
malloc , 'malloc', \
|
||||
free , 'free', \
|
||||
getchar , 'getchar'
|
||||
end data
|
||||
|
||||
do_morph:
|
||||
push ebp
|
||||
mov eax, 1
|
||||
mov edx, dword [num_block]
|
||||
lea ecx, [block_ptrs + 4*edx]
|
||||
mov ecx, dword [ecx]
|
||||
|
||||
cmp ecx, 0 ; If the block ptr is null return
|
||||
jz .finish
|
||||
|
||||
inc edx
|
||||
mov dword [num_block], edx
|
||||
lea edx, [ecx+512]
|
||||
mov edi, mrph
|
||||
|
||||
.mod:
|
||||
cmp ecx, edx
|
||||
jz .finish
|
||||
movzx eax, byte [ecx]
|
||||
movzx ebp, byte [edi]
|
||||
xor eax, ebp
|
||||
mov byte [edi], al
|
||||
inc edi
|
||||
inc ecx
|
||||
xor eax, eax
|
||||
jmp .mod
|
||||
|
||||
.finish:
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
; No args, flushes input.
|
||||
flush_inp:
|
||||
call [getchar]
|
||||
cmp eax, -1
|
||||
jz .finish
|
||||
cmp eax, ENDL
|
||||
jnz flush_inp
|
||||
.finish:
|
||||
ret
|
||||
|
||||
; On entrance to each shellcode segment the ebx register will be a vtable of std funcs
|
||||
; esi contains the base address of the shellcode segment
|
||||
; edi contains the address of the part of the flag that this segment fills
|
||||
; edx contains the number of the block
|
||||
run_morphed:
|
||||
mov esi, mrph
|
||||
mov edx, dword [num_block]
|
||||
dec edx
|
||||
lea edi, [flag + 4*edx]
|
||||
mov ebx, func_vtable
|
||||
call mrph
|
||||
ret
|
||||
|
||||
start:
|
||||
call do_morph
|
||||
cmp eax, 0
|
||||
jnz .finish
|
||||
call run_morphed
|
||||
call flush_inp
|
||||
jmp start
|
||||
|
||||
.finish:
|
||||
ret
|
||||
|
||||
section '.dat' data readable writeable
|
||||
|
||||
num_block dd 0
|
||||
|
||||
func_vtable dd printf, puts, scanf, sin, cos, tan, asin, acos, atan, malloc, free, 0
|
||||
|
||||
flag db 64 dup (0)
|
||||
|
||||
%s
|
39
self-modifier/out.txt
Normal file
39
self-modifier/out.txt
Normal file
|
@ -0,0 +1,39 @@
|
|||
1
|
||||
1
|
||||
3
|
||||
5
|
||||
9
|
||||
17
|
||||
31
|
||||
57
|
||||
105
|
||||
193
|
||||
355
|
||||
653
|
||||
1201
|
||||
2209
|
||||
4063
|
||||
7473
|
||||
13745
|
||||
25281
|
||||
46499
|
||||
85525
|
||||
157305
|
||||
289329
|
||||
532159
|
||||
978793
|
||||
1800281
|
||||
3311233
|
||||
6090307
|
||||
11201821
|
||||
20603361
|
||||
37895489
|
||||
69700671
|
||||
128199521
|
||||
235795681
|
||||
433695873
|
||||
797691075
|
||||
1467182629
|
||||
2698569577
|
||||
668475985
|
||||
539260895
|
7
self-modifier/problem.yml
Normal file
7
self-modifier/problem.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
title: Morphin
|
||||
category: Reverse Engineering
|
||||
value: 450
|
||||
author: r3ndom
|
||||
autogen: false
|
||||
files:
|
||||
- morpher.exe
|
120
self-modifier/second.asm
Normal file
120
self-modifier/second.asm
Normal file
|
@ -0,0 +1,120 @@
|
|||
format binary
|
||||
use32
|
||||
include 'std.inc'
|
||||
|
||||
; On entrance to each shellcode segment the ebx register will be a vtable of std funcs
|
||||
; printf
|
||||
; puts
|
||||
; scanf
|
||||
; sin
|
||||
; cos
|
||||
; tan
|
||||
; asin
|
||||
; acos
|
||||
; atan
|
||||
; malloc
|
||||
; free
|
||||
; esi contains the base address of the shellcode segment
|
||||
; edi contains the address of the part of the flag that this segment fills
|
||||
; edx contains the number of the block
|
||||
|
||||
push edi
|
||||
|
||||
lea ecx, [esi+pattern_text]
|
||||
push ecx
|
||||
lea eax, [ebx + 0x4]
|
||||
mov eax, dword [eax]
|
||||
call dword [eax]
|
||||
pop ebp
|
||||
|
||||
mov ecx, 0
|
||||
printLoop:
|
||||
push ecx
|
||||
call adv_fib
|
||||
push eax
|
||||
lea ecx, [esi + format_text]
|
||||
mov eax, dword [ebx]
|
||||
push ecx
|
||||
call dword [eax]
|
||||
pop ecx
|
||||
pop ebp
|
||||
pop ecx
|
||||
inc ecx
|
||||
cmp ecx, 6
|
||||
jnz printLoop
|
||||
|
||||
lea ecx, [esi+empty_text]
|
||||
lea eax, [ebx + 0x4]
|
||||
mov eax, dword [eax]
|
||||
push ecx
|
||||
call dword [eax]
|
||||
pop ebp
|
||||
|
||||
|
||||
lea ecx, [esi+inputVal]
|
||||
push ecx
|
||||
lea eax, [ebx + 8]
|
||||
mov eax, dword [eax]
|
||||
lea ecx, [esi+unsignFmt]
|
||||
push ecx
|
||||
call dword [eax]
|
||||
add esp, 8
|
||||
|
||||
mov ecx, dword [esi+inputVal]
|
||||
pop edi
|
||||
; 433695873 is the answer
|
||||
; (struct.unpack('<I', b'_ok_')[0] ^ 0x19d9ac81)
|
||||
; This part of the flag is _ok_ ^ the 35th value in the pattern.
|
||||
xor ecx, 0x46b2c3de
|
||||
mov dword [edi], ecx
|
||||
|
||||
push edi
|
||||
lea ecx, [esi+pray_text]
|
||||
mov eax, dword [ebx]
|
||||
push ecx
|
||||
call dword [eax]
|
||||
pop ecx
|
||||
pop edi
|
||||
|
||||
mov dword [esi+inputVal], 0
|
||||
|
||||
ret
|
||||
|
||||
pattern_text db 'What is the 35th number (index 34) in the following sequence?', 0
|
||||
format_text db '%d ', 0
|
||||
|
||||
; ecx = arg
|
||||
adv_fib:
|
||||
cmp ecx, 2
|
||||
jg do_more
|
||||
mov eax, 1
|
||||
ret
|
||||
|
||||
unsignFmt db '%u', 0
|
||||
inputVal dd 0
|
||||
|
||||
do_more:
|
||||
push edx
|
||||
dec ecx
|
||||
push ecx
|
||||
call adv_fib
|
||||
pop ecx
|
||||
push eax
|
||||
dec ecx
|
||||
push ecx
|
||||
call adv_fib
|
||||
pop ecx
|
||||
push eax
|
||||
dec ecx
|
||||
call adv_fib
|
||||
pop edx
|
||||
add eax, edx
|
||||
pop edx
|
||||
add eax, edx
|
||||
pop edx
|
||||
ret
|
||||
|
||||
empty_text db 0
|
||||
pray_text db 'Hope you got it right! Result: [%s]', ENDL, 0
|
||||
|
||||
resv_stuff 512-$
|
BIN
self-modifier/second.bin
Normal file
BIN
self-modifier/second.bin
Normal file
Binary file not shown.
32
self-modifier/std.inc
Normal file
32
self-modifier/std.inc
Normal file
|
@ -0,0 +1,32 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Standard Includes of my
|
||||
; code
|
||||
include 'char.inc'
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; File descriptor macros
|
||||
STDIN equ 0
|
||||
STDOUT equ 1
|
||||
STDERR equ 2
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
; Standard prologue of a function
|
||||
macro prologue
|
||||
{
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
}
|
||||
|
||||
; Standard epilogue of a function
|
||||
macro epilogue
|
||||
{
|
||||
mov esp, ebp
|
||||
pop ebp
|
||||
}
|
||||
|
||||
; Allocates space on the stack for something
|
||||
macro local_alloc size
|
||||
{
|
||||
sub esp,size
|
||||
}
|
110
self-modifier/third.asm
Normal file
110
self-modifier/third.asm
Normal file
|
@ -0,0 +1,110 @@
|
|||
format binary
|
||||
use32
|
||||
include 'std.inc'
|
||||
|
||||
; On entrance to each shellcode segment the ebx register will be a vtable of std funcs
|
||||
; printf
|
||||
; puts
|
||||
; scanf
|
||||
; sin
|
||||
; cos
|
||||
; tan
|
||||
; asin
|
||||
; acos
|
||||
; atan
|
||||
; malloc
|
||||
; free
|
||||
; esi contains the base address of the shellcode segment
|
||||
; edi contains the address of the part of the flag that this segment fills
|
||||
; edx contains the number of the block
|
||||
|
||||
jmp start
|
||||
|
||||
startup_text db 'What did you say?',0
|
||||
|
||||
start:
|
||||
push edi
|
||||
|
||||
lea ecx, [esi+startup_text]
|
||||
push ecx
|
||||
lea eax, [ebx + 0x4]
|
||||
mov eax, dword [eax]
|
||||
call dword [eax]
|
||||
pop ebp
|
||||
|
||||
xor eax, eax
|
||||
push eax
|
||||
push eax
|
||||
mov eax, esp
|
||||
push eax
|
||||
|
||||
lea eax, [ebx + 8]
|
||||
mov eax, dword [eax]
|
||||
lea ecx, [esi+scanf_text]
|
||||
push ecx
|
||||
call dword [eax]
|
||||
add esp, 8
|
||||
|
||||
pop ecx
|
||||
pop eax
|
||||
pop edi
|
||||
|
||||
mov dword [edi], ecx
|
||||
|
||||
lea edx, [esi+to_match]
|
||||
|
||||
.check:
|
||||
movzx ecx, byte [edi]
|
||||
call check_char
|
||||
cmp eax, 0
|
||||
jz idiot
|
||||
|
||||
inc edi
|
||||
inc edx
|
||||
cmp byte [edx], 0
|
||||
jnz .check
|
||||
|
||||
ret
|
||||
|
||||
scanf_text db '%4[^',ENDL,']'
|
||||
|
||||
; ecx = input'd char
|
||||
; edx = ptr to char to match
|
||||
check_char:
|
||||
cmp ecx, CHAR_a ; 97
|
||||
jl fail
|
||||
cmp ecx, 126
|
||||
jge fail
|
||||
|
||||
sub ecx, CHAR_a ; 97
|
||||
add ecx, esi
|
||||
lea ecx, [ecx + alphabet]
|
||||
movzx eax, byte [ecx]
|
||||
cmp byte [edx], al
|
||||
jnz fail
|
||||
|
||||
mov eax, 1
|
||||
ret
|
||||
|
||||
idiot_text db 'Wrong...', 0
|
||||
|
||||
fail:
|
||||
mov eax, 0
|
||||
ret
|
||||
|
||||
to_match db 'ezpr', 0
|
||||
|
||||
idiot:
|
||||
lea ecx, [esi+idiot_text]
|
||||
push ecx
|
||||
lea eax, [ebx + 0x4]
|
||||
mov eax, dword [eax]
|
||||
call dword [eax]
|
||||
pop ebp
|
||||
dec esp
|
||||
ret
|
||||
|
||||
alphabet db '{m}krzyjfwngpshteoialduqxvcb|', 0
|
||||
; abcdefghijklmnopqrstuvwxyz{|}
|
||||
; flag is "qfme"
|
||||
resv_stuff 512-$
|
BIN
self-modifier/third.bin
Normal file
BIN
self-modifier/third.bin
Normal file
Binary file not shown.
Loading…
Reference in a new issue