baby_boi (A Textbook CTF ROP Tutorial)

CSAW CTF Qualifiers 2019

Welcome to pwn.

nc pwn.chal.csaw.io 1005

Ahhh, CSAW CTF. Amidst all the other CTFs where we’re competing with security professionals who probably have decades of experience and who follow security developments for a living or whatever, there remains a competition where scrubs like me can apply our extremely basic CTF skills and still feel kinda smart by earning points. Now that I’ve graduated and am no longer eligible, our team was pretty small and I didn’t dedicate the full weekend to the CTF, but it means I got to do the really easy challenges in the categories that I was the worst at, by which I mean pwn.

baby_boi is pretty much the simplest possible modern ROP (the modern security protections NX and ASLR are not artificially disabled, but you get everything you need to work around them). We even get source code.

So there’s nothing novel here for experienced pwners, but I feel like there is a shortage of tutorials that walk you through how to solve a textbook ROP the way you’d want to solve it in a CTF, so here is a writeup.

Introduction to Puzzlehunts

not part of the ongoing series, but you can almost pretend it is. This sentence and the one before it are not a puzzle.

Imagine a word search.

Now imagine you aren’t told what words to look for.

Now imagine you aren’t told it’s a word search.

Now imagine it isn’t a word search.

This post aims to be a fairly comprehensive introduction to puzzlehunts and their puzzles, a single post where I can just point people. I erred towards comprehensiveness in this post because I am not aware of any similar resources, especially for puzzlers interested in trying harder puzzlehunts who might not know any more experienced puzzlers to solve with. It’s possible to start solving some puzzles after reading much shorter guides, e.g. Puzzled Pint’s “Puzzling Basics” (PDF), so feel free to skip around, stop reading midway through, or bookmark this to read only after you’ve spent more time solving.

What is a Puzzlehunt?

A puzzlehunt1 is an event where people, usually in teams, solve a series of puzzles.

This is not a very useful definition. The more interesting question is, what is the kind of “puzzle”2 that appears in a puzzlehunt? The concept of a puzzlehunt puzzle is fuzzy and difficult to define precisely. Just about any hard rule one might try to state will be broken by some puzzle, sometimes deliberately. Still, here are some common features of puzzlehunt puzzles:

Cook Like You're Not on MasterChef

part of the “what I learned after four years at MIT” series, I guess?

When I was very young, I thought cooking was easy. I sliced plastic vegetables with a toy knife and then Velcroed them back together, ad infinitum. For at least some time, I wanted to be a chef when I grew up.

When I was slightly less young, I thought cooking was hard. My reference points were mostly (1) my parents, who seemed to know how to make a million different dishes in inscrutable ways without thinking, and (2) MasterChef contestants (who I assume were better at cooking than my parents because they were, well, on MasterChef) messing things up and getting kicked off the show.

Now, I think I probably elided some meaningful distinctions there in my youthful naïveté. Cooking food that will keep you from getting kicked off MasterChef is hard. Cooking edible food is easy.1 Cooking storebought dumplings in particular is so stupidly easy it’s unfair. More generally, though, most recipes tolerate a lot of substitutions,2 number fudging,3 and even straight-up skipping pesky instructions, like the ones in baking recipes where you mix two sets of ingredients separately in specific orders. There are reasons for those steps, but ignoring them and dumping everything into the same mixing bowl usually won’t make your results inedible. You can also just decide to omit ingredients you don’t like. Probably the least tolerant ingredient measurements in recipes are the measurements of baking soda or baking powder, which by the way are different things, in baking recipes. But otherwise you’d really be surprised how many corners you can get away with cutting — I’ve even completely winged one baking soda/powder measurement with decent results. I think this is especially important to know for people from technical backgrounds like me, who have an instinct to treat the numbers in recipes as precisely measured, painstakingly optimized choices to produce the best dish. They usually aren’t, and even if they are optimized for the recipe author’s palate, they probably won’t be optimized for yours.4 And they certainly aren’t optimized for any tradeoffs you might want to make between food quality versus the time and effort you’re putting into cooking. Make the tradeoffs you want. You’re not on MasterChef.

