Add script artifact type
This commit is contained in:
parent
5ece0e0f15
commit
105809ddec
@ -49,10 +49,12 @@ const (
|
||||
KernelModule ArtifactType = iota
|
||||
// KernelExploit is the privilege escalation exploit
|
||||
KernelExploit
|
||||
// Script for information gathering or automation
|
||||
Script
|
||||
)
|
||||
|
||||
func (at ArtifactType) String() string {
|
||||
return [...]string{"module", "exploit"}[at]
|
||||
return [...]string{"module", "exploit", "script"}[at]
|
||||
}
|
||||
|
||||
// UnmarshalTOML is for support github.com/naoina/toml
|
||||
@ -63,6 +65,8 @@ func (at *ArtifactType) UnmarshalTOML(data []byte) (err error) {
|
||||
*at = KernelModule
|
||||
} else if strings.Contains(stypelower, "exploit") {
|
||||
*at = KernelExploit
|
||||
} else if strings.Contains(stypelower, "script") {
|
||||
*at = Script
|
||||
} else {
|
||||
err = fmt.Errorf("Type %s is unsupported", stype)
|
||||
}
|
||||
@ -77,6 +81,8 @@ func (at ArtifactType) MarshalTOML() (data []byte, err error) {
|
||||
s = "module"
|
||||
case KernelExploit:
|
||||
s = "exploit"
|
||||
case Script:
|
||||
s = "script"
|
||||
default:
|
||||
err = fmt.Errorf("Cannot marshal %d", at)
|
||||
}
|
||||
@ -129,6 +135,8 @@ type Artifact struct {
|
||||
SourcePath string
|
||||
SupportedKernels []KernelMask
|
||||
|
||||
Script string
|
||||
|
||||
Qemu struct {
|
||||
Cpus int
|
||||
Memory int
|
||||
|
33
debug.go
33
debug.go
@ -170,20 +170,29 @@ func (cmd *DebugCmd) Run(g *Globals) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
buildDir, outFile, output, err := build(tmp, ka, ki, g.Config.Docker.Timeout.Duration)
|
||||
if err != nil {
|
||||
log.Print(err, output)
|
||||
return
|
||||
}
|
||||
var buildDir, outFile, output, remoteFile string
|
||||
|
||||
remoteFile := "/tmp/exploit"
|
||||
if ka.Type == config.KernelModule {
|
||||
remoteFile = "/tmp/module.ko"
|
||||
}
|
||||
if ka.Type == config.Script {
|
||||
err = q.CopyFile("root", ka.Script, ka.Script)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
buildDir, outFile, output, err = build(tmp, ka, ki, g.Config.Docker.Timeout.Duration)
|
||||
if err != nil {
|
||||
log.Print(err, output)
|
||||
return
|
||||
}
|
||||
|
||||
err = q.CopyFile("user", outFile, remoteFile)
|
||||
if err != nil {
|
||||
return
|
||||
remoteFile = "/tmp/exploit"
|
||||
if ka.Type == config.KernelModule {
|
||||
remoteFile = "/tmp/module.ko"
|
||||
}
|
||||
|
||||
err = q.CopyFile("user", outFile, remoteFile)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Copy all test files to the remote machine
|
||||
|
11
examples/script/.out-of-tree.toml
Normal file
11
examples/script/.out-of-tree.toml
Normal file
@ -0,0 +1,11 @@
|
||||
# out-of-tree configuration file
|
||||
# docs at https://out-of-tree.io
|
||||
name = "out-of-tree script example"
|
||||
type = "script"
|
||||
|
||||
script = "script.sh"
|
||||
|
||||
[[supported_kernels]]
|
||||
distro_type = "Ubuntu"
|
||||
distro_release = "22.04"
|
||||
release_mask = ".*"
|
3
examples/script/README.md
Normal file
3
examples/script/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# out-of-tree script example
|
||||
|
||||
See .out-of-tree.toml
|
5
examples/script/script.sh
Normal file
5
examples/script/script.sh
Normal file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
uname -a
|
||||
|
||||
ls /proc | grep config
|
60
pew.go
60
pew.go
@ -266,6 +266,10 @@ func build(tmp string, ka config.Artifact, ki config.KernelInfo,
|
||||
return
|
||||
}
|
||||
|
||||
func runScript(q *qemu.System, script string) (output string, err error) {
|
||||
return q.Command("root", script)
|
||||
}
|
||||
|
||||
func testKernelModule(q *qemu.System, ka config.Artifact,
|
||||
test string) (output string, err error) {
|
||||
|
||||
@ -300,12 +304,16 @@ func testKernelExploit(q *qemu.System, ka config.Artifact,
|
||||
|
||||
func genOkFail(name string, ok bool) (aurv aurora.Value) {
|
||||
state.Overall += 1
|
||||
s := " " + name
|
||||
if name == "" {
|
||||
s = ""
|
||||
}
|
||||
if ok {
|
||||
state.Success += 1
|
||||
s := " " + name + " SUCCESS "
|
||||
s += " SUCCESS "
|
||||
aurv = aurora.BgGreen(aurora.Black(s))
|
||||
} else {
|
||||
s := " " + name + " FAILURE "
|
||||
s += " FAILURE "
|
||||
aurv = aurora.BgRed(aurora.White(aurora.Bold(s)))
|
||||
}
|
||||
return
|
||||
@ -347,15 +355,19 @@ func dumpResult(q *qemu.System, ka config.Artifact, ki config.KernelInfo,
|
||||
ki.DistroRelease, ki.KernelRelease)
|
||||
|
||||
colored := ""
|
||||
if ka.Type == config.KernelExploit {
|
||||
switch ka.Type {
|
||||
case config.KernelExploit:
|
||||
colored = aurora.Sprintf("[*] %40s: %s %s", distroInfo,
|
||||
genOkFail("BUILD", res.Build.Ok),
|
||||
genOkFail("LPE", res.Test.Ok))
|
||||
} else {
|
||||
case config.KernelModule:
|
||||
colored = aurora.Sprintf("[*] %40s: %s %s %s", distroInfo,
|
||||
genOkFail("BUILD", res.Build.Ok),
|
||||
genOkFail("INSMOD", res.Run.Ok),
|
||||
genOkFail("TEST", res.Test.Ok))
|
||||
case config.Script:
|
||||
colored = aurora.Sprintf("[*] %40s: %s", distroInfo,
|
||||
genOkFail("", res.Test.Ok))
|
||||
}
|
||||
|
||||
additional := ""
|
||||
@ -398,6 +410,20 @@ func dumpResult(q *qemu.System, ka config.Artifact, ki config.KernelInfo,
|
||||
func copyArtifactAndTest(slog zerolog.Logger, q *qemu.System, ka config.Artifact,
|
||||
res *phasesResult, remoteTest string) (err error) {
|
||||
|
||||
// Copy all test files to the remote machine
|
||||
for _, f := range ka.TestFiles {
|
||||
if f.Local[0] != '/' {
|
||||
if res.BuildDir != "" {
|
||||
f.Local = res.BuildDir + "/" + f.Local
|
||||
}
|
||||
}
|
||||
err = q.CopyFile(f.User, f.Local, f.Remote)
|
||||
if err != nil {
|
||||
slog.Error().Err(err).Msg("copy test file")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
switch ka.Type {
|
||||
case config.KernelModule:
|
||||
res.Run.Output, err = q.CopyAndInsmod(res.BuildArtifact)
|
||||
@ -407,18 +433,6 @@ func copyArtifactAndTest(slog zerolog.Logger, q *qemu.System, ka config.Artifact
|
||||
}
|
||||
res.Run.Ok = true
|
||||
|
||||
// Copy all test files to the remote machine
|
||||
for _, f := range ka.TestFiles {
|
||||
if f.Local[0] != '/' {
|
||||
f.Local = res.BuildDir + "/" + f.Local
|
||||
}
|
||||
err = q.CopyFile(f.User, f.Local, f.Remote)
|
||||
if err != nil {
|
||||
slog.Error().Err(err).Msg("copy test file")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
res.Test.Output, err = testKernelModule(q, ka, remoteTest)
|
||||
if err != nil {
|
||||
slog.Error().Err(err).Msg(res.Test.Output)
|
||||
@ -440,6 +454,15 @@ func copyArtifactAndTest(slog zerolog.Logger, q *qemu.System, ka config.Artifact
|
||||
}
|
||||
res.Run.Ok = true // does not really used
|
||||
res.Test.Ok = true
|
||||
case config.Script:
|
||||
res.Test.Output, err = runScript(q, remoteTest)
|
||||
if err != nil {
|
||||
slog.Error().Err(err).Msg(res.Test.Output)
|
||||
return
|
||||
}
|
||||
slog.Info().Msg(res.Test.Output)
|
||||
res.Run.Ok = true
|
||||
res.Test.Ok = true
|
||||
default:
|
||||
slog.Fatal().Msg("Unsupported artifact type")
|
||||
}
|
||||
@ -568,7 +591,10 @@ func testArtifact(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact,
|
||||
result := phasesResult{}
|
||||
defer dumpResult(q, ka, ki, &result, dist, tag, binaryPath, db)
|
||||
|
||||
if binaryPath == "" {
|
||||
if ka.Type == config.Script {
|
||||
result.Build.Ok = true
|
||||
testPath = ka.Script
|
||||
} else if binaryPath == "" {
|
||||
// TODO: build should return structure
|
||||
start := time.Now()
|
||||
result.BuildDir, result.BuildArtifact, result.Build.Output, err =
|
||||
|
Loading…
Reference in New Issue
Block a user