1
0
Fork 0

Add script artifact type

timestamps
dump_stack() 2023-03-22 20:56:44 +00:00
parent 5ece0e0f15
commit 105809ddec
Signed by: dump_stack
GPG Key ID: BE44DA8C062D87DC
6 changed files with 92 additions and 30 deletions

View File

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

View File

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

View 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 = ".*"

View File

@ -0,0 +1,3 @@
# out-of-tree script example
See .out-of-tree.toml

View File

@ -0,0 +1,5 @@
#!/bin/sh
uname -a
ls /proc | grep config

60
pew.go
View File

@ -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 =