Java Web安全-代码审计(二)

Java Web安全-代码审计(一)

四、Java Web基础

1. Java分层思想

为了更好的管理项目我们通常会采用分层架构的方式来开发Java Web项目,分层设计的好处在于可以非常方便的分清楚包之间的业务逻辑关系。

常见的JavaWeb项目分层:

视图层(View 视图)
控制层(Controller、Action 控制层)
服务层(Service)
业务逻辑层BO(business object)  
实体层(entity 实体对象、VO(value object) 值对象 、模型层(bean)。
持久层(dao- Data Access Object 数据访问层、PO(persistant object) 持久对象)

基于Java分层架构的示例项目:

Java Web安全-代码审计(二)

2. Java模块化开发

如今的较为大型的Java Web项目通常都采用了模块化方式开发,借助于Maven、Gradle依赖管理工具,Java可以非常轻松的完成模块化开发。除此之外使用OSGi(Open Service Gateway initiative 可实现模块热部署)技术开发来Java动态模块化系统也是较为常见的。

采用模块化开发也会给我们做代码审计带来一定的难度,因为需要在更多的依赖库中去寻找需要我们审计的代码。

使用Maven开发的JavaWeb项目示例:

Java Web安全-代码审计(二)

Java Web安全-代码审计(二)

3. 什么是Servlet?

Servlet是在Java Web容器上运行的小程序,通常我们用Servlet来处理一些较为复杂的服务器端的业务逻辑。值得注意的是在Servlet3.0之后(Tomcat7+)可以使用注解方式配置Servlet了。

基于注解的Servlet

Java Web安全-代码审计(二)

Servlet3.0之前的版本都需要在web.xml中配置,Servlet是两对标签,由和组成,Spring MVC框架就是基于Servlet技术实现的。

基于配置实现的Servlet

Java Web安全-代码审计(二)

HttpServlet类

Java Web安全-代码审计(二)

实现一个Servlet很简单,只需要继承javax.servlet.http.HttpServlet类并重写doXXX方法或者service方法就可以了,其中需要注意的是重写HttpServlet类的service方法可以获取到上述七种Http请求方法的请求。

4. JSP、Servlet之间的关系

JSP、JSPX文件是可以直接被Java容器直接解析的动态脚本,jsp和其他脚本语言无异,不但可以用于页面数据展示,也可以用来处理后端业务逻辑。

从本质上说JSP就是一个Servlet,因为jsp文件最终会被编译成class文件,而这个class文件实际上就是一个特殊的Servlet。

JSP文件会被编译成一个java类文件,如index.jsp在Tomcat中Jasper编译后会生成index_jsp.java和index_jsp.class两个文件。而index_jsp.java 继承于HttpJspBase类,HttpJspBase是一个实现了HttpJspPage接口并继承了HttpServlet的标准的Servlet,__jspService方法其实是HttpJspPage接口方法,类似于Servlet中的service方法,这里的__jspService方法其实就是HttpJspBase的service方法调用。

Java Web安全-代码审计(二)

5. 什么是Filter

Filter是JavaWeb中的过滤器,用于过滤URL请求。通过Filter我们可以实现URL请求资源权限验证、用户登陆检测等功能。Filter是一个接口,实现一个Filter只需要重写init、doFilter、destroy方法即可,其中过滤逻辑都在doFilter方法中实现。

Filter和Servlet一样是Java Web中最为核心的部分,使用Servlet和Filter可以实现后端接口开发和权限控制,当然使用Filter机制也可以实现MVC框架,Struts2实现机制就是使用的Filter。

Filter的配置类似于Servlet,由和两组标签组成,如果Servlet版本大于3.0同样可以使用注解的方式配置Filter。

Java Web安全-代码审计(二)

6. Filter和Servlet的总结

对于基于Filter和Servlet实现的简单架构项目,代码审计的重心集中于找出所有的Filter分析其过滤规则,找出是否有做全局的安全过滤、敏感的URL地址是否有做权限校验并尝试绕过Filter过滤。第二点则是找出所有的Servlet,分析Servlet的业务是否存在安全问题,如果存在安全问题是否可以利用?是否有权限访问?利用时是否被Filter过滤等问题,切勿看到Servlet、JSP中的漏洞点就妄下定论,不要忘了Servlet前面很有可能存在一个全局安全过滤的Filter。

Filter和Servlet都是Java Web提供的API,简单的总结了下有如下共同点。

Filter和Servlet都需要在web.xml或注解(@WebFilter、@WebServlet)中配置,而且配置方式是非常的相似的。
Filter和Servlet都可以处理来自Http请求的请求,两者都有request、response对象。
Filter和Servlet基础概念不一样,Servlet定义是容器端小程序,用于直接处理后端业务逻辑,而Filter的思想则是实现对Java Web请求资源的拦截过滤。
Filter和Servlet虽然概念上不太一样,但都可以处理Http请求,都可以用来实现MVC控制器(Struts2和Spring框架分别基于Filter和Servlet技术实现的)。
一般来说Filter通常配置在MVC、Servlet和JSP请求前面,常用于后端权限控制、统一的Http请求参数过滤(统一的XSS、sql注入、Struts2命令执行等攻击检测处理)处理,其核心主要体现在请求过滤上,而Servlet更多的是用来处理后端业务请求上。

7. 初识JavaWeb MVC框架

传统的开发存在结构混乱易用性差耦合度高可维护性差等多种问题,为了解决这些毛病分层思想和MVC框架就出现了。MVC即模型(Model)、视图(View)、控制器(Controller), MVC模式的目的就是实现Web系统的职能分工。

截至2018年底,绝大多数的新项目都已然改为了基于Spring Boot的Spring MVC实现,也就是说曾经站在JavaWeb MVC最巅峰的Struts2框架已经逐渐陨落。

7.1 Spring MVC 控制器

在Spring进入了3.0时代,使用Java注解的方式也逐渐的流行了起来,曾经写一个Spring的控制器我们通常要在xml中声明Spring bean并配置处理的URL,而在新时代的Spring项目中我们通常用Spring MVC注解就可以轻松完成Spring MVC的配置了。

一个基于Spring 注解配置的控制器:

package org.javaweb.codereview.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class IndexController {

@RequestMapping("/index.php")
public String index() {
return "/index.html";
}
}

Spring Controller注解:

  1. @Controller
  2. @RestController
  3. @RepositoryRestController
    Spring MVC请求配置注解:

  4. @RequestMapping

  5. @GetMapping
  6. @PostMapping
  7. @PutMapping
  8. @DeleteMapping
  9. @PatchMapping
    Spring MVC除了上述6种Http请求处理注解以外还有Spring Data JPA Rest提供的特殊的@RepositoryRestResource注解,@RepositoryRestResource是基于Spring Data JPA REST库实现的,Spring Data JPA REST提供的API可支持通过JPA查询数据并处理Http请求服务。

基于xml配置的Spring MVC

对于一些老旧的项目可能还保留了一些基于xml配置的方式Spring MVC项目,这里只简单的介绍下如何配置不做过多的描述。基于配置方式的控制器一般是在Controller类中实现了Spring的org.springframework.web.servlet.mvc.Controller接口的handleRequest方法(当然还有其他途径,如:AbstractCommandController和SimpleFormController但都已经过时了)。

TestController.java示例代码:

package org.javaweb.codereview.controller;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author yz
 */
public class TestController implements Controller {

@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView();
mv.setViewName("index");

return mv;
}

}

xml配置具体的bean

<bean name="/test.do" class="org.javaweb.codereview.controller.TestController"/>

7.2 Struts2控制器

Struts2主要的开发模式是基于xml配置,在struts.xml中配置Action地址和对应的处理类。
Java Web安全-代码审计(二)

不过Struts2(2.1.6版本开始)也可以使用struts2-convention-plugin插件来实现基于注解方式的配置。

Java Web安全-代码审计(二)

需要注意的是Struts2的参数是可以通过get/set方法传入的,如上图TestActionAnnotation类的username变量是可以直接在Http请求中的URL传入的。

7.3 快速找出Http请求请求URL

代码审计中我们可以选择优先从Controller、Servlet和JSP中入手,也可以选择从漏洞点反向推出Http请求的入口地址,这里将讲解下如何快速找到这些请求入口,因为Struts2和Spring MVC的原理比较接近,所以本节只以Spring MVC为例。

7.3.1 查找Spring MVC所有的控制器

如果有源码的情况下可以使用find命令或者IDEA的全局搜索功能即可快速搜索到所有的控制器,如果只有class文件的情况下可以使用find命令:

find ~/cms/ -type f -name "*.class" |xargs grep -E "Controller|@RestController|RepositoryRestController"
7.3.2 查找所有的请求处理URL

查找请求处理URL的方式同理,使用如下find命令查找所有class中的请求处理注解:

find ~/cms/ -type f -name "*.class" |xargs grep -E "RequestMapping|GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping|RepositoryRestResource"

```7.4 Spring MVC和Struts2控制器小结
这一小节我们只是简单的介绍下Spring MVC和Struts2的控制器,在后面的框架服务章节将会详细介绍。至于如何去快速定位Struts2的action请自行参考Spring MVC的Controller查找方式这里不再讲解。

### 五、Java语言的动态性
Java语言动态性一直以来都比较差,并不像PHP那样灵活。在Java中的动态性往往需要使用一些曲折的方式来实现.这里简单列举了Java十余种动态性相关技术并总结部分技术实现安全问题。

1. Java反射机制
2. MethodHandle
3. JDK动态代理
4. 使用JVM上的动态语言(如:Groovy、JRuby、Jython)
5. 表达式库(如:OGNL、MVEL、SpEL、EL)
6. JSP、JSPX、Quercus(Resin容器提供了PHP5支持)
7. 字节码库(如:Asm、Javassist、Cglib、BCEL)
8. ScriptEngineManager(脚本引擎)。
9. 动态编译(如:JDT、JavaCompiler)
10. classLoader、URLclassLoader
11. 模版引擎(如:Freemarker、Velocity)
12. 序列化、反序列化(包含Java 对象序列化、xml、JSON等)
13. JNI、JNA(Java调用C/C++)
14. OSGi(Open Service Gateway initiative)
15. RMI(Java远程方法调用,基于对象序列化机制实现)
16. WebService
17. JDWP(Java Platform Debugger Architecture Java调试协议)
18. JMX(Java Management Extensions)

#### 1. Java反射机制特性
Java反射机制可以无视类方法、变量访问权限修饰符,可以调用任何类的任意方法、访问并修改成员变量值。也就是说只要发现一处Java反射调用漏洞几乎就可以为所欲为了。当然前提可能需要你能控制反射的类名、方法名和参数。

一行代码即可实现反射调用Runtime执行本地命令:

```java
Runtime.class.getMethod("exec", String.class).invoke(Runtime.class.getMethod("getRuntime").invoke(null), "whoami")

获取一个类的对象(如Runtime类)我们一般会采用如下几种方式:

  1. class.forName(“java.lang.Runtime”)、””.getclass().forName(“java.lang.Runtime”)
  2. Runtime.class
  3. classLoader.getSystemclassLoader().loadclass(“java.lang.Runtime”)
    Java反射获取类方法有两种方式:

getMethod(xxx),getMethods()
getDeclaredMethod(xxx)、getDeclaredMethods()。
区别在于getMethod会返回当前类和父类的所有public方法,而getDeclaredMethod返回的是当前的所有方法。

Java反射获取类成员变量有两种方式:

getField(xxx)、getFields()
getDeclaredField(xxx)、getDeclaredFields()
getField和getDeclaredField区别同上,如果想要调用private修饰的Field或者Method只需要设置下setAccessible为true就可以了,如:xxxMethod.setAccessible(true)。

Java的大部分框架都是采用了反射机制来实现的(如:Spring MVC、ORM框架等),所以我们不得不掌握Java反射机制来提升我们的代码审计能力。

Java反射机制实现无关键字执行命令

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Scanner;

/**
 * @author yz
 */
