Skip to content

[Challenge 7] bonus auth

Justin Chadwell edited this page Oct 25, 2020 · 3 revisions

For the final bonus challenge, we get given a simple binary to investigate.

Well, we've taken control of their servers.

I guess we're done! But if you're still looking for a bit of a challenge, I did find this hidden away, as a more advanced version of that last one.

Good luck and goodbye!

If we run the binary, we get a very similar interface to the one before:

$ ./sh
---------------------------------------
***  ENHANCED PROTECTION ENABLED  *** 
TRIPLE-PASSWORD AUTHENTICATION REQUIRED
---------------------------------------
password:

Last time, we just ran strings on the binary, so let's try doing that again:

$ strings sh | grep HTM
HTM{...-....-..-..}

Hm, it looks like the actual content in the flag has been redacted, so we'll need to have a way to get it.

In a setting where we start to reverse-engineer a binary, it's often worth first trying to observe it running dynamically before starting to pull apart the assembly code. That's because static analysis can just take a long time, while dynamic analysis can be relatively quick.

We can use the ltrace tool to monitor library calls, and see if we can detect anything interesting:

$ ltrace ./sh
setbuf(0x7f17c1591800, 0)                        = <void>
setbuf(0x7f17c1592520, 0)                        = <void>
setbuf(0x7f17c1592440, 0)                        = <void>
puts("--------------------------------"...---------------------------------------
)      = 40
puts(" ***  ENHANCED PROTECTION ENABLE"... ***  ENHANCED PROTECTION ENABLED  *** 
)      = 40
puts("TRIPLE-PASSWORD AUTHENTICATION R"...TRIPLE-PASSWORD AUTHENTICATION REQUIRED
)      = 40
puts("--------------------------------"...---------------------------------------
)      = 40
printf("password: "password: )                             = 10
fgets(hello
"hello\n", 256, 0x7f17c1591800)            = 0x7ffc17bfdc20
strlen("hello\n")                                = 6
strlen("hello")                                  = 5
strncmp("hunter-root-4", "hello", 5)             = 16
puts("shell access has been rejected!"shell access has been rejected!
)          = 32
+++ exited (status 1) +++

Right after the password prompt, we can see that our input "hello" has been compared to the string "hunter-root-4", so there's a pretty good chance this is the password. Let's try it again with ltrace:

$ ltrace ./sh
setbuf(0x7f41bdf3d800, 0)                        = <void>
setbuf(0x7f41bdf3e520, 0)                        = <void>
setbuf(0x7f41bdf3e440, 0)                        = <void>
puts("--------------------------------"...---------------------------------------
)      = 40
puts(" ***  ENHANCED PROTECTION ENABLE"... ***  ENHANCED PROTECTION ENABLED  *** 
)      = 40
puts("TRIPLE-PASSWORD AUTHENTICATION R"...TRIPLE-PASSWORD AUTHENTICATION REQUIRED
)      = 40
puts("--------------------------------"...---------------------------------------
)      = 40
printf("password: "password: )                             = 10
fgets(hunter-root-4
"hunter-root-4\n", 256, 0x7f41bdf3d800)    = 0x7ffda5bfc740
strlen("hunter-root-4\n")                        = 14
strlen("hunter-root-4")                          = 13
strncmp("hunter-root-4", "hunter-root-4", 13)    = 0
puts("UNLOCKED"UNLOCKED
)                                 = 9

Awesome! We unlocked the first level of protection, so let's continue on:

printf("password: "password: )                             = 10
fgets(test
"test\n", 256, 0x7f41bdf3d800)             = 0x7ffda5bfc740
strlen("test\n")                                 = 5
strlen("test")                                   = 4
puts("shell access has been rejected!"shell access has been rejected!
)          = 32
+++ exited (status 1) +++

Hm, we can see a new password being read in, and the same calls to strlen being made, but no more string comparison function! There's lots of ways of comparing strings, or the password might not be used directly as a string, so no library function gets called, so ltrace won't detect it.

It's time to disassemble! Let's open it up in Ghidra!

In the main function, we can see a number of check_password functions referenced as function pointers, and stored in an array ps.

Then later, we can see a reference to the variable p which calls these functions.

Cool, let's take a look at these functions one by one.

check_password1:

check_password1 is the one we got before, and simply compares the input to the string "hunter-root-4". We can also see that it uses the provided password to start populating the FLAG variable.

check_password2:

This function checks all of the characters one by one in a loop, using i as a counter. Each character is checked if it's outside the bounds, of between '1' and '9', and if it's not, the password is marked as invalid.

If the character is in the right range, we add it as a digit to the count variable. Then we continue to compare count to the value 0x1bba7, which is 113575 in decimal:

We can check the password:

$ ./sh
---------------------------------------
***  ENHANCED PROTECTION ENABLED  *** 
TRIPLE-PASSWORD AUTHENTICATION REQUIRED
---------------------------------------
password: hunter-root-4
UNLOCKED
password: 113575
UNLOCKED
password:

Awesome, only one left to go!

check_password3:

This check goes through each character in the password, performing an XOR operation with the key "abcsecretkey", comparing the results to goal3.

Because the XOR operation is perfectly reversible, all we need to do is XOR the key with the goal, and we can extract the password!

We can do this with a quick python snippet:

>>> bytearray(x ^ y for x, y in zip(b"abcsecretkey", b"\x29\x0b\x2e\x06\x35\x13\x37\x11\x33\x04\x21"))
bytearray(b'HiMuPpEtGoD')

We get the third password as "HiMuPpEtGoD".

Let's try it:

$./sh
---------------------------------------
***  ENHANCED PROTECTION ENABLED  *** 
TRIPLE-PASSWORD AUTHENTICATION REQUIRED
---------------------------------------
password: hunter-root-4
UNLOCKED
password: 113575
UNLOCKED
password: HiMuPpEtGoD
UNLOCKED
---------------------------------------
***     AUTHENTICATION SUCCESS    *** 
---------------------------------------

FLAG: HTM{7H3-G4M3-15-uP}

And we have the final flag "HTM{7H3-G4M3-15-uP}"!

Clone this wiki locally