2023_VNCTF
VNCTF2023(复现)
WEB
象棋王子
签到题,查看js源码,在play.js里面发现一段jsfuck,复制到控制台直接运行
电子木鱼
rust的web题目,主打一手语言难度
先放出源码:
use actix_files::Files; |
参考这个文章
if payload.name == "Donate" || payload.name == "Cost" { |
当post的时候,name参数为Donate和Cost的时候,cost会进行计算乘上参数quantity的值
if cost != 0 { |
然后就更新功德的数值,我们需要将功德打到1_000_000_000就能输出flag
cost又是32位的数值,可以表示-2_147_483_647~2_147_483_646,2_147_483_647溢出为-1,所以3_147_483_646为-1_000_000_000,因为还乘了10,所以传参差不多是314_748_364左右就能溢出,或者计算下一轮的溢出都可以,不唯一
name=Cost&quantity=314748364 |
BabyGo
Go语言,又是主打一手语言难度
先看源码
package main |
路由挺多的,都看一下
/:设置session,并且创建文件夹,在文件夹里面创建一个user.gob,然后存放User结构体
POST:/upload:进行文件上传,但是不能是.gob跟.go文件
/unzip:c.Query()表示get请求的参数,传入的path参数和userUploadDisr进行拼接后filepath.Clean()将拼接的路径进行简化替换成等效的最短路径,即将路径字串中的.、..进行整合,然后将userUploadDir下的文件解压到新路径中,这里能造成路径穿越
/backdoor:将路径下的.gob文件进行解析,对ctfer进行定义,如果Power是admin就能进行goeval.Eval()
得了解goval.Eval()各个参数的作用
直接去github仓库看:
func Eval(defineCode string, code string, imports ...string) (re []byte, err error) { |
接受三个参数defineCode string, code string, imports ...string,imports
会经过拼接形成go语言中的
import ( |
格式,code会拼接到func main(){..}中,然后fullCode = fmt.Sprintf(tmp, importStr, defineCode, code)会将三个片段经i选哪个拼接形成一个完整的go代码,接着会写入.go文件中执行.
解法一:
这样一来,就有办法了,go语言中,如果存在func init(){...}会先执行initial()后再执行main(),所以我们能控制pkg参数,进行传参,传入需要利用的模块后,闭合import(接着继续写入init()函数,最后闭合import的右括号)
结合要利用的模块,需要构造成如下的形式:
import ( |
所以pkg的参数应该为:os/exec"%0A"fmt")%0Afunc%09init()%7B%0Acmd:=exec.Command("/bin/sh","-c","ls${IFS}/")%0Ares,err:=cmd.CombinedOutput()%0Afmt.Println(err)%0Afmt.Println(string(res))%0A}%0Aconst(%0Aevil="123
首先需要生成.gob文件,其中的User.Power=admin,Path为题目给出的路径,然后压缩为压缩包上传
生成user.gob:
package main |
压缩后进行上传
然后去访问/unzip并且带上path=/../../../../tmp/4c89ef614806230cdcb4b1adff054ac1
最后访问/backdoor,带上pkg=os/exec"%0A"fmt")%0Afunc%09init()%7B%0Acmd:=exec.Command("/bin/sh","-c","ls${IFS}/")%0Ares,err:=cmd.CombinedOutput()%0Afmt.Println(err)%0Afmt.Println(string(res))%0A}%0Aconst(%0Aevil="123
最后cat${IFS}/ffflllaaaggg
BLOCKCHAIN
SignIN
先看合约的源码:
pragma solidity ^0.4.23; |
可知要使welcomeMessage与year两个变量拼起来等于Welcome to VNCTF2023,year已经是2022,要减去_newyear变成2023,而solidits版本是0.4.23,是存在整数溢出的,year是uint16类型(表示的范围为0~\(2^{16}-1\)(65535)),所以2022-65536=2022,即2022-65535=2023,所以_newyear=65535即可造成整数溢出
但是刚接触区块链,题目给出rpc链接,导不进去metamask不会用。。。。,没写出来。。。
看B1ue1nWh1te师傅的wp是使用py脚本进行交互直接调用漏洞合约的setMsg()函数,学习一下,用py交互打自己写好的exp:
pragma solidity ^0.4.23; |
先创建账户,需要打钱进账户,给了水管,直接用水管给账户领钱,就能拿到contract address,写的exp是重新创建一个合约,再创建漏洞合约的对象,调用漏洞合约的setMsg()函数,然后将exp合约部署到私链上调用hack()函数进行攻击
交互脚本为:
from Poseidon.Blockchain import * # https://github.com/B1ue1nWh1te/Poseidon |
打过去后直接到nc界面获取flag即可
GetoffmyMoney!
重入攻击,学习一下
先看源码:
pragma solidity ^0.8.7; |