Merge branch 'master' of github.com:failedxyz/easyctf

This commit is contained in:
neptunia 2017-03-12 10:36:29 -04:00
commit f67df367b2
103 changed files with 1754 additions and 152 deletions

View file

@ -1 +1 @@
What is this file saying? Help me. My friend sent me [this file](${20xx_dtm}) and told me to git gud.

View file

@ -8,17 +8,20 @@ from collections import Counter
problem_names = os.listdir(os.path.dirname(os.path.abspath(__file__))) problem_names = os.listdir(os.path.dirname(os.path.abspath(__file__)))
problems = [] problems = []
failed = []
for problem_name in problem_names: for problem_name in problem_names:
folder = os.path.dirname(os.path.abspath(__file__)) + os.sep + problem_name
if not (os.path.exists(folder) and os.path.isdir(folder)): continue
try: try:
metadata_file = os.path.dirname(os.path.abspath(__file__)) + os.sep + problem_name + os.sep + "problem.yml" metadata_file = folder + os.sep + "problem.yml"
with open(metadata_file, "r") as f: with open(metadata_file, "r") as f:
metadata_raw = f.read() metadata_raw = f.read()
metadata = yaml.load(metadata_raw) metadata = yaml.load(metadata_raw)
if "category" in metadata: if "category" in metadata:
problems.append(metadata) problems.append(metadata)
except: except:
pass failed.append(problem_name)
# print traceback.format_exc()
problems.sort(key=lambda p: p.get("value"), reverse=True) problems.sort(key=lambda p: p.get("value"), reverse=True)
print("Grand Total: %d" % len(problems)) print("Grand Total: %d" % len(problems))
@ -34,3 +37,8 @@ for category, count in categories:
for problem in problems: for problem in problems:
if problem.get("category") != category: continue if problem.get("category") != category: continue
print(" %s %s %sp" % (problem.get("title") + " " * (maxtitle - len(problem.get("title"))), problem.get("author") + " " * (maxauthor - len(problem.get("author"))), problem.get("value"))) print(" %s %s %sp" % (problem.get("title") + " " * (maxtitle - len(problem.get("title"))), problem.get("author") + " " * (maxauthor - len(problem.get("author"))), problem.get("value")))
print("\nThe following problems failed to parse.")
for title in failed:
if title in [".git"]: continue
print(" %s" % title)

View file

@ -0,0 +1 @@
I just intercepted some odd [messages.txt](${messages_txt}). It appears to be a Diffie-hellman protocol, but my math isn't good enough to figure out what the final shared key is. Help! (The answer is a number. There is no `easyctf{}`)

4
diffie-cult/grader.py Normal file
View file

@ -0,0 +1,4 @@
def grade(autogen, answer):
if answer == ("906730649345"):
return True, "Correct!"
return False, "Nope, try again."

4
diffie-cult/messages.txt Normal file
View file

@ -0,0 +1,4 @@
g^a mod p = 791868216278
g^b mod p = 722955066776
p = 986314922069

9
diffie-cult/problem.yml Normal file
View file

@ -0,0 +1,9 @@
title: Diffie-cult
author: arxenix
hint: Wikipedia explains Diffie-hellman pretty well.
category: Cryptography
autogen: false
programming: false
value: 140
files:
- messages.txt

View file

@ -0,0 +1 @@
There seems to be an issue with this binary. Can you exploit it? View the problem in the shell server `/problems/doubly_dangerous` directory.

Binary file not shown.

View file

@ -0,0 +1,45 @@
//compile with:
//gcc -m32 -std=c99 -Wall -fno-stack-protector doubly_dangerous.c -o doubly_dangerous
//sol: input "A"*40+"\x00\x80\x34\x41"
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
void give_flag() {
FILE *f = fopen("flag.txt", "r");
gid_t gid = getegid();
setresgid(gid, gid, gid);
if (f != NULL) {
char c;
while ((c = fgetc(f)) != EOF) {
putchar(c);
}
fclose(f);
}
else {
printf("Failed to open flag file!\n");
}
}
int main(int argc, char **argv){
volatile float modified;
char buffer[64];
modified = 0;
printf("Give me a string: \n");
gets(buffer);
if (modified == 11.28125) {
printf("Success! Here is your flag:\n");
give_flag();
}
else {
printf("nope!\n");
}
}

View file

@ -0,0 +1,4 @@
def grade(random, key):
if key.find("bofs_and_floats_are_d0uble_tr0uble!") != -1:
return True, "Correct!"
return False, "Nope :("

View file

@ -0,0 +1,9 @@
title: Doubly Dangerous
author: arxenix
hint: How are floating-point numbers represented?
category: Binary Exploitation
autogen: false
programming: false
value: 110
files:
- doubly_dangerous

View file

@ -1,9 +1,17 @@
Write a program that outputs the numbers 1 through n, in incremental order, one per line. Write a program that takes an integer `n` as input.
However, replace any line that is a multiple of 3 with "Fizz" and any that are a multiple of 5 with "Buzz". Any line that is a multiple of 3 and 5 should be written as "FizzBuzz". Output the numbers 1 through `n`, in increasing order, one per line.
However, replace any line that is a multiple of 3 with `Fizz` and any that are a multiple of 5 with `Buzz`. Any line that is a multiple of 3 and 5 should be written as `FizzBuzz`.
The input will be the number of lines to write, n, followed by a linebreak. The input will be the number of lines to write, n, followed by a linebreak.
Sample input:
```
17
```
Sample output: Sample output:
``` ```
@ -12,14 +20,16 @@ Sample output:
Fizz Fizz
4 4
Buzz Buzz
Fizz
... 7
8
Fizz
Buzz
11
Fizz
13 13
14 14
FizzBuzz FizzBuzz
16 16
17 17
...
``` ```

View file

@ -1,4 +1,12 @@
def grade(random, key): n = input()
if key.find("PUT A NEW KEY HERE!!!!") != -1:
return True, "Correct!" for i in range(1, n + 1):
return False, "Nope." if i % 3 == 0 and i % 5 == 0:
print 'FizzBuzz'
elif i % 3 == 0:
print 'Fizz'
elif i % 5 == 0:
print 'Buzz'
else:
print i

View file

@ -0,0 +1 @@
I dropped my alphabet on its head, can you help me reassemble it? `easyctf{r_wlmg_vevm_mvvw_zm_zhxrr_gzyov}`

View file

@ -0,0 +1,4 @@
def grade(autogen, key):
if key.find("i_dont_even_need_an_ascii_table") != -1:
return True, "Correct!"
return False, "Nope!"

View file

@ -0,0 +1,8 @@
author: GenericNickname
title: Flip My Letters
hint: What happens if you turn the alphabet upside down?
category: Cryptography
autogen: false
programming: false
value: 20
files:

84
hexable-autogen/char.inc Normal file
View 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
}

View file

@ -0,0 +1,2 @@
I tried to hide a flag sneakily, can you find it?
[Download](${hexable})

45
hexable-autogen/elf.inc Normal file
View file

@ -0,0 +1,45 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ELF header for stuff
RLIMIT_AS equ 0x09
macro reserve name,size
{
name db 0
repeat size-1
db 0
end repeat
}
macro print message
{
mov eax, message
@@:
cmp byte [eax], 0
jz @f
inc eax
jmp @b
@@:
mov edx, eax
sub edx, message
mov eax, 4
mov ebx, 1
mov ecx, message
int 0x80
}
macro read out_buff, cnt
{
mov ebx, 0
mov eax, 3
mov ecx, out_buff
mov edx, cnt
int 0x80
}
macro exit exitcode
{
mov ebx, exitcode
mov eax, 1
int 0x80
}

22
hexable-autogen/grader.py Normal file
View file

@ -0,0 +1,22 @@
from cStringIO import StringIO
def gen_flag(random, length):
x = ''
for i in range(0, length):
x += random.choice(list('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQSTUVWXYZ0123456789'))
return x
def grade(random, key):
if key.find(gen_flag(random, 14)) != -1:
return True, "Correct!"
return False, "Nope."
def generate(random):
dat = b'\x7fELF\x01\x01\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00\x01\x00\x00\x00\x91\x80\x04\x084\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004\x00 \x00\x02\x00(\x00\x00\x00\x00\x00\x01\x00\x00\x00t\x00\x00\x00t\x80\x04\x08t\x80\x04\x08G\x00\x00\x00G\x00\x00\x00\x07\x00\x00\x00\x00\x10\x00\x00\x01\x00\x00\x00\xbb\x00\x00\x00\xbb\x90\x04\x08\xbb\x90\x04\x080\x00\x00\x000\x00\x00\x00\x06\x00\x00\x00\x00\x10\x00\x00\x89\xc8\x808\x00t\x03@\xeb\xf8\x89\xc2)\xca\xb8\x04\x00\x00\x00\xbb\x01\x00\x00\x00\x89\xc9\xcd\x80\xc3\xb9\xbb\x90\x04\x08\xe8\xd9\xff\xff\xff\xbb\x00\x00\x00\x00\xb8\x01\x00\x00\x00\xcd\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Can you find the flag?\n\x00easyctf{abcdef__123456}\x00'
output = bytearray(dat[:0xdb])
flag = gen_flag(random, 14)
output.extend(flag.encode('utf-8'))
output.extend(dat[0xdb + 14:])
return dict(files={"hexable": (lambda r: StringIO(output))})

BIN
hexable-autogen/hexable Normal file

Binary file not shown.

View file

@ -0,0 +1,35 @@
format ELF executable 3
entry start
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Buffer macros
BUFF_SIZE equ 32
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Includes of macros
include 'elf.inc'
include 'char.inc'
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Code
segment executable writeable readable
put:
print ecx
ret
start:
mov ecx, msg
call put
exit 0
reserve no_code,20
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Data
segment readable writeable
msg db 'Can you find the flag?',ENDL,0
flag db 'easyctf{abcdef__123456}'
reserve temp,1
;;;;;;;;;;;;;;;;;;;;;;;;;;;

View file

@ -0,0 +1,6 @@
title: Hexable
category: Reverse Engineering
value: 25
author: r3ndom
autogen: true
hint: Try using a hex editor.

View file

@ -0,0 +1,19 @@
import random
dat = b'\x7fELF\x01\x01\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00\x01\x00\x00\x00\x91\x80\x04\x084\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004\x00 \x00\x02\x00(\x00\x00\x00\x00\x00\x01\x00\x00\x00t\x00\x00\x00t\x80\x04\x08t\x80\x04\x08G\x00\x00\x00G\x00\x00\x00\x07\x00\x00\x00\x00\x10\x00\x00\x01\x00\x00\x00\xbb\x00\x00\x00\xbb\x90\x04\x08\xbb\x90\x04\x080\x00\x00\x000\x00\x00\x00\x06\x00\x00\x00\x00\x10\x00\x00\x89\xc8\x808\x00t\x03@\xeb\xf8\x89\xc2)\xca\xb8\x04\x00\x00\x00\xbb\x01\x00\x00\x00\x89\xc9\xcd\x80\xc3\xb9\xbb\x90\x04\x08\xe8\xd9\xff\xff\xff\xbb\x00\x00\x00\x00\xb8\x01\x00\x00\x00\xcd\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Can you find the flag?\n\x00easyctf{abcdef__123456}\x00'
def gen_flag(length):
x = ''
for i in range(0,length):
x += random.choice(list('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQSTUVWXYZ0123456789'))
return x
output = bytearray(dat[:0xdb])
flag = gen_flag(14)
output.extend(flag.encode('utf-8'))
output.extend(dat[0xdb+14:])
print(output)
#o = open(flag, 'wb')
#o.write(output)
#o.close()

32
hexable-autogen/std.inc Normal file
View 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
}

View file

