Skip to content

Commit

Permalink
Add another CVE, make detection more generic, better console output
Browse files Browse the repository at this point in the history
Signed-off-by: Philipp Deppenwiese <[email protected]>
  • Loading branch information
zaolin committed Mar 15, 2023
1 parent 87f1518 commit 9c32f0e
Show file tree
Hide file tree
Showing 10 changed files with 199 additions and 31 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

dist/
25 changes: 25 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# This is an example .goreleaser.yml file with some sane defaults.
# Make sure to check the documentation at http://goreleaser.com
before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
goarch:
- amd64
main: ./cmd/tpm-vuln-checker
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ incpatch .Version }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
29 changes: 22 additions & 7 deletions cmd/tpm-vuln-checker/cmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import (

"github.com/fatih/color"
"github.com/immune-gmbh/tpm-vuln-checker/pkg/cloud"
"github.com/immune-gmbh/tpm-vuln-checker/pkg/cve"
"github.com/immune-gmbh/tpm-vuln-checker/pkg/cve201715361"
"github.com/immune-gmbh/tpm-vuln-checker/pkg/cve20231017"
"github.com/immune-gmbh/tpm-vuln-checker/pkg/tss"
"github.com/manifoldco/promptui"
)
Expand All @@ -27,6 +28,7 @@ var (
NonVulnerableStyle = color.New(color.FgGreen, color.BgBlack, color.Bold).SprintFunc()
VulnerableStyle = color.New(color.FgRed, color.BgBlack, color.Bold).SprintFunc()
MaybeVulnerableStyle = color.New(color.FgYellow, color.BgBlack, color.Bold).SprintFunc()
InfoStyle = color.New(color.FgBlue, color.BgBlack, color.Bold).SprintFunc()
)