Money Matters

part of the “what I learned after four years at MIT” series, I guess?

There’s some oft-cited psychology studies that suggest that once your salary goes above $75,000, additional money doesn’t make you happier. This sounds like a sage bit of life advice if it were true, the ultimate rebuff against excessive greed and materialism and sacrificing other things for a six-digit salary, but it overstates the case a bit. 80,000 Hours’ analysis of money and happiness is probably the analysis I’d trust the most here; I think it would be more accurate just to say that you get diminishing returns of happiness from salaries above $70,000.1 Still, that was enough for me to decide fairly early on that I wasn’t interested in trying to get a high-paying job for its own sake, or in spending too much effort trying to invest my way to a fortune.2 I wanted my job to be personally satisfying and good for the world, while paying enough for me and my family (current and future) to get by, but I planned to treat any additional money after that as little more than a bonus used for breaking ties.

I still mostly stand by that decision today, but over the intervening years I realized there were a whole host of reasons to want money that weren’t that selfish at all.

Go to Class (Most of the Time)

part of the “what I learned after four years at MIT” series, I guess? A short post this time.

I can’t begin to count the number of times we were exhorted in high school to go to class. College is different, they said. Nobody is going to force you to go to class any more. This is what you came to college to do, what you paid so much time and money for. It’s on you to make sure you’re learning.

By and large I followed this advice, until I considered that I might have overcorrected given the exhortations. There are a lot of definitely bad reasons to skip class, chief among them being too lazy to get out of bed. There are also some non-obvious reasons to go to class, such as getting the professors to recognize you — this is a reason to go to office hours even if you’re not particularly struggling with the class, or if you know people who might be able to help you that you could ask more comfortably or more conveniently; professors who know you may eventually be able to give you career advice, research opportunities, or letters of recommendation. (Of course, you shouldn’t try to befriend professors purely for these selfish motives; they’re also good to know just as fellow humans.)

But there are also plenty of legitimate reasons to skip class. (It’s really unclear how many people out there need to hear this, but my past self did, and I want this draft out of the way-too-long queue of posts.) Here are some.

Multiplication by Juxtaposition

Evaluating 8÷2(2+2) in Haskell (and some other languages)

We interrupt the irregularly scheduled philosophical posts for some programming memes:

Over the last few days, the Internet has divided itself over what the value of the expression 8÷2(2+2) should be. Some say it should be evaluated as (8÷2)×(2+2) = 16. Some say it should be evaluated as 8÷(2×(2+2)) = 1.

At the risk of belaboring the obvious, the core dispute here is not really mathematical. There is not some sequence of mathematical operations that produces some number, where mathematicians disagree about what number it produces. Instead, this is a dispute about mathematical notation: what sequence of mathematical operations the expression corresponds to the way it’s written. Specifically, it is a dispute about whether multiplication written as juxtaposition (how “2” is written right next to “(2+2)”) has strictly higher precedence than division. It is closer to a linguistic or typographical dispute than a purely mathematical one, and the correct answer to the dispute is that whoever wrote the expression that way should learn to write math better.

This debate is not even new. The internet had fun arguing over 48÷2(9+3) and 6÷2(1+2), which are functionally identical ambiguous expressions, eight years ago. I don’t know why the debate is resurging now and why we still haven’t gotten tired of it.

But life is short, so since we’re here anyway, let’s make some additional memes.

Asking the computer

Some of my coworkers had the idea to ask some programming languages what the answer was. The results were underwhelming.

