昨天打了第四届上海市大学生网络安全大赛,这里记录下四道web的解题过程。
题目描述:what are you doing?
这题说实话比较脑洞。。
进来之后,页面没什么东西,注释有提示robots.txt
:flag.php
应该是放flag的,直接看source.php
有什么还是注释有提示,根据注释,添加header:X-Client-IP:127.0.0.1
以及post admin=1
就可以看到下一步关键提示按照提示post过去给了一个图片的链接,访问一下发现是没东西的一开始以为是要拼速度啥的,写了脚本,发现不是。回头再来看有没有被遗漏的点。发现url这个参数的解析符合parse_url
的特征可以看这篇文章对parse_url
的特性讲解。从而想到有可能是SSRF,尝试一波这里要想一下回显可能在哪里,自然地想到很可能就是在图片那了。访问图片,发现确实打到了东西然后直接构造url=file://@www.ichunqiu.com/var/www/html/flag.php
,再访问图片即可读到flag。
题目描述:Can you hack me?
进来之后同样是一个没东西的页面这次注释也没东西,那么直接扫一波目录,发现有.index.php.swp
,下载下来,用vim -r
复原所有代码如下:
<?php
error_reporting(0);
class come{
private $method;
private $args;
function __construct($method, $args) {
$this->method = $method;
$this->args = $args;
}
function __wakeup(){
foreach($this->args as $k => $v) {
$this->args[$k] = $this->waf(trim($v));
}
}
function waf($str){
$str=preg_replace("/[<>*;|?\n ]/","",$str);
$str=str_replace('flag','',$str);
return $str;
}
function echo($host){
system("echo $host");
}
function __destruct(){
if (in_array($this->method, array("echo"))) {
call_user_func_array(array($this, $this->method), $this->args);
}
}
}
$first='hi';
$var='var';
$bbb='bbb';
$ccc='ccc';
$i=1;
foreach($_GET as $key => $value) {
if($i===1)
{
$i++;
$$key = $value;
}
else{break;}
}
if($first==="doller")
{
@parse_str($_GET['a']);
if($var==='give'){
if($bbb==='me'){
if($ccc==='flag'){
echo "<br>welcome</br>";
$come=@$_POST['come'];
unserialize($come);
}
}
else{
echo "<br>think about it</br>";
}
}
else{
echo "no";
}
}
else{
echo "can you hack me?";
}
?>
前面是一个类的声明,然后看这个部分它只能进行一次变量覆盖,我们看后面的代码,有一个parse_str
,那时候再进行其它变量的覆盖也不迟,所以这里首先处理$first
,传入first=doller
,然后是一个parse_str
,只需要把想改变值的变量传进a就可以了,注意&
要进行url编码,最终到达内层的payload
是first=doller&a=var=give%26bbb=me%26ccc=flag
然后就是一个反序列化,我们来看看这个类首先可以看到,__wakeup()
里面对$args
进行了一个foreach
的操作,每个$v
都要进行waf(trim($v))
的处理,这里很明显,$args
得是一个数组。
然后再看,waf
函数禁用了一些东西,但是好像本来就没打算用得上,还把flag替换为空,简单双写即可绕过。
再看echo
函数,调用了system()
,而且参数可控,明显可以命令注入。
最后看__destruct
,这里限定了传进去的$method
只能是echo
,然后用echo
函数对$args
数组进行处理。
所以,我们可以这么构造然后传入再构造一次,读flag即可
题目描述:GOOD JOB
代码审计题
<?php
//error_reporting(0);
//$dir=md5("icq" . $_SERVER['REMOTE_ADDR']);
$dir=md5("icq");
$sandbox = '/var/sandbox/' . $dir;
@mkdir($sandbox);
@chdir($sandbox);
if($_FILES['file']['name']){
$filename = !empty($_POST['file']) ? $_POST['file'] : $_FILES['file']['name'];
if (!is_array($filename)) {
$filename = explode('.', $filename);
}
$ext = end($filename);
if($ext==$filename[count($filename) - 1]){
die("emmmm...");
}
$new_name = (string)rand(100,999).".".$ext;
move_uploaded_file($_FILES['file']['tmp_name'],$new_name);
$_ = $_POST['hehe'];
if(@substr(file($_)[0],0,6)==='@<?php' && strpos($_,$new_name)===false){
include($_);
}
unlink($new_name);
}
else{
highlight_file(__FILE__);
}
这题刚拿到手,还以为是今年HITCON的one-line-php-challenge
的升级版,吓得我都打开了各种wp待命,后面仔细看了才发现其实没啥关系。首先我们需要绕过这个这个东西,记性好的一秒钟就想到网鼎杯的那道上传题了,这里也一样,用数组即可绕过然后再看下面的部分这两行代码首先把文件名拼接,然后上传,这里通过构造拼接的文件名为../../../../../../tmp/comrade.php
就可以把文件传到/tmp
目录下。再看下面这里首先限定了上传的文件开头6位必须是@<?php
,我们知道这文件内容现在是完全可控的,并没有什么实现难度,然后要求$_
中不能有$new_name
,这个也没什么难度。然后就include($_)
了
我们知道,可以把文件传到/tmp
目录下,然后这里$_
又是可控的,事情就变得很简单了。像这样构造数据包然后,读flag。
题目描述:GOOD LUCK.
进来之后有一个id输入框,还有个登录框第一时间测测SQL注入,发现id是存在注入的。id=sd' or 1#
:id=sd' or 0#
:这里有个值得注意的地方,就是这句$content=str_replace($value,"",$content)
,很明显它在提示我们,后台很有可能把某些关键词替换为空了。fuzz一下,发现load_file
和union
和information_schema.???
(手动测的)系列都被ban了想了一下,觉得首先要找到它把什么替换为空了才能突破。进行了漫长的测试后,发现from
和select
都被替换为空。id=sd' or (selselectect 1)#
:id=sd' or (selselectect 1 fromfromfrom)#
:知道了这两个词被替换为空,那么能不能把他们插入到被ban的关键词中,从而实现绕过呢?id=unifromon
:没有报get out hacker!!
,说明是可以的。然后进行注入,发现这是令人愉悦的有回显的注入(其实是后面才想起来,一开始完全就是当布尔盲注做的-_-0)
id=sd' unifromon selselectect (seselectlect database()),2#
:id=sd' unifromon selselectect (seselectlect group_concat(table_name)frfromom information_schemafrom.tables where table_schema='web'),2#
:id=sd' unifromon selselectect (seselectlect group_concat(column_name)frfromom information_schemafrom.columns where table_name='user' and table_schema='web'),2#
:id=sd' unifromon selselectect (seselectlect group_concat(username,':',password)frfromom web.user),2#
:注出admin
的密码的md5,拿去解密然后登录
登录进来之后看到一个文件上传的表单尝试传点东西,发现不能直接传php,看看数据包发现无论传过去的文件名是什么,后台都会在最后面加个.txt
,而且提示说要upload to ./flag.php
,而且这是个假的上传,访问返回的链接是没有东西的。这里首先发现,最终的文件名是uploaddir
和fileField
的文件名共同组成的,两者配合可以弄出一个php的后缀。剩下的问题就只有如何去掉这个.txt
,第一感觉当然就是截断了,尝试了#,00截断都不行。卡住了好久好久,甚至回到sql注入那里看看能不能load_file
读读后台到底是怎么写的,但是不行。最后还是觉得要截断,试了几个常见的,%0a,%09
,都不行,实在是没办法了,打算把不可见字符都试一遍,试到%02
的时候,成了。??