This is my (Ron's / iagox86's) author writeups for the BSides San Francisco 2022 CTF. You can get the full source code for everything on github. Most have either a Dockerfile or instructions on how to run locally. Enjoy!
First, a bit of history: the original idea I had behind Glitter Printer was to make a video game challenge involving cartridge-swap, where I'd write a handful of simple video games in 100% x86 code with no imports or anything (like an old fashioned cartridge game), and the player could swap between them without memory being re-initialized. Folks used to do this sorta thing on NES, and maybe I'll use it in a future challenge, but I decided to make this a bit simpler.
While experimenting with writing libraries without libc, I realized just how much work it was going to be to write a bunch of games, and decided to simplify. My next ide was to write a "driver" type thing, where a blob of code is loaded into +RWX memory and the player could go wild on it. The the name Glitter Printer came across my radar, I don't even remember why, and that gave me the idea to do an LPR server.
That's quite the background!
It's designed to be a sort of "server management software". I sort of chose that theme to play off the Solarwinds thing, the theme wasn't super linked to the challenge.
The challenge was to analyze and reverse engineer a piece of client-side software that "checks in" with a server. For the check-in, the client is required to "validate" itself. The server sends a random "challenge" - which is actually a block of randomized x86 code - and that code used to checksum active memory to prevent tampering. If anybody reading this worked on bots for the original Starcraft (and other Battle.net games), this might seem familiar! It's based on Battle.net's CheckRevision code.
This is actually a reasonable simple challenge, overall. I got the idea of using a bad mt19937 implementation (the Mersenne Twister PRNG used by Ruby and Python) from SANS Holiday Hack Challenge 2020 (which is still online if you want to play!), and wanted to build a challenge around it. I had the idea of Battleship originally, but ended up deciding on Hangman for reasons I no longer remember, but that I'm sure made sense at the time.
Both parts are reasonably simple reverse engineering challenges. I provide the compiled binaries to the player (you can find those in the respective distfiles/ folders), and you have to figure out what to do with them.
Both challenges use the same basic code as the runme challenges, where you send shellcode that is executed. Only in this case, the shellcode must be modified or "encoded" in some way first!
This is going to be a writeup for the Runme suite of challenges from BSides San Francisco 2021.
The three challenges I'll cover are runme, runme2, and runme3, which are increasingly difficult write-shellcode challenges. As always, the binary and info the player gets is in the respective distfiles/ folder, and source is in challenge/.
Thanks to symmetric (aka Brandon Enright) for this wonderful guest post! I tried to proofread it, but holy math Batman!! --Ron / @iagox86
Hey all, this is symmetric here! I was thrilled to be once again involved in running the BSidesSF CTF with such creative teammates and skilled CTF players.
My favorite challenge this year was rsa-debugger which, despite getting 12 solves, was actually quite hard. In this post I’d like to tell you a bit about the genesis of the challenge and how to solve it.
As I was really ramping up challenge making this year Microsoft had the great timing to release CVE-2020-0601. As something of a "crypto nerd" I was pretty interested in the details. Fortunately Thomas Ptacek (@tqbf) wrote up a great first-take on the vulnerability on Hacker News which turned out to be essentially spot-on. tbqf also linked to Cryptopals Exercise 61 which gets even further into the math behind the Curveball attack.
But the relevant part of that exercise was the final comment about RSA:
Since RSA signing and decryption are equivalent operations, you can use this same technique for other surprising results. Try generating a random (or chosen) ciphertext and creating a key to decrypt it to a plaintext of your choice!
When I read that, I knew I had to make a challenge that would have users do just that!
For my third and final blog post about the BSidesSF CTF, I wanted to cover the solution to Chameleon. Chameleon is loosely based on a KringleCon challenge I wrote (video guide), which is loosely based on a real-world penetration test from a long time ago. Except that Chameleon is much, much harder than either.
As mentioned in a previous post, I was honoured to once again help run BSidesSF CTF!
This is going to be a quick writeup for three challenges: config-me, rusty1, and rusty2. All three are reversing challenges written in Rust, although the actual amount of reversing required is low for the first two.
Once again, it was my distinct privilege to be a BSidesSF CTF organizer! As somebody who played CTFs for years, it really means a lot to me to organize one, and watch folks struggle through our challenges. And more importantly, each person that comes up to us and either thanks us or tells us they learned something is a huge bonus!
But this week, I want to post writeups for some of the challenges I wrote. I'm starting with my favourite - Gman!
I run a lot of lockpicking villages and such, and have a pretty big collection of locks, picks, and knowledge. A ton of people ask me how to get started, and unfortunately I don't think there are any particularly good walkthroughs of how to get the basic stuff needed to start. Since Peterson just announced their winter sale, and I've had several requests to recommend lockpicking-based Christmas gifts, I figured this would be a good time to post some info!
Lots of the advice I see is around clear (acrylic) locks and progressive locks. I'm gonna be slightly controversial here by saying: clear and progressive locks are almost universally bad for learning or training - they're badly made, unrealistic, have cheap parts, etc. They're great for learning how locks work, but not for any serious practice.
In this post, I will talk about a few things: what are the first picks you should get, what are some good locks to practice on, and what are good resources to use for learning?
In addition to genius, whose writeup I already posted, my other favourite challenge I wrote for BSidesSF CTF was called launchcode. This will be my third and final writeup for BSidesSF CTF for 2019, but you can see all the challenges and solutions on our Github releases page.
This post will be more about how I developed this, since the solution is fairly straight forward once you know how it's implemented.
This is yet another author's writeup for BSidesSF CTF challenges! This one will focus on three crypto challenges I wrote: mainframe, mixer, and decrypto!
This is going to be an author's writeup of the BSidesSF 2019 CTF challenge: genius!
genius is probably my favourite challenge from the year, and I'm thrilled that it was solved by 6 teams! It was inspired by a few other challenges I wrote in the past, including Nibbler. You can grab the sourcecode, solution, and everything needed to run it yourself on our Github release!
It is actually implemented as a pair of programs: loader and genius. I only provide the binaries to the players, so it's up to the player to reverse engineer them. Fortunately, for this writeup, we'll have source to reference as needed!
This is a technical rundown of a vulnerability that we've dubbed "WebExec". The summary is: a flaw in WebEx's WebexUpdateService allows anyone with a login to the Windows system where WebEx is installed to run SYSTEM-level code remotely. That's right: this client-side application that doesn't listen on any ports is actually vulnerable to remote code execution! A local or domain account will work, making this a powerful way to pivot through networks until it's patched.
High level details and FAQ at https://webexec.org! Below is a technical writeup of how we found the bug and how it works.
A couple months ago, we ran BSides San Francisco CTF. It was fun, and I posted blogs about it at the time, but I wanted to do a late writeup for the level b-64-b-tuff.
The challenge was to write base64-compatible shellcode. There's an easy solution - using an alphanumeric encoder - but what's the fun in that? (also, I didn't think of it :) ). I'm going to cover base64, but these exact same principles apply to alphanumeric - there's absolutely on reason you couldn't change the SET variable in my examples and generate alphanumeric shellcode.
In this post, we're going to write a base64 decoder stub by hand, which encodes some super simple shellcode. I'll also post a link to a tool I wrote to automate this.
I can't promise that this is the best, or the easiest, or even a sane way to do this. I came up with this process all by myself, but I have to imagine that the generally available encoders do basically the same thing. :)