2023第四届“安恒杯”CTF新生赛题解
Misc
Exif
下载图片后右键查看属性,发现图片的注释就是flag

是谁在搞渗透?
下载图片后用010 Editor打开,发现最后有一段PHP代码,是一句话木马,POST参数就是flag内容

加密的压缩包1
通过阅读题面,怀疑是压缩包伪加密。使用010 Editor打开,发现"struct ZIPFILERECORD record"的"enum COMPTYPE frCompression"(全局加密标志)与"struct ZIPDIRENTRY dirEntry"的"ushort deFlags"(单个文件加密标志)不一致,将后者改为8,保存后解压,得到flag
详细请参考:https://blog.csdn.net/xiaozhaidada/article/details/124538768

我唱片怎么坏了
听音频,发现有一段声音有问题,用Audacity或Adobe Audition打开,使用频谱图直接看到flag

黑铁的鱼影
使用010 Editor打开,发现模板运行报CRC校验错误

结合图片观察(使用Windows自带的照片应用可以打开,其他软件可能会直接报错打不开),发现图片被截取了一部分,猜测是手动改变了高度导致看图软件无法完全显示,将高度改大,或使用CRC爆破脚本,恢复原来的高度,即可看到完整的图片。
PS: 如果做别的题目看到图片是撕裂的且CRC校验错误,也有可能是改变了宽度。
凡凡的照片
使用Wireshark打开下载的pcapng文件,发现有一段HTTP POST流量,导出后发现是一张图片,打开后发现是flag
导出文件的办法:
显示分组字节,自动渲染图片

使用binwalk或foremost提取pcapng中的文件
OSINT1
打开图片,仔细观察,发现车次和发车时间信息

搜索D3135时刻表,发现11:54发车的是海宁西站
QRCode.txt
下载附件得到一串疑似RGB信息的文本,行数为29*29,编写脚本将其转换为图片,得到缺失的二维码,补上三个定位点后扫码即可得到flag


OSINT2
首先阅读题面,搜索2023深圳1024程序员节CTF比赛,发现比赛地点在“深圳市龙华区北站中心公园”。
观察题目给的图片,发现对面有一座中国石化加油站。在比赛地点附近搜索,并比对图片与卫星图中的马路、天桥、周围建筑等特征,找到拍摄人所处的楼宇是“鸿荣源·天俊D栋”

聪明的小明
阅读密码提示,使用python脚本生成字典
使用john破解(office2john),得到密码:xiaoMing20210818()
打开PPT后发现需要寻找flag,按下Ctrl+F搜索“flag”或用Ctrl+A全选或打开选择窗格发现有一段隐藏的文本,即为flag

Web
被挡住了捏
按F12打开浏览器开发者工具或Ctrl+U查看源码即可拿到flag

Dino
抓包修改数值,可使用Hackbar或BurpSuite或浏览器开发者工具-网络,大于规定值即可得到flag


