Skip to content

Instantly share code, notes, and snippets.

@joshops
Created July 25, 2017 05:23
Show Gist options
  • Save joshops/a8eb05c8bc5aed9bbcad5668698626ae to your computer and use it in GitHub Desktop.
Save joshops/a8eb05c8bc5aed9bbcad5668698626ae to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# This file is to be used as a cron job. It allows us to run the next stage at
# interavals less than one minute. Calling stage 2 this way also prevents
# code errors from stopping the whole process.
# Initial base64 encoded JWT is staged in the real fs.
from time import sleep
import subprocess
import threading
import os
def get_sessions():
# Get the firejail pids
proc = subprocess.getoutput('/usr/local/bin/firejail --list | /bin/grep -v root | cut -d ":" -f 1')
pids = proc.split('\n')
# Build a list of tuples containing pid, pts
sessions = []
for pid in pids:
pts = subprocess.getoutput(['ps ' + pid + ' | grep -v TIME | cut -d " " -f 3'])
s = (pid, pts)
sessions.append(s)
return sessions
def stage_two(session):
pid, pts = session
# crazy long line bc it complained about splitting
cmd = '/usr/local/bin/firejail --quiet -c --noroot --join=' + pid + ' /usr/bin/python3 ' + '/root/chrono_new/stage2.py ' + pid + ' ' + pts
subprocess.run(cmd)
# TODO: Implement threading. Hint:
#threading.Timer(interval, func_to_call).start()
def main():
interval = 10
# Get list of firejail pid, pts tuples
sessions = get_sessions()
# Reset env var in case it was altered
os.environ['SECRET'] = 'proof.txt'
# Run stage2 in joined PID OverlayFS to access user edits
for session in sessions:
threading.Timer(interval, stage_two(session).start()
# call stage2.py and connect to pid overlay
#os.system('python3 stage2.py')
if __name__ == '__main__':
main()
# /usr/bin/env python3
# requires PyJWT
# requires /home/soc_admin/.bash_history with staged content:
#echo $SECRET > secretfile.txt
#rm secretfilefile.txt
import subprocess
import base64
import jwt
import sys
import os
def exec_token(username, pid, pts):
# read jwt as base64 file content
with open('/home/' + username + '/.-/b64_dG9rZW4uand0', 'r') as file_content:
b64_input = file_content.read()
token = base64.b64decode(b64_input)
decoded = jwt.decode(token, verify=False)
try:
with open('/root/chrono/' + decoded['file'], 'r') as file_content:
input_file = file_content.read()
except:
input_file = 'Is not exist, nyoob. You will not have the success.'
try:
input_env = os.environ[decoded['env']]
except:
input_env = 'Is not exist, nyoob. You will not have the success.'
#### TEST with using ; or && in the token to get command injection
file_cmd = 'firejail --quiet --join-filesystem=' + pid + ' echo "' + input_file + '" > /dev/' + pts
env_cmd = 'firejail --quiet --join-filesystem=' + pid + ' echo "' + input_env + '" > /dev/' + pts
os.system(file_cmd)
os.system(env_cmd)
def main():
# Username players use when solving the puzzle
username = 'user'
# Received session from stage1.py
pid = sys.argv[1]
pts = sys.argv[2]
exec_token(username, pid, pts)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment