CrossCTF Finals 2018 : The Evilness (Misc)
First Blood by : OSI Layer 8
Ready for something ridiculously difficult?
nc ctf.pwn.sg 4020
Challenge
Once we connect to the address, we get:
#!/usr/bin/env python
import sys
import flag
import signal
import os
import tempfile
temp_file = tempfile.NamedTemporaryFile(prefix="cartoon-",
suffix=".dat",
delete=True)
def handler(signum, frame):
write("Times up!")
temp_file.close()
sys.exit(0)
def write(data, endl='\n'):
sys.stdout.write(data + endl)
sys.stdout.flush()
def readline():
return sys.stdin.readline().strip()
def main():
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)
signal.signal(signal.SIGALRM, handler)
signal.alarm(10)
# Write the flag to the temp file
temp_file.file.write(flag.flag)
temp_file.file.flush()
# Oh I'm sorry, did you want this?
del flag.flag
write(open(__file__).read())
command = "/usr/bin/shred " + temp_file.name
write("Here comes the shredder! (%s)" % command)
######################################################################
#
# INCOMING TRANSMISSION...
#
# CAREFUL AGENT. WE DO NOT HAVE MUCH TIME. I'VE OPENED A WORMHOLE IN
# THE FABRIC OF TIME AND SPACE TO INTRODUCE A FAULT IN ONE BYTE!
#
# MAKE USE OF IT WISELY!
#
command_fault = list(command)
index = int(readline())
byt = int(readline(), 16)
if (0x0 <= index < len(command_fault)):
if (0x0 <= byt <= 0xff):
command_fault[index] = chr(byt)
command = "".join(command_fault)
#
# TRANSMISSION ENDED
#
######################################################################
# Oooh, did you want this too? Too bad it's being... shredded.
os.system(command)
if __name__ == "__main__":
main()
Here comes the shredder! (/usr/bin/shred /tmp/cartoon-EcqWge.dat)
Basically, we get to change one character in command /usr/bin/shred /tmp/cartoon-XXXXX.dat
to any character we want, and the flag is stored in /tmp/cartoon-XXXXX.dat
Solution
There is a less known editor called ed
on Linux systems. We can type in !sh
inside the editor to drop into the shell. We can replace the letter 'h' with '&' in the command to instead run:
/usr/bin/sh&ed /tmp/cartoon-XXXXX.dat
which will run /usr/bin/sh
(which doesn't exist), and then run ed /tmp/cartoon-XXXXX.dat
.
To replace the character, we send a index of 11, and
I was too lazy to Ask the Oracle on how to actually use ed
, so I just went to shell and ran cat flag
The solution script is here