2022Bilibili-1024ctf wp
T1
core.js
一个脚本
function SHA256(s) { |
可以看到随机选了一个nonce值,然后挖矿算出需要的值然后post
所以我们可以自己构造nonce,降低难度快速计算然后post
用户名admin,密码爆破,nonce设定为最小的9,random去请求然后匹配出来
顺便还能拿到cookie,因为尝试过发现后端会检查random和token匹配
payload:
import requests |
T2
upload.php
|
5d47c5d8a6299792.php
|
phar反序列化
|
生成phar文件,改后缀上传,但这里没有上传按钮
自己写一个html页面然后上传
<form action="http://42.192.54.239/upload.php" method="post" enctype="multipart/form-data"> |
得到上传路径后访问 upload.php?c=phar://upload/xxxx.jpg 就能得到/tmp/flag.php的base64内容
T3
题目提示behind,一眼冰蝎流量,而且没有明文交互,没有密钥获取,因此是冰蝎3不是冰蝎2
密钥不知道,估计是求密钥
那么肯定是xor,如果是aes根本解不出
观察流量包,很多请求开头是 JgkTFVwJHRcNQTAcEA...
,很多返回的开头是 HU4SE1IPNxZK...
推测有特定的格式或者开头
根据冰蝎明文的特点,比如冰蝎请求中的开头一般是 @error_reporting(0);
求key的脚本
from base64 import b64decode |
把这个key循环右移一位后直接用冰蝎客户端解码
T4
第一题响应头除了flag,还有一个提示说back2.png
访问back2.png,对比原本的back.png发现多了 {sepolia@0x053cd080A26CB03d5E6d2956CeBB31c56E7660CA}
// SPDX-License-Identifier: MIT |
这是一个token代币, _balances 里存的就是bili币的数量, _ebalances里存的是购买币(相当于eth,这里就称作e币)的数量
卖出bili币的价格为6,而如果 _ebalances 大于233,买入的价格就为1,这样利用差价不断买入卖出, _ebalances 会快速增加
关键就在于怎么拿到初始的 234个 e币
第一个方法是弄很多个账号,每个账号能借2个bili币,20个账号能借2x20=40个bili币,把这些代币都转给一个账号,然后就能卖出40x6=240个 e币
第二个方法是调用flashloan()闪电贷,借出300个e币。
需要满足以下条件
require(scoupon.coupon.loankey == 0, "loan key error"); |
auth1() 和 auth2() 很容易过,那么第三条require就过了
第二条require调用者需要为本地址,发现最后有个 testborrowtwice()
函数,调用了 MyToken(this).flashloan(scoupon);
但是testborrowtwice的 require(scoupon.coupon.loankey == 2233);
和 flashloan() 第一条require的require(scoupon.coupon.loankey == 0, "loan key error");
冲突,但实际上能过。
这是solidity 8.16 版本之前的 bug Head Overflow Bug in Calldata Tuple ABI-Reencoding | Solidity Blog (soliditylang.org)
0.5.8 引入,0.8.16被修复
通俗来说,就是如果一个结构体中间有一个变长的结构,比如string或者bytes,那么他在第二次打包的时候会出现bug,导致结构体的第一个字段被改成0
有了足够的e币之后,利用差价不断买入卖出,完成两次withdraw即可,或者完成一次withdraw +重入
给出第二种闪电贷的exp
pragma solidity 0.8.12; |
T5
第二题解出后的界面
/**
* bilibili@2022.
* Congratulations! This is The Flag!
* Auth: K3iove@github
* Repo: 1024-cheers
* @link https://security.bilibili.com/
* @license https://www.bilibili.com/
*/flag2{PhAr_The_bEsT_Lang}
给了一个github仓库
api test workspace : bilibili-1024-cheers
搜索api test workspace,找到postman里一个workspace
有个api http://101.132.189.74/index 返回
{ |
nmap扫描一下,发现80, 2222, 8081, 8082, 8088,github repo issue里提到的9200端口扫不出来
8088端口是Grafana服务,Grafana v8.2.6有个任意文件读取漏洞(CVE-2021-43798)
拿到源码
package server |
可以通过 /get?t=xxx 的方式请求资源。尝试 get?t=http://www.baidu.com
发现能跳转,一眼ssrf
有一些过滤,只能http, https开头,不能出现@ or ./
而且要通过 IsInternalIp() 检查,不能回环,不能是特定的私网ip,不能是错误的ipv4地址
但是0.0.0.0没有被过滤,代表当前主机
这里不太懂go的解析url.Parse和检查,好像编码绕过不太行(可能是我太菜了
http://101.132.189.74/get?t=http://0.0.0.0:9200 可行,返回了9200端口服务内容
这里也可以用 [DNS Rebinding](DNS Rebinding 域名重新绑定攻击技术 - FreeBuf网络安全行业门户)
使用的是一个网上的开发服务:rbndr.us dns rebinding service (cmpxchg8b.com)
填入A和B的地址:
- A: 127.0.0.1
- B: 101.132.189.74
DNS解析会在这两个结果IP之间随机返回
访问 http://101.132.189.74/get?t=http://7f000001.6584bd4a.rbndr.us:9200
{ |
再搜 Elasticsearch 的漏洞,有一个未授权访问
Elasticsearch 常见漏洞复现合集_安全小工坊的博客-CSDN博客_elasticsearch漏洞
尝试 http://101.132.189.74/get?t=http://0.0.0.0:9200/_search
{ |
得到用户名ctfer,密码1qaz@WSX
登录8082端口的服务,找到一个 ssh_info 文件,得到 ctfer/91431d5438eb28f7
用这个用户名密码 ssh登录2222端口,得到flag
flag5{Ez_G0laNg_SsRf}