| 
									
										
										
										
											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
										 |  |  | } |