You stumbled upon someone’s “JS Safe” on the web. It’s a simple HTML
file that can store secrets in the browser’s localStorage. This means
that you won’t be able to extract any secret from it (the secrets are on
the computer of the owner), but it looks like it was hand-crafted to
work only with the password of the owner…
The challenge consists of a fancy HTML file with a cute but
irrelevant animated cube and some embedded JavaScript.
The hardest challenge of not very many I solved in this CTF. What a
struggle! I have a long way to improve. It was pretty fun though. (I
solved “You Already Know”, and got the essence of “ghettohackers:
Throwback”, but didn’t guess the right flag format and believe I was
asleep when they released the hint about it.)
The challenge consists of a simple PHP script that opens a MySQL
connection and then feeds our input into a custom PHP extension
shellme.so.
The extension basically just executes $_POST['shell'] as
shellcode after a strict SECCOMP call, prctl(22,
1).
This means that we can only use the four syscalls read,
write, and exit, and sigreturn,
where the latter two aren’t particularly useful.
Disassembled innermost function of
interest in shellme.so
The goal is to read the flag from the open MySQL connection.
We are presented with a big zip file of SML code, which implements an
interpreter for a small ML-like language with a form of taint analysis
in its type checker, called Wolf. Concretely, every type in
Wolf’s type system has an associated secrecy: it is either
“private” or “public”, and in theory, the type system makes it
impossible to do any computation on private data to get a public
result.
Of course, this is a CTF, so the challenge is all about breaking the
theoretical guarantees of the type system. When we submit code, it’s
evaluated in a context with a private integer variable
flag; our code is typechecked, executed, and printed, but
only if its type is public. The goal is to break the type system and
write code that produces a public value that depends on
flag, so that we can exfiltrate flag
itself.
In all, there are three progressively harder Wolf problems, named
Pupper, Doggo, and Woofer. Doggo and Woofer are each encrypted with the
flag of the challenge before it, so that you need to solve them in order
(unless you can somehow blindly exploit servers running SML
programs).
Wolf Overview
Let’s first go over the Wolf syntax and semantics. (There are small
differences between the three problems, but they’re syntactically
identical and only semantically differ in cases that we’ll naturally get
to.) The examples folder has some examples of valid
code:
This challenge is a video of somebody’s messy desk, with what is
apparently the audio from a Futurama clip.
The desk is indeed extremely messy and full of things that aren’t
particularly useful for us, but close examination reveals a QR code
reflected in the globe in the middle.
The challenge is all about getting that QR code. After trying our
best to clean up the image, we ended up with this:
Woo, first CTF writeup. I got the opportunity to participate in the
2017 CSAW CTF finals with Don’t Hack Alone.
Dumped by my core, left to bleed out bytes on the heap, I was
stripped of my dignity… The last thing I could do was to let other
programs strip me of my null-bytes just so my memory could live on.
We are provided with a core dump. Examining the flavor-text and the
dump, we notice that the dump has no null bytes; we conjecture that they
have been stripped out.
Next, we examine the hexdump and look for any clues. There are a
bunch of ASCII strings, but they look like normal debugging symbols. One
thing that jumps out is that there are a couple fairly convincing
regular striped patterns that become vertically aligned if you display
20 bytes in each line. Once we do that, we notice the following section.
(This dump is from xxb but
xxd -c 20 thoroughlyStripped is quite sufficient.)
Disassembling the executable produces a huge amount of code. There
are some basic obfuscations like a lot of trivial identity functions
nested in each other, and a few functions that wrap around identity
functions but just add some constant multiple of 16. Most of the meat is
in one very large function, though. If you disassemble this function
with IDA, you see a lot of variable initializations and then a lot of
interesting loops that are quite similar:
Did I say “fun”? That was short for function calls. Which are fun
too, admittedly. Blah, I always go to such lengths to come up with
snappy yet justified post titles and end up achieving neither.
One more complimentary breakfast later:
This is it.
Google Code Jam World Finals.
Let me take a moment to reflect. Seriously. I do not know how I made it
this far this year. I guess I might be a top-500-ish competitive
programmer globally, maybe even top-150-ish, but definitely not
top-25-ish. And
Log
Set, the hard problem that got me through Round 3, doesn’t seem like
it plays to my forte particularly either. It’s a bit mathy, but the math
bits aren’t the hard part; I think it’s largely implementation, with one
psychological hurdle where you have to realize that, because of how few
distinct integers there are in S′, you can efficiently solve the
subset-sum instances you need to produce the lexicographically earliest
answer. I’m actually kind of impressed I got that. It seems like the
sort of hurdle I usually get stuck on. How did this happen?
Maybe randomness. Maybe I was just particularly clear-minded during
the round and wrote less buggy code than usual, because I had no
expectation of making it whatsoever and so could look at the contest
detachedly (until midway through the contest I accidentally noticed that
my rank was under 20, and even then I tried very very hard not to think
about it, and it kind of worked).
But it happened, and now I’m here. Time to roll.
In some emails much earlier in the Code Jam logistical process,
Google had asked for “requests for changes and/or additions” to the
software that would be installed on our competition computers, and I had
sent them a long list:
Hi, Here are some things I’d like if they were installed, in
decreasing order of priority:
The Vim plugin syntastic ( https://github.com/scrooloose/syntastic )
a Haskell compiler (probably Haskell Platform 2014.2.0.0
https://www.haskell.org/platform/ even though it’s a year old)
the Haskell package hdevtools (
https://hackage.haskell.org/package/hdevtools ) so that the above two
may be integrated
(I don’t have enough Linux experience to name a specific thing to
install, but command-line utilities that are the equivalent of pbcopy
and pbpaste on Mac OS X, which allow me to redirect text into or out of
the clipboard from the command line easily)
Of course, this is my first Code Jam and I don’t know how reasonable
these requests are. Any nontrivial subset would be appreciated.
Nope, still no meaningful post today. Instead here is a pretty diagram of the A* search algorithm (A-star in English, for my search crawler overlords). At least, I hope it is; I spent more time fiddling with the pretty colors than making sure the algorithm I implemented was actually A*. It looks right, though? In the background, red component measures traversed distance from start, (inverted) green component measures difference between the traversed distance plus heuristic distance and the theoretically optimal heuristic distance from the start, blue component measures heuristic distance to goal.
tl;dr: anybody want to add me on Line or tell/remind me about
other phone chat apps? betaveros as always.
Wow, talk about uninspired post titles.
I got a new phone today. Or, well, it’s second-hand, actually. I try
to make electronics last a long time, but I think this was justified
given the state of my last phone’s screen:
Besides, I’m going off to college and all. Anyway, the phone is
pretty cool. It’s a slick shade of red, it came with a cover and
everything, and it has one of those fancy 3x3-grid locks. How secure are
those again?