$ python3
Python 3.6.7 (default, Oct 22 2018, 11:32:17)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 8/2(2+2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable

Writing for the Mundane

part of the “what I learned after four years at MIT” series, I guess?

I hated timed essays in high school. It’s pretty clear if you skim that part of the blog archives:

My [SAT] essay got a 10 out of 12. It’s an essay I’d be ashamed of posting anywhere else; it’s disgustingly traditional and formulaic. […] This was simply because I knew that using my normal essay-writing mindset, I’d get maybe a 3, because I’d spend the first twenty minutes debating myself over which side I was on and rewrite the introduction ten times. Too bad. I wasn’t there to write a good essay; I was there to get a good score on the SAT.

The worst issue is that students do not need to give in-depth explanation of anything they learned. Due to its stringent time limit, the essay portion rewards quick reckless writing much more than deep thought. […] encouraging students to practice writing 25-minute essays in order to improve their college-bound skills is like encouraging people to play Grand Theft Auto in order to improve their driving skills.

I took the Grand Theft Auto analogy pretty far. I’m not proud enough of these posts to link them, but you can find them if you try. In short, past me thought timed essays rewarded writing too quickly, with a disregard not only for facts but for the opportunity to lay out your opinions and thoughts so you could clarify and revise them, which was actually the most valuable part of writing.1 I conceded that the time limits made sense as a practical concession to allow you to test students’ writing skills fairly,2 but I felt like there was still way too much emphasis on the raw speed.


Part of a series of posts about what I learned after four years at MIT. We’re ramping up to deeper topics eventually, I promise. Soon™.

This post is about things. You know, physical objects. Earthly possessions. The indispensable yet fickle chains that bind us to this plane of existence.

As a freshman I loved getting free stuff. I went into my first career fair starry-eyed, taking free pens and t-shirts and sunglasses and drawstring bags from every company that would let me; I’m sure many other MIT students have gone through the same ritual of passing. There seemed to be no downside. Besides, all the swag was probably small change for most of the companies anyway, due to VC funding or massive government contracts or whatever. So I might as well make full use of it.

Less normally (although I have no idea by how much), I also hoarded a lot of things that naturally pop up in everyday life, the stuff that would otherwise get thrown away: extra napkins, plastic bags, produce containers, boxes, those payment envelopes that come with magazine subscriptions and exhort you to Subscribe Now To 12 Issues For 20% Off!! At some point I kept the fortune from every fortune cookie I had ever eaten in a tiny resealable bag. The rationale was basically the same: they might be useful some day1 and there was no downside.

How to Choose an MIT Username

I wanted to write a post after two years at college about everything I had learned. I didn’t, firstly because I didn’t make it a priority, and secondly because trying to write about everything I’ve learned at MIT over any nontrivial length of time is the kind of poorly scoped endeavor that I could never complete to my own satisfaction.

Two years came and went, and now it’s been two more years and I’ve learned even more things, not to mention, actually graduated. Jeez. I tried to self-impose a deadline for the big post, but it didn’t work out. There were still too many higher priorities, most of which were also natural consequences of graduating. I also couldn’t bring myself to cut anything, because unlike most of the stuff I haphazardly throw onto this blog, I can actually imagine an audience for just about everything I wanted to write about.

Finally I decided that I would break it into lots of small posts on specific topics. This way, at least the perfectionism can’t bleed between posts too much. The first topic I wanted to write about is simple, mundane, and also fairly limited in scope itself: how to choose your MIT username.


0CTF/TCTF 2019 Quals

Environment: Ubuntu 16.04+latex

In this challenge, we get a gzipped file called perf.data and a minimal description of an environment. Googling this reveals that perf.data is a record format of the perf tool, a Linux profiler. Installing perf allows us to read perf.data and see some pretty interactive tables of statistics in our terminal describing the profiling results, from which we can see some libraries and addresses being called, but they don’t reveal much about what’s going on. One hacky way to see more of the underlying data in a more human-readable way (and to see just how much of it there is) is perf report -D, which dumps the raw data in an ASCII format, but this is still not that useful. (One might hope that one could simply grep for the flag in this big text dump, but it’s nowhere to be seen.) Still, from this file, we can definitely read off all the exact library versions that the perf record was run against.