To get the flag, we need to open a file named "flag" in the current directory.
We are restricted by:
<ph[(cobras.den)]+~
Some functions we can use under these constraints are abs(), hash(), open(), chr(), ord(), repr().
Now, we need to make an instruction that simplifies to open("flag").read()
. Because we cannot use the characters to make the string "flag", we'll use chr()
to represent letters, making our new instruction open(chr(102)+chr(108)+chr(97)+chr(103))
. How do we make numbers if we can't type any?
There are many different ways you could approach this, but the way I figured it out was when you provide an empty tuple to hash()
, it returns a number output. This is too big to be useful, so we turn it into -1 with hash(())+~hash(())
. Now, we can start crafting a string.
We can make more numbers by using the binary NOT operator ~
, the absolute value function abs()
, and the left shift operator <<
like so:
I wanted to make it small enough for the length restriction, so I had to limit how many times I used the -1 equivalent.
The way I constructed the chr()
numbers from this was to use many left bit shifts and adding/subtracting values from that. So, here is the new instruction:
Going up the substitutions, the final payload is only 905 characters! Sending it returns the flag.
This is what it looks like:
irisctf{pyth0n_has_s(+([]<[]))me_whacky_sh(+([]<[[]]))t}