Some (more) thoughts on community…

A week ago, I had the unique privilege of declaring the second Great Purge of the Platypus Initiative. Among the other Australian information security communities, this concept is unique to us – a time when all “idle” accounts are deleted from our Slack channel, and if they have access, our other resources.

To give an idea of the scale of this exercise:

Of a community of just over 200, 68 is a sizeable number to remove. Why do we do this to ourselves?

The Platypus Initiative was created as a highly participatory environment, where we help each other build knowledge.

Just over a year ago, I had the pleasure of taking part in creating the first iteration of the Platypus Initiative, a small group by the name of Let’s Just Hack Shit. Initially, this group was intended to bring together like-minded individuals who could work together in pursuit of pure technical goals, all together contributing their specialist knowledge for the betterment of our members.

We distinguished ourselves from other communities by this mantra alone: that is, where other groups often tried to be everything to everyone, we focussed on technical excellence above all else, applying ourselves to the arduous trek of self-improvement.

All were expected to participate – at the time, we agreed among ourselves that we would put time and effort into bettering ourselves, as opposed to sitting in a presentation, intellectual begging bowl in hand, only to forget everything as we drunk ourselves senseless by the evening’s end: as was the tradition in the local information security scene.

let’s learn how to apt-get install shit again~~~

It is with some pride that I look back upon that time, when we were but a handful in number, and our chat channels filled with technical content to some extent.

In growing, we have become complacent. In embracing community, we have forgotten the ideals which brought us together.

Over the past year, it has become increasingly apparent that we have strayed from this initial ideal. Personally, I think this is a natural result of the growth we have experienced – as we have grown, we have diversified our interests, and now serve more as community organisers rather than technical drivers.

If I had to search for a word to describe this condition – “complacency” is the first that comes to mind. In growing, we became lazy and idle, and unable to drive the technical content so sorely lacking locally. In embracing community, we have begun to sit on our laurels.

… my name is ozymandias, king of kings …

This is not “wrong”, per se: merely disappointing. We are still doing better than the hilarious intellectual tick-box exercise that passes for commercial penetration testing nowdays. Someone complained to me earlier in the week that commercial penetration testing did not allow him to “learn” – if you want to really learn about infosec beyond a certain, unspoken limit while pentesting in Australia, go home and jerk off instead.

To be clear, I’m not implying there’s no good pentesting teams in Australia. There’s some good places to work, but extremely few manage to (or have a need to!) push the envelope. Nor am I implying that people don’t have a desire to learn – ultimately, Australia suffers from a problem of scale, where there is simply no requirement to push beyond the established norms of industry.

I do, however, mean to say that people simply neglect to try. Cool projects are happening out there, all it requires is a willingness to apply themselves and a base knowledge of programming (i.e. C, or “low-level systems programming” in today’s parlance, once known as “regular programming” or “high-level languages”).

Still, while I don’t have a solution, my message is not one of hopelessness:

It is time we refocused the community again – we grow together, or we suffer slow death-by-no-content like everyone else.

For those of you who have been with us through the two Great Purges we’ve had so far, this line will be familiar to you. It is the third and final pillar of our Great Purge strategy: that is, in proactively removing idleness from our ranks, we give ourselves opportunity to refocus, and reapply ourselves.

Unfortunately, this approach doesn’t scale. Such Great Purges are often announced with some fanfare, and for a week or so, technical content comes to the fore once more – before everyone resettles into their comfort zone.

Most importantly, this includes us – and among organisers of communities, stagnation is death.

To me, it is time we looked beyond our local communities for a more sustainable solution, and in doing so, challenge ourselves and our achievements. As Platypus – as a community, by pooling resources, we have given ourselves the ability to do this – whether this be internet-based collaboration (RIP. Platypus Facts Show) or hopefully flying people into Australia to speak in coming years. If anything gives me hope, it’s this.

As for the here and now – the meager handful of you willing to make sacrifices in order to reach for technical excellence, let’s take this opportunity to refocus ourselves and strive ever onwards.

As for everyone else, may you take this opportunity to reflect, and consider the possibilities open to you, if you were to reach beyond the scope of what your day job would have you do.

See you all at BSides.

 

Posted in Bards | Tagged | Leave a comment

Writeups – Shane and the Binary Files, MI6 (Pragyan CTF)

