SANS Core NetWars RSAC 2017 Writeup

Tagged under: Linux, CTFs, and RSAC

Posted on 28 May 2017

A few months ago I went to RSA Conference 2017, and participated in the SANS Core NetWars CTF there. The CTF is broken up into five levels of increasing difficulty, with each level consisting of a series of questions that you have to answer. Some of the easiest questions are trivial Linux knowledge, while the more advanced questions require you to do anything from hack mobile phones to pivot across a corporate network, and the highest level is a PVP mode. You start by being given a VM image of a Linux machine, and have to work your way from there. I scored 117 points in the three hours alloted, netting me first place and a cool trophy and challenge coin.

Level One

Level one is mostly trivial questions — “what is the user name of the user you are logged in as” type stuff. They’re mostly reconnaissance, and easy recon at that.

Level Two

Level Two is exploitation — brute force an FTP server that is running on the machine, then get yourself in the sudo group. I think the intended solution was to use Single User Mode or something; I just mounted the hard drive in another VM and chrooted into it. After that, you set up persistent access with SSH and you move on to Level Three.

Level Three

When you get to Level Three, you are issued credentials to a web server that looks like a CI suite for a mobile app developer; you can install apps and view web pages from the perspective of an Android VM. The first questions have you use the web page viewer to exfiltrate some info about the VM host, and the final question requires you to remotely root the VM. I got stuck here; I could generate backdoored apk’s with meterpreter, but the installer kept failing for some reason. I suspect the problem was with the apk’s digital signatures.


NetWars was the highlight of my RSA Conference, and I’ll be trying again (and other CTFs) in the future.

Read More

A Short Rant about the Esquilo Air

Tagged under: Programming, Embedded, and Rants

Posted on 04 Jul 2016

A friend of mine gave me an Esquilo Air for my birthday a while ago, and I decided to try to use it for an over-engineered clock I’m in the process of building.

Picture of the Esquilo Air. Credit

The Esquilo Air features an embedded a 120MHz ARM processor, embedded WiFi, μSD card slot, built-in cloud features, and a slew of the usual inputs and outputs. Its headline feature is its built-in browser IDE running the Squirrel language — no other programming option exists. On paper, it seems like a great introduction to IoT and embedded development. Unfortunately, it has a number of issues, one of which made it simply unworkable for my purposes.

Squirrel, the Language

Squirrel is an interesting language. It seems to primarily compte with good ol’ Lua, the small embedded language of choice for game devs for ages. Both Lua and Squirrel feature very easy integration and small, efficient interpreters. I am lukewarm on Lua; its type system and (lack of) OOP does not endear me to it but I wouldn’t complain too much about having to use it if I needed to. Before I get to the rant, I’m going to be fair and list off the things that I like about Squirrel, especially comparing to Lua:

  • Actual OOP support, with classes, inheritance, and static methods. Lua has none of that (although it can be bolted on via metamethods).
  • Slightly more elegant lambda syntax than Lua.
  • Functional programming constructs (specifically map, reduce, and filter) built-in.
  • Default/optional arguments to functions.

Squirrel, the Rant

On the other hand, Squirrel has some design decisions that strike me as simply bizarre:

  • Almost a complete lack of string manipulation. Specifically, there is no string.replace, nor string.join (although that can be implemented with reduce). If I wanted to deal with C’s useless string library I would just use C.
  • The syntax is inconsistent. The left-arrow operator (<-) is used to “create slots” (AKA store values in new variables) while = is used only to assign to already-existing slots (variables). Except if you’re dealing with a local variable. Then you use = exclusively: local x <- 3 is not correct; local x = 3 is. By comparison x = 3 is an error (assuming x doesn’t exist previously), while x <- 3 is correct.
  • Default function parameters cannot refer to class members. In other words, the following code will not work:
class Foo {
	x = null;
	function bar(y = x) {

Esquilo, the Rant

The Esquilo iteslf is not without its own problems, either:

  • The getting started guide is out of date: It tells you to use a menu to load libraries when they switched to programmatic library loading (require('lib')) in one of the first updates released.
  • The HTTP library errors when it receives a response that is too large for it to handle. The error it throws is identical to the one thrown when the response is not properly formed per the HTTP specification, and the specific error (or the max content size) is not documented anywhere.

The last one is what really sunk it for use in my project — It couldn’t handle almost any of the API.


In short: The Esquilo Air is a nice, albeit limited piece of hardware running a language that has good ideas but some extremely poor design decisions made along the way.

Read More

The Magic Matrix Algorithm

Tagged under: Cheating, Reverse Engineering, Linux, and C

Posted on 11 May 2016

So I got an assignment in my Computer Architecture class: Write a method in C to perform a specific matrix operation, causing as few cache misses as possible. The first question I had was of course, “how do you measure cache misses?”

Memory Tracing with Valgrind

It turns out that we won’t be measuring cache misses on any kind of real cache — instead, we’re running Valgrind’s memory access tracer (valgrind --log-fd=1 --tool=lackey -v --trace-mem=yes /path/to/binary). The tracer produces a file which has each memory address the program accesses, in order, as well as keeping track of whether it was a read, write, modify (i.e. read followed by write), or instruction load. The trace file looks like this:

I 0400d7d4,8
 M 0421c7f0,4
 L 04f6b868,8
 S 7ff0005c8,9

Each line starts with a symbol denoting the kind of access (Instruction load, Modify, Load, Store), followed by an address, and the amount of memory accessed. This trace is then fed to a cache simulator, which simulates a simplistic cache and tells us how many hypothetical cache misses we had.

Grading Process

To submit our code for grading (or to grade locally), we write code that is then compiled an executable binary that the main grader calls; the binary does not consist wholly of student code, and there is some boilerplate to make grading easier. This is very, very important, as you’ll see in a moment. The main grader program calls Valgrind’s tracer on the secondary binary (with the student code in it), and the secondary binary does the following:

  1. Check to see if the student’s method produces the correct output.
  2. Write to a marker memory location.
  3. Call the student’s method again.
  4. Write to a different marker location.
  5. Pass back to the main grader the correctness result, via environment variables.

The main grader then looks for the beginning and ending marker locations in the memory trace, and feeds just that segment to the cache simulator, using the rsults of that for grading.

Being Naughty With My Grader

So let’s look at the source for the secondary binary, shall we? In the header file that student code #includes for some convinience methods:

/* Markers used to bound trace regions of interest */

/*Later on...*/
for (i=0; i < func_counter; i++) {
		(*func_list[i].func_ptr)(M, N, A, B);
		MARKER_END = 34;

Quick, what’s wrong with this code, security-wise?

The markers aren’t static! If I declare some volatile char’s with the right names in my code, they will point to the same symbols as the markers, so if I write to MARKER_END on the first line of my turned-in method, it looks like I had almost zero cache misses.

And that’s how I created the ‘magic’ algorithm that achieved a record-setting 2 cache misses over an entire 64×64 array.

Read More

Rupee Collector Classic: A short game I wrote

Tagged under: Lua, LÖVE2D, and Game Dev

Posted on 24 Sep 2015

I’m currently taking Chris Holden’s honors class, titled “Local Games in ABQ”, and this week’s homework assignment was to create a small game, either using a GUI tool that we have been using in class or some other method. I chose to remix Rupee Collector, a game we had played in class about running around collecting rupees. The game was created using the LÖVE engine, a free 2D game engine that uses Lua as its scripting language.

The goal of the game is to collect as many rupees as possible within 60 seconds, using the arrows to move around.



Download a copy of Rupee Collector and run it.

Mac OS X

Download a copy of Rupee Collector, unzip it, and run it. Note: OS X is untested, as I do not own a Mac.


Download a copy of LÖVE from your distribution’s package manager or their website, then download a copy of Rupee Collector and open it in LÖVE.

Source Code

…is available here.

Read More

An Exploration of Linux Multithreading Security

Tagged under: Cheating, Reverse Engineering, Linux, and C

Posted on 06 May 2015

I’m currently taking a class in C with the excellent Prof. Joel Castellanos for my CS degree, and the final project was to write an AI for a game, described in the assignment slides. The short version of the game is that 1-6 players are placed in a 500x300 square grid with a small amount of randomly generated obstacles placed inside. Each turn, every player may expand to one grid square connected to any of their existing grid squares; the player with the most grid squares claimed at the end of the game is the winner. Rather than a traditional approach, I decided to see if I could creatively break the game instead of coming up with a winning strategy.

Technical Aspects of the Game

Each player in the game is run in a separate thread, and are given 5ms per round to compute their move. If they go over time, they are skipped that turn, and are given another chance to finish in the next 5ms, and so on until they return a move or the game ends. Because of the multithreading approach, I thought to try and ‘cheat’ the game by attempting to freeze or crash my opponents’ threads.

First Foray: Let’s See How Robust the Main Program Is

The rules of the game state that any player whose AI causes the main program to crash or exit unexpectedly is disqualified. I therefore expected some kind of enforcement, perhaps by creating a signal handler for SIGSEGV in each thread to notify the main program and exit if the AI crashes. To test this, I compiled a simple AI into the main program, and used gdb to pause it when my AI is first called. I then grabbed its PID from ps -a, cd‘d into the corresponding part of the /proc/ filesystem, and found the thread ID in /proc/[PID]/task/; it only had two entries - the main thread, whose TID is the same as the program’s PID, and my threads ID. A simple kill -SIGSEGV [TID] tested the response to the ‘crash’, and lo and behold, the whole program crashed. No signal handler. Darn.

A Side Note on Linux Thread ID’s

Before moving on to other methods of breaking threads, I decided to try and figure out how to determine my AI’s thread ID at runtime. A little Googling revealed that there is in fact a Linux syscall for this, gettid(), which for some reason lacks a glibc wrapper. Unfortunately, the opaque thread pointers returned by pthread_self and friends cannot be converted to or from Linux TID’s, which will be important later.


Looking through the process signal list (kill -l) revealed the existence of SIGSTOP and SIGKILL. SIGKILL just kills the whole program, even when sent to a specific thread. No dice. SIGSTOP on the other hand, does work on specific threads… if you’re running Linux < 2.26 or so; this behavior is apparently a bug, as POSIX dictates that SIGSTOP applies only to whole processes. This was fixed, so no easy freezing for me.

Third Time’s The Charm: pthread Methods

Well the main program uses pthreads, so let’s see what’s available in that library. I see three possibilities:

  • pthread_cancel: This is actually a voluntary thing - it just sends a signal and the thread being cancelled has to manually check for and respond to it.
  • pthread_destroy: This would actually work, except that it may cause weird behavior when the program tries to do anything else with the thread I’ve just killed.
  • pthread_suspend: This would work perfectly, except that Linux doesn’t implement it. Grr.

Also, there’s no way to get a handle to a pthread, you have to get it direct from the return value of pthread_create. You also can’t convert Linux TID’s to pthread handles. Once again, not useful.

Last, and certainly not least: ptrace!

The last thing I tried was ptrace, the Linux debugger interface. It includes PTRACE_SUSPEND, which is exactly what I want! It even works on [P|T]ID’s rather than thread handles, which is perfect for me. I tried a simple example, running PTRACE_ATTACH and then PTRACE_SUSPEND after manually determining which TID belonged to my opponent. Unfortunately, ptrace only works on threads that have already called PTRACE_TRACEME (or if you’re root), which means that I have to fork() the whole main program and trace it that way. It doesn’t work due to complications involving multithreading and graphics.


Well, I learned a lot about Linux internals, and how security is handled. Unfortunately, I won’t be winning any competitions with my non-working cheaty code. Oh well.

Read More

Hello, World!

Tagged under:

Posted on 02 May 2015

Welcome to my blog! I will hopefully remember to document interesting things here. Don’t worry, I hate people posting pictures of their lunch just as much as you do.

In the mean time, feel free to check out my projects or to learn more about me.

Read More


Hi! I'm Shea Polansky, a computer science student at the University of New Mexico. You can find more information about me on my about page, and a sampling of my projects on the projects page. I use this blog to post things I make, and ramblings about topics than interest me.

You can find my contact info here if you need to get in touch with me.