-
md5()函数
得到flag的条件是变量username和password不等,但是其经过md5加密后相等。若经过md5加密后是==,则可构造payload为?username=QNKCDZO&password=240610708;但此处是===,所以只能通过数组的方式来绕过,即构造的payload为?username[]=1&password[]=a。
-
数组返回NULL绕过
这里有两种方式得到flag,一是利用ereg()函数与strpos()函数的共同漏洞(ereg()比较一个数组和字符串时会返回-1,即变为-1===FALSE;传入一个数组给strpos()时,会出错返回null,即变为null!==FALSE。)所以可以构造payload为?password[]=
二是利用%00对于ereg()函数的字符串截断漏洞(即ereg()无法将%00后的字符串读进去进行比较),所以可以构造payload为?password=1%00--
-
sha()函数比较绕过
得到flag的条件便是变量name和变量password不等,但是经过sha1()函数后相等,这里利用sha1()函数处理的参数为数组时会报错并返回null的漏洞,可以构造payload为?name[]=1&password[]=2
-
md5加密相等绕过
这里直接利用QNKCDZO与240610708经过md5加密后相等这一事实得到flag,所以payload为?a=240610708
-
十六进制与数字比较
此处变量$temp不能是数字,否则会报错;但是又要与十进制的3735929054相等;所以将3735929054的十六进制赋给password便可。构造的payload为?password=0xdeadc0de
-
ereg正则%00截断
嗯。。。这题是个盗版,只能这样说。漏洞上面已经讲过了,可以直接利用数组的独特性,构造payload为?password[]=
嗯。。。。如果是原题的话,也可以使用这种方式来构造payload:?password=1e9%00 * - *
(注意到没?就是这个*-*
),此时有两个点,一是通过科学记数法来达到赋给password的值字节长度小于8但是数值要大于9999999;二是利用%00截断的作用,绕过上面的只能输入数字,字母这个条件。
-
strpos数组绕过
嗯。。。。。我还能说什么呢???题型和上面的不是一样吗?嗯,分数提高了不少。。。。。直接构造payload为?ctf[]=或者是?ctf=1%00%23biubiubiu(注意,这里是#的URL形式,因为采用的是get的方式进行数据请求,若不进行URL编码则会产生乱码,若为post方式则就不需要了)。
- _GET、_COOKIE的数组;所以这里的意思是可以采用post和get两种方式将表域名为hello的数据赋值给变量$a,不过为了简便,后面的payload采用的是get方式。
- var_dump()
这里是将变量a的值打印到界面中。
- eval()
会将传入的字符串当做 PHP内部的代码来执行,这是一个常见的漏洞。
这题有两种思路:
-
直接将flag.php文件读入变量hello中,然后让var_dump打印到界面中。
所以payload可为:?hello=get_file_contents('flag.php')或者?hello=file('flag.php)
file_get_contents()
将括号内的文件读入到一个字符串中去。
file()
将括号内的文件读入到一个数组中去。
-
利用eval()会将括号内的字符串当作php内部的代码来执行这一漏洞,构造payload ?hello=);print_r(file(%22./flag.php%22));//
由于eval()会将括号内的字符串当成php代码,所以会形成var_dump();print_r(file(%22./flag.php%22));//)这个程序,执行后得到flag的值。
print_r(),var_dump(),echo()之间的比较
-
print_r()
是一个函数,打印关于一个变量的易于理解的信息,如果给出的是string、integer或float,将打印变量值本身。如果给出的是array,将会按照一定的格式显示键和元素。
函数原型:bool print_r(mixed result ])
<pre>
<?php
$a=array('a'=>'apple','b'=>'banana','c'=>array('x','y','z'));
print_r($a);
?>
</pre>
结果输出:
<pre>
Array
(
[a]=>apple
[b]=>banana
[c]=>Array
(
[0]=>x
[1]=>y
[2]=>z
)
)
</pre>
-
var_dump()
是一个函数,显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。直接将结果输出到浏览器,如果需要将结果保存到一个string变量中,可使用输出控制函数来捕获当前函数的输出。
函数原型:void var_dump(mixed ....])
<?php
$a=array(1,2,array("a","b","c"));
var_dump($a);
$b=3.1;
$c=true;
var_dump($b,$c);
?>
输出结果:
array(3){
[0]=>int(1)
[1]=>int(2)
[2]=>array(3){
[0]=>string(1) "a"
[1]=>string(1) "b"
[2]=>string(1) "c"
}
}
float(3.1)
bool(true)
-
echo()
是php语句,不是函数。输出一个或多个字符串(或变量值),由于不是函数,所以没有返回值
echo $str,'world','hello!';
echo $str;
输出结果:
world,hello!
- 秋名山老司机
import re #导入正则表达式模块re
import requests #导入requests库
s=requests.session() #创建一个session对象
url=['http://120.24.86.145:8002/qiumingshan/](http://120.24.86.145:8002/qiumingshan/)' #URL为某某某网址
cl=s.get(url).content.decode('utf-8') #用session对象发出请求,获取网址的源代码
print(cl) #打印出网址的源代码
reg=r'([0-9].+)=' #进行正则匹配
num=eval(re.findall(reg,cl)[0]) #返回cl中所有与reg相匹配的全部字串
data={'value':num}
a=s.post(url,data=data).content.decode('utf-8')
print(a)
得到结果:
- urldecode编码二次绕过
相关函数:
eregi():
在一个字符串中搜索指定的模式的字符串,搜索不区分大小,可以有用的检查有效性字符串,如密码。
urldecode():
解码已编码的URL字符串。
关键点:
- _GET函数本身会对括号内的字符串进行一次URL解码,所以最终满足flag条件时的字符串经过了两次URL解码。
经过分析,这里发现得到flag的条件便是:通过$_GET变量搜集的以id为表域名的字符串不含有hackerDJ(不分字母大小)这个字符串,且经过两次URL解码后为hackerDJ,所以payload便是?id=xxxxx(xxxxx为“hackerDJ”的二次URL编码)。开始一直傻傻的使用网上的编码工具,发现都无法将hackerDJ进行URL编码,后来找了张URL编码的对照表,才完成第一次编码,然后用工具进行第二次编码,最终得到flag。
本题涉及的的其他知识点
-
strcmp比较字符串
die():输出括号内的消息并退出当前脚本。
strcmp(string1,string2):比较括号内的两个字符串string1和string2,当他们两个相等时,返回0;string1的大于string2时,返回>0;小于时返回<0。
isset($_GET['a']):判断通过$_GET变量搜集的以a为表单域名的数据是否存在。
所以得到flag的思路便是:通过flag的字符串值flag{xxxx}相等,使得经过strcmp函数作用后返回0,然后0==0,为真,即1,然后得到flag。但是若是早已知道了flag{xxx},题目早就出来了,所以这是行不通的,查找一下php手册中关于strcmp函数的描述,这里涉及了一个数组对strcmp()函数的绕过问题。
在php的手册中发现在5.3及以后的php版本中,当strcmp()括号内是一个数组与字符串比较时,也会返回0。(当然,在以前的版本中是返回-1)
所以此时构造的payload为?a[1](当然也可以是2,3,4,。。。。只要是数组就行,但是一定要以a为数组名(由于isset()的作用))
-
extract变量覆盖
符号是变量符号,在后面加上一个字符串后,这个字符串就是一个变量名或者对象名。此处$flag这个整体则表示flag这个变量。
extract($_GET):
_GET 中。(URL:统一资源定位符,全球性地址,用于定位网上的资源;具体点,比如bugku题目的URL就是http://ctf.bugku.com/challenges,当你访问这个网址的时候便会得到bugku的所有题目,本题flag的URL则是http://120.24.86.145:9009/1.php,但是根据题目提示,你需要通过get的方式传递参数,当参数满足条件时,便会给你flag.)
extract():从数组中将变量导入到当前的符号表。该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。
isset($shiyan):是否设置变量shiyan
trim(file_get_contents($flag)):
trim():移除字符串两侧的空白字符或其他预定义字符。(这里是移除字符串两侧的空格)
file_get_contents():将整个文件读入一个字符串
这题涉及extract()的变量覆盖,所以payload便是?shiyan=&flag=或者?shiyan=&flag
解释一下思路:payload的含义便是将payload语句中两个变量shiyan与flag(注意,这里的flag不是题目中的flag='xxx'中的flag,是另外引用的一个新的flag,只不过名字也叫flag。)都赋值为空。此时payload中的变量flag名与题目中的flag='xxx'变量名重名,由于对于extract()函数,当括号内的变量名与括号外的变量名若重名的话,从extract()函数开始,便会以extract()函数内的变量为主。此时即flag在接下来的程序执行过程中也为空;而变量$content经过相关函数后最终也为空,与变量shiyan的值相等,所以输出flag。
payload解释:有效载荷:https://www.cnblogs.com/tjtest/p/7688616.html
推荐一篇关于覆盖漏洞的文章:http://www.freebuf.com/column/150731.html
-
密码
这个直接构造KEY{zs19970315}就行了,一般人采用生日和姓名做密码时,密码大都是名字的首字母+出生日期,(可能有变化的就是名字的大小写)这没啥好说的。
-
信息查找
嗯.......直接百度下bugku.cn,在网页上出现
所以为KEY{462713425},最下面那个,嗯。。。。最好的解决方式。
-
简单个人信息搜集
这题算是有一丢丢水平,先下载压缩文件,打开时发现需要输入密码,猜测为伪加密(在文件头的加密标志位做修改,进而再打开文件时识被别为加密压缩包。),使用RAR压缩软件的工具部分的修复功能进行修复,然后重新打开。
-
社工进阶
嗯。。。这题挺变态的,开始百度一下孤长离,有一个他的微博,上去转了下,没发现啥,上贴吧搜了下,找到这个
根据另一个提示:‘弱口令’,则应该和登陆bkctftest@163.com有关,用弱口令a123456试着登一下,成功进去
-
简单的社工尝试
下载后发现是一个图片
先用百度试一下,发现
似乎不太好吧,简书直接就出来了。嗯。。。换google试一下,得到这个
往下翻翻,得到这个
点进去看一下,有个微博的链接似乎有用。
在里面发现一个邮箱和一个图片,邮箱试了下没啥效果,然后访问了下图片上的地址,得到了flag。