@ -0,0 +1 @@
I need help logging into this [website](https://injection1.web.easyctf.com) to get my flag! If it helps, my username is `admin`.

4
injection1/grader.py Normal file
View file

@ -0,0 +1,4 @@
def grade(autogen, key):
if key.find("a_prepared_statement_a_day_keeps_the_d0ctor_away!") != -1:
return True, "You got it!"
return False, "Nope. Keep poking around."

7
injection1/problem.yml Normal file
View file

@ -0,0 +1,7 @@
author: mzhang
title: SQL Injection 1
hint: What does "injection" mean? How can you "inject" code into your username to control the username lookup?
category: Web
autogen: false
programming: false
value: 100

View file

@ -2,10 +2,10 @@ Your librarian has a 2-row bookshelf that can contain N books in each row. She w
Input: the integer, N (1<=N<=2^1024) Input: the integer, N (1<=N<=2^1024)
Output: the number of ways you can place red-colored books and blue-colored books onto the bookshelf. Since this number might be really big, output it mod 10^9+7. Output: the number of ways you can place red-colored books and blue-colored books onto a N-column bookshelf. Since this number might be really big, output it mod 10^9+7.
Example: Example:
Input: 3 Input: 2
Your valid bookshelf layouts are: Your valid bookshelf layouts are:
``` ```

11
library/generator.py Normal file
View file

@ -0,0 +1,11 @@
import random
C = input()
if C==1:
print 1
elif C==2:
print 2
elif C==3 or C==4:
print random.randint(3, 100)
else:
print random.randint(2**(C**3-1), 2**(C**3))

45
library/grader.py Normal file
View file

@ -0,0 +1,45 @@
# Very easy problem. Compute a few values w/ brute force or something, then check OEIS.
# Part of: https://oeis.org/A001333
# Tells us: f(n) = (1/4) * Trace( [[0,0,1,0],[0,1,0,1],[1,0,2,0],[0,2,0,1]] )
# just write a program to compute this quickly
# this sol takes something like ~O(log n) i think?
x = input() + 1
mat = [[0,0,1,0],[0,1,0,1],[1,0,2,0],[0,2,0,1]]
mod = 10**9+7
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m
def matmult(mtx_a, mtx_b, mod):
tpos_b = zip( *mtx_b)
rtn = [[ sum( ea*eb for ea,eb in zip(a,b))%mod for b in tpos_b] for a in mtx_a]
return rtn
def trace(A):
return sum(A[j][j] for j in range(len(A)))
def matpow(A, p):
ret = A
for bit in bin(p)[3:]:
ret = matmult(ret, ret, mod)
if bit=='1':
ret = matmult(ret, A, mod)
return ret
inv4 = modinv(4, mod)
ans = trace(matpow(mat, x))%mod
ans = (ans * inv4)% mod
print ans

10
library/problem.yml Normal file
View file

@ -0,0 +1,10 @@
author: arxenix
title: library
category: Programming
autogen: false
programming: true
value: 175
test_cases: 10
time_limit: 1000
memory_limit: 256000

View file

@ -3,6 +3,7 @@ Your librarian is back again with another challenge for you. She recently acquir
Input: Input:
``` ```
N (number of words in the dictionary)
word1: list of words in word1 definition word1: list of words in word1 definition
word2: list of words in word2 definition word2: list of words in word2 definition
... etc ... etc
@ -17,6 +18,7 @@ Ex:
Input: Input:
``` ```
5
arggiq: blah iz yiq arggiq: blah iz yiq
blah: ok blah: ok
iz: ok blah iz: ok blah
@ -28,3 +30,7 @@ Output:
``` ```
1 1
``` ```
Explanation:
If you understand the word 'ok', you can understand the word 'blah'. If you understand 'ok' and 'blah', you can understand 'iz'. 'iz', and 'ok' lets you understand 'yiq'. 'yiq', 'iz', and 'blah' let you understand 'arggiq'.

112
library2/grader.py Normal file
View file

@ -0,0 +1,112 @@
N = input()
dictionary = {}
word_idx = {}
for i in range(N):
line = raw_input()
sp = line.split(": ")
word = sp[0]
defn = sp[1].split(" ")
dictionary[word] = defn
word_idx[word] = i
#print dictionary
graph = {} #adj-list graph of word dependencies
for i in range(N):
graph[i] = []
for word in dictionary:
idx = word_idx[word]
for dword in dictionary[word]:
toidx = word_idx[dword]
graph[idx].append(toidx)
#print graph
index = 0
components = []
S = []
v_index = {}
v_lowlink = {}
v_onStack = {}
def strongConnect(v):
global index
global components
global S
global v_index
global v_lowlink
global v_onStack
v_index[v] = index
v_lowlink[v] = index
index += 1
S.append(v)
v_onStack[v] = True
# for edges of V
for w in graph[v]:
if w not in v_index:
strongConnect(w)
v_lowlink[v] = min(v_lowlink[v], v_lowlink[w])
elif v_onStack[w]:
v_lowlink[v] = min(v_lowlink[v], v_lowlink[w])
if v_lowlink[v] == v_index[v]:
component = []
while True:
w = S.pop()
v_onStack[w] = False
component.append(w)
if w==v:
break
components.append(component)
def SCC(graph):
global index
global components
global S
global v_index
global v_lowlink
global v_onStack
index = 0
components = []
S = []
v_index = {}
v_lowlink = {}
v_onStack = {}
for v in graph:
if v not in v_index:
strongConnect(v)
return components
comps = SCC(graph)
#print comps
newnodemap = {}
for idx in range(len(comps)):
comp = comps[idx]
for node in comp:
newnodemap[node] = idx
newgraph = {}
for idx in range(len(comps)):
comp = comps[idx]
outgoing = set([])
for node in comp:
nodeout = graph[node]
newnodeout = set([])
for no in nodeout:
newnodeout.add(newnodemap[no])
outgoing = outgoing.union(newnodeout)
outgoing.discard(idx)
newgraph[idx] = list(outgoing)
#print newgraph
# count number of nodes with no incoming edges
ans = 0
for node in newgraph:
if len(newgraph[node])==0:
ans += 1
print ans

View file

@ -1 +1 @@
We intercepted a secret message, but we can't tell what it's saying. Maybe you can help? [super secret message](${listenclosely_wav})? We intercepted a secret message, but we can't tell what it's saying. Maybe you can help? [super secret message](${listenclosely_wav})

View file

@ -4,6 +4,6 @@ hint: 1, 16, 8000
category: Cryptography category: Cryptography
autogen: false autogen: false
programming: false programming: false
value: 300 value: 200
files: files:
- listenclosely.wav - listenclosely.wav

View file

@ -1,10 +1,10 @@
author: GenericNickname author: GenericNickname
title: Match Me title: Match Me
hint: This is a fairly well-known graph problem, there's probably some sort of internet source on it. hint: This is a fairly well-known graph problem, there's probably some sort of internet source on it.
category: Algorithms category: Programming
autogen: false autogen: false
programming: false programming: false
value: 400 value: 300
files: files:
- female_prefs.txt - female_prefs.txt
- male_prefs.txt - male_prefs.txt

View file

@ -3,5 +3,6 @@ category: Reverse Engineering
value: 450 value: 450
author: r3ndom author: r3ndom
autogen: false autogen: false
hint: Maybe write a script.
files: files:
- _67k.zip - _67k.zip

BIN
risky-business/casino Normal file

Binary file not shown.

View file

@ -0,0 +1,3 @@
We wanted to branch into the casino business, but human employees are too expensive so we decided to automate it. I feel like we missed something obvious though... Oh well! Here's the binary: [casino](${casino})
Solve this problem by logging into the shell server and navigating to `/problems/casino`.

1
risky-business/flag.txt Normal file
View file

@ -0,0 +1 @@
easyctf{m4by3_w3_c0u1d_h4v3_d0n3_th47_b3t7er}

4
risky-business/grader.py Normal file
View file

@ -0,0 +1,4 @@
def grade(autogen, key):
if key.find("m4by3_w3_c0u1d_h4v3_d0n3_th47_b3t7er") != -1:
return True, "Correct!"
return False, "Nope!"

75
risky-business/main.cpp Normal file
View file

@ -0,0 +1,75 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdlib.h>
bool gamble()
{
if (rand() % 5 == 0)
{
return true;
}
return false;
}
void printflag()
{
std::cout << "Welcome to our exclusive club!" << std::endl;
std::ifstream flagI("flag.txt");
std::string flag;
getline(flagI, flag);
flagI.close();
std::cout << "Here's our special flag: " << flag << std::endl;
}
int networth = 100000;
int main()
{
std::cout << "Welcome to the EasyCTF 2017 Casino" << std::endl;
std::cout << "Try your luck and gain access to our exclusive club!" << std::endl;
while (true)
{
std::cout << std::endl;
std::cout << "Your net worth is: $" << networth << std::endl;
if (networth > 2000000000)
{
printflag();
break;
}
std::cout << "Please enter how much you would like to bet:" << std::endl;
std::string tmp;
getline(std::cin, tmp);
std::stringstream s(tmp);
int inp;
s >> inp;
if (!s.eof() || s.fail())
{
std::cout << "That was not a valid number :(";
continue;
}
if (inp <= 0)
{
std::cout << "You must bet a positive amount" << std::endl;
continue;
}
if (inp > 100000000)
{
std::cout << "Sorry, the most we can allow you to bet is $100,000,000" << std::endl;
continue;
}
if (!gamble())
{
std::cout << "Sorry, I'm afraid you've lost :(" << std::endl;
networth -= inp;
}
else
{
std::cout << "Congratulations, you won!" << std::endl;
networth += inp;
}
}
return 0;
}

View file

@ -0,0 +1,9 @@
author: GenericNickname
title: Risky Business
hint: I wonder how you could make a lot of money...
category: Binary Exploitation
autogen: false
programming: false
value: 100
files:
- casino

View file

@ -39,7 +39,7 @@ def generate_ciphertext(random):
def generate(random): def generate(random):
return dict(files={ return dict(files={
"ciphertext_rsa1.txt": generate_ciphertext "ciphertext.txt": generate_ciphertext
}) })
def grade(random, key): def grade(random, key):

View file

@ -4,4 +4,4 @@ hint: Go google RSA if you're stuck.
category: Cryptography category: Cryptography
autogen: true autogen: true
programming: false programming: false
value: 25 value: 50

View file

@ -38,7 +38,7 @@ def generate_ciphertext(random):
def generate(random): def generate(random):
return dict(files={ return dict(files={
"ciphertext_rsa2.txt": generate_ciphertext "ciphertext.txt": generate_ciphertext
}) })
def grade(random, key): def grade(random, key):

View file

@ -4,4 +4,4 @@ hint: It's like RSA 1 but harder. Have fun!
category: Cryptography category: Cryptography
autogen: true autogen: true
programming: false programming: false
value: 35 value: 80

View file

@ -1,5 +1 @@
<<<<<<< HEAD We came across another [message]($rsa3) that follows the same cryptographic schema as those other RSA messages. Take a look and see if you can crack it.
I found somebody's notes on their private RSA! Help me crack [this](${ciphertext_txt}).
=======
We came across another [message]($rsa3) that follows the same cryptographic schema as those other Really Scary Admin messages. Take a look and see if you can crack it.
>>>>>>> 93577ddee37a489cf0aa1a4b987d23a3bc3d2657

View file

@ -1,56 +1,4 @@
<<<<<<< HEAD
from cStringIO import StringIO
flag = "wh3n_y0u_h4ve_p&q_RSA_iz_ez"
def modx(base,exp,mod):
r = 1;
while (exp > 0):
if (exp % 2 == 1):
r = (r * base) % mod
base = (base * base) % mod
exp = exp/2
return r
def probprime(s):
if s%2==0:
s += 1
smolprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
while len(set([modx(i,s-1,s) for i in smolprimes])) != 1 or modx(2,s-1,s) != 1:
s+=2
return(s)
def get_problem(random):
# add Probable Prime function later
p = probprime(random.randint(3*10**79,4*10**79))
q = probprime(random.randint(3*10**79,4*10**79))
e = 3
salt = "".join([random.choice("0123456789abcdef") for i in range(8)])
return (p, q, e, salt)
def generate_ciphertext(random):
p, q, e, salt = get_problem(random)
encoded = int(("easyctf{%s_%s}" % (flag, salt)).encode('hex'),16)
ciphertext = 'p: '+str(p)+'\n'
ciphertext += 'q: '+str(q)+'\n'
ciphertext += 'e: '+str(e)+'\n'
ciphertext += 'c: '+str(pow(encoded, e, p*q))+'\n'
return StringIO(ciphertext)
def generate(random):
return dict(files={
"ciphertext_rsa1.txt": generate_ciphertext
})
def grade(random, key):
n, salt = get_problem(random)
if key.find("%s_%s" % (flag, salt)) >= 0:
return True, "Correct!"
return False, "Nope."
=======
def grade(autogen, key): def grade(autogen, key):
if key.find("tw0_v3ry_merrry_tw1n_pr1m35!!_417c0d") != -1: if key.find("tw0_v3ry_merrry_tw1n_pr1m35!!_417c0d") != -1:
return True, "Really Superb! Applause!" return True, "Really Superb! Applause!"
return False, "RIP" return False, "RIP"
>>>>>>> 93577ddee37a489cf0aa1a4b987d23a3bc3d2657

View file

@ -1,19 +1,9 @@
<<<<<<< HEAD
title: RSA 1
author: neptunia
hint: Go google RSA if you're stuck.
category: Cryptography
autogen: true
programming: false
value: 25
=======
author: blockingthesky author: blockingthesky
title: RSA 3 title: RSA 3
hint: You might want to read up on how RSA works. hint: You might want to read up on how RSA works.
category: Cryptography category: Cryptography
autogen: false autogen: false
programming: false programming: false
value: 70 value: 135
files: files:
- rsa3 - rsa3
>>>>>>> 93577ddee37a489cf0aa1a4b987d23a3bc3d2657

View file

@ -1 +0,0 @@
We came across another [message]($rsa4) that follows the same cryptographic schema as those other RSA messages. Take a look and see if you can crack it.

View file

@ -1,8 +0,0 @@
<<<<<<< HEAD
<<<<<<< HEAD
I found somebody's notes on their private RSA! Help me crack [this](${ciphertext_txt}).
=======
We came across another [message]($rsa3) that follows the same cryptographic schema as those other Really Scary Admin messages. Take a look and see if you can crack it.
>>>>>>> 93577ddee37a489cf0aa1a4b987d23a3bc3d2657
=======
>>>>>>> f9a58afef003d40f3ada9c1645eda26363521cf3

View file

@ -1,8 +0,0 @@
<<<<<<< HEAD
<<<<<<< HEAD
I found somebody's notes on their private RSA! Help me crack [this](${ciphertext_txt}).
=======
We came across another [message]($rsa3) that follows the same cryptographic schema as those other Really Scary Admin messages. Take a look and see if you can crack it.
>>>>>>> 93577ddee37a489cf0aa1a4b987d23a3bc3d2657
=======
>>>>>>> f9a58afef003d40f3ada9c1645eda26363521cf3

View file

@ -1 +0,0 @@
We came across another [message]($rsa3) that follows the same cryptographic schema as those other Really Scary Admin messages. Take a look and see if you can crack it.

View file

@ -1 +0,0 @@
We came across another [message]($rsa3) that follows the same cryptographic schema as those other Really Scary Admin messages. Take a look and see if you can crack it.

View file

@ -1,5 +0,0 @@
<<<<<<< HEAD
I found somebody's notes on their private RSA! Help me crack [this](${ciphertext_txt}).
=======
We came across another [message]($rsa3) that follows the same cryptographic schema as those other Really Scary Admin messages. Take a look and see if you can crack it.
>>>>>>> 93577ddee37a489cf0aa1a4b987d23a3bc3d2657

View file

@ -1,5 +0,0 @@
<<<<<<< HEAD
I found somebody's notes on their private RSA! Help me crack [this](${ciphertext_txt}).
=======
We came across another [message]($rsa3) that follows the same cryptographic schema as those other Really Scary Admin messages. Take a look and see if you can crack it.
>>>>>>> 93577ddee37a489cf0aa1a4b987d23a3bc3d2657

View file

@ -1,4 +0,0 @@
def grade(autogen, key):
if key.find("tw0_v3ry_merrry_tw1n_pr1m35!!_417c0d") != -1:
return True, "Really Superb! Applause!"
return False, "RIP"

View file

@ -1,9 +0,0 @@
author: blockingthesky
title: RSA 4
hint: You might want to read up on how RSA works.
category: Cryptography
autogen: false
programming: false
value: 130
files:
- rsa3

View file

@ -1,2 +0,0 @@
{N : e : c}
{0x27335d21ca51432fa000ddf9e81f630314a0ef2e35d81a839584c5a7356b94934630ebfc2ef9c55b111e8c373f2db66ca3be0c0818b1d4eda7d53c1bd0067f66a12897099b5e322d85a8da45b72b828813af23L : 0x10001 : 0x9b9c138e0d473b6e6cf44acfa3becb358b91d0ba9bfb37bf11effcebf9e0fe4a86439e8217819c273ea5c1c5acfd70147533aa550aa70f2e07cc98be1a1b0ea36c0738d1c994c50b1bd633e3873fc0cb377e7L}

View file

@ -1,2 +0,0 @@
{N : e : c}
{0x27335d21ca51432fa000ddf9e81f630314a0ef2e35d81a839584c5a7356b94934630ebfc2ef9c55b111e8c373f2db66ca3be0c0818b1d4eda7d53c1bd0067f66a12897099b5e322d85a8da45b72b828813af23L : 0x10001 : 0x9b9c138e0d473b6e6cf44acfa3becb358b91d0ba9bfb37bf11effcebf9e0fe4a86439e8217819c273ea5c1c5acfd70147533aa550aa70f2e07cc98be1a1b0ea36c0738d1c994c50b1bd633e3873fc0cb377e7L}

BIN
self-modifier/b0.bin Normal file

Binary file not shown.

BIN
self-modifier/b1.bin Normal file

Binary file not shown.

BIN
self-modifier/b2.bin Normal file

Binary file not shown.

BIN
self-modifier/b3.bin Normal file

Binary file not shown.

1
self-modifier/b4.bin Normal file
View 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><35>€ÏbBbŒ<62>Ž|<7C>˜™šœ<E280BA>žŸ µ£¤¥¦§¨©ª±ãÁßÕ<C39F>²Œ´µ¶å¸¹º»½¼¼¼ÄÄÄÄÌÌÌÌÄÄÄÄÜÜÜÜÄÄÄÄÌÌÌÌÄÄÄÄüüüüÄÄÄÄÌÌÌÌÄÄÄÄÜÜÜÜÄÄÄÄÌÌÌÌÄÄÄļ¼¼¼DDDDLLLLDDDD\\\\DDDDLLLLDDDD||||DDDDLLLLDDDD\\\\DDDDLLLLDDDD¼¼¼¼ÄÄÄÄÌÌÌÌÄÄÄÄÜÜÜÜÄÄÄÄÌÌÌÌÄÄÄÄüüüüÄÄÄÄÌÌÌÌÄÄÄÄÜÜÜÜÄÄÄÄÌÌÌÌÄÄÄļ¼¼¼DDDDLLLLDDDD\\\\DDDDLLLLDDDD||||DDDDLLLLDDDD\\\\

View file

@ -0,0 +1,5 @@
format binary
use32
include 'std.inc'
resv_stuff 512-$

Binary file not shown.

90
self-modifier/build.py Normal file
View 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
View 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
}

