Add script artifact type
This commit is contained in:
parent
5ece0e0f15
commit
105809ddec
@ -49,10 +49,12 @@ const (
|
|||||||
KernelModule ArtifactType = iota
|
KernelModule ArtifactType = iota
|
||||||
// KernelExploit is the privilege escalation exploit
|
// KernelExploit is the privilege escalation exploit
|
||||||
KernelExploit
|
KernelExploit
|
||||||
|
// Script for information gathering or automation
|
||||||
|
Script
|
||||||
)
|
)
|
||||||
|
|
||||||
func (at ArtifactType) String() string {
|
func (at ArtifactType) String() string {
|
||||||
return [...]string{"module", "exploit"}[at]
|
return [...]string{"module", "exploit", "script"}[at]
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalTOML is for support github.com/naoina/toml
|
// UnmarshalTOML is for support github.com/naoina/toml
|
||||||
@ -63,6 +65,8 @@ func (at *ArtifactType) UnmarshalTOML(data []byte) (err error) {
|
|||||||
*at = KernelModule
|
*at = KernelModule
|
||||||
} else if strings.Contains(stypelower, "exploit") {
|
} else if strings.Contains(stypelower, "exploit") {
|
||||||
*at = KernelExploit
|
*at = KernelExploit
|
||||||
|
} else if strings.Contains(stypelower, "script") {
|
||||||
|
*at = Script
|
||||||
} else {
|
} else {
|
||||||
err = fmt.Errorf("Type %s is unsupported", stype)
|
err = fmt.Errorf("Type %s is unsupported", stype)
|
||||||
}
|
}
|
||||||
@ -77,6 +81,8 @@ func (at ArtifactType) MarshalTOML() (data []byte, err error) {
|
|||||||
s = "module"
|
s = "module"
|
||||||
case KernelExploit:
|
case KernelExploit:
|
||||||
s = "exploit"
|
s = "exploit"
|
||||||
|
case Script:
|
||||||
|
s = "script"
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("Cannot marshal %d", at)
|
err = fmt.Errorf("Cannot marshal %d", at)
|
||||||
}
|
}
|
||||||
@ -129,6 +135,8 @@ type Artifact struct {
|
|||||||
SourcePath string
|
SourcePath string
|
||||||
SupportedKernels []KernelMask
|
SupportedKernels []KernelMask
|
||||||
|
|
||||||
|
Script string
|
||||||
|
|
||||||
Qemu struct {
|
Qemu struct {
|
||||||
Cpus int
|
Cpus int
|
||||||
Memory int
|
Memory int
|
||||||
|
33
debug.go
33
debug.go
@ -170,20 +170,29 @@ func (cmd *DebugCmd) Run(g *Globals) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
buildDir, outFile, output, err := build(tmp, ka, ki, g.Config.Docker.Timeout.Duration)
|
var buildDir, outFile, output, remoteFile string
|
||||||
if err != nil {
|
|
||||||
log.Print(err, output)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
remoteFile := "/tmp/exploit"
|
if ka.Type == config.Script {
|
||||||
if ka.Type == config.KernelModule {
|
err = q.CopyFile("root", ka.Script, ka.Script)
|
||||||
remoteFile = "/tmp/module.ko"
|
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)
|
remoteFile = "/tmp/exploit"
|
||||||
if err != nil {
|
if ka.Type == config.KernelModule {
|
||||||
return
|
remoteFile = "/tmp/module.ko"
|
||||||
|
}
|
||||||
|
|
||||||
|
err = q.CopyFile("user", outFile, remoteFile)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy all test files to the remote machine
|
// 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
|
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,
|
func testKernelModule(q *qemu.System, ka config.Artifact,
|
||||||
test string) (output string, err error) {
|
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) {
|
func genOkFail(name string, ok bool) (aurv aurora.Value) {
|
||||||
state.Overall += 1
|
state.Overall += 1
|
||||||
|
s := " " + name
|
||||||
|
if name == "" {
|
||||||
|
s = ""
|
||||||
|
}
|
||||||
if ok {
|
if ok {
|
||||||
state.Success += 1
|
state.Success += 1
|
||||||
s := " " + name + " SUCCESS "
|
s += " SUCCESS "
|
||||||
aurv = aurora.BgGreen(aurora.Black(s))
|
aurv = aurora.BgGreen(aurora.Black(s))
|
||||||
} else {
|
} else {
|
||||||
s := " " + name + " FAILURE "
|
s += " FAILURE "
|
||||||
aurv = aurora.BgRed(aurora.White(aurora.Bold(s)))
|
aurv = aurora.BgRed(aurora.White(aurora.Bold(s)))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -347,15 +355,19 @@ func dumpResult(q *qemu.System, ka config.Artifact, ki config.KernelInfo,
|
|||||||
ki.DistroRelease, ki.KernelRelease)
|
ki.DistroRelease, ki.KernelRelease)
|
||||||
|
|
||||||
colored := ""
|
colored := ""
|
||||||
if ka.Type == config.KernelExploit {
|
switch ka.Type {
|
||||||
|
case config.KernelExploit:
|
||||||
colored = aurora.Sprintf("[*] %40s: %s %s", distroInfo,
|
colored = aurora.Sprintf("[*] %40s: %s %s", distroInfo,
|
||||||
genOkFail("BUILD", res.Build.Ok),
|
genOkFail("BUILD", res.Build.Ok),
|
||||||
genOkFail("LPE", res.Test.Ok))
|
genOkFail("LPE", res.Test.Ok))
|
||||||
} else {
|
case config.KernelModule:
|
||||||
colored = aurora.Sprintf("[*] %40s: %s %s %s", distroInfo,
|
colored = aurora.Sprintf("[*] %40s: %s %s %s", distroInfo,
|
||||||
genOkFail("BUILD", res.Build.Ok),
|
genOkFail("BUILD", res.Build.Ok),
|
||||||
genOkFail("INSMOD", res.Run.Ok),
|
genOkFail("INSMOD", res.Run.Ok),
|
||||||
genOkFail("TEST", res.Test.Ok))
|
genOkFail("TEST", res.Test.Ok))
|
||||||
|
case config.Script:
|
||||||
|
colored = aurora.Sprintf("[*] %40s: %s", distroInfo,
|
||||||
|
genOkFail("", res.Test.Ok))
|
||||||
}
|
}
|
||||||
|
|
||||||
additional := ""
|
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,
|
func copyArtifactAndTest(slog zerolog.Logger, q *qemu.System, ka config.Artifact,
|
||||||
res *phasesResult, remoteTest string) (err error) {
|
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 {
|
switch ka.Type {
|
||||||
case config.KernelModule:
|
case config.KernelModule:
|
||||||
res.Run.Output, err = q.CopyAndInsmod(res.BuildArtifact)
|
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
|
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)
|
res.Test.Output, err = testKernelModule(q, ka, remoteTest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error().Err(err).Msg(res.Test.Output)
|
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.Run.Ok = true // does not really used
|
||||||
res.Test.Ok = true
|
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:
|
default:
|
||||||
slog.Fatal().Msg("Unsupported artifact type")
|
slog.Fatal().Msg("Unsupported artifact type")
|
||||||
}
|
}
|
||||||
@ -568,7 +591,10 @@ func testArtifact(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact,
|
|||||||
result := phasesResult{}
|
result := phasesResult{}
|
||||||
defer dumpResult(q, ka, ki, &result, dist, tag, binaryPath, db)
|
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
|
// TODO: build should return structure
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
result.BuildDir, result.BuildArtifact, result.Build.Output, err =
|
result.BuildDir, result.BuildArtifact, result.Build.Output, err =
|
||||||
|
Loading…
Reference in New Issue
Block a user