RE ONE
One thing I meant to make more clear but sort of got lost in the translation to the live system: while it is possible to run these challenges locally, it is also possible (even desired!) to solve all three without ever doing so. The output displayed on the hbh challenge page is functionally equivalent to what you would get by running the downloaded binary with your username. The ultimate goal is to introduce interesting new binary challenges that can’t just be solved by dropping a breakpoint and picking the most “passwordy” value you see. I feel like these first three softly introduce the concepts required to eventually get to this goal, but the line dividing them from the already-established application
challenges is more blurry than I’d intended.
Feedback is always appreciated
Hi all!
I’ve been getting a few questions privately regarding the “correct” steps to take towards solving these challenges and I thought I’d drop a small amount of that information here. Remember, this is a new challenge category for working with new tools in a lane that this site doesn’t cover very heavily. Most people are struggling and there’s no reason to feel like you shouldn’t be asking for a hand. Anyway.
General tips:
- YOU CAN ANALYZE LINUX BINARIES ON A WINDOWS SYSTEM. You don’t have to change your host platform or set up a vm or dual boot or whatever unless you want to try and run the challenges (which isn’t necessary). Generally speaking, the linux binaries will be easier to analyze since they won’t have to go through all the hoops of interacting with the windows api. I apologize it took so long for me to notice this, but y’all gotta ask more questions if you’re looking for more answers!
- Decompilation is a fuzzy process. You’re going to see things that “don’t make sense” because… well… they’re wrong. When the decompilation engine takes assembly and tries to make, say, functions, from it, it has to “guess” at simple things- like the types of the arguments being passed in or even how many arguments there are. If you’re seeing a bunch of arguments passed to a function but most of them just… aren’t being used, then that’s your cue to either look closer at the assembly and really figure out what’s going on, or, as I usually do, just delete the arguments (in ghidra: right click the fn name -> edit fn signature) and see if it breaks anything. You can always undo if it does
- You can use
...
in a function signature to say “we can have a buncha args here”. If it seems like a function might be taking a variable number of arguments depending on how it’s called, this might be able to make things more clear.
Tips for windows binaries:
- Gonna have to make a bunch of guesses to be able to find what’s important. There is significantly more “chaff” code that you’ll have to filter through to get to the sweet gooey center of what’s important.
- You can see a ton of strings. You know that I wrote these and that they weren’t generated by “windows”. Maybe start tracing from there?
search -> for strings
and thenright click -> references -> show references to ...
. - If you look at the labeled functions (ghidra:
symbol tree (one of the left windows) -> functions
) you should seeentry
. This is the main entry point to the program. It leads you to a messy function that eventually leads you to the function that contains all our strings. It then returns the output of that stringy function or exits the program. It does a bunch of other stuff, but maybe that stuff isn’t super important…
I’m sure there’s more. Please ask questions! I’d like to see at least a couple more solved on these suckers. We also just picked the point values “randomly”- that is, the team didn’t have a good feel for how hard these would be. If you’ve solved them and this you deserve more points, let me or one of the staff know! If you have ideas or suggestions or whatever, let me or one of the staff know! I’ve got a couple more “cool” ideas in the pipeline but if no one cares then it gets harder for me to care.
Enjoy!
[Edit immediately: formatting]