Daffodil

Web-2022强网杯babyweb-writeup

2022-08-01 · 4 min read
强网杯 web writeup


打开网站首页 只有登录注册功能 注册一个账户 发现admin账户存在 爆破弱口令无果


随便注册一个账号 进去看功能 发现是个websocket bot


测试下bugreport 功能存在ssrf

于是自己创建一个页面

执行

admin密码 成功修改 进入admin后台

购买一个hint 根据提示下载源码

app.py

@app.route("/buy", methods=['POST'])
def buy():
    if not session:
        return redirect('/login')
    elif session['user'] != 'admin':
        return "you are not admin"
    else :
        result = {}
        data = request.get_json()
        product = data["product"]
        for i in product:
            if not isinstance(i["id"],int) or not isinstance(i["num"],int):
                return "not int"
            if i["id"] not in (1,2):
                return "id error"
            if i["num"] not in (0,1,2,3,4,5):
                return "num error"
            result[i["id"]] = i["num"]
        sql = "select money,flag,hint from qwb where username='admin'"
        conn = sqlite3.connect('/root/py/test.db')
        c = conn.cursor()
        cursor = c.execute(sql)
        for row in cursor:
            if len(row):
                money = row[0]
                flag = row[1]
                hint = row[2]
        data = b'{"secret":"xxxx","money":' + str(money).encode() + b',' + request.get_data()[1:] #secret已打码
        r = requests.post("http://127.0.0.1:10002/pay",data).text
        r = json.loads(r)
        if r["error"] != 0:
            return r["error"]
        money = int(r["money"])
        hint = hint + result[1]
        flag = flag + result[2]
        sql = "update qwb set money={},hint={},flag={} where username='admin'".format(money,hint,flag)
        conn = sqlite3.connect('/root/py/test.db')
        c = conn.cursor()
        try:
            c.execute(sql)
            conn.commit()
        except Exception as e:
            conn.rollback()
            c.close()
            conn.close()
            return "database error"
        return "success"

pay.go

package main

import (
	"github.com/buger/jsonparser"
    "fmt"
	"net/http"
    "io/ioutil"
    "io"
)

func pay(w http.ResponseWriter, r *http.Request) {
    var cost int64 = 0
	var err1 int64 = 0
    json, _ := ioutil.ReadAll(r.Body)
	secret, err := jsonparser.GetString(json, "secret")
	if err != nil {
        fmt.Println(err)
    }
	if secret != "xxxx"{   //secret已打码
		io.WriteString(w, "{\"error\": \"secret error\"}")
		return
	}
	money, err := jsonparser.GetInt(json, "money")
	if err != nil {
        fmt.Println(err)
    }
	_, err = jsonparser.ArrayEach(
			json,
            func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
                id, _ := jsonparser.GetInt(value, "id")
                num, _ := jsonparser.GetInt(value, "num")
				if id == 1{
					cost = cost + 200 * num
				}else if id == 2{
					cost = cost + 1000 * num
				}else{
					err1 = 1
				}
            },
        "product")
	if err != nil {
		fmt.Println(err)
	}
	if err1 == 1{
		io.WriteString(w, "{\"error\": \"id error\"}")
		return
	}
	if cost > money{
		io.WriteString(w, "{\"error\": \"Sorry, your credit is running low!\"}")
		return
	}
	money = money - cost
    io.WriteString(w, fmt.Sprintf("{\"error\":0,\"money\": %d}", money))
}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/pay", pay)
    http.ListenAndServe(":10002", mux)
}

python解析含有重复key的json时 后来的值会覆盖原来的值
如下为例

{"key":"1", "key":"2", "key":"3", "key2":"4"}
经过解析,结果却如下所示:
{
"key":"3",
"key2":"4"
}
github.com/buger/jsonparser 解析时只会读取第一个值

所以

搞定

2022 第六届 强网杯