sqli1
使用万能密码('or 1=1#)即可登录


源码如下:
username=admin' or '1'='1'#拼接后的SQL语句如下:
也可以用username=admin&password=' or '1'='1,拼接后的SQL语句如下:
执行后都可以select到admin的信息,登录成功。
easyHTTP
考点: HTTP协议方法以及结构
第一步:修改GET参数中npc的值为alice

第二步:修改GET参数中npc的值为bob

第三步:POST传参,使用Hackbar或其他工具POST传递指定参数和内容

得到信息

第四步:转到jack并修改HTTP请求头部


魔法猫咪
PHP反序列化漏洞
这里是我们可以利用的类

这里告诉我们可传入进行反序列化的参数名是lawn

这里理一下pop链 unserialize-> sunflower.__wakeup() -> eggplant.__debugInfo() -> cat.toString() ->flag
编写代码获得序列化结果

构造paylod: ?lawn=O:9:"sunflower":1:{s:3:"sun";O:8:"eggplant":3:{s:3:"egg";b:1;s:5:"plant";O:3:"cat":0:{}s:6:"zombie";N;}}

这里附上php的魔法函数(记得保存)
魔术方法
魔术方法是会在某种条件下发生自行调用的方法
__construct()
当对象创建(new)时会自动调用。但在 unserialize() 时是不会自动调用的。(构造函数)
__destruct()
当对象被销毁时会自动调用。(析构函数)
__wakeup()
使用 unserialize 反序列化时自动调用
__sleep()
使用 serialize 序列化时自动调用
__set()
在给未定义的属性赋值时自动调用
__get()
调用未定义的属性时自动调用
__isset()
使用 isset() 或 empty() 函数时自动调用
__unset()
使用 unset() 时自动调用
__call()
调用一个不存在的方法时自动调用
__callStatic()
调用一个不存在的静态方法时自动调用
__toString()
把对象转换成字符串时自动调用
__invoke()
当尝试把对象当方法调用时自动调用
__set_state()
当使用 var_export() 函数时自动调用,接受一个数组参数
__clone()
当使用 clone 复制一个对象时自动调用
__debugInfo()
使用 var_dump() 打印对象信息时自动调用
坤言坤语
考点:目录爆破
题目给了很明确的提示

爆破之后发现了 有备份压缩包

下载下来

阅读源码发现是一个简单的加密函数

简单编写解码函数 获得四个密文的明文


构造payload传参,进行蚁剑连接(或者手搓命令执行)
?sing=jI&dance=Ni&rap=TaI&basketball=Mei

找到flag

babybabyweb
考点:javaweb web.xml泄露
啥都不输都能登录 说明这个登录框肯定没用

点开登录框下的链接
发现是java后端和一个file攻击点
尝试读取javaweb的配置文件web.xml

读取成功
看到了源码地址 尝试继续下载

读取成功

class文件用ide反编译一下即可

新人爆照
考点:文件上传漏洞,.user.ini利用
先随便传个东西 发现疑似有过滤

F12检查后发现是 前端验证


控制台直接写个同名函数给他覆盖掉
成功绕过,抓个包研究一下

发现还有后端检测

再尝试php,php3,php4,php5,phtml,pht等等一系列后缀后发现全部被过滤了
通过返回包的请求标头或使用浏览器插件Wappalyzer可以发现后端服务器是Nginx
尝试上传.user.ini文件恶意修改配置文件
修改一下文件类型和文件头绕过后端验证(仅需文件开头是图片头就可以,这里用GIF是为了方便输入)

参考连接:浅析.user.ini的利用
发现上传成功

再传一句话木马,同样加上图片头

成功

此时访问该文件夹的任意PHP文件,发现我们上传的图片马已经被附加到页面中了

直接蚁剑链接拿到flag

sqli2
考点:SQL注入布尔盲注,前端加密
首先和sqli1一样尝试万能密码登录,发现可以登录,说明存在SQL注入漏洞,闭合符号为',进入后台没发现flag,则尝试读取数据库内容
首先猜测后端PHP代码如下:
将username设为admin,如果判断条件为真(如password=' and '1'='1),则登录成功,否则登录失败,由此判断可以使用布尔盲注。
但是抓包时发现,传递的内容经过加密的
查阅前端代码,发现如下js代码:
可以看到,前端使用了AES加密,密钥为4tu39rvb6h3wbif4,加密模式为CBC,填充模式为Pkcs7,加密后的内容为base64编码
尝试使用工具解密验证加密方式和密钥,解密成功,同时可以直观地看到明文的结构

加密的形式和密钥我们都已经知道了,那么这个加密过程就可以用脚本实现了
解题思路:使用python脚本,将需要执行的语句加密后传递给后端,后端解密后执行,根据返回的结果判断是否成功,从而实现布尔盲注。这里我们仅演示手工注入,也可以使用flask框架开启一个HTTP端口接收sqlmap的请求,这样就能用sqlmap快速获取数据库的内容了。
如果遇到无法加解密的情况,如加密函数特别复杂,也可以使用爬虫的方式模拟输入和点击。这里不再演示。
黑心商店
考点:任意文件读取,逻辑漏洞
查看url并尝试改变参数发现,图片数据是以base64的形式传输到前端的 尝试利用这个先读取一下index.php的内容

发现可以读取


研究一下源码看看还可以读什么(或者尝试爆破) 发现两个 读取一下

分析后发现loginServer.php没用 但是register.php 里有passcode的格式

按照正则表达式直接构造一个 passcode=as1as1as1aa11aa11a|/|/1111 正则表达式解析网站: https://c.runoob.com/front-end/7625/#!flags=&re=%5E(%5Ba-z%5D%2B%5B0-5%5D)%7B3%7D(%5Cw%7B2%7D%5Cd%7B2%7D)%7B2%7D%5Ba-zA-Z%5D%2B(%5C%7C%5C%2F)%7B2%7D%5Cd%7B4%7D%24 (但还是建议大家学会人工分析)

注册成功

然后进行登录 发现打工时总是会出现把我们金币重制(所以脚本暴力发包法失效)

先把服务端源码读下来

这一块发现了逻辑漏洞没有检测传入数量的合法性直接计算,那么如果我们的数量参数为负数,那这个价格就变成负数了,下面对数据库修改我们金币的时候就会减去一个负数,使我们的金币变多

传负数的时候发现还是有前端验证,可以先输入一个正数再抓包进行修改


获得金币后直接购买flag,得到答案


Crypto
胡言乱语
简单替换密码,通过比对翻译后的文本和题目给的密文,可以得到字母的对应关系,即可解密。
这题也可以用quipqiup快速解密,输入密文即可破解得到明文。
摩西摩西
考点:摩斯密码
观察文本内容,发现共有3种字词,分别是摩西、喂、?,并且?疑似作为分隔符,结合题目名,猜测是摩斯密码,将摩西和喂分别替换为-和.,?替换为空格,摩斯解码后即可得到明文。
下面是使用CyberChef的示例

Vigenere
维吉尼亚密码,发现没有给密钥,搜索维吉尼亚爆破,即可找到Vigenère Solver
破解后即为flag
rot13
简单的rot13解码,使用工具解码后得到flag内容
easyCaeser
考点:变异凯撒
根据题面,将"cj`dy"与"flag{"对照,发现偏移量为3213...,猜测偏移的规律为321循环,编写脚本解密
easyRSA
这个解密脚本是基于RSA加密算法的。RSA算法是一种非对称加密算法,即加密和解密使用的是两个不同的密钥。在这个脚本中,公钥是(n, e),私钥是(n, d)。
RSA基础推荐视频: 数学不好也能听懂的算法 - RSA加密和解密原理和过程
以下是解密脚本的步骤:
首先,脚本导入了long_to_bytes函数,这个函数可以将长整数转换为字节。
然后,脚本定义了p、q和c的值。这些值在加密脚本中生成并打印出来,现在我们需要它们来解密。
脚本计算n的值,n是p和q的乘积。这是RSA公钥的一部分。
脚本计算φ(n)的值,φ(n)是欧拉函数,计算小于n且与n互质的正整数个数。在这里,φ(n) = (p-1)*(q-1)。
脚本定义了e的值,这是RSA公钥的另一部分。
脚本计算d的值,d是e模φ(n)的乘法逆元。这是RSA私钥的一部分。
最后,脚本使用私钥(n, d)对密文c进行解密,得到明文m。解密的过程是计算c的d次方模n的余数,即c^d mod n。
脚本打印出解密后的明文m,但是m是一个长整数,所以我们需要使用long_to_bytes函数将其转换为字节,这样才能看到原始的明文信息。
easyXOR
这个解密脚本是基于XOR加密的。XOR加密是一种简单的对称加密算法,即加密和解密使用的是同一个密钥。在这个脚本中,密钥是前一个字符的ASCII值。
以下是解密脚本的步骤:
首先,脚本导入了加密后的十六进制列表。
然后,脚本将十六进制列表转换为整数列表。
脚本定义了初始的明文字符串,这是已知的第一个字符。
脚本使用一个循环,从第二个字符开始,将每个字符的ASCII值与前一个字符的ASCII值进行XOR运算,得到原始的字符。然后将这个字符添加到明文字符串中。
最后,脚本打印出解密后的明文字符串。
这个解密脚本的关键是理解XOR运算的性质:一个数与另一个数进行XOR运算两次,结果还是原来的数。也就是说,如果我们有a XOR b = c,那么c XOR b = a。在这个脚本中,a是原始的字符,b是前一个字符,c是加密后的字符。所以我们可以通过c XOR b得到a。
谍影重重
下载文本后,发现是一篇新闻,仔细阅读后发现有部分单词拼写错误,在网上搜索原文,与该文本比较不同之处(在线工具或自行编写脚本),将所有不相同的字符按顺序排列后得到meetyouatb113,即为flag
欧拉欧拉
分析题目给出的加密程序
只给出了e、n、c即公钥指数、模数以及密文
观察题目特征,发现没有生成素数q的代码,仅有一素数p
猜测n仅由p构成,即n = p**k,k可为任意整数
进入以下网站尝试进行n分解:http://www.factordb.com/index.php
分解n得到 n = p**5
计算私钥d需要先得出欧拉函数phi
遂查找有关欧拉函数的性质,可找到 根据欧拉函数性质则有 phi=(pk)-(pk-1)
尝试根据此式进行解密
p = 123011670148156067171935017378169146187754569417088208031467924757125444876573376178582752555425433929702259279078270486096811298079151854743684067475773465936777306722083390498141106158684676959748784222921618751967668182812790014845198142516241615533512211354021631481436898405968025433478683545771726278893
可得到b'flag{d66a8e00-8ada-46eb-bded-6840b583c98f}'
Reverse
test you ida
测试你的ida,用ida打开后即可发现flag
也可以用strings等工具查找字符串
easyBase64
方法一(优雅做法)
首先检查一下程序是什么架构的,是32位还是64位的

然后通过64位的ida打开程序,看到如下的汇编代码

通过f5键,将汇编代码转换成伪代码,如下图所示

上面的代码不方便阅读,我们进行注释和格式,如下
通过我练习时长两月半的C++编程功底,我发现这个程序的逻辑是这样的
输入一个字符串
进行base64编码
然后和
target进行比较,如果相等就输出Congratulations! You got the flag!,否则输出Sorry, you are wrong!程序结束
那么我们就需要找到target的值,然后进行base64解码,然后就可以得到flag了
于是,我们双击target,跳转到对应的位置来查看一下

发现什么东西都没有,感觉被骗了,但是仔细回想,我们这个程序用到了很多类似std::string的东西,这些东西都是C++的标准库,那么target应该就是std::string变量
在C++全局变量一般是在__static_initialization_and_destruction,这个神奇的函数中进行初始化的

然后发现了target,内容是
base64_chars的内容是
对base64的编码函数进行分析,可以发现, base64_chars就是码表
所以综上,我们可以知道target的值是通过一个变码表的base64编码的, 所以最后的结果就是
然后结果是

方法二(不优雅)
用ida打开,发现疑似是一个将输入的字符串Base64编码后于另一个字符串(编码后的flag)进行比较的程序
观察函数没有得到有效的信息,按Shift+F12查看字符串,发现有一个疑似自定义Base64字符集和编码后的flag的字符串
尝试使用自定义字符集解码字符串,得到flag

easyRe
这道题目缺少了信息,即加密后的flag(工作疏忽,望谅解)
反汇编后的加密函数如下
这段代码是一个名为encrypt的函数,它接受两个参数:一个字符串a1和一个整数a2。这个函数的主要目的是对输入的字符串进行加密。
首先,函数定义了一些变量和数组
v3,数组v3被初始化为[3, 7, 1, 4, 5]。然后,函数计算输入字符串
a1的长度,并将其存储在变量v5中。接下来,函数进入第一个for循环,该循环遍历输入字符串的每个字符。在每次迭代中,它都会取
v3数组中的一个元素(索引为当前字符的索引对数组长度取余)与当前字符进行异或操作,然后将结果存储在a2 + i的位置。在第一个for循环之后,函数进入第二个for循环。在这个循环中,函数每次迭代两个字符,然后交换这两个字符的位置。
最后,函数在字符串的末尾添加一个空字符,以确保结果字符串是以null结尾的,然后返回这个结果字符串的指针。
这个函数的加密过程包括两个步骤:首先,使用一个固定的数组对字符串进行异或操作;然后,交换字符串中的字符位置。这两个步骤共同构成了这个函数的加密算法。
那么我们编写解密脚本的步骤就是:首先,将字符串中的字符位置交换回来;最后,使用一个固定的数组对字符串进行异或操作。
py一下
根据题目提示,搜索打包工具并结合图标形状,确定打包工具为pyinstaller,使用pyinstxtractor提取后得到pyc文件

针对nihaoya.pyc进行反编译,可以使用pycdc,也可以使用在线工具
源码如下
简单的字母替换和移位加密
对于小写字母,将字符替换为字母表中后五位的字母。对于大写字母,将字符替换为字母表中后十三位的字母。对于数字,将数字替换为其加上五后对10取余的结果。再将字符串循环右移四位。
simpleMaze
运行程序,发现是一个迷宫游戏,1,2,3,4分别表示上下左右,flag为正确的移动路径
使用ida打开,关键代码是下面这一行,用于判断行走路径是否正确
查看(int)maze的值,发现是一串由0和1组成的字符串
再查看isValidMove函数,发现其功能是判断移动的目标是否为0
由此可以推测(int)maze字符串中的0表示可以通过的路径,1表示不可通过的路径
通过do while函数可知迷宫的大小为10*11
则将(int)maze字符串按照10*11的大小分割,得到地图形状如下
据此可得到flag为flag{md5(242444414442233233322222444411114422422)}即flag{909449cac803ef4e95abbb0aefeaddd8}
Last updated