public class ReflectionTest {

public static void exec() {
try {
System.out.println(Runtime.class.getMethod("exec", String.class).invoke(Runtime.class.getMethod("getRuntime").invoke(null), "curl -i localhost:8000"));
} catch (Exception e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
try {
String str = "whoami";

// java.lang.Runtime
String runtime = new String(new byte[]{106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 82, 117, 110, 116, 105, 109, 101});

// Runtime.class
class c = class.forName(runtime);

// 获取getRuntime方法,Runtime.getRuntime()
Method m1 = c.getMethod(new String(new byte[]{103, 101, 116, 82, 117, 110, 116, 105, 109, 101}));

// 获取Runtime的exec方法,rt.exec(xxx)
Method m2 = c.getMethod(new String(new byte[]{101, 120, 101, 99}), String.class);

// Runtime.getRuntime().exec(str)
Object obj2 = m2.invoke(m1.invoke(null), 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);

// process.getInputStream()
InputStream in = (InputStream) m.invoke(obj2, new Object[]{});

// 输出InputStream内容到
Scanner scanner = new Scanner(in).useDelimiter("\\A");
System.out.println(scanner.hasNext() ? scanner.next() : "");
} catch (Throwable t) {
t.printStackTrace();
}
}

}

2. JDK7+ MethodHandle

JDK7开始Java提供了MethodHandle可以非常方便的访问和调用类方法,MethodHandle的能力和Java反射机制相似,但效率却远高出Java反射机制,但MethodHandle也并不是那么完美的,缺点是MethodHandle必须要求JDK版本大于等于1.7,MethodHandle也无法像反射那样调用私有方法和变量。

参考:通过代码简单介绍JDK 7的MethodHandle,并与.NET的委托对比。

基于MethodHandle实现的调用Runtime执行系统命令

import java.io.InputStream;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.Scanner;

/**
 * @author yz
 */
public class MethodHandlesTest {

public static void main(String[] args) {
try {
String               str          = "ping p2j.cn -c 1";
class                runtimeclass = Runtime.class;
MethodHandles.Lookup lookup       = MethodHandles.lookup();

// Runtime rt = Runtime.getRuntime()
MethodHandle methodHandle = lookup.findStatic(
runtimeclass, "getRuntime", MethodType.methodType(runtimeclass)
);

// 获取Runtime的exec方法
MethodHandle execMethod = lookup.findVirtual(
runtimeclass, "exec", MethodType.methodType(Process.class, new class[]{
String.class
})
);

// 获取Process的getInputStream方法
MethodHandle inputStreamMethod = lookup.findVirtual(
Process.class, "getInputStream", MethodType.methodType(InputStream.class)
);

// 调用Runtime.getRuntime().exec(xxx).getInputStream()
InputStream in = (InputStream) inputStreamMethod.invoke(
execMethod.invoke(methodHandle.invoke(), str)
);

// 输出InputStream内容到
Scanner scanner = new Scanner(in).useDelimiter("\\A");
System.out.println(scanner.hasNext() ? scanner.next() : "");
} catch (Throwable t) {
t.printStackTrace();
}
}

}

六、Java代码审计-Checklist

通常我喜欢把代码审计的方向分为业务层安全问题、代码实现和服务架构安全问题,。

1. 业务层安全常见问题

业务层的安全问题集中在业务逻辑和越权问题上,我们在代码审计的过程中尽可能的去理解系统的业务流程以便于发现隐藏在业务中的安全问题。

1.1 业务层中常见的安全问题Checklist

用户登陆、用户注册、找回密码等功能中密码信息未采用加密算法。
用户登陆、用户注册、找回密码等功能中未采用验证码或验证码未做安全刷新(未刷新Session中验证码的值)导致的撞库、密码爆破漏洞。
找回密码逻辑问题(如:可直接跳过验证逻辑直接发包修改)。
手机、邮箱验证、找回密码等涉及到动态验证码等功能未限制验证码失败次数、验证码有效期、验证码长度过短导致的验证码爆破问题。
充值、付款等功能调用了第三方支付系统未正确校验接口(如:1分钱买IPhone X)。
后端采用了ORM框架更新操作时因处理不当导致可以更新用户表任意字段(如:用户注册、用户个人资料修改时可以直接创建管理员账号或其他越权修改操作)。
后端采用了ORM框架查询数据时因处理不当导致可以接收任何参数导致的越权查询、敏感信息查询等安全问题。
用户中心转账、修改个人资料、密码、退出登陆等功能未采用验证码或Token机制导致存在CSRF漏洞。
后端服务过于信任前端,重要的参数和业务逻辑只做了前端验证(如:文件上传功能的文件类型只在JS中验证、后端不从Session中获取用户ID、用户名而是直接接收客户端请求的参数导致的越权问题)。
用户身份信息认证逻辑问题(如:后台系统自动登陆时直接读取Cookie中的用户名、用户权限不做验证)。
重要接口采用ID自增、ID可预测并且云端未验证参数有效性导致的越权访问、信息泄漏问题(如:任意用户订单越权访问)。
条件竞争问题,某些关键业务(如:用户转账)不支持并发、分布式部署时不支持锁的操作等。
重要接口未限制请求频率,导致短信、邮件、电话、私信等信息轰炸。
敏感信息未保护,如Cookie中直接存储用户密码等重要信息。
弱加密算法、弱密钥,如勿把Base64当成数据加密方式、重要算法密钥采用弱口令如123456。
后端无异常处理机制、未自定义50X错误页面,服务器异常导致敏感信息泄漏(如:数据库信息、网站绝对路径等)。
使用DWR框架开发时前后端不分漏洞(如:DWR直接调用数据库信息把用户登陆逻辑直接放到了前端来做)。

2. 代码实现常见问题

代码审计的核心是寻找代码中程序实现的安全问题,通常我们会把代码审计的重心放在sql注入、文件上传、命令执行、任意文件读写等直接威胁到服务器安全的漏洞上,因为这一类的漏洞杀伤力极大也是最为致命的。

2.1 代码实现中常见的安全问题Checklist

任意文件读写(文件上传、文件下载)、文件遍历、文件删除、文件重命名等漏洞
sql注入漏洞
XXE(xml实体注入攻击)
表达式执行(SpEL、OGNL、MVEL2、EL等)
系统命令执行漏洞(ProcessBuilder)
反序列化攻击(ObjectInputStream、JSON、xml等)
Java反射攻击
SSRF攻击

2.1.1 Java 文件名空字节截断漏洞(%00 Null Bytes)

空字节截断漏洞漏洞在诸多编程语言中都存在,究其根本是Java在调用文件系统(C实现)读写文件时导致的漏洞,并不是Java本身的安全问题。不过好在高版本的JDK在处理文件时已经把空字节文件名进行了安全检测处理。

2013年9月10日发布的Java SE 7 Update 40修复了空字节截断这个历史遗留问题。此次更新在java.io.File类中添加了一个isInvalid方法,专门检测文件名中是否包含了空字节。

Java Web安全-代码审计(二)

修复的JDK版本所有跟文件名相关的操作都调用了isInvalid方法检测,防止空字节截断。

Java Web安全-代码审计(二)

修复前(Java SE 7 Update 25)和修复后(Java SE 7 Update 40)的对比会发现Java SE 7 Update 25中的java.io.File类中并未添加\u0000的检测。

Java Web安全-代码审计(二)

受空字节截断影响的JDK版本范围:JDK<1.7.40,单是JDK7于2011年07月28日发布至2013年09月10日发表Java SE 7 Update 40这两年多期间受影响的就有16个版本,值得注意的是JDK1.6虽然JDK7修复之后发布了数十个版本,但是并没有任何一个版本修复过这个问题,而JDK8发布时间在JDK7修复以后所以并不受此漏洞影响。

参考:

JDK-8014846 : File and other classes in java.io do not handle embedded nulls properly。
维基百科-Java版本歷史
Oracle Java 历史版本下载

2.1.2 测试Java写文件截断测试

测试类FileNullBytes.java:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author yz
 */
public class FileNullBytes {

public static void main(String[] args) {
try {
String fileName = "/tmp/null-bytes.txt\u0000.jpg";
FileOutputStream fos = new FileOutputStream(new File(fileName));
fos.write("Test".getBytes());
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

使用JDK1.7.0.25测试成功截断文件名:

Java Web安全-代码审计(二)
使用JDK1.7.0.80测试写文件截断时抛出java.io.FileNotFoundException: Invalid file path异常:

Java Web安全-代码审计(二)

空字节截断利用场景

Java空字节截断利用场景最常见的利用场景就是文件上传时后端使用了endWith、正则使用如:.(jpg|png|gif)$验证文件名后缀且文件名最终原样保存,同理文件删除(delete)、获取文件路径(getCanonicalPath)、创建文件(createNewFile)、文件重命名(renameTo)等方法也可适用。

空字节截断修复方案

最简单直接的方式就是升级JDK,如果担心升级JDK出现兼容性问题可在文件操作时检测下文件名中是否包含空字节,如JDK的修复方式:fileName.indexOf(‘\u0000’)即可。

2.1.2 任意文件读取漏洞

任意文件读取漏洞即因为没有验证请求的资源文件是否合法导致的,此类漏洞在Java中有着较高的几率出现,任意文件读取漏洞看似很简单,但是在这个问题上翻车的有不乏一些知名的中间件:Weblogic、Tomcat、Resin又或者是主流MVC框架:Spring MVC、Struts2。所以在审计文件读取功能的时候要非常仔细,或许很容易就会有意想不到的收获!

任意文件读取示例代码file-read.jsp:



&lt;% File file = new File(request.getParameter(&quot;path&quot;)); FileInputStream fis = new FileInputStream(file); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] b = new byte[1024]; int a = -1; while ((a = fis.read(b)) != -1) { baos.write(b, 0, a); } out.write(&quot;<pre>" + new String(baos.toByteArray()) + "</pre>"); fis.close(); %&gt;

访问file-read.jsp文件即可读取任意文件:http://localhost:8080/file/file-read.jsp?path=/etc/passwd

Java Web安全-代码审计(二)

快速发现这类漏洞得方式其实也是非常简单的,在IDEA中的项目中重点搜下如下文件读取的类。

JDK原始的java.io.FileInputStream类
JDK原始的java.io.RandomAccessFile类
Apache Commons IO提供的org.apache.commons.io.FileUtils类
JDK1.7新增的基于NIO非阻塞异步读取文件的java.nio.channels.AsynchronousFileChannel类。
JDK1.7新增的基于NIO读取文件的java.nio.file.Files类。常用方法如:Files.readAllBytes、Files.readAllLines
如果仍没有什么发现可以搜索一下FileUtil很有可能用户会封装文件操作的工具类。

Java WebSevice
Web Service是一种基于SOAP协议实现的跨语言Web服务调用,在Java中Web Service有如下技术实现:Oracle JWS、Apache Axis1、2、XFire、Apache CXF、JBossWS。

Axis1.4 配置

web.xml配置Axis1.4

Java Web安全-代码审计(二)
配置server-config.wsdd文件注册Web Service服务类和方法:

Java Web安全-代码审计(二)

FileService类,提供了文件读写接口:

Java Web安全-代码审计(二)

使用IDEA创建Web Service项目默认会创建管理Web Service的API:/servlet/AxisServlet、/services、SOAPMonitor、/servlet/AdminServlet,*.jws以及用监控Web Service的端口5001或5101。

Java Web安全-代码审计(二)

访问Web Service的FileService服务加上?wsdl参数可以看到FileService提供的服务方法和具体的参数信息。

Java Web安全-代码审计(二)
使用SOAP-UI调用Web Service接口示例:

Java Web安全-代码审计(二)

需要注意的是Web Service也是可以设置授权认证的,如实现了WS-Security的WSS4J。
Java Web安全-代码审计(二)

使用IDEA根据wsdl生成Web Service客户端代码:

Java Web安全-代码审计(二)
设置wsdl地址、包名:

Java Web安全-代码审计(二)

新建FileServiceTest类测试接口调用:

package org.javaweb.codereview.axis.client;

import java.net.URL;

/**
 * 文件Web Service服务测试
 *
 * @author yz
 */
public class FileServiceTest {

public static void main(String[] args) {
try {
FileServiceService         fileService   = new FileServiceServiceLocator();
URL                        webServiceUrl = new URL("http://localhost:8080/services/FileService");
FileServiceSoapBindingStub soapService   = new FileServiceSoapBindingStub(webServiceUrl, fileService);

String content = soapService.readFile("/etc/passwd");

System.out.println(content);
} catch (Exception e) {
e.printStackTrace();
}
}
}

参考:

Axis1.4框架 实现webservice服务器和客户端
使用IDEA根据wsdl生成WebServices客户端代码-Java
axis2 利用小工具cat.aar

原创文章,作者:abseo,如若转载,请注明出处:http://absec.cn/?p=964

发表评论

电子邮件地址不会被公开。 必填项已用*标注

联系我们

010-61943626

在线咨询:点击这里给我发消息

邮件:marketing@anbai.com

工作时间:电话:周一至周五,10:00-18:30,节假日休息,邮件随时发哦~