java基础漏洞学习----基础命令执行漏洞
java基础漏洞学习----基础命令执行漏洞
基础命令执行常见方法
1.ProcessBuilder
package com.example.servletdemo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Command1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
String ip = request.getParameter("ip");
if(ip!=null && !ip.isEmpty()){
try{
String command = "ping "+ip;
ProcessBuilder pb = new ProcessBuilder("cmd","/c",command);
Process p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
StringBuilder result = new StringBuilder();
String line;
while((line = reader.readLine())!=null){
result.append(line).append("\n");
}
response.getWriter().print(result.toString());
} catch (IOException e){
e.printStackTrace();
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
} else {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
}
}
}
web.xml中添加路由
<servlet>
<servlet-name>Command1</servlet-name>
<servlet-class>com.example.servletdemo.Command1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Command1</servlet-name>
<url-pattern>/command1</url-pattern>
</servlet-mapping>
传参ip=127.0.0.1%26dir
但是好像命令里面不让有反斜杠
2.Runtime exec
1)Runtime exec执行字符串参数和数组参数
1.字符串参数
稍微修改一下代码
import java.lang.Runtime;
...
String command = "ping "+ip;
Process p = Runtime.getRuntime().exec(command);
此时再传入ip=baidu.com%26dir会报错,显然将传入的参数当一个整体让ping命令执行了
然后再改
String command = "cmd.exe /c ping "+ip;
ip=baidu.com%26dir 这样可以了
2.数组参数
再改
String[] command = {"cmd.exe","/c","ping"+ip};
ip=baidu.com%26dir 这样可以了 但是不让有空格
3.深入理解其原因
先选择exec,然后ctrl+右键进入类
发现
public Process exec(String cmdarray[]) throws IOException {
return exec(cmdarray, null, null);
}
然后再跟进exec
public Process exec(String[] cmdarray, String[] envp, File dir)
throws IOException {
return new ProcessBuilder(cmdarray)
.environment(envp)
.directory(dir)
.start();
}
然后在当前类里搜索exec 发现如果传入的是字符串类型的话会经过StringTokenizer处理
public Process exec(String command, String[] envp, File dir)
throws IOException {
if (command.isEmpty())
throw new IllegalArgumentException("Empty command");
StringTokenizer st = new StringTokenizer(command);
String[] cmdarray = new String[st.countTokens()];
for (int i = 0; st.hasMoreTokens(); i++)
cmdarray[i] = st.nextToken();
return exec(cmdarray, envp, dir);
}
根据此处的英文注释发现\t\n\r\f
会对传入的字符串进行分割,分割完成后会返回一个cmdarray数组,所以传入字符串参数和传入数组参数返回结果不同
例如linux命令
String command = "/bin/sh -c \"ping -t 3 baidu.com;id\"";
会被拆分为
{"/bin/sh","-c",""ping","-t","3","baidu.com;id","""}
相当于ping 'baidu.com;id'这个域名
3.Reflect Method
用途:jsp免杀木马
通过Class.forName获得恶意类
通过runtimeClass.getMethod获得恶意类中的方法
使得恶意类和恶意方法可以通过编码进行混淆绕过静态检测
package com.example.servletdemo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
public class Command3 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
String ip = request.getParameter("ip");
if(ip!=null && !ip.isEmpty()){
try{
// 获取Runtime类
Class<?> runtimeClass = Class.forName("java.lang.Runtime");
// 获取getRuntime方法
Method getRuntimeMethod = runtimeClass.getMethod("getRuntime");
// 调用getRuntime方法获取Runtime对象
Object runtimeObject = getRuntimeMethod.invoke(null);
// 获取exec方法
Method execMethod = runtimeClass.getMethod("exec", String.class);
// 执行命令
String command = "cmd.exe /c ping "+ip;
Process p = (Process) execMethod.invoke(runtimeObject, command);
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
StringBuilder result = new StringBuilder();
String line;
while((line = reader.readLine())!=null){
result.append(line).append("\n");
}
response.getWriter().print(result.toString());
} catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException | IOException e ){
e.printStackTrace();
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
} else {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
}
}
}
ip=baidu.com%26dir
代码审计
搜索ProcessBuilder,Process,exec,Runtime,getRuntime,追踪反射类等等