diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7e99e36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pyc \ No newline at end of file diff --git a/bizarro/problem.yml b/bizarro/problem.yml index eab180d..e41572d 100644 --- a/bizarro/problem.yml +++ b/bizarro/problem.yml @@ -1,6 +1,6 @@ author: blockingthesky title: Bizarro -category: Steganography +category: Forensics autogen: false programming: false value: 400 diff --git a/count.py b/count.py index 9623aba..60f1ed1 100644 --- a/count.py +++ b/count.py @@ -20,13 +20,17 @@ for problem_name in problem_names: pass # print traceback.format_exc() -print "Grand Total: %d" % len(problems) -print "Category Breakdown:" +problems.sort(key=lambda p: p.get("value"), reverse=True) +print("Grand Total: %d" % len(problems)) +print("Category Breakdown:") + +maxtitle = max(map(lambda p: len(p.get("title")), problems)) + 3 +maxauthor = max(map(lambda p: len(p.get("author")), problems)) + 3 c = Counter(map(lambda p: p.get("category", ""), problems)) categories = sorted(c.items(), key=lambda c: c[1], reverse=True) for category, count in categories: - print " %s: %s" % (category, count) + print(" %s: %s" % (category, count)) for problem in problems: if problem.get("category") != category: continue - print " %s" % problem.get("title") + print(" %s %s %sp" % (problem.get("title") + " " * (maxtitle - len(problem.get("title"))), problem.get("author") + " " * (maxauthor - len(problem.get("author"))), problem.get("value"))) diff --git a/decode-me/problem.yml b/decode-me/problem.yml index d1ac42b..58059a7 100644 --- a/decode-me/problem.yml +++ b/decode-me/problem.yml @@ -1,7 +1,7 @@ title: Decode Me author: dududum561 hint: Simple decoding :) -category: Forensics +category: Cryptography autogen: false programming: false value: 100 diff --git a/dijkstra/description.md b/dijkstra/description.md deleted file mode 100644 index 80240a6..0000000 --- a/dijkstra/description.md +++ /dev/null @@ -1,22 +0,0 @@ -This is a high-level programming challenge. Given a set of vertices corresponding to the map below, your program must output the shortest path from `a` to `z`. - -![image](${dijkstra_map_svg}) - -The length of the line segments is randomized such that the length (`l`) satisfies `20 <= l <= 120`. - -Input will consist of 49 lines in the format `vertex1 vertex2 distanceBetween` - -Here are a few lines of example input: -```shell -h i 94 -h o 40 -i l 95 -l k 65 -l t 63 -t u 47 -``` - -The output should be written to a file named "dijkstra.out" in the current directory. Output will consist of the entire path, with `->` in between vertices. Print the current distance traveled in parenthesis after each vertex, as shown below. -``` -a -> b(113) -> c(210) -> f(262) -> h(291) -> i(326) -> m(381) -> s(409) -> x(444) -> y(534) -> z(557) -``` \ No newline at end of file diff --git a/dijkstra/dijkstra_map.svg b/dijkstra/dijkstra_map.svg deleted file mode 100644 index 5cc8600..0000000 --- a/dijkstra/dijkstra_map.svg +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - - - - - - - -A -B -E -C -D -F -J -K -L - - - - -M -I -H -G - - - - - - - - - - - - -P -Q -R -X -Y -Z -V -U - -T -S -N -O -W - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Start: ATarget: Z - diff --git a/dijkstra/grader.py b/dijkstra/grader.py deleted file mode 100644 index edf74d0..0000000 --- a/dijkstra/grader.py +++ /dev/null @@ -1,4 +0,0 @@ -def grade(autogen, answer): - if answer.find("edsger_wybe_dijkstra_was_a_happy_accident") != -1: - return True, "Great Job! That's a tough one." - return False, "Nope, try again." \ No newline at end of file diff --git a/dijkstra/problem.yml b/dijkstra/problem.yml deleted file mode 100644 index b6292db..0000000 --- a/dijkstra/problem.yml +++ /dev/null @@ -1,9 +0,0 @@ -title: Dijkstra -author: ztaylor54 -hint: You might consider reading up on shortest-path algorithms. -category: Programming -autogen: false -programming: false -value: 450 -files: - - dijkstra_map.svg \ No newline at end of file diff --git a/fizz-buzz-2/source_grader.py b/fizz-buzz-2/source_grader.py new file mode 100644 index 0000000..ebd2523 --- /dev/null +++ b/fizz-buzz-2/source_grader.py @@ -0,0 +1,5 @@ +code = raw_input() +if ("i" in code) or ("I" in code) or ("?" in code): + print "Your program contains an 'i', 'I', or '?'. Please remove it and try again." +else + print "OK" \ No newline at end of file diff --git a/flag-peg/problem.yml b/flag-peg/problem.yml index 13c6e47..1080de2 100644 --- a/flag-peg/problem.yml +++ b/flag-peg/problem.yml @@ -4,6 +4,6 @@ hint: You're not looking deep enough category: Forensics autogen: false programming: false -value: 50 +value: 150 files: - heresaflag.jpg diff --git a/listen-closely/problem.yml b/listen-closely/problem.yml index d25404f..051ef0d 100644 --- a/listen-closely/problem.yml +++ b/listen-closely/problem.yml @@ -1,9 +1,9 @@ author: GenericNickname title: Listen Closely hint: 1, 16, 8000 -category: Crytpography +category: Cryptography autogen: false programming: false -value: 50 +value: 300 files: - listenclosely.wav diff --git a/luckyguess/problem.yml b/luckyguess/problem.yml index 741186c..682babe 100644 --- a/luckyguess/problem.yml +++ b/luckyguess/problem.yml @@ -1,6 +1,6 @@ author: blockingthesky title: Lucky Guess -category: Reversing +category: Reverse Engineering autogen: false programming: false value: 200 diff --git a/match-me/problem.yml b/match-me/problem.yml index f5608f7..bf9854d 100644 --- a/match-me/problem.yml +++ b/match-me/problem.yml @@ -4,7 +4,7 @@ hint: This is a fairly well-known graph problem, there's probably some sort of i category: Algorithms autogen: false programming: false -value: 50 +value: 400 files: - female_prefs.txt - male_prefs.txt diff --git a/phunkypython1/problem.yml b/phunkypython1/problem.yml index 449ec04..2f3722b 100644 --- a/phunkypython1/problem.yml +++ b/phunkypython1/problem.yml @@ -1,6 +1,6 @@ author: blockingthesky title: Phunky Python I -category: Reversing +category: Reverse Engineering autogen: true programming: false -value: 30 \ No newline at end of file +value: 30 diff --git a/phunkypython2/problem.yml b/phunkypython2/problem.yml index 1095691..7e88f3b 100644 --- a/phunkypython2/problem.yml +++ b/phunkypython2/problem.yml @@ -1,6 +1,6 @@ author: blockingthesky title: Phunky Python II -category: Reversing +category: Reverse Engineering autogen: true programming: false -value: 115 \ No newline at end of file +value: 115 diff --git a/qr-1/description.md b/qr-1/description.md new file mode 100644 index 0000000..6db579b --- /dev/null +++ b/qr-1/description.md @@ -0,0 +1,2 @@ +I just saw this QR code the other day, but couldn't tell what data it has. Can you help? +[Here](${qr1_bmp}) it is. \ No newline at end of file diff --git a/qr-1/grader.py b/qr-1/grader.py new file mode 100644 index 0000000..1348b0f --- /dev/null +++ b/qr-1/grader.py @@ -0,0 +1,4 @@ +def grade(autogen, answer): + if answer.find("n0w_who-w0u1d_do_thAT_to_Th3ir_QR?") != -1: + return True, "Congrats!" + return False, "Nope, try again." \ No newline at end of file diff --git a/qr-1/problem.yml b/qr-1/problem.yml new file mode 100644 index 0000000..f0a64e7 --- /dev/null +++ b/qr-1/problem.yml @@ -0,0 +1,9 @@ +title: QR 1 +author: wiresboy +category: Forensics +autogen: false +programming: false +value: 100 +hint: Is the image only black and white? +files: + - qr1.bmp \ No newline at end of file diff --git a/qr-1/qr1.bmp b/qr-1/qr1.bmp new file mode 100644 index 0000000..f43285c Binary files /dev/null and b/qr-1/qr1.bmp differ diff --git a/qr-2/description.md b/qr-2/description.md index 254c112..65e6596 100644 --- a/qr-2/description.md +++ b/qr-2/description.md @@ -1 +1 @@ -When I am not practicing my [Oboe](https://en.wikipedia.org/wiki/Oboe) for band, I have been working on a QR code generator. For some reason, some of the images are not scannable. [Here](${qr_bmp}) is one, can you tell me what it says? \ No newline at end of file +When I am not practicing my [Oboe](https://en.wikipedia.org/wiki/Oboe) for band, I have been working on a QR code generator. For some reason, some of the images are not scannable. [Here](${qr2_bmp}) is one, can you tell me what it says? \ No newline at end of file diff --git a/qr-2/problem.yml b/qr-2/problem.yml index ec4b83f..597ffd3 100644 --- a/qr-2/problem.yml +++ b/qr-2/problem.yml @@ -3,7 +3,7 @@ author: wiresboy category: Forensics autogen: false programming: false -value: 180 +value: 330 hint: Is there another kind of Oboe? files: - - qr.bmp \ No newline at end of file + - qr2.bmp \ No newline at end of file diff --git a/qr-2/qr.bmp b/qr-2/qr2.bmp similarity index 100% rename from qr-2/qr.bmp rename to qr-2/qr2.bmp diff --git a/qrt/description.md b/qrt/description.md new file mode 100644 index 0000000..8872c46 --- /dev/null +++ b/qrt/description.md @@ -0,0 +1 @@ +I've stumbled upon a very strange [QR code](${flag_png})... seems like it was generated with [this generator](http://hexqr.web.easyctf.com). What could it mean? \ No newline at end of file diff --git a/qrt/flag.png b/qrt/flag.png new file mode 100644 index 0000000..d03a93f Binary files /dev/null and b/qrt/flag.png differ diff --git a/qrt/grader.py b/qrt/grader.py new file mode 100644 index 0000000..0ff92c3 --- /dev/null +++ b/qrt/grader.py @@ -0,0 +1,330 @@ +from cStringIO import StringIO +from PIL import Image, ImageDraw +from math import ceil, sqrt + +ALTCONST = sqrt(3) / 2.0 +ISIZE = 784.0 +IMARGIN = 22.0 + +def empty_hex(size): + c = 0 + points = [] + for i in range(2, size * 2 + 2, 2): + points.append([0] * i) + middle = [] + for i in range(size * 2 - 1): + row = [0] * (size * 2) + middle.append(row) + epoints = list(row[:] for row in points[::-1]) + return points + middle + epoints + +def intify(points): + return map(lambda c: (int(c[0]), int(c[1])), points) + +def draw_triangle(im, points, cell, size): + draw = ImageDraw.Draw(im) + # draw.polygon(points, outline=(0, 0, 0)) + if cell: + draw.polygon(intify(points), fill=(0, 0, 0)) + return im + +def getsection(i, size): + return 0 if i <= size - 1 else (1 if i < 3 * size - 1 else 2) + +def getspace(size): + return max(0, sum(len(filter(lambda a: a == 0, b)) for b in empty_hex(size)) - 2) + +def generate_image(string, debug=False): + size = 0 + binstring = bin(int(string.encode("hex"), 16)).strip("0b") + while size < 2 or getspace(size + 1) < len(binstring): + size += 1 + n = getspace(size) + # print size, len(binstring) + if debug: print "SIZE", size, " n =", n + im = Image.new("RGB", (int(ISIZE), int(ISIZE)), "white") + pattern = empty_hex(size) + # print len(binstring) + # print sum(len(i) for i in pattern) + pattern[0][len(string) % 2] = 1 + curr = (1, 1 + len(string) % 2, 3 - len(string) % 2) + # 0 1 + # 3 2 + for c in range(n): # range(len(binstring)): + i, j, d = curr + row = pattern[i] + if c < len(binstring): + b = int(binstring[c]) + pattern[i][j] = b + if c % 2 == 0: + pattern[i][j] ^= 1 + + section = getsection(i, size) + leftfacing = [j % 2 == 0, j % 2 != (i - size) % 2, j % 2 == 0][section] + if debug: print "c =", c, ", i =", i, ", j =", j, ", d =", d, ", s =", section, ", l =", leftfacing + if section == 0: + if getsection(i + 1, size) == 0: + if leftfacing: + if d == 0: + if j == 0: + curr = i + 1, j, (d + 2) % 4 + else: + curr = i - 1, j - 1, d + elif d == 1 or d == 2: + curr = i, j + 1, d + elif d == 3: + curr = i + 1, j + 1, d + else: + if d == 0: + curr = i, j - 1, d + elif d == 1: + if j == len(row) - 1: + curr = i + 1, j + 2, (d + 2) % 4 + else: + curr = i - 1, j - 1, d + elif d == 2: + curr = i + 1, j + 1, d + elif d == 3: + curr = i, j - 1, d + elif getsection(i + 1, size) == 1: + if leftfacing: + if d == 0: + if j == 0: + curr = i + 1, j, (d + 2) % 4 + else: + curr = i - 1, j - 1, d + elif d == 1 or d == 2: + curr = i, j + 1, d + elif d == 3: + curr = i + 1, j, d + else: + if d == 0: + curr = i, j - 1, d + elif d == 1: + if j == len(row) - 1: + curr = i + 1, j, (d + 2) % 4 + else: + curr = i - 1, j - 1, d + elif d == 2: + curr = i + 1, j, d + elif d == 3: + curr = i, j - 1, d + elif section == 1: + if getsection(i - 1, size) == 0: + if leftfacing: + if j == len(row) - 1: + if d == 1: + curr = i + 2, j, (d + 2) % 4 + elif d == 2: + curr = i + 2, j, (d + 2) % 4 + elif d == 3: + curr = i + 1, j, d + else: + if d == 0: + curr = i - 1, j, d + elif d == 1 or d == 2: + curr = i, j + 1, d + elif d == 3: + curr = i + 1, j, d + else: + if j == 0: + if d == 0: + curr = i + 2, j, (d + 2) % 4 + elif d == 2: + curr = i + 1, j, d + elif d == 3: + curr = i + 2, j, (d + 2) % 4 + else: + if d == 0 or d == 3: + curr = i, j - 1, d + elif d == 1: + curr = i - 1, j, d + elif d == 2: + curr = i + 1, j, d + elif getsection(i - 1, size) == 1: + if getsection(i + 1, size) == 1: + if leftfacing: + if j == len(row) - 1: + if d == 0: + curr = i - 1, j, d + elif d == 1: + curr = i + 2, j, (d + 2) % 4 + elif d == 2: + curr = i + 2, j, (d + 2) % 4 + elif d == 3: + curr = i + 1, j, d + else: + if d == 0: + curr = i - 1, j, d + elif d == 1 or d == 2: + curr = i, j + 1, d + elif d == 3: + curr = i + 1, j, d + else: + if j == 0: + if d == 0: + curr = i + 2, j, (d + 2) % 4 + elif d == 1: + curr = i - 1, j, d + elif d == 2: + curr = i + 1, j, d + elif d == 3: + curr = i + 2, j, (d + 2) % 4 + else: + if d == 0 or d == 3: + curr = i, j - 1, d + elif d == 1: + curr = i - 1, j, d + elif d == 2: + curr = i + 1, j, d + elif getsection(i + 1, size) == 2: + if leftfacing: + if j == len(row) - 1: + if d == 0: + curr = i - 1, j, d + elif d == 2: + curr = i + 1, j, (d + 2) % 4 + else: + if d == 0: + curr = i - 1, j, d + elif d == 1: + curr = i, j + 1, d + elif d == 2: + curr = i, j + 1, d + elif d == 3: + curr = i + 1, j, d + else: + if d == 0: + curr = i, j - 1, d + elif d == 1: + curr = i - 1, j, d + elif d == 2: + curr = i + 1, j, d + elif d == 3: + if j == 0: + curr = i + 1, j, (d + 2) % 4 + else: + curr = i, j - 1, d + elif section == 2: + if getsection(i - 1, size) == 1: + if leftfacing: + if d == 0: + curr = i - 1, j, d + elif d == 1: + curr = i, j + 1, d + elif d == 2: + curr = i, j + 1, d + elif d == 3: + if j == 0: + curr = i + 1, j, (d + 2) % 4 + else: + curr = i + 1, j - 1, d + else: + if d == 0 or d == 3: + curr = i, j - 1, d + elif d == 1: + curr = i - 1, j, d + elif d == 2: + if j == len(row) - 1: + curr = i + 1, j - 2, (d + 2) % 4 + else: + curr = i + 1, j - 1, d + elif getsection(i - 1, size) == 2: + if leftfacing: + if d == 0: + curr = i - 1, j + 1, d + elif d == 1 or d == 2: + curr = i, j + 1, d + elif d == 3: + if j == 0: + curr = i + 1, j, (d + 2) % 4 + else: + curr = i + 1, j - 1, d + else: + if j == len(row) - 1: + if d == 0: + curr = i, j - 1, d + elif d == 1: + curr = i - 1, j + 1, d + elif d == 2: + curr = i + 1, j - 2, (d + 2) % 4 + else: + if d == 0 or d == 3: + curr = i, j - 1, d + elif d == 1: + curr = i - 1, j + 1, d + elif d == 2: + curr = i + 1, j - 1, d + # for i in range(len(pattern)): + # for j in range(len(pattern[i])): + # section = 0 if i <= size - 1 else (1 if i < 3 * size - 1 else 2) + # leftfacing = [j % 2 == 0, j % 2 != (i - size) % 2, j % 2 == 0][section] + # if not leftfacing: + # print j, + # print + sidelen = (ISIZE - IMARGIN * 2) / (2.0 * size) + altitude = sidelen * ALTCONST + # print sidelen, altitude + for i in range(len(pattern)): + section = getsection(i, size) + row = pattern[i] + rowleft = (ISIZE / 2) - (altitude * len(row) / 2) + if section % 2 == 0: + evenrow = i % 2 == 0 + for j in range(len(row)): + cell = row[j] + top = ceil(i / 2.0) * sidelen - (0.5 * sidelen if not evenrow else 0) + IMARGIN + bottom = top + sidelen + if j % 2 == 0: + points = [ + (rowleft + altitude * j, top + sidelen / 2), + (rowleft + altitude * (j + 1), top), (rowleft + altitude * (j + 1), bottom) + ] + else: + points = [ + (rowleft + altitude * (j + 1), top + sidelen / 2), + (rowleft + altitude * j, top), (rowleft + altitude * j, bottom) + ] + draw_triangle(im, points, cell, size) + else: + evenrow = (i - size) % 2 == 1 + for j in range(len(row)): + cell = row[j] + top = ceil(i / 2.0) * sidelen - (0.5 * sidelen if i % 2 == 1 else 0) + IMARGIN + bottom = top + sidelen + if j % 2 == (i - size) % 2: + points = [ + (rowleft + altitude * (j + 1), top + sidelen / 2), + (rowleft + altitude * j, top), (rowleft + altitude * j, bottom) + ] + else: + points = [ + (rowleft + altitude * j, top + sidelen / 2), + (rowleft + altitude * (j + 1), top), (rowleft + altitude * (j + 1), bottom) + ] + draw_triangle(im, points, cell, size) + return im + +FLAG = "are_triangles_more_secure_than_squares?_%s" + +def get_salt(random): + salt = "".join([random.choice("0123456789abcdef") for i in range(8)]) + return salt + +def generate_flag(random): + salt = get_salt(random) + im = generate_image("easyctf{%s}" % (FLAG % salt)) + flag = StringIO() + im.save(flag, format="PNG") + return flag + +def generate(random): + return dict(files={ + "flag.png": generate_flag + }) + +def grade(random, key): + salt = get_salt(random) + if key.find(FLAG % salt) >= 0: + return True, "Correct!" + return False, "Nope." diff --git a/qrt/problem.yml b/qrt/problem.yml new file mode 100644 index 0000000..1851c8f --- /dev/null +++ b/qrt/problem.yml @@ -0,0 +1,5 @@ +title: Hex QR +category: Reverse Engineering +value: 200 +author: mzhang +autogen: true diff --git a/qrt/qrt.py b/qrt/qrt.py new file mode 100644 index 0000000..4175d36 --- /dev/null +++ b/qrt/qrt.py @@ -0,0 +1,311 @@ +from PIL import Image, ImageDraw +from math import ceil, sqrt + +ALTCONST = sqrt(3) / 2.0 +ISIZE = 784.0 +IMARGIN = 22.0 + +def empty_hex(size): + c = 0 + points = [] + for i in range(2, size * 2 + 2, 2): + points.append([0] * i) + middle = [] + for i in range(size * 2 - 1): + row = [0] * (size * 2) + middle.append(row) + epoints = list(row[:] for row in points[::-1]) + return points + middle + epoints + +def intify(points): + return map(lambda c: (int(c[0]), int(c[1])), points) + +def draw_triangle(im, points, cell, size): + draw = ImageDraw.Draw(im) + # draw.polygon(points, outline=(0, 0, 0)) + if cell: + draw.polygon(intify(points), fill=(0, 0, 0)) + return im + +def getsection(i, size): + return 0 if i <= size - 1 else (1 if i < 3 * size - 1 else 2) + +def getspace(size): + return max(0, sum(len(filter(lambda a: a == 0, b)) for b in empty_hex(size)) - 2) + +def generate(string, debug=False): + size = 0 + binstring = bin(int(string.encode("hex"), 16)).strip("0b") + while size < 3 or getspace(size + 1) - 8 < len(binstring): + size += 1 + n = getspace(size) + # print size, len(binstring) + if debug: print "SIZE", size, " n =", n + im = Image.new("RGB", (int(ISIZE), int(ISIZE)), "white") + pattern = empty_hex(size) + # print len(binstring) + # print sum(len(i) for i in pattern) + pattern[0][len(string) % 2] = 1 + curr = (1, 1 + len(string) % 2, 3 - len(string) % 2) + # 0 1 + # 3 2 + for c in range(n): # range(len(binstring)): + i, j, d = curr + row = pattern[i] + if c < len(binstring): + b = int(binstring[c]) + pattern[i][j] = b + if c % 2 == 0: + pattern[i][j] ^= 1 + + section = getsection(i, size) + leftfacing = [j % 2 == 0, j % 2 != (i - size) % 2, j % 2 == 0][section] + if debug: print "c =", c, ", i =", i, ", j =", j, ", d =", d, ", s =", section, ", l =", leftfacing + if section == 0: + if getsection(i + 1, size) == 0: + if leftfacing: + if d == 0: + if j == 0: + curr = i + 1, j, (d + 2) % 4 + else: + curr = i - 1, j - 1, d + elif d == 1 or d == 2: + curr = i, j + 1, d + elif d == 3: + curr = i + 1, j + 1, d + else: + if d == 0: + curr = i, j - 1, d + elif d == 1: + if j == len(row) - 1: + curr = i + 1, j + 2, (d + 2) % 4 + else: + curr = i - 1, j - 1, d + elif d == 2: + curr = i + 1, j + 1, d + elif d == 3: + curr = i, j - 1, d + elif getsection(i + 1, size) == 1: + if leftfacing: + if d == 0: + if j == 0: + curr = i + 1, j, (d + 2) % 4 + else: + curr = i - 1, j - 1, d + elif d == 1 or d == 2: + curr = i, j + 1, d + elif d == 3: + curr = i + 1, j, d + else: + if d == 0: + curr = i, j - 1, d + elif d == 1: + if j == len(row) - 1: + curr = i + 1, j, (d + 2) % 4 + else: + curr = i - 1, j - 1, d + elif d == 2: + curr = i + 1, j, d + elif d == 3: + curr = i, j - 1, d + elif section == 1: + if getsection(i - 1, size) == 0: + if leftfacing: + if j == len(row) - 1: + if d == 1: + curr = i + 2, j, (d + 2) % 4 + elif d == 2: + curr = i + 2, j, (d + 2) % 4 + elif d == 3: + curr = i + 1, j, d + else: + if d == 0: + curr = i - 1, j, d + elif d == 1 or d == 2: + curr = i, j + 1, d + elif d == 3: + curr = i + 1, j, d + else: + if j == 0: + if d == 0: + curr = i + 2, j, (d + 2) % 4 + elif d == 2: + curr = i + 1, j, d + elif d == 3: + curr = i + 2, j, (d + 2) % 4 + else: + if d == 0 or d == 3: + curr = i, j - 1, d + elif d == 1: + curr = i - 1, j, d + elif d == 2: + curr = i + 1, j, d + elif getsection(i - 1, size) == 1: + if getsection(i + 1, size) == 1: + if leftfacing: + if j == len(row) - 1: + if d == 0: + curr = i - 1, j, d + elif d == 1: + curr = i + 2, j, (d + 2) % 4 + elif d == 2: + curr = i + 2, j, (d + 2) % 4 + elif d == 3: + curr = i + 1, j, d + else: + if d == 0: + curr = i - 1, j, d + elif d == 1 or d == 2: + curr = i, j + 1, d + elif d == 3: + curr = i + 1, j, d + else: + if j == 0: + if d == 0: + curr = i + 2, j, (d + 2) % 4 + elif d == 1: + curr = i - 1, j, d + elif d == 2: + curr = i + 1, j, d + elif d == 3: + curr = i + 2, j, (d + 2) % 4 + else: + if d == 0 or d == 3: + curr = i, j - 1, d + elif d == 1: + curr = i - 1, j, d + elif d == 2: + curr = i + 1, j, d + elif getsection(i + 1, size) == 2: + if leftfacing: + if j == len(row) - 1: + if d == 0: + curr = i - 1, j, d + elif d == 2: + curr = i + 1, j, (d + 2) % 4 + else: + if d == 0: + curr = i - 1, j, d + elif d == 1: + curr = i, j + 1, d + elif d == 2: + curr = i, j + 1, d + elif d == 3: + curr = i + 1, j, d + else: + if d == 0: + curr = i, j - 1, d + elif d == 1: + curr = i - 1, j, d + elif d == 2: + curr = i + 1, j, d + elif d == 3: + if j == 0: + curr = i + 1, j, (d + 2) % 4 + else: + curr = i, j - 1, d + elif section == 2: + if getsection(i - 1, size) == 1: + if leftfacing: + if d == 0: + curr = i - 1, j, d + elif d == 1: + curr = i, j + 1, d + elif d == 2: + curr = i, j + 1, d + elif d == 3: + if j == 0: + curr = i + 1, j, (d + 2) % 4 + else: + curr = i + 1, j - 1, d + else: + if d == 0 or d == 3: + curr = i, j - 1, d + elif d == 1: + curr = i - 1, j, d + elif d == 2: + if j == len(row) - 1: + curr = i + 1, j - 2, (d + 2) % 4 + else: + curr = i + 1, j - 1, d + elif getsection(i - 1, size) == 2: + if leftfacing: + if d == 0: + curr = i - 1, j + 1, d + elif d == 1 or d == 2: + curr = i, j + 1, d + elif d == 3: + if j == 0: + curr = i + 1, j, (d + 2) % 4 + else: + curr = i + 1, j - 1, d + else: + if j == len(row) - 1: + if d == 0: + curr = i, j - 1, d + elif d == 1: + curr = i - 1, j + 1, d + elif d == 2: + curr = i + 1, j - 2, (d + 2) % 4 + else: + if d == 0 or d == 3: + curr = i, j - 1, d + elif d == 1: + curr = i - 1, j + 1, d + elif d == 2: + curr = i + 1, j - 1, d + # for i in range(len(pattern)): + # for j in range(len(pattern[i])): + # section = 0 if i <= size - 1 else (1 if i < 3 * size - 1 else 2) + # leftfacing = [j % 2 == 0, j % 2 != (i - size) % 2, j % 2 == 0][section] + # if not leftfacing: + # print j, + # print + sidelen = (ISIZE - IMARGIN * 2) / (2.0 * size) + altitude = sidelen * ALTCONST + # print sidelen, altitude + for i in range(len(pattern)): + section = getsection(i, size) + row = pattern[i] + rowleft = (ISIZE / 2) - (altitude * len(row) / 2) + if section % 2 == 0: + evenrow = i % 2 == 0 + for j in range(len(row)): + cell = row[j] + top = ceil(i / 2.0) * sidelen - (0.5 * sidelen if not evenrow else 0) + IMARGIN + bottom = top + sidelen + if j % 2 == 0: + points = [ + (rowleft + altitude * j, top + sidelen / 2), + (rowleft + altitude * (j + 1), top), (rowleft + altitude * (j + 1), bottom) + ] + else: + points = [ + (rowleft + altitude * (j + 1), top + sidelen / 2), + (rowleft + altitude * j, top), (rowleft + altitude * j, bottom) + ] + draw_triangle(im, points, cell, size) + else: + evenrow = (i - size) % 2 == 1 + for j in range(len(row)): + cell = row[j] + top = ceil(i / 2.0) * sidelen - (0.5 * sidelen if i % 2 == 1 else 0) + IMARGIN + bottom = top + sidelen + if j % 2 == (i - size) % 2: + points = [ + (rowleft + altitude * (j + 1), top + sidelen / 2), + (rowleft + altitude * j, top), (rowleft + altitude * j, bottom) + ] + else: + points = [ + (rowleft + altitude * j, top + sidelen / 2), + (rowleft + altitude * (j + 1), top), (rowleft + altitude * (j + 1), bottom) + ] + draw_triangle(im, points, cell, size) + return im + +# im = generate("easyctf{are_triangles_more_secure_than_squares?}") +# im.save("flag.png") + +# for i in range(40, 60): +# generate("A" * i, "/tmp/%d.png" % i) \ No newline at end of file diff --git a/qrt/server.py b/qrt/server.py new file mode 100644 index 0000000..51c70de --- /dev/null +++ b/qrt/server.py @@ -0,0 +1,30 @@ +from flask import Flask, request +from qrt import generate +from base64 import b64encode +from binascii import b2a_base64 +from cStringIO import StringIO +from traceback import format_exc + +app = Flask(__name__) + +@app.route("/", methods=["GET", "POST"]) +def index(): + try: + html = "hex qr
enter a string:
" + if request.method == "POST": + if not request.form.get("text"): + html %= "" + html += "

empty

" + else: + html %= request.form["text"] + im = generate(request.form["text"]) + buf = StringIO() + im.save(buf, format="JPEG") + html += "" % b2a_base64(buf.getvalue()) + else: + html %= "" + return html + except: + return "" % format_exc() + +app.run(host="0.0.0.0", port=5000) \ No newline at end of file diff --git a/rsa1/description.md b/rsa1/description.md index d44c07b..c61c847 100644 --- a/rsa1/description.md +++ b/rsa1/description.md @@ -1 +1,5 @@ -I found somebody's notes on their private RSA! Help me crack [this](${ciphertext_txt}). \ No newline at end of file +<<<<<<< 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 diff --git a/rsa1/grader.py b/rsa1/grader.py index 222805a..4f6a800 100644 --- a/rsa1/grader.py +++ b/rsa1/grader.py @@ -1,3 +1,4 @@ +<<<<<<< HEAD from cStringIO import StringIO flag = "wh3n_y0u_h4ve_p&q_RSA_iz_ez" @@ -47,3 +48,9 @@ def grade(random, key): if key.find("%s_%s" % (flag, salt)) >= 0: return True, "Correct!" return False, "Nope." +======= +def grade(autogen, key): + if key.find("tw0_v3ry_merrry_tw1n_pr1m35!!_417c0d") != -1: + return True, "Really Superb! Applause!" + return False, "RIP" +>>>>>>> 93577ddee37a489cf0aa1a4b987d23a3bc3d2657 diff --git a/rsa1/problem.yml b/rsa1/problem.yml index 0015feb..8ff5a4d 100644 --- a/rsa1/problem.yml +++ b/rsa1/problem.yml @@ -1,7 +1,19 @@ +<<<<<<< HEAD title: RSA 1 author: neptunia hint: Go google RSA if you're stuck. category: Cryptography autogen: true programming: false -value: 25 \ No newline at end of file +value: 25 +======= +author: blockingthesky +title: RSA 3 +hint: You might want to read up on how RSA works. +category: Cryptography +autogen: false +programming: false +value: 70 +files: + - rsa3 +>>>>>>> 93577ddee37a489cf0aa1a4b987d23a3bc3d2657 diff --git a/rsa1/rsa3 b/rsa1/rsa3 new file mode 100644 index 0000000..bda7c13 --- /dev/null +++ b/rsa1/rsa3 @@ -0,0 +1,2 @@ +{N : e : c} +{0x27335d21ca51432fa000ddf9e81f630314a0ef2e35d81a839584c5a7356b94934630ebfc2ef9c55b111e8c373f2db66ca3be0c0818b1d4eda7d53c1bd0067f66a12897099b5e322d85a8da45b72b828813af23L : 0x10001 : 0x9b9c138e0d473b6e6cf44acfa3becb358b91d0ba9bfb37bf11effcebf9e0fe4a86439e8217819c273ea5c1c5acfd70147533aa550aa70f2e07cc98be1a1b0ea36c0738d1c994c50b1bd633e3873fc0cb377e7L} \ No newline at end of file diff --git a/simple-rop/Makefile b/simple-rop/Makefile new file mode 100644 index 0000000..96f2342 --- /dev/null +++ b/simple-rop/Makefile @@ -0,0 +1,2 @@ +(all): + gcc -m32 -o simple-rop -fno-stack-protector -O0 simple-rop.c \ No newline at end of file diff --git a/simple-rop/description.md b/simple-rop/description.md new file mode 100644 index 0000000..feda140 --- /dev/null +++ b/simple-rop/description.md @@ -0,0 +1,3 @@ +On the shell there is a folder ``. +Read flag.txt +[Source](${simple-rop.c}) \ No newline at end of file diff --git a/simple-rop/flag.txt b/simple-rop/flag.txt new file mode 100644 index 0000000..43e31ae --- /dev/null +++ b/simple-rop/flag.txt @@ -0,0 +1 @@ +easyctf{r0p_7o_v1ct0ry} \ No newline at end of file diff --git a/simple-rop/grader.py b/simple-rop/grader.py new file mode 100644 index 0000000..31e162c --- /dev/null +++ b/simple-rop/grader.py @@ -0,0 +1,4 @@ +def grade(random, key): + if key.find("r0p_7o_v1ct0ry") != -1: + return True, "Correct!" + return False, "Nope." diff --git a/simple-rop/problem.yml b/simple-rop/problem.yml new file mode 100644 index 0000000..14f06a3 --- /dev/null +++ b/simple-rop/problem.yml @@ -0,0 +1,7 @@ +title: Simple Rop +category: Binary Exploitation +value: 75 +author: r3ndom +autogen: false +files: + - simple-rop.c diff --git a/simple-rop/simple-rop.c b/simple-rop/simple-rop.c new file mode 100644 index 0000000..f3c33e3 --- /dev/null +++ b/simple-rop/simple-rop.c @@ -0,0 +1,25 @@ +#include +#include + +void print_flag(); +void what_did_you_say(); + +int main(int argc, char* argv[]) +{ + gid_t gid = getegid(); + setresgid(gid, gid, gid); + what_did_you_say(); + return 0; +} + +void print_flag() +{ + system("cat flag.txt"); +} + +void what_did_you_say() +{ + char buff[64]; + gets(buff); + printf("You said: %s\n", buff); +} diff --git a/wayward-space-junk/solution.txt b/wayward-space-junk/solution.txt new file mode 100644 index 0000000..bee1d74 --- /dev/null +++ b/wayward-space-junk/solution.txt @@ -0,0 +1,4 @@ +In reality, the space junk will be following a very predictable orbit, around +a polar function, which means that it will eventually be repeating as well. +The trick is to just shoot a bunch of test ones and see how far off you miss. +The pilot key simply identifies the team so they can enter the correct flag.