Call me maybe?
nc rev.chal.csaw.io 1001
A rev with a nasty binary. There are so many functions. I do not like this binary.
Static Analysis
After staring at the sea of functions in IDA for a little bit, I gave up and tried dumb things instead.
$ strings callsite | grep flag
flag.txt
WARNING: Unsupported flag value(s) of 0x%x in DT_FLAGS_1.
s->_flags2 & _IO_FLAGS2_FORTIFY
version == NULL || (flags & ~(DL_LOOKUP_ADD_DEPENDENCY | DL_LOOKUP_GSCOPE_LOCK)) == 0
imap->l_type == lt_loaded && (imap->l_flags_1 & DF_1_NODELETE) == 0
Oh neat, flag.txt
is a lead. It’s not hard to find the string in IDA, and then follow cross-references to reach the code referencing it.
Purely circumstantially, this looks a lot like code we’d like to call to print the flag. Phew! We’ve found the most important lines of assembly from among the hundreds of functions. It appears that there is a comparison between some string and the suspiciously alphanumeric string “aaGr6xly5gT42” before the code to print the flag.
Dynamic Analysis
After trying a bunch of things in gdb
I basically just learned that callsite 1234 5678
segfaults while trying to execute the address 0x1234. In addition, there were some suspicious strings to be found in the registers when that segfault happens. (This output is from voltron show reg
.)
[ o d I t s z a P c ]
[ ]
RIP 0000000000001234 | 4....... |
RAX 0000000000000001 | ........ |
RBX 0000000000715580 | .Uq..... | => "aaaj23.Ahui1k"
RBP 00007FFFFFFFDE68 | h....... | => 0x7FFFFFFFE217 => "/home/fidget/portal/callsite"
RSP 00007FFFFFFFDC78 | x....... | => 0x400693 => "1"
RDI 0000000000715580 | .Uq..... | => "aaaj23.Ahui1k"
RSI 0000000000000000 | ........ |
RDX 00007FFFFFFFDC88 | ........ | => "40x200
RCX 0000000000000000 | ........ |
R8 0000000000000000 | ........ |
R9 0000000000000000 | ........ |
R10 0000000000000000 | ........ |
R11 00000000004BA260 | `.K..... |
R12 0000000000407AD0 | .z@..... | => "UH"
R13 0000000000000000 | ........ |
R14 00000000006E4018 | .@n..... | => 0x450830 => "H"
R15 0000000000000000 | ........ |
CS 0033 DS 0000
ES 0000 FS 0000
GS 0000 SS 002B
More in-depth interactive stepping allowed me to determine that the segfaulting instruction was 0x40068f
, although this wasn’t actually that useful:
.text:000000000040068F call [rsp+0C8h+var_C0]
However, the function in which this instruction resides disassembles moderately well, and it has a few clues in the form of string literals:
There’s some "%lx"
energy floating around, corroborating how our first argument was interpreted as hexadecimal to obtain an address. As for "aa"
, which suspiciously appears at the start of the string we saw pointed to by our registers as well as the string literal being compared against, fortenforge figured out that the C crypt function was being called on the second argument we passed to callsite
, and the result was this suspicious string. crypt
is an ancient DES-based hash function with a salt of exactly two characters, which happened to be aa
in this case. So it seems like we should reverse the hash aaGr6xly5gT42
to figure out what the second argument should be.
We fed the hash to hashcat for maybe an hour before fortenforge also realized we could probably just cut the Gordian knot by jumping to the code after the check at 0x400cbb
. I did so, and:
$ nc rev.chal.csaw.io 1001
Give me two args, space separated:
400cbb whatever
flag{you_got_the_call_site}
Wrong!
“Wrong” is a social construct, as they say.