xctf-web backup

打开靶场看见的就是 index.php 的备份文件,最开始以为是 svn 源码泄露的题,后来 url 加上 /.svn/entries 没反应。

查了一下常见的备份文件名:.git .svn .swp .svn .~ .bak .bash_history

加上 index.php.bak 以后,下载了该文件,源码里有 flag。

xctf-web simple_js

看名字感觉是 javaScript 的题,靶场地址打开是一个弹窗,让输密码。

不过不管输入啥都只返回 FAUX PASSWORD HAHA 。

用 burp 抓了下包,看到了 JavaScript 的代码。

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
<script type="text/javascript">
function dechiffre(pass_enc){
var pass = "70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65";
var tab = pass_enc.split(',');
var tab2 = pass.split(',');
var i,j,k,l=0,m,n,o,p = "";
i = 0;j = tab.length;
k = j + (l) + (n=0);
n = tab2.length;
for(i = (o=0); i < (k = j = n); i++ )
{
o = tab[i-l];
p += String.fromCharCode((o = tab2[i]));
if(i == 5)break;
}
for(i = (o=0); i < (k = j = n); i++ )
{
o = tab[i-l];
if(i > 5 && i < k-1)
p += String.fromCharCode((o = tab2[i]));
}
p += String.fromCharCode(tab2[17]);
pass = p;return pass;
}
String["fromCharCode"](dechiffre("\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30"));

h = window.prompt('Enter password');
alert( dechiffre(h) );
</script>

正好在看 JavaScript 的书,来分析一下代码。

先了解几个里面用到的函数 :

String.fromCharCode(): 将 Unicode 编码转换成字符。

split(): 将字符串以指定的符号分开,返回字符串数组。

1.首先是定义了一个 dechiffre 函数,形参变量为 pass_enc。

2.既然有函数定义,总要使用把:

1
String["fromCharCode"](dechiffre("\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30"))

首先,将 Unicode 编码转换成字符:”55,56,54,79,115,69,114,116,107,49,50”,然后传入函数 dechiffre,实参为转换的字符。

3.然后对传入的变量,和在函数内部定义的变量进行处理,利用 split() 分开,返回两个字符串数组。

tab=[55,56,54,79,115,69,114,116,107,49,50]

tab2=[70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65]

1
2
var tab  = pass_enc.split(',');
var tab2 = pass.split(',');

4.然后函数内部定义了几个变量,i、j、k 、m、n、o 都没有赋值,为 undefined 类型;l=0,p= “”;然后给 i 赋值 0;j 赋值为 tab 长度 11;k 的值为11;n 的值为18。

1
2
3
4
var i,j,k,l=0,m,n,o,p = "";
i = 0;j = tab.length;
k = j + (l) + (n=0);
n = tab2.length;

5.然后是两个 for 循环,这个代码很乱,先简化一下。for 循环中第一次对 o 的赋值没有,因为在执行 p += String.fromCharCode((o = tab2[i])); 的时候,o 被重新赋值,第一个循环执行到 i=5 ,break。所以此时 p 的值为 FAUX P;然后开始第二次循环输出,此时 p 的值为 FAUX PASSWORD HAH;最后加上 tab2 中的最后一个值的 Ascii 编码,返回最后 p 的值为 FAUX PASSWORD HAHA。

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
#简化前
for(i = (o=0); i < (k = j = n); i++ )
{
o = tab[i-l];
p += String.fromCharCode((o = tab2[i]));
if(i == 5)break;
}
for(i = (o=0); i < (k = j = n); i++ )
{
o = tab[i-l];
if(i > 5 && i < k-1)
p += String.fromCharCode((o = tab2[i]));
}
p += String.fromCharCode(tab2[17]);
pass = p;
return pass;
#简化后
for(i = 0; i < 18; i++ )
{
o = tab[i-l];
p += String.fromCharCode((o = tab2[i]));
if(i == 5)break;
}
for(i = 0; i < 18; i++ )
{
o = tab[i-l];
if(i > 5 && i < k-1)
p += String.fromCharCode((o = tab2[i]));
}
p += String.fromCharCode(tab2[17]);
pass = p;
return pass;

6.所以不管输入啥,都只能返回 FAUX PASSWORD HAHA。所以传进来的参数溜达了一圈啥也没干?所以把这个不知道干啥的函数去了吧,直接执行转换然后输出。得到 flag。

1
2
var n=String.fromCharCode(55,56,54,79,115,69,114,116,107,49,50);
document.write(n);

xctf-web xff_referer

打开靶场显示,ip地址必须来自123.123.123.123。

所以肯定要改 http 请求头,尝试加 referer 不对,题目是 xff_referer,查了一下这个。

维基百科:

X-Forwarded-For(XFF)是用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段。

所以直接用 burp 在 http 请求中加入该参数。抓了响应包,还要求请求来自goole。

再上 Referer 参数就可以了。

xctf-web command_execution

看题目简介感觉应该是命令执行,进了靶场就看见 ping ,直接尝试命令执行。

flag 文件在 /home 下。

xctf-web simple_php

打开之后是一段 php 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
show_source(__FILE__);
include("config.php");
$a=@$_GET['a'];
$b=@$_GET['b'];
if($a==0 and $a){
echo $flag1;
}
if(is_numeric($b)){
exit();
}
if($b>1234){
echo $flag2;
}
?>

先来看里面用到的函数:

show_source(): 对文件进行语法高亮显示。

is_numeric():用于检测变量是否为数字或数字字符串。

1.定义两个变量 a,b 分别接收 GET 方式传入的参数。

1
2
$a=@$_GET['a'];
$b=@$_GET['b'];

2.三个判断条件,第一个要求同时满足 $a==0 and $a,因为 php 是弱语言类型,这里直接在 url 后面加上 ?a=’0’。可以看到输出一般 flag。

1
2
3
4
5
6
7
8
9
if($a==0 and $a){
echo $flag1;
}
if(is_numeric($b)){
exit();
}
if($b>1234){
echo $flag2;
}

3.后面的两个判断,先检查 b 是不是数字或数字字符,然后判断是否大于 1234,同样的道理,因为 php 语言的性质,传入 b=1235a 会转换为 1235。得到 flag。

xctf-web cat

看题目信息没什么东西,“抓住那只猫?”

进靶场环境让输入域名,最开始也是以为是命令执行什么的,但是加上命令特殊字符被转义而且提示 Invalid URL 。

不知道从哪下手,太菜了。查看了官方给的 wp 学习了一下。

后台执行了两部分文件,一部分是 php,一部分是 Django。

题目利用的点有以下两个:

Django使用的是gbk编码,超过%F7的编码不在gbk中有意义。所以使用%80以后的编码会报错。

CURLOPT_SAFE_UPLOAD 为 true 时,如果在请求前面加上@的话phpcurl组件是会把后面的当作绝对路径请求,来读取文件。

结合这两点来找一下 flag。首先加上 %80 查看报错文件。报错内容很多,

我们需要的是 Django 的配置文件 settings.py 的路径信息。

payload:?url=@/opt/api/api/settings.py 获取数据库名

payload:?url=@/opt/api/database.sqlite3 获取数据库内容