1
0
out-of-tree/main.go

210 lines
6.0 KiB
Go
Raw Normal View History

// 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
// (or later) that can be found in the LICENSE file.
package main
import (
2018-12-10 02:51:15 +00:00
"fmt"
"log"
"os"
2018-11-19 15:31:25 +00:00
"os/exec"
"os/user"
"sort"
kingpin "gopkg.in/alecthomas/kingpin.v2"
2018-11-17 20:18:50 +00:00
2019-02-02 21:24:29 +00:00
"code.dumpstack.io/tools/out-of-tree/config"
)
func findFallback(kcfg config.KernelConfig, ki config.KernelInfo) (rootfs string) {
for _, k := range kcfg.Kernels {
if !exists(k.RootFS) || k.DistroType != ki.DistroType {
continue
}
if k.RootFS < ki.RootFS {
rootfs = k.RootFS
return
}
}
return
}
func handleFallbacks(kcfg config.KernelConfig) {
sort.Sort(sort.Reverse(config.ByRootFS(kcfg.Kernels)))
for i, k := range kcfg.Kernels {
if !exists(k.RootFS) {
newRootFS := findFallback(kcfg, k)
s := k.RootFS + " does not exists "
if newRootFS != "" {
s += "(fallback to " + newRootFS + ")"
} else {
s += "(no fallback found)"
}
kcfg.Kernels[i].RootFS = newRootFS
log.Println(s)
}
}
}
2018-12-10 02:51:15 +00:00
func checkRequiredUtils() (err error) {
// Check for required commands
for _, cmd := range []string{"docker", "qemu-system-x86_64"} {
_, err := exec.Command("which", cmd).CombinedOutput()
if err != nil {
return fmt.Errorf("Command not found: %s", cmd)
}
}
return
}
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>")
2018-12-01 18:12:44 +00:00
app.Version("0.2.0")
2018-10-27 08:14:10 +00:00
pathFlag := app.Flag("path", "Path to work directory")
2018-10-27 07:48:06 +00:00
path := pathFlag.Default(".").ExistingDir()
usr, err := user.Current()
if err != nil {
return
}
defaultKcfgPath := usr.HomeDir + "/.out-of-tree/kernels.toml"
kcfgPathFlag := app.Flag("kernels", "Path to main kernels config")
2018-12-02 20:23:48 +00:00
kcfgPath := kcfgPathFlag.Default(defaultKcfgPath).String()
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
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-27 15:33:54 +00:00
pewGuessFlag := pewCommand.Flag("guess", "Try all defined kernels")
pewGuess := pewGuessFlag.Bool()
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")
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")
kernelGenallCommand := kernelCommand.Command("genall",
"Generate all kernels for distro")
genallDistroFlag := kernelGenallCommand.Flag("distro", "Distributive")
distro := genallDistroFlag.Required().String()
genallVerFlag := kernelGenallCommand.Flag("ver", "Distro version")
version := genallVerFlag.Required().String()
2018-11-17 13:20:29 +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-12-10 02:51:15 +00:00
err = checkRequiredUtils()
if err != nil {
log.Fatalln(err)
2018-11-19 15:31:25 +00:00
}
if !exists(usr.HomeDir + "/.out-of-tree/images") {
log.Println("No ~/.out-of-tree/images: " +
"Probably you need to run `out-of-tree bootstrap`" +
" for downloading basic images")
}
if !exists(usr.HomeDir + "/.out-of-tree/kernels.toml") {
log.Println("No ~/.out-of-tree/kernels.toml: Probably you " +
2018-12-02 20:25:33 +00:00
"need to run `out-of-tree kernel autogen` in " +
"directory that contains .out-of-tree.toml " +
"with defined kernel masks " +
"(see docs at https://out-of-tree.io)")
2018-12-02 03:19:41 +00:00
}
kingpin.MustParse(app.Parse(os.Args[1:]))
2018-11-17 20:18:50 +00:00
kcfg, err := config.ReadKernelConfig(*kcfgPath)
if err != nil {
log.Println(err)
}
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)
}
}
}
handleFallbacks(kcfg)
2018-10-27 08:14:10 +00:00
switch kingpin.MustParse(app.Parse(os.Args[1:])) {
case pewCommand.FullCommand():
err = pewHandler(kcfg, *path, *pewKernel, *pewBinary,
*pewTest, *pewGuess, *qemuTimeout, *dockerTimeout)
2018-11-17 13:20:29 +00:00
case kernelListCommand.FullCommand():
err = kernelListHandler(kcfg)
case kernelAutogenCommand.FullCommand():
2018-12-01 15:11:43 +00:00
err = kernelAutogenHandler(*path)
case kernelDockerRegenCommand.FullCommand():
err = kernelDockerRegenHandler()
case kernelGenallCommand.FullCommand():
err = kernelGenallHandler(*distro, *version)
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()
}
if err != nil {
log.Fatalln(err)
}
if somethingFailed {
os.Exit(1)
}
}