Over the past few weeks, numerous side projects (including starting lecturing for the COMP6443 course at UNSW, as well as attempting to unravel the fucking magic carpet ride that is OpenBTS) have significantly reduced the time I’ve been able to spend playing CTFs. This weekend, I was happy to at least participate in the Pragyan CTF.

I have documented two of the challenges I was able to complete in the time allocated. Without further ado:

Shane and the Binary Files

This challenge was presented as an archive, containing three Java class files. You can download this here.

Upon unzipping the archive, we are met with three Java .class files. These are obfuscated to a trivial degree, and could be decompiled using jd-gui. The most interesting code was found in nq2eige2ig2323f.class:

parallel_magic

This appeared to show as simple comparison test – that is, the user entered a “key”, and if it matched the program’s expectation, it would print out the flag (or at least something useful) We could emulate this condition by placing the “win” condition into an empty Java application. A few moments of Java later, and we have the flag:

parallel_solve

You can download the final Java solution used here.

MI6

This challenge was presented as an executable file, which you can download here. Furthermore, we were provided with a ciphertext, which we were to decrypt. This was as follows:

"26 25 30 28 22 25 20 23 21 29 22 24 26 23 21 26 27 20 28 22 25 23
 30 29 23 28 24 20 21 26 25 20 23 27 23 29 25 22 23 26 27 29 24 23
 30 21 25 24 26 20 24 22 21 30 26 20 25 24 21 23 27 29 26 22 20 21
 23 22 30 26 29 26 28 27 22 20 27 29 26 30 28 27 26 23 29 21 22 25
 27 24 21 29 25 24 20 25 23 22 30 28 27 29 25 20 24 21 23 20 23 21
 29 26"

Upon initial inspection, it is clear that not all is as it seems – this is a Linux executable bash script, rather than a Windows executable. On further inspection, this appears to unpack and install a piece of Ruby code. By commenting out the installation operation, we are able to retrieve the Ruby script, reverse_1.rb:

mi6_nops

For me, this was an interesting challenge, as I have minimal experience with Ruby, having used it a grand total of once previously. As such, I began Googling various bits of Ruby syntax in order to understand the code.

At this point, a helpful hint from our comrades at CaptureTheSwag shortened the process – the code was from StackOverflow, and was being used without attribution.

This helped put context around the code. A little bit of Googling later, and I understood the concept it was trying to implement:

mi6-wikipedia

In a nutshell, the code would:

  • xor each character by 61 (decimal 61, not the usual 0x61)
  • “partition” the resulting number, using only numbers between 20 and 30
  • print out all the integer partitions together

From a decryption standpoint, the challenge would be to automatically determine how many numbers made up one partitioned character – especially considering that in certain circumstances, there could be multiple options. Given the time constraint, I built a Python script which allowed me to manually try various combinations until I got the flag:

mi6

You can download the Python script here.

I’d like to thank the Pragyan CTF organisers for hosting this event, and while it could be argued that the clues for this event were too cryptic / the challenges did not “lead the player through” a logical sequence (evidenced by the extremely low – near 10% – solve rate of most challenges), I enjoyed solving some of these challenges nonetheless.

See you in the 0CTF qualifiers in two weeks 🙂

Posted in Bards, Computers, Jesting | Tagged , | Leave a comment

Writeup – pinlock (BSides San Francisco)

This past weekend, I participated to some degree in the BSides San Francisco CTF, the HackIM CTF and Codegate Qualifier CTF. Due to the baleful glare of the Day Star pushing temperatures to above 40 degrees in Australia, my participation in these events was limited.

That said, I was able to participate in a good portion of the BSides San Francisco CTF. While a number of challenges was solved, I will present my writeup of the “pinlock” challenge, which I solved with some assistance from our friends at Capture The Swag (who pointed me to the README file, after I missed it initially).

Pinlock

This challenge was presented as an Android application file, which you can download here.

Our initial steps are to unpack the challenge (unzip the APK), attempt to convert the classes.dex file to a JAR file, and then decompile the JAR. This process works quickly, and we are able to begin source code review of the application in jd-gui:

1

From this viewpoint, we can immediately see some interesting code, in the SecretDisplay class, and the releated CryptoUtilities class. We can see the application works in the following logical manner:

2

From here, we should note the README file in the “assets” directory, indicating a switch to “v2” of the database (while the code indicates “v1” is in use, code for what is presumably “v2” is also present).

Our next stop is the “pinlock.db” database: we note that we can extract a secret from both secretsDBv1 and secretsDBv2, which is presumably the flag:

4_fetchdata

At this point, we have both the decryption algorithm, as well as the secret to be decrypted – we are only missing the key, which is derived from a user’s PIN. The PIN is 4 digits long, so this is an easily brute-forceable problem, but we note the presence of the “fetchPin” function within the code:

3_fetchpin

One more trip in to the database, and we can grab the PIN:

5_fetchpin

This looks suspiciously hash-like, so we pass it through crackstation.net, to derive the correct PIN of “7489”.

From here, we have all we need to build our own decryption app, copying and pasting code from the challenge application itself to make our lives easier. A few moments of Java later:

6_flag

You can download the Java solution file here – please forgive my shitty Java, it’s been a while.

I would like to thank the organisers of all three CTF’s this weekend – thankyou for putting together these events for everyone to enjoy, and while I was not able to participate in much of these events, I enjoyed the challenges presented.

See you all in the Boston Key Party Qualifier and VolgaCTF Qualifier in two weeks time!

Posted in Bards, Computers, Jesting | Tagged , , | Leave a comment

Writeups – Catalyst, UnVM Me, Unknown Format, Mailclient

This weekend, I participated in the AlexCTF competition, hosted by Alexandria University. Overall, this event was easier than many previous CTF’s, with the last challenges being released significantly spiking the difficulty.

As always, I will present writeups for the challenges I found most interesting below:

Catalyst

This challenge was presented as an x86 ELF binary, which you can download here. From initial analysis, the structure of the program is as follows (the functions were not initially named thus, this is from an in-progress IDA session):

rev150-initial

We begin our investigation by trying to call the do_flag function directly. Unfortunately, this produces an invalid flag. On further investigation, we note that the flag is derived from the password:

rev150_doflag

Our first step is to patch out the delay calls. Once done, we can focus on the four “check” functions towards the bottom right. By observing which paramters (corresponding to fgets calls) match which arguments are passed to the functions – we can tell that the first three functions check for the username alone. The first function is reasonably uninteresting:

rev150_check_strlen

The next function appears to be a series of linear equations:

rev150_check_username

From this, we can observe the following:

  • The username is likely 12 characters in length, as it is divided up into three 32-bit register-sized chunks for processing here.
  • Part0-Part1+Part2 = 0x5C664B56
  • (Part0+Part2)*3 + Part1 = 0x2E700C7B2
  • Part1 * Part2 = 0x32AC30689A6AD314

Furthermore, we can also determine the valid character set (‘a’-‘z’ + ‘_’) by looking at the third check function.

This is enough to derive the username via a “cheap” brute-force attack – by checking for all the combinations where:

  • Each byte of Part1 is a legitimate character
  • Part2 = 0x32AC30689A6AD314 / Part1
  • Each byte of Part2 is a legitimate character

We can determine that Part1 is “lyst” and Part2 is “_ceo”: making the username “catalyst_ceo”. We can confirm this with a breakpoint at the fourth check function (0x400977), which gets hit:

rev150_breakpt

From here, we can continue on to an analysis of the fourth check function. This check function uses the “username” to seed a PRNG, which is used to generate a series of random numbers to validate the password. No problem, we can simply breakpoint each of the checks, to reveal the password, four characters at a time:

rev150_breakpw

Slowly, bit by 4-byte bit, we build up our password, eventually revealing the flag:

rev150_flag

UnVM Me

This challenge was presented as a compiled Python file, which you can download here.

For this challenge, we can use the “uncompyle” utility, which spits out a nice chunk of Python source code, complete with symbols:

rev250_unvmme_fixed

From this, we know that the program will accept a flag, and “match” each chunk of 5 characters from a user input (the flag) against a set of known MD5’s – if all of them match, you’ve got the flag.

The solution to this is a trivial efficient brute force of the 5-character keyspace, noting down which “chunks” match the known MD5’s, revealing the flag after a few moments of brute forcing:

rev200_flag

