[HCTF 2018]WarmUp
打开链接后是一张图片,看看源码提示source.php,进入source.php后看到一串的php代码,接下来就是代码审计了。
这里需要补充一个知识点:phpmyadmin 4.8.1任意文件包含
上图只是做一个粗略的介绍,看不懂的看下面:
首先,白名单(whilelist)里面有一个叫hint.php的东西,访问一下,得到一个
不知道干嘛用,先放着,应该能用上的,毕竟是hint。
然后开始代码审计:
这块相当于C语言里面的main函数,上面部分的内容相当于定义了一个函数,那个函数在main函数里面被调用,先看看main函数长啥样。首先上传一个file,file必须满足三个条件才能继续执行下去:
1.file必须不为空
2.file必须是字符串
3.file在执行emmm::checkFile函数后返回值必须为True。
然后返回去看看emmm函数是干吗用的。
首先传入一个$page,也就是main函数里面的file,从上往下必须满足4个条件:
1.page不为空且为字符串(在main函数里已经判断过了,这里没啥用)
2.page变量必须在白名单里面
3.接下来,两个函数一个mb_substr和mb_strpos,意思就是截取$page中?前面的字符串,然后再进行白名单校验。
4.在url解码后的$page的?前面是否在whitelist里面
接下来开始构造url:
1.根据白名单,那么肯定要构造 ?source.php
2.因为$page的问号前面的东西必须在白名单里面,白名单只包括source.php,所以source.php后面必须跟一个问号。但是如果传参的内容有问号的话不符合传参的格式,然后就会报错,那选择url编码一下。然后,因为url在上传到服务器的时候会自动解码一次,所以这里需要二重编码:? => %3F => %25%33%46 ,所以前面部分就是 ?source.php%25%33%46
3.接下来,只要利用../回到服务器的根目录下,找到flag就行,经过测试,需要4个../,但是多打几个其实也可以,然后就是 ?source.php%25%33%46../../../../ffffllllaaaagggg
得到falg:
[强网杯 2019]随便注
我相信看了上面的链接之后,读者应该对堆叠注入至少有一个粗浅的认识了。其实很简单,就是用分号隔开然后执行多个命令。
试了一下,发现这里滤过了select。 不知道这里是怎么闭合的,先试试 1'; 以及 1; 然后发现当输入 1';的时候,下面会出现一条横线,盲猜就这样子接着输入。试了一下1' order by 2; 可以回显,但是当order by 3的时候,就出现错误,那这边就有两个注入点;
于是构造以下语句:
1';show tables;
出现了两个表名,一个是 1919810931114514 ,另一个是 words。先试第一个:
1';show columns from `1919810931114514`;
这里要注意数字串为表名的表操作时要加反引号(就是键盘esc下面那个按键)
既然已经出现flag了,那就不需要试word那个表了。然后想办法进入flag这个字段就行。
然后再介绍一下预处理语句的使用方式:
PREPARE sqla from '[my sql sequece]'; //预定义SQL语句
EXECUTE sqla; //执行预定义SQL语句
(DEALLOCATE || DROP) PREPARE sqla; //删除预定义SQL语句
这里我们只需要定义,不需要删除。本来我们只需要构建一句:
1';select flag from `1919810931114514`;
但是前面也介绍过了,这里滤过了select,于是构建:
1';concat("sel","ect flag from `1919810931114514`);
但是这样子没有回显,于是想到了采用预处理的办法:
1';set @sql=concat("sel","ect flag from `1919810931114514`");
prepare mysql from @sql;
execute mysql;
这里的@sql、mysql只是一个变量,随便输什么。
发现这里滤过了小写,那只要set跟prepare随便一个改成大写就行。
1';SET @sql=concat("sel","ect flag from `1919810931114514`");prepare mysql from @sql;execute mysql;
easy_tornado
这里主要涉及到模板注入这个知识点,补充一下:https://www.freebuf.com/vuls/83999.html
首先,打开链接,发现有三个文件。依次点过去看看,第一个文件写的是flag所在的地址:flag in /fllllllllllllag。第二个文件写的是render,再结合题目,盲猜是模板注入。第三个文件夹是hint,提示md5(cookie_secret+md5(filename)),目前还不知道干吗用,先放着。
这里分析一下url,url的格式是filename + 一个哈希值,然后结合一下第三个文件里教你md5怎么算,可能哈希值就是用这个公式算的,然后filename就是 /fllllllllllllag ,然后问题在于不知道cookie_secret。
第一个文件提示 /fllllllllllllag ,先试试filename=/fllllllllllllag试试。虽然报错了,但是很神奇的出现了一个变量叫msg。
这个结合一下render,可能这个就是模板注入的注入点。试试构造 ?msg={{datetime}} 看看这是不是注入点:
有回显,那就是找对了。但是要知道cookie_secret在哪,才能搞到值呀,大佬说在handler.settings变量里面,我不是很懂,文末会给出大佬博客,可以自己去看看,这里等我弄懂了再回来更新。
所以构造:/error?msg={{handler.settings}}
知道了cookie_secret后,就爆MD5就完事了。根据md5(cookie_secret+md5(filename)),先把filename加密了,再两个拼一起进行加密。可以选择在线网站
拼一起后:ef7aabe3-1511-4986-aee0-e2231aa7d73d3bf9f6cf685a6dd8defadabfb41a03a1
所以构造payload:file?filename=/fllllllllllllag&filehash=1cf14dbc4dce086ab497e3cb3000a994
或者直接上脚本:
import hashlib
cookie = 'ef7aabe3-1511-4986-aee0-e2231aa7d73d'
filename = '/fllllllllllllag'
md5_filename = hashlib.md5(filename.encode(encoding='UTF-8')).hexdigest()
word=cookie+md5_filename
flag=hashlib.md5(word.encode(encoding='UTF-8')).hexdigest()
print(flag)
大佬博客:https://blog.csdn.net/weixin_44677409/article/details/94410580
[SUCTF 2019]EasySQL
补充:系统变量@@sql_modesql_mode:是一组mysql支持的基本语法及校验规则
PIPES_AS_CONCAT:将“||”视为字符串的连接操作符而非或运算符,这和Oracle数据库是一样的,也和字符串的拼接函数Concat相类似
源码可在GitHub上面查看https://github.com/team-su/SUCTF-2019/tree/master/Web/easy_sql
源码如下:
首先看看黑名单:
"prepare|flag|unhex|xml|drop|create|insert|like|regexp|outfile|readfile|where|from|union|update|delete|if|sleep|extractvalue|updatexml|or|and|&|\",辣么多。然后看看执行的语句:$sql="select ".$post['query']."||flag from Flag";
两种解法:
第一种:正规解法。
通过堆叠注入,使得sql_mode的值为PIPES_AS_CONCAT。构造:setsql_mode=PIPES_AS_CONCAT;
所以整个语句为:1;set sql_mode=PIPES_AS_CONCAT;select 1
第二种:非预期解。
根据题目给的 $sql="select ".$post['query']."||flag from Flag"; 来构造query:*,1
然后执行的$sql = select *,1 || flag from Flag;
因为*查询了所有的数据,所以flag也就出来了。
[HCTF 2018]admin
进入页面,观察一下,发现是一个很简单的页面,右上角有注册和登录两个功能。查看了一下源码,发现
那提示很明显,应该是将admin的密码改一下或者冒充admin进行一系列操作。不管怎么样先注册一个账户吧
然后看右上角,有三个(四个)功能区:主页、上传、修改密码、退出。
我的想法是参考我写的文章:https://www.jianshu.com/p/c51db608cf44中的《bug》这一块,修改密码的时候抓包一下,然后把用户名修改为admin,那就可以将admin的密码改了。但是,事实是这个并不能这么玩,抓到的是
莫得用户名,但是这边有session,说不定用户信息就藏在这里。但是我们也没办法对它进行解密啊。
查看了一下修改密码界面的源码,发现了一个好东西
应该是服务器就搭在github上,访问一下这个网址,得到这个服务的源码,接下来进行代码审计即可,先把代码clone下来。因为项目是flask,大佬说先看routes.py。看一下index的注册函数代码:
发现index注册函数没做什么处理,直接返回index.html渲染模版,于是我们看一下templates/index.html代码:
这里提示要登录用户名为admin才可以弹出我们想要的flag:hctf{xxxx}。
这里补充一下知识点:
1.flask的session是存储在客户端cookie中的,而且flask仅仅对数据进行了签名。而签名的作用是防篡改,而无法防止被读取。而flask并没有提供加密操作,所以其session的全部内容都是可以在客户端读取的,这就可能造成一些安全问题。具体可参考:https://www.leavesongs.com/PENETRATION/client-session-security.html
2.flask中session的计算是统一的,GitHub上可以找到具体的脚本,待会会附上。
3.密码的计算需要明文加秘钥,而session的计算也一样,明文自己造,但是我们需要找到秘钥。
首先我们需要做的是找到计算session的秘钥,在那么多py文件中,找到了config.py文件:
盲猜ckj123就是我们需要的秘钥。那接下来找找脚本:链接: https://pan.baidu.com/s/13H5kJIxhAjTeUoZyj-dC3A 提取码: kxck
脚本使用的格式如下:
解密:'python 1.py' + 'encode(编码)' + '-s + 秘钥' + '-c + session值'
加密:'python 1.py' + 'decode(解码)' + '-s + 秘钥' + '-t + 明文'
注意格式,在windows下的操作,文本都需要带上英文输入法下的双引号,而linux支持单双引号。
然后得到了解密以后的session:
{'_fresh': True, '_id': b'4a30a6c0a4830dafb3a022de99f44906ec743ed4779af47471eb406c314845fce8ec7216b0f206ff52df2e11a781a893c7f186101061f89796588187e838bb97', 'csrf_token': b'406525a54149d714aabcb476c778abf10aad4003', 'image': b'mrTu', 'name': '123', 'user_id': '10'}
那把name改为admin,再进行加密即可:
得到:.eJxFkMuKg0AQRX9lqHUWPpJNIAtDqyRQLYY2TvdGjBqflQFN0OmQf58mAzO74t7icKqekF3Hampgex8f1QqytoTtEz4usAUe-hpD35F633BWm_nUKDpoKbxvpNMQiYE4izfI1CB1YaFz7jkr3CgNTF5YXAeD7OKZE2oU8ZqzM0knWasUXewMt9sTdp6jSNqGR0jJgqnvRixoItZrqUtCUTsovAWZXFRXb7juHS7qtcldJWodhcc2EsUOXisopvGa3b_66vZ_AvPM-sGWIrGMwkaxYuFh0EjirVE0pxndMGhV588yDYy-N-O8e-Nayuvqj3T5PCZl_NvccjIF5CW1N1jBY6rG99_AtuD1A_qgbG4.XeiGhg.-AM3md6rj8_HE6Li7r6ARdXZliU
注意操作的界面要在index界面进行抓包,不是对修改密码的界面进行抓包。
PS:这里写的只是一种做法,大佬的简书上面写了三种,但是我不太会,这里附上大佬的链接大家自己解读一下。
https://www.jianshu.com/p/f92311564ad0
[强网杯 2019]高明的黑客
不太会写脚本,这个题目的博客也看不太懂,等啥时候会了再做。