I was helped on this one because I’m a
fucking retardpleb
I didn’tcopy+paste
the password and repeatedly typed it in wrong
Resources/Tips
- Link to challenge
- Disassemble on Windows 64-bit using IDA
-
Reversing for beginners (Coutersy of
@SeargantSkid
)
Main flow of the program
- print(prompt)
- get(username)
- compare(username)
- Continue if comparison succeeds
- Else fail and die
- print(prompt)
- get(password)
- compare(password)
- Continue if comparison succeeds
- Else fail and die
- print()
tl;dr
- Disassemble the program
- The username and password in plaintext is laid right infront of you
- Figure out the control flow to find out why the program early exits…
New concepts
It was easy to get thrown off by:
-
The source file being
C++
, which probably looked like this:#include<iostream> using namespace std; int main() { cout<<"Hello World"; return 0; }
instead of this:
#include <stdio.h> int main() { printf("Hello World"); return 0; }
-
the different calling conventions, 64-bit PE uses
rcx,rdx,r8,r9
during fastcall which differs from the x64 convention on Linux which usesrdi,rsi,rdx,rcx,r8,r9
… -
Also the function name mangling — like who the fuck calls
scanf
as_ZStrsIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E
-
C++ uses “vtables” for classes, which becomes very complex to understand in the disassembly (especially when first starting out like me!)
Learning new things
Some of this knowledge I got from @SeargantSkid
-
cin
andistream
can be thought of asstdin
-
cout
andostream
can be thought of asstdout
- Pay attention to the operator symbol in the function comments
The first red block can be identified as a comparison function (==
) even though the function name is mangled, also notice how all the ostream functions have the arrows in the left direction?
When using stdin
/stdout
:
- You first have to initialize a stream
- Then whenever you need to use
cout
, you allocate the stream tocout
- From there you pass your data and the stream together to a function that will print to stdout
Google is your best friend (sometimes)
Based on the application logic itself I knew it was some form of comparison:
But by throwing the function name in Google, I found several sites that do some code coverage analysis or something… but when I looked up the actual function the results were amazing!
The code seems to be in /usr/include/c++/4.8/bits/basic_string.h
:
Granted this does not work with every mangled function name, but its always worth a shot!