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; |