Tokens v2.0
We have discovered that the upper echelon of Butcher Corp. uses a temporary token generator along with their brain chips as a form of 2FA(Two-Factor Authentication) for their most restricted systems. Our intel team got their source code, but we still haven’t got the seed right. We need you to get it for us, as we’re sure it will be useful for other systems! The name of one of this system’s users is “Dúfa van Tryggvadóttir”, vice president of the company.
Source Code:
Link
Mirror
Server: nc 200.136.213.114 4000
Id: tokens_v20
Total solves: 22
Score: 283
Categories: Exploitation
This exploitation challenge is about this python script:
https://pastebin.com/144yVeZF
This challenge has 3 steps to be solved:
1 | 1 - Find a regex that matches "Dúfa van Tryggvadóttir" with some restrictions. |
Find a regex that matches “Dúfa van Tryggvadóttir” with some restrictions.
This is easy even with these restrictions:
1 | limit = 22 |
The first regex matches every single character not present in the list below [^A-z+]:
- A-z a single character in the range between A (index _65_) and z (index 122) (case sensitive)
- + matches the character + literally (case sensitive)
The second regex matches every single character present in the list below [\[\]]:
- [ matches the character [ literally (case sensitive)
- ] matches the character ] literally (case sensitive)
So we can use characters from index _65_ to index _122_ any others outside this range is forbidden(consult http://www.asciitable.com/index/asciifull.gif) and we can’t user [ or ] and a limit of 22 characters.
Our aproach to this step was easy to find something that was equivalent to the . character, which in regex means matching any character except for new line, we have the + character. We used the following regex:
If we test this in the binary we can see it worked!:
1 | $ nc 200.136.213.114 4000 |
Bypass de options checks and run gen function
This is the part of the code we need to analyse:
1 | if role == "President" and "Open" in option or "Revoke" in option: |
The first thing we have to do here is to choose Revoke, we don’t have the Presidents name so if we don’t want to exit the program, there will be a second check:
1 | if authorized: |
As we can see above doesn’t matter what we choose we will always exit the program so what we do here? we need to find a trick, to bypass this and still have the option “Open” as we can see in the end they are removing all \ of the string in the final of the loop:
1 | class string(object): |
And the calls:1
2
3
4 "Truncated code of the loop"
option = string(option)
if option.strip() == "Open":
gen()
This very useful! this removes newlines or \ characters! The regex expression that splits the string does this:
If we inject O\pen it will match the words O and pen and when we enter in the loop we won’t choose any of the options not exiting the program, after this the string class will help us getting the Open string!
If we do this we will run the gen function:
1 | $ nc 200.136.213.114 4000 |
Bypass the Sand box and print the seed (Which was the flag)
First we have some characters we can’t use:
1 | def validation(input): |
Analysing the regular expression we have:
The characters between the range _43_ and _47_ are:
We can’t use any of the characters above and there is more, we can’t use most of the built_in functions because they are being removed here:
1 | def safe(): |
We tried hard to bypass and we couldn’t do it, we knew that we needed to run raw_input(seed) this function would print the seed for us unfortunately the _ character was filtered too, so we found this function within the code:
1 | def Option(): |
This is perfect if we run gen Options() it will run another raw_input without any filters and then we can inject any character we want! Here is the example how to do it:
The flag was CTF-BR{fiev4zi3Nais7ue7aiSh}