View 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
View 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

Binary file not shown.

167
self-modifier/fourth.asm Normal file
View 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

Binary file not shown.

13
self-modifier/grader.py Normal file
View 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
View 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

Binary file not shown.

109
self-modifier/morpher.asm Normal file
View 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

Binary file not shown.

View 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
View 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

View 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
View 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

Binary file not shown.

32
self-modifier/std.inc Normal file
View 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
View 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

Binary file not shown.

View file

@ -3,4 +3,6 @@ category: Forensics
value: 300 value: 300
hint: 010100110110010101110010011010010110000101101100001011100010111000101110 hint: 010100110110010101110010011010010110000101101100001011100010111000101110
author: wiresboy author: wiresboy
autogen: true autogen: false
files:
- serial.wav

View file

@ -1,3 +1,5 @@
On the shell there is a folder `<insert location>`. On the shell there is a folder `/problems/simple-rop`.
Read flag.txt Read flag.txt
[Source](${simple-rop.c})
[Source](${simple_rop_c})

View file

@ -5,6 +5,7 @@ autogen: false
programming: true programming: true
value: 15 value: 15
grader_language: python
test_cases: 10 test_cases: 10
time_limit: 1000 time_limit: 1000
memory_limit: 256000 memory_limit: 256000

View file

@ -7,7 +7,7 @@ elif N == 1:
elif N == 2: elif N == 2:
print '123 456 3\n5 7 11' print '123 456 3\n5 7 11'
elif N == 3: elif N == 3:
print '1 10000000 16\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16' print '1 10000000 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16'
else: else:
import random as r import random as r
r.seed(N) r.seed(N)

Binary file not shown.

View file

@ -1 +0,0 @@
# done in grader.java

View file

@ -5,6 +5,7 @@ autogen: false
programming: true programming: true
value: 210 value: 210
grader_language: java
test_cases: 15 test_cases: 15
time_limit: 1000 time_limit: 1000
memory_limit: 256000 memory_limit: 256000

1
tiny-eval/description.md Normal file
View file

@ -0,0 +1 @@
This [page](https://tinyeval.web.easyctf.com) will evaluate anything you give it.

Some files were not shown because too many files have changed in this diff Show more