type context struct {
Expand All @@ -37,7 +39,7 @@ type versionCmd struct {
}

type checkCmd struct {
NonInteractive bool `flag optional name:"batch" help:"Always uploads anonymized data without asking"`
NonInteractive bool `flag optional name:"auto-upload" help:"Always uploads anonymized data without asking"`
}

func (v *versionCmd) Run(ctx *context) error {
Expand All @@ -58,9 +60,10 @@ func (v *checkCmd) Run(ctx *context) error {
if err != nil {
return err
}
fmt.Printf("TPM Manufacturer: \t%s\nTPM Spec Revision: \t%s\nTPM Family: \t\t%s\n",
fmt.Printf("TPM Manufacturer: \t\t%s\nTPM Spec Revision: \t\t%s\nTPM Family: \t\t\t%s\n",
tpmInfo.Manufacturer.String(), tpmInfo.SpecRevision.String(), tpmInfo.Family.String())
vulnerable, cveData, err := cve.Detect(socket)
fmt.Printf("\nStarting TPM vulnerabilities checks.. This may take few seconds!\n\n")
vulnerable, cveData20231017, err := cve20231017.IsVulnerable(socket)
if err != nil {
if err.Error() == "unknown" {
fmt.Printf("CVE 2023-1017/2023-1018: \t%s", MaybeVulnerableStyle("Probably Not Vulnerable"))
Expand All @@ -69,14 +72,26 @@ func (v *checkCmd) Run(ctx *context) error {
}
} else {
if vulnerable {
fmt.Printf("CVE 2023-1017/2023-1018: \t%s", VulnerableStyle("Vulnerable"))
fmt.Printf("CVE 2023-1017/2023-1018: \t%s\n", VulnerableStyle("Vulnerable"))
fmt.Printf("%s", InfoStyle("Please apply the latest BIOS update to update the TPM firmware. OEMs/ODMs ship TPM updates as part of BIOS updates."))
} else {
fmt.Printf("CVE 2023-1017/2023-1018: \t%s", NonVulnerableStyle("Not Vulnerable"))
}
}
fmt.Println()
vulnerable, cveData201715361, err := cve201715361.IsVulnerable(socket)
if err != nil {
fmt.Printf("CVE 2017-15361: \t\t%s", MaybeVulnerableStyle("Check Error"))
} else {
if vulnerable {
fmt.Printf("CVE 2017-15361: \t\t%s\n", VulnerableStyle("Vulnerable"))
} else {
fmt.Printf("CVE 2017-15361: \t\t%s", NonVulnerableStyle("Not Vulnerable"))
}
}
fmt.Println()
if v.NonInteractive {
if err := cloud.UploadAnonData(tpmInfo, cveData, vulnerable); err != nil {
if err := cloud.UploadAnonData(tpmInfo, cveData20231017, cveData201715361); err != nil {
return err
}
} else {
Expand All @@ -89,7 +104,7 @@ func (v *checkCmd) Run(ctx *context) error {
if err != nil {
return nil
}
if err := cloud.UploadAnonData(tpmInfo, cveData, vulnerable); err != nil {
if err := cloud.UploadAnonData(tpmInfo, cveData20231017, cveData201715361); err != nil {
return err
}
}
Expand Down
4 changes: 2 additions & 2 deletions docs/_config.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
domain: vuln.immune.gmbh
url: https://vuln.immune.gmbh
markdown: kramdown
remote_theme: immune-gmbh/midnight@master
remote_theme: pages-themes/midnight@v0.2.0
plugins:
- jekyll-remote-theme
- jekyll-remote-theme
8 changes: 3 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ require (
)

require (
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect
github.com/chzyer/readline v1.5.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
golang.org/x/sys v0.6.0 // indirect
)

require (
github.com/google/uuid v1.3.0
golang.org/x/sys v0.3.0
)
require github.com/google/uuid v1.3.0
14 changes: 9 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
github.com/chzyer/logex v1.2.0 h1:+eqR0HfOetur4tgnC8ftU5imRnhi4te+BadWS95c5AM=
github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
github.com/chzyer/readline v1.5.0 h1:lSwwFrbNviGePhkewF1az4oLmcwqCZijQ2/Wi3BGHAI=
github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/chzyer/test v0.0.0-20210722231415-061457976a23 h1:dZ0/VyGgQdVGAss6Ju0dt5P0QltE0SFY5Woh6hbIfiQ=
github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
Expand Down Expand Up @@ -163,9 +166,10 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20210629170331-7dc0b73dc9fb/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Expand Down
15 changes: 8 additions & 7 deletions pkg/cloud/cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import (
"net/http"

"github.com/google/uuid"
"github.com/immune-gmbh/tpm-vuln-checker/pkg/cve"
"github.com/immune-gmbh/tpm-vuln-checker/pkg/cve201715361"
"github.com/immune-gmbh/tpm-vuln-checker/pkg/cve20231017"
"github.com/immune-gmbh/tpm-vuln-checker/pkg/tss"
)

Expand All @@ -31,19 +32,19 @@ const (
)

type AnonInfo struct {
Info *tss.TPM20Info `json:"info"`
Vulnerable bool `json:"vulnerable"`
Raw *cve.CVEData `json:"cvedata"`
Info *tss.TPM20Info `json:"info"`
CVEData20231017 *cve20231017.CVEData `json:"cveData-20231017"`
CVEData201715361 *cve201715361.CVEData `json:"cveData-201715361"`
}

func UploadAnonData(info *tss.TPM20Info, raw *cve.CVEData, vuln bool) error {
func UploadAnonData(info *tss.TPM20Info, cveData20231017 *cve20231017.CVEData, cveData201715361 *cve201715361.CVEData) error {
if info == nil {
return fmt.Errorf("tpm info is nil")
}
var payload AnonInfo
payload.Info = info
payload.Vulnerable = vuln
payload.Raw = raw
payload.CVEData20231017 = cveData20231017
payload.CVEData201715361 = cveData201715361
data, err := json.Marshal(payload)
if err != nil {
return err
Expand Down
104 changes: 104 additions & 0 deletions pkg/cve201715361/cve-2017-15361.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// MIT License
//
// Copyright (c) 2017, Jonathan Rudenberg
// Copyright (c) 2017, CRoCS, EnigmaBridge Ltd.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
package cve201715361

import (
"crypto/rsa"
"fmt"
"io"
"math/big"

"github.com/google/go-tpm/tpm2"
"github.com/immune-gmbh/tpm-vuln-checker/pkg/tss"
)

type CVEData struct {
Vulnerable bool
}

type test struct {
Prime *big.Int
Fingerprints map[int64]struct{}
}

var tests = make([]test, 17)

func init() {
bigOne := big.NewInt(1)
n := &big.Int{}
// relations table from https://github.com/crocs-muni/roca/pull/40
for i, r := range [][2]int64{
{2, 11}, {6, 13}, {8, 17}, {9, 19}, {3, 37}, {26, 53}, {20, 61},
{35, 71}, {24, 73}, {13, 79}, {6, 97}, {51, 103}, {53, 107},
{54, 109}, {42, 127}, {50, 151}, {78, 157},
} {
fps := make(map[int64]struct{})
bp := big.NewInt(r[1])
br := big.NewInt(r[0])
for j := int64(0); j < r[1]; j++ {
if n.Exp(big.NewInt(j), br, bp).Cmp(bigOne) == 0 {
fps[j] = struct{}{}
}
}
tests[i] = test{
Prime: big.NewInt(r[1]),
Fingerprints: fps,
}
}
}

// IsWeak returns true if a RSA public key is vulnerable to Return of
// Coppersmith's Attack (ROCA).
func IsVulnerable(rwc io.ReadWriteCloser) (bool, *CVEData, error) {
var cveData CVEData
_ = tpm2.Startup(rwc, tpm2.StartupClear)
session, _, err := tss.StartAuthSession(
rwc,
tpm2.HandleNull,
tpm2.HandleNull,
make([]byte, 16),
nil,
tpm2.SessionHMAC,
tpm2.AlgXOR,
tpm2.AlgSHA256)
if err != nil {
return false, nil, fmt.Errorf("")
}
defer tpm2.FlushContext(rwc, session)

hnd, publicKey, err := tpm2.CreatePrimary(rwc, tpm2.HandleEndorsement, tpm2.PCRSelection{}, "", "", tss.RSAPublicKey)
if err != nil {
return false, nil, fmt.Errorf("")
}
defer tpm2.FlushContext(rwc, hnd)
tmp := &big.Int{}
key := publicKey.(*rsa.PublicKey)
for _, t := range tests {
if _, ok := t.Fingerprints[tmp.Mod(key.N, t.Prime).Int64()]; !ok {
cveData.Vulnerable = false
return false, &cveData, nil
}
}
cveData.Vulnerable = true
return true, &cveData, nil
}
13 changes: 8 additions & 5 deletions pkg/cve/cve.go → pkg/cve20231017/cve-2023-1017.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cve
package cve20231017

import (
"errors"
Expand All @@ -26,9 +26,10 @@ import (
)

type CVEData struct {
RawString string
Valid int
Code uint64
RawString string
Valid int
Code uint64
Vulnerable bool
}

func hex2int(hexStr string) uint64 {
Expand Down Expand Up @@ -64,7 +65,7 @@ func parserError(err error) (*CVEData, error) {
return nil, fmt.Errorf("couldn't parse error strings: %s", strErr)
}

func Detect(rwc io.ReadWriteCloser) (bool, *CVEData, error) {
func IsVulnerable(rwc io.ReadWriteCloser) (bool, *CVEData, error) {
_ = tpm2.Startup(rwc, tpm2.StartupClear)
session, _, err := tss.StartAuthSession(
rwc,
Expand Down Expand Up @@ -97,8 +98,10 @@ func Detect(rwc io.ReadWriteCloser) (bool, *CVEData, error) {
if cveData != nil && cveData.Valid == 1 {
switch cveData.Code {
case 0x1a:
cveData.Vulnerable = false
return false, cveData, nil
case 0x15:
cveData.Vulnerable = true
return true, cveData, nil
}
} else if cveData != nil && cveData.Valid != 1 {
Expand Down
16 changes: 16 additions & 0 deletions pkg/tss/tpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,22 @@ var ECCPublicKey = tpm2.Public{
},
}

var RSAPublicKey = tpm2.Public{
Type: tpm2.AlgRSA,
NameAlg: tpm2.AlgSHA256,
Attributes: tpm2.FlagFixedTPM | tpm2.FlagFixedParent | tpm2.FlagSensitiveDataOrigin |
tpm2.FlagUserWithAuth | tpm2.FlagRestricted | tpm2.FlagDecrypt,
AuthPolicy: []byte{},
RSAParameters: &tpm2.RSAParams{
Symmetric: &tpm2.SymScheme{
Alg: tpm2.AlgAES,
KeyBits: 128,
Mode: tpm2.AlgCFB,
},
KeyBits: 2048,
},
}

func RunCommand(rw io.ReadWriter, tag tpmutil.Tag, Cmd tpmutil.Command, in ...interface{}) ([]byte, error) {
resp, code, err := tpmutil.RunCommand(rw, tag, Cmd, in...)
if err != nil {
Expand Down

0 comments on commit 9c32f0e

Please sign in to comment.