You can download the solution script here. It’s not pretty, and requires about 5 minutes of manual “sorting the chunks” after you’re done, but it works.

Unknown Format

This challenge was presented as a packet capture file, which you can download here.

Upon initial analysis, we can see that this is a USB bulk data transfer capture. We begin by reconstructing the file being transferred:

for200-usbcap

Having recompiled the file,a quick inspection reveals this to be a Kindle Update file – the “SP01” header is a tell for this, and the filenames referencing books are but more confirmation.

Nothing obvious showed up in the file itself, but a bit of Google led to a tool for hiding data within Kindle Update files:

for200-lolgithub

A bit of compiling later, and we are able to extract another file from the original update binary. Unlike the original, this file contains a surprise:

alex_lol_gzip

One “-e” argument to binwalk later, and we have another extracted file containing what appears to be garbage. This time, strings reveals success:

alex_forensics_flag

Mailclient

This challenge was presented as a GDB core file, which you can download here. The goal of the challenge was to find a username and a password.

Initially, I had no idea how to tackle this challenge. I began by manually inspecting the file in a hex editor, and using “strings” to extract interesting text. From what I could derive, this was a crash dump from the “mutt” mail client (i.e. the clue about this being a Thunderbird crash was a troll).

Initially, I identified some promising content: an email address (alexctf@example.com) and an [sm]tp_pass variable, containing a password:

alex_forensics_mutt

Unfortunately, sending these yielded no success. My next avenue of attack was to install “mutt”, and try to use GDB to search through the program memory – unfortunately (and logically, in hindsight), this too was fruitless – besides, any interesting data would be contained in the core file, legitimate mutt install or not.

I then applied the power of brute force best force, simply trying to log in to the challenge server with “alexctf@example.com” and each of the strings in the binary as the password:

alex_forensics_lol_2

You can download the brute force script here. The “uniqnotes” file is simply a sorted list of unique strings, generated from the core file.

As always, I would like to thank our hosts, Alexandria University, for putting on this event. I enjoyed the event overall, and I believe this is the first such CTF (at least I didn’t see it last year) – if so, well done for putting together this event and having it run so smoothly.

See you all next week in HackIM / Codegate Qualifiers!

Posted in Bards, Computers, Jesting | Tagged , | 2 Comments

Writeup – Simple Secret 2 (Break In CTF), grgsm_livemon Headless Mode

During the last week, I participated in the Break In CTF. Unfortunately, I completely neglected to take notes or save binaries, therefore, I can only provide a single writeup, based on the only binary I saved.

Simple Secret 2

This challenge is presented as a Linux binary, which you can download here.

 

Upon initial analysis, we can see that this binary takes an input string, processes it somehow, then compares it against an existing string:

breakin-comp01

If this check succeeds, the program then makes an HTTP GET request to the CTF server, which retrieves the flag.

Going a bit further, we can investigate the “input processing” function, at 0x400BB6:

breakin-comp02

The rand() call is a little worrying – if it turns out that input is somehow combined with random input, we’ll need to either patch this out, or use an LD_PRELOAD hook to make the results of this static for testing purposes.

Our next step is to study this a bit further at runtime using gdb, to break on the strcmp call, to see if we can see anything obvious:

breakin-lol

Quickly, we can see that we got trolled, and it’s simply comparing our input against a static string. With this string in hand, we try to run the program again, giving us the flag:

breakin-win

As always, I would like to thank the organisers of the Break In CTF for organising this event. Looking on their website, it appears they run events quite frequently, and in a well organised manner – congratulations to the team for pulling this off. I enjoyed this event (what little time I could spend on it), and look forward to the next one.

grgsm_livemon Headless (+ misc. thoughts)

During this weekend, I also spent some time playing around with my bladeRF. While I am by all accounts a noob, I’ve quickly found this device to be quite versatile, but the interface with which to speak to it (i.e. gnuradio) is rather significant.

bladerf_fuckyou

I am currently working on understanding the GSM stack, and as part of this, I have modified the grgsm_livemon code to work in headless mode, with no dependency on Qt. You can download this code here.

(It turns out that the Python generated by gnuradio-companion is generally pretty old).

I look forward to exploring more of the SDR world, and posting more about what I learn.

See you all next week in AlexCTF.

Posted in Bards, Computers, Jesting | Tagged | Leave a comment