From a08861cc19ffe7ae04a9bb6b8c4093f71b2e0d3d Mon Sep 17 00:00:00 2001 From: Mikhail Klementev Date: Tue, 20 Aug 2019 00:05:19 +0000 Subject: [PATCH] Implements KPTI flag --- CHANGELOG.md | 7 ++++--- config/config.go | 1 + debug.go | 22 +++++++++++++++------- main.go | 6 ++++-- qemu/qemu-kernel.go | 15 +++++++++++++++ 5 files changed, 39 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0cd72ae..fe7f82e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,8 +32,8 @@ - Now debugging environment is automatically looking for debug kernel on the host system. -- Added ability to enable/disable kaslr/smep/smap for debugging by - command line flags. +- Added ability to enable/disable kaslr/smep/smap/kpti for debugging + by command line flags. - New parameter `--threads=N` is added for `pew` and allows to specify maximum number of threads that will be used for parallel @@ -47,7 +47,8 @@ - New command `pack` that perform tests in subdirectories. -- Added ability to disable kaslr/smep/smap for in artifact definition. +- Added ability to disable kaslr/smep/smap/kpti for in artifact + definition. - Added ability to change amount of memory/CPUs and set qemu timeout in artifact definition (`.out-of-tree.toml`). diff --git a/config/config.go b/config/config.go index f473530..3c50672 100644 --- a/config/config.go +++ b/config/config.go @@ -119,6 +119,7 @@ type Artifact struct { DisableSmep bool DisableSmap bool DisableKaslr bool + DisableKpti bool } } diff --git a/debug.go b/debug.go index 1375d1b..ff2b839 100644 --- a/debug.go +++ b/debug.go @@ -83,8 +83,8 @@ func interactive(q *qemu.System) (err error) { } func debugHandler(kcfg config.KernelConfig, workPath, kernRegex, gdb string, - dockerTimeout time.Duration, yekaslr, yesmep, yesmap, - nokaslr, nosmep, nosmap bool) (err error) { + dockerTimeout time.Duration, yekaslr, yesmep, yesmap, yekpti, + nokaslr, nosmep, nosmap, nokpti bool) (err error) { ka, err := config.ReadArtifactConfig(workPath + "/.out-of-tree.toml") if err != nil { @@ -113,12 +113,10 @@ func debugHandler(kcfg config.KernelConfig, workPath, kernRegex, gdb string, q.Memory = ka.Qemu.Memory } - fmt.Printf("[*] SMP: %d CPUs\n", q.Cpus) - fmt.Printf("[*] Memory: %d MB\n", q.Memory) - q.SetKASLR(false) // set KASLR to false by default because of gdb q.SetSMEP(!ka.Mitigations.DisableSmep) q.SetSMAP(!ka.Mitigations.DisableSmap) + q.SetKPTI(!ka.Mitigations.DisableKpti) if yekaslr { q.SetKASLR(true) @@ -138,6 +136,12 @@ func debugHandler(kcfg config.KernelConfig, workPath, kernRegex, gdb string, q.SetSMAP(false) } + if yekpti { + q.SetKPTI(true) + } else if nokpti { + q.SetKPTI(false) + } + redgreen := func(name string, enabled bool) aurora.Value { if enabled { return aurora.BgGreen(aurora.Black(name)) @@ -146,10 +150,14 @@ func debugHandler(kcfg config.KernelConfig, workPath, kernRegex, gdb string, return aurora.BgRed(aurora.Gray(name)) } - fmt.Printf("[*] %s %s %s\n", + fmt.Printf("[*] %s %s %s %s\n", redgreen("KASLR", q.GetKASLR()), redgreen("SMEP", q.GetSMEP()), - redgreen("SMAP", q.GetSMAP())) + redgreen("SMAP", q.GetSMAP()), + redgreen("KPTI", q.GetKPTI())) + + fmt.Printf("[*] SMP: %d CPUs\n", q.Cpus) + fmt.Printf("[*] Memory: %d MB\n", q.Memory) q.Debug(gdb) coloredGdbAddress := aurora.BgGreen(aurora.Black(gdb)) diff --git a/main.go b/main.go index ffd4001..3141486 100644 --- a/main.go +++ b/main.go @@ -180,10 +180,12 @@ func main() { yekaslr := debugCommand.Flag("enable-kaslr", "Enable KASLR").Bool() yesmep := debugCommand.Flag("enable-smep", "Enable SMEP").Bool() yesmap := debugCommand.Flag("enable-smap", "Enable SMAP").Bool() + yekpti := debugCommand.Flag("enable-kpti", "Enable KPTI").Bool() nokaslr := debugCommand.Flag("disable-kaslr", "Disable KASLR").Bool() nosmep := debugCommand.Flag("disable-smep", "Disable SMEP").Bool() nosmap := debugCommand.Flag("disable-smap", "Disable SMAP").Bool() + nokpti := debugCommand.Flag("disable-kpti", "Disable KPTI").Bool() bootstrapCommand := app.Command("bootstrap", "Create directories && download images") @@ -299,8 +301,8 @@ func main() { err = genConfig(config.KernelExploit) case debugCommand.FullCommand(): err = debugHandler(kcfg, *path, *debugKernel, *debugGDB, - *dockerTimeout, *yekaslr, *yesmep, *yesmap, - *nokaslr, *nosmep, *nosmap) + *dockerTimeout, *yekaslr, *yesmep, *yesmap, *yekpti, + *nokaslr, *nosmep, *nosmap, *nokpti) case bootstrapCommand.FullCommand(): err = bootstrapHandler() case logQueryCommand.FullCommand(): diff --git a/qemu/qemu-kernel.go b/qemu/qemu-kernel.go index d393bf7..e0865de 100644 --- a/qemu/qemu-kernel.go +++ b/qemu/qemu-kernel.go @@ -75,6 +75,7 @@ type System struct { noKASLR bool noSMEP bool noSMAP bool + noKPTI bool // Timeout works after Start invocation Timeout time.Duration @@ -202,6 +203,10 @@ func (q System) cmdline() (s string) { s += " nosmap" } + if q.noKPTI { + s += " nokpti" + } + return } @@ -402,6 +407,11 @@ func (q *System) SetSMAP(state bool) { q.noSMAP = !state } +// SetKPTI is changing KPTI state through kernel boot args +func (q *System) SetKPTI(state bool) { + q.noKPTI = !state +} + // GetKASLR is retrieve KASLR settings func (q *System) GetKASLR() bool { return !q.noKASLR @@ -417,6 +427,11 @@ func (q *System) GetSMAP() bool { return !q.noSMAP } +// GetKPTI is retrieve KPTI settings +func (q *System) GetKPTI() bool { + return !q.noKPTI +} + // GetSSHCommand returns command for connect to qemu machine over ssh func (q System) GetSSHCommand() (cmd string) { addrPort := strings.Split(q.sshAddrPort, ":")