2018-10-06 19:25:03 +00:00
|
|
|
// Copyright 2018 Mikhail Klementev. All rights reserved.
|
2018-10-08 20:51:32 +00:00
|
|
|
// Use of this source code is governed by a AGPLv3 license
|
2018-10-06 19:25:03 +00:00
|
|
|
// (or later) that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"log"
|
|
|
|
"os"
|
2018-11-19 15:31:25 +00:00
|
|
|
"os/exec"
|
2018-11-17 13:44:03 +00:00
|
|
|
"os/user"
|
2018-10-06 19:25:03 +00:00
|
|
|
|
2018-10-26 18:26:43 +00:00
|
|
|
kingpin "gopkg.in/alecthomas/kingpin.v2"
|
2018-11-17 20:18:50 +00:00
|
|
|
|
2018-11-17 20:20:36 +00:00
|
|
|
"github.com/jollheef/out-of-tree/config"
|
2018-10-06 19:25:03 +00:00
|
|
|
)
|
|
|
|
|
2018-10-26 18:26:43 +00:00
|
|
|
func main() {
|
2018-10-27 08:14:10 +00:00
|
|
|
app := kingpin.New(
|
|
|
|
"out-of-tree",
|
|
|
|
"kernel {module, exploit} development tool",
|
|
|
|
)
|
|
|
|
|
|
|
|
app.Author("Mikhail Klementev <jollheef@riseup.net>")
|
|
|
|
app.Version("0.1.0")
|
|
|
|
|
|
|
|
pathFlag := app.Flag("path", "Path to work directory")
|
2018-10-27 07:48:06 +00:00
|
|
|
path := pathFlag.Default(".").ExistingDir()
|
|
|
|
|
2018-11-17 13:44:03 +00:00
|
|
|
usr, err := user.Current()
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defaultKcfgPath := usr.HomeDir + "/.out-of-tree/kernels.toml"
|
|
|
|
|
2018-12-01 16:57:15 +00:00
|
|
|
kcfgPathFlag := app.Flag("kernels", "Path to main kernels config")
|
|
|
|
kcfgPath := kcfgPathFlag.Default(defaultKcfgPath).ExistingFile()
|
|
|
|
|
|
|
|
defaultUserKcfgPath := usr.HomeDir + "/.out-of-tree/kernels.user.toml"
|
|
|
|
userKcfgPathFlag := app.Flag("user-kernels", "User kernels config")
|
|
|
|
userKcfgPathEnv := userKcfgPathFlag.Envar("OUT_OF_TREE_KCFG")
|
|
|
|
userKcfgPath := userKcfgPathEnv.Default(defaultUserKcfgPath).String()
|
2018-10-27 07:48:06 +00:00
|
|
|
|
2018-10-27 19:06:24 +00:00
|
|
|
qemuTimeoutFlag := app.Flag("qemu-timeout", "Timeout for qemu")
|
|
|
|
qemuTimeout := qemuTimeoutFlag.Default("1m").Duration()
|
|
|
|
|
|
|
|
dockerTimeoutFlag := app.Flag("docker-timeout", "Timeout for docker")
|
|
|
|
dockerTimeout := dockerTimeoutFlag.Default("1m").Duration()
|
2018-10-27 08:14:10 +00:00
|
|
|
pewCommand := app.Command("pew", "Build, run and test module/exploit")
|
2018-10-27 15:09:28 +00:00
|
|
|
pewKernelFlag := pewCommand.Flag("kernel", "Override kernel regex")
|
|
|
|
pewKernel := pewKernelFlag.String()
|
2018-10-26 18:26:43 +00:00
|
|
|
|
2018-10-27 15:33:54 +00:00
|
|
|
pewGuessFlag := pewCommand.Flag("guess", "Try all defined kernels")
|
|
|
|
pewGuess := pewGuessFlag.Bool()
|
|
|
|
|
2018-10-27 19:35:47 +00:00
|
|
|
pewBinaryFlag := pewCommand.Flag("binary", "Use binary, do not build")
|
|
|
|
pewBinary := pewBinaryFlag.String()
|
|
|
|
|
|
|
|
pewTestFlag := pewCommand.Flag("test", "Override path test")
|
|
|
|
pewTest := pewTestFlag.String()
|
|
|
|
|
2018-11-17 13:20:29 +00:00
|
|
|
kernelCommand := app.Command("kernel", "Manipulate kernels")
|
|
|
|
kernelListCommand := kernelCommand.Command("list", "List kernels")
|
2018-11-28 22:41:17 +00:00
|
|
|
kernelAutogenCommand := kernelCommand.Command("autogen",
|
|
|
|
"Generate kernels based on a current config")
|
2018-12-01 15:11:43 +00:00
|
|
|
kernelDockerRegenCommand := kernelCommand.Command("docker-regen",
|
|
|
|
"Regenerate kernels config from out_of_tree_* docker images")
|
2018-11-17 13:20:29 +00:00
|
|
|
|
2018-11-23 09:11:18 +00:00
|
|
|
genCommand := app.Command("gen", "Generate .out-of-tree.toml skeleton")
|
|
|
|
genModuleCommand := genCommand.Command("module",
|
|
|
|
"Generate .out-of-tree.toml skeleton for kernel module")
|
|
|
|
genExploitCommand := genCommand.Command("exploit",
|
|
|
|
"Generate .out-of-tree.toml skeleton for kernel exploit")
|
|
|
|
|
2018-11-25 14:46:29 +00:00
|
|
|
debugCommand := app.Command("debug", "Kernel debug environment")
|
|
|
|
debugCommandFlag := debugCommand.Flag("kernel", "Regex (first match)")
|
|
|
|
debugKernel := debugCommandFlag.Required().String()
|
2018-11-25 14:53:56 +00:00
|
|
|
debugFlagGDB := debugCommand.Flag("gdb", "Set gdb listen address")
|
|
|
|
debugGDB := debugFlagGDB.Default("tcp::1234").String()
|
2018-11-25 14:46:29 +00:00
|
|
|
|
2018-12-01 17:34:57 +00:00
|
|
|
bootstrapCommand := app.Command("bootstrap",
|
|
|
|
"Create directories && download images")
|
|
|
|
|
2018-11-19 15:31:25 +00:00
|
|
|
// Check for required commands
|
|
|
|
for _, cmd := range []string{"timeout", "docker", "qemu"} {
|
|
|
|
_, err := exec.Command("which", cmd).CombinedOutput()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalln("Command not found:", cmd)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-17 13:44:03 +00:00
|
|
|
kingpin.MustParse(app.Parse(os.Args[1:]))
|
|
|
|
|
2018-11-17 20:18:50 +00:00
|
|
|
kcfg, err := config.ReadKernelConfig(*kcfgPath)
|
2018-11-17 13:17:28 +00:00
|
|
|
if err != nil {
|
2018-11-17 13:28:56 +00:00
|
|
|
log.Fatalln(err)
|
2018-11-17 13:17:28 +00:00
|
|
|
}
|
|
|
|
|
2018-12-01 16:57:15 +00:00
|
|
|
if exists(*userKcfgPath) {
|
|
|
|
userKcfg, err := config.ReadKernelConfig(*userKcfgPath)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalln(err)
|
|
|
|
}
|
|
|
|
|
2018-12-01 17:13:38 +00:00
|
|
|
for _, nk := range userKcfg.Kernels {
|
|
|
|
if !hasKernel(nk, kcfg) {
|
|
|
|
kcfg.Kernels = append(kcfg.Kernels, nk)
|
|
|
|
}
|
|
|
|
}
|
2018-12-01 16:57:15 +00:00
|
|
|
}
|
|
|
|
|
2018-10-27 08:14:10 +00:00
|
|
|
switch kingpin.MustParse(app.Parse(os.Args[1:])) {
|
|
|
|
case pewCommand.FullCommand():
|
2018-11-17 13:17:28 +00:00
|
|
|
err = pewHandler(kcfg, *path, *pewKernel, *pewBinary,
|
2018-10-27 19:35:47 +00:00
|
|
|
*pewTest, *pewGuess, *qemuTimeout, *dockerTimeout)
|
2018-11-17 13:20:29 +00:00
|
|
|
case kernelListCommand.FullCommand():
|
|
|
|
err = kernelListHandler(kcfg)
|
2018-11-28 22:41:17 +00:00
|
|
|
case kernelAutogenCommand.FullCommand():
|
2018-12-01 15:11:43 +00:00
|
|
|
err = kernelAutogenHandler(*path)
|
|
|
|
case kernelDockerRegenCommand.FullCommand():
|
|
|
|
err = kernelDockerRegenHandler()
|
2018-11-23 09:11:18 +00:00
|
|
|
case genModuleCommand.FullCommand():
|
|
|
|
err = genConfig(config.KernelModule)
|
|
|
|
case genExploitCommand.FullCommand():
|
|
|
|
err = genConfig(config.KernelExploit)
|
2018-11-25 14:46:29 +00:00
|
|
|
case debugCommand.FullCommand():
|
2018-11-25 14:53:56 +00:00
|
|
|
err = debugHandler(kcfg, *path, *debugKernel, *debugGDB,
|
|
|
|
*dockerTimeout)
|
2018-12-01 17:34:57 +00:00
|
|
|
case bootstrapCommand.FullCommand():
|
|
|
|
err = bootstrapHandler()
|
2018-10-26 18:26:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
2018-11-17 13:28:56 +00:00
|
|
|
log.Fatalln(err)
|
2018-10-26 18:26:43 +00:00
|
|
|
}
|
2018-10-06 19:25:03 +00:00
|
|
|
}
|