1
0

10 Commity

12 zmienionych plików z 200 dodań i 72 usunięć

12
.github/workflows/macos.yml vendored Normal file
Wyświetl plik

@ -0,0 +1,12 @@
name: macOS
on: [push]
jobs:
build:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v1
- name: Build
run: go build

23
.github/workflows/ubuntu.yml vendored Normal file
Wyświetl plik

@ -0,0 +1,23 @@
name: Ubuntu
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Build
run: go build
- name: Install dependencies for tests
run: |
sudo apt-get update
sudo apt-get install qemu
- name: Bootstrap
run: ./tools/qemu-debian-img/bootstrap.sh
- name: Test
run: go test -parallel 1 -v ./...

Wyświetl plik

@ -4,6 +4,34 @@
[Semantic Versioning](https://semver.org/spec/v2.0.0.html). [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.2.0] 2019-11-15
### Added
- Flag for Verbose output. Right now only qemu status messages is
implemented.
### Fixed
- Kpti settings was not affected for regular runs.
## [1.1.2] 2019-09-05
### Added
- Added policykit-1 to rootfs for Ubuntu.
### Fixed
- Avoided slow mirrors with use of mirror://mirrors.ubuntu.com for
Ubuntu 16.04 and newer.
## [1.1.1] 2019-08-31
### Fixed
- macOS support.
## [1.1.0] 2019-08-30 ## [1.1.0] 2019-08-30
### Added ### Added

Wyświetl plik

@ -1,5 +1,5 @@
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/aba4aad2046b4d1a9a99cf98e22c018b)](https://app.codacy.com/app/jollheef/out-of-tree?utm_source=github.com&utm_medium=referral&utm_content=jollheef/out-of-tree&utm_campaign=Badge_Grade_Dashboard) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/aba4aad2046b4d1a9a99cf98e22c018b)](https://app.codacy.com/app/jollheef/out-of-tree?utm_source=github.com&utm_medium=referral&utm_content=jollheef/out-of-tree&utm_campaign=Badge_Grade_Dashboard)
[![Build Status](https://travis-ci.com/jollheef/out-of-tree.svg?branch=master)](https://travis-ci.org/jollheef/out-of-tree) [![Build Status](https://travis-ci.com/jollheef/out-of-tree.svg?branch=master)](https://travis-ci.com/jollheef/out-of-tree)
[![Go Report Card](https://goreportcard.com/badge/code.dumpstack.io/tools/out-of-tree)](https://goreportcard.com/report/code.dumpstack.io/tools/out-of-tree) [![Go Report Card](https://goreportcard.com/badge/code.dumpstack.io/tools/out-of-tree)](https://goreportcard.com/report/code.dumpstack.io/tools/out-of-tree)
[![Documentation Status](https://readthedocs.org/projects/out-of-tree/badge/?version=latest)](https://out-of-tree.readthedocs.io/en/latest/?badge=latest) [![Documentation Status](https://readthedocs.org/projects/out-of-tree/badge/?version=latest)](https://out-of-tree.readthedocs.io/en/latest/?badge=latest)
[![Donate](https://img.shields.io/badge/donate-paypal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=R8W2UQPZ5X5JE&source=url) [![Donate](https://img.shields.io/badge/donate-paypal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=R8W2UQPZ5X5JE&source=url)

Wyświetl plik

@ -19,7 +19,6 @@ import (
"time" "time"
"github.com/naoina/toml" "github.com/naoina/toml"
"github.com/zcalusic/sysinfo"
"code.dumpstack.io/tools/out-of-tree/config" "code.dumpstack.io/tools/out-of-tree/config"
) )
@ -163,6 +162,13 @@ func generateBaseDockerImage(registry string, commands []config.DockerCommand,
switch sk.DistroType { switch sk.DistroType {
case config.Ubuntu: case config.Ubuntu:
d += "ENV DEBIAN_FRONTEND=noninteractive\n" d += "ENV DEBIAN_FRONTEND=noninteractive\n"
if sk.DistroRelease >= "16.04" {
from := "http://.*ubuntu/"
to := "mirror://mirrors.ubuntu.com/mirrors.txt"
file := "/etc/apt/sources.list"
s := fmt.Sprintf("sed -i 's;%s;%s;' %s", from, to, file)
d += "RUN " + s + "\n"
}
d += "RUN apt-get update\n" d += "RUN apt-get update\n"
d += "RUN apt-get install -y build-essential libelf-dev\n" d += "RUN apt-get install -y build-essential libelf-dev\n"
d += "RUN apt-get install -y wget git\n" d += "RUN apt-get install -y wget git\n"
@ -419,66 +425,6 @@ func listDockerImages() (diis []dockerImageInfo, err error) {
return return
} }
func genHostKernels(download bool) (kcfg config.KernelConfig, err error) {
si := sysinfo.SysInfo{}
si.GetSysInfo()
distroType, err := config.NewDistroType(si.OS.Vendor)
if err != nil {
return
}
cmd := exec.Command("ls", "/lib/modules")
rawOutput, err := cmd.CombinedOutput()
if err != nil {
log.Println(string(rawOutput), err)
return
}
kernelsBase := "/boot/"
files, err := ioutil.ReadDir(kernelsBase)
if err != nil {
return
}
// only for compatibility, docker is not really used
dii := dockerImageInfo{
ContainerName: config.KernelMask{
DistroType: distroType,
DistroRelease: si.OS.Version,
}.DockerName(),
}
rootfs, err := genRootfsImage(dii, download)
if err != nil {
return
}
for _, k := range strings.Fields(string(rawOutput)) {
ki := config.KernelInfo{
DistroType: distroType,
DistroRelease: si.OS.Version,
KernelRelease: k,
KernelSource: "/lib/modules/" + k + "/build",
KernelPath: kernelsBase + genKernelPath(files, k),
InitrdPath: kernelsBase + genInitrdPath(files, k),
RootFS: rootfs,
}
vmlinux := "/usr/lib/debug/boot/vmlinux-" + k
log.Println("vmlinux", vmlinux)
if exists(vmlinux) {
ki.VmlinuxPath = vmlinux
}
kcfg.Kernels = append(kcfg.Kernels, ki)
}
return
}
func updateKernelsCfg(host, download bool) (err error) { func updateKernelsCfg(host, download bool) (err error) {
newkcfg := config.KernelConfig{} newkcfg := config.KernelConfig{}

77
kernel_linux.go Normal file
Wyświetl plik

@ -0,0 +1,77 @@
// Copyright 2018 Mikhail Klementev. All rights reserved.
// Use of this source code is governed by a AGPLv3 license
// (or later) that can be found in the LICENSE file.
// +build linux
package main
import (
"io/ioutil"
"log"
"os/exec"
"strings"
"code.dumpstack.io/tools/out-of-tree/config"
"github.com/zcalusic/sysinfo"
)
func genHostKernels(download bool) (kcfg config.KernelConfig, err error) {
si := sysinfo.SysInfo{}
si.GetSysInfo()
distroType, err := config.NewDistroType(si.OS.Vendor)
if err != nil {
return
}
cmd := exec.Command("ls", "/lib/modules")
rawOutput, err := cmd.CombinedOutput()
if err != nil {
log.Println(string(rawOutput), err)
return
}
kernelsBase := "/boot/"
files, err := ioutil.ReadDir(kernelsBase)
if err != nil {
return
}
// only for compatibility, docker is not really used
dii := dockerImageInfo{
ContainerName: config.KernelMask{
DistroType: distroType,
DistroRelease: si.OS.Version,
}.DockerName(),
}
rootfs, err := genRootfsImage(dii, download)
if err != nil {
return
}
for _, k := range strings.Fields(string(rawOutput)) {
ki := config.KernelInfo{
DistroType: distroType,
DistroRelease: si.OS.Version,
KernelRelease: k,
KernelSource: "/lib/modules/" + k + "/build",
KernelPath: kernelsBase + genKernelPath(files, k),
InitrdPath: kernelsBase + genInitrdPath(files, k),
RootFS: rootfs,
}
vmlinux := "/usr/lib/debug/boot/vmlinux-" + k
log.Println("vmlinux", vmlinux)
if exists(vmlinux) {
ki.VmlinuxPath = vmlinux
}
kcfg.Kernels = append(kcfg.Kernels, ki)
}
return
}

18
kernel_macos.go Normal file
Wyświetl plik

@ -0,0 +1,18 @@
// Copyright 2018 Mikhail Klementev. All rights reserved.
// Use of this source code is governed by a AGPLv3 license
// (or later) that can be found in the LICENSE file.
// +build darwin
package main
import (
"errors"
"code.dumpstack.io/tools/out-of-tree/config"
)
func genHostKernels(download bool) (kcfg config.KernelConfig, err error) {
err = errors.New("generate host kernels for macOS is not supported")
return
}

12
main.go
Wyświetl plik

@ -84,7 +84,7 @@ func main() {
) )
app.Author("Mikhail Klementev <root@dumpstack.io>") app.Author("Mikhail Klementev <root@dumpstack.io>")
app.Version("1.1.0") app.Version("1.1.2")
pathFlag := app.Flag("path", "Path to work directory") pathFlag := app.Flag("path", "Path to work directory")
path := pathFlag.Default(".").ExistingDir() path := pathFlag.Default(".").ExistingDir()
@ -155,6 +155,9 @@ func main() {
pewTagFlag := pewCommand.Flag("tag", "Log tagging") pewTagFlag := pewCommand.Flag("tag", "Log tagging")
pewTag := pewTagFlag.String() pewTag := pewTagFlag.String()
pewVerboseFlag := pewCommand.Flag("verbose", "Show more information")
pewVerbose := pewVerboseFlag.Bool()
kernelCommand := app.Command("kernel", "Manipulate kernels") kernelCommand := app.Command("kernel", "Manipulate kernels")
kernelNoDownload := kernelCommand.Flag("no-download", kernelNoDownload := kernelCommand.Flag("no-download",
"Do not download qemu image while kernel generation").Bool() "Do not download qemu image while kernel generation").Bool()
@ -264,6 +267,10 @@ func main() {
log.Fatalln("Only one of disable/enable can be used at once") log.Fatalln("Only one of disable/enable can be used at once")
} }
if *yekpti && *nokpti {
log.Fatalln("Only one of disable/enable can be used at once")
}
kcfg, err := config.ReadKernelConfig(*kcfgPath) kcfg, err := config.ReadKernelConfig(*kcfgPath)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
@ -299,7 +306,8 @@ func main() {
case pewCommand.FullCommand(): case pewCommand.FullCommand():
err = pewHandler(kcfg, *path, *pewKernel, *pewBinary, err = pewHandler(kcfg, *path, *pewKernel, *pewBinary,
*pewTest, *pewGuess, stop, *qemuTimeout, *dockerTimeout, *pewTest, *pewGuess, stop, *qemuTimeout, *dockerTimeout,
*pewMax, *pewRuns, *pewDist, *pewTag, *pewThreads, db) *pewMax, *pewRuns, *pewDist, *pewTag, *pewThreads,
db, *pewVerbose)
case kernelListCommand.FullCommand(): case kernelListCommand.FullCommand():
err = kernelListHandler(kcfg) err = kernelListHandler(kcfg)
case kernelAutogenCommand.FullCommand(): case kernelAutogenCommand.FullCommand():

Wyświetl plik

@ -51,7 +51,8 @@ func packHandler(db *sql.DB, path, registry string, stop time.Time,
pewHandler(kcfg, workPath, "", "", "", false, pewHandler(kcfg, workPath, "", "", "", false,
stop, dockerTimeout, qemuTimeout, stop, dockerTimeout, qemuTimeout,
kernelRuns, exploitRuns, pathDevNull, tag, threads, db) kernelRuns, exploitRuns, pathDevNull,
tag, threads, db, false)
} }
return return

23
pew.go
Wyświetl plik

@ -303,7 +303,7 @@ func copyTest(q *qemu.System, testPath string, ka config.Artifact) (
func whatever(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact, func whatever(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact,
ki config.KernelInfo, binaryPath, testPath string, ki config.KernelInfo, binaryPath, testPath string,
qemuTimeout, dockerTimeout time.Duration, dist, tag string, qemuTimeout, dockerTimeout time.Duration, dist, tag string,
db *sql.DB) { db *sql.DB, verbose bool) {
defer swg.Done() defer swg.Done()
@ -328,6 +328,7 @@ func whatever(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact,
q.SetKASLR(!ka.Mitigations.DisableKaslr) q.SetKASLR(!ka.Mitigations.DisableKaslr)
q.SetSMEP(!ka.Mitigations.DisableSmep) q.SetSMEP(!ka.Mitigations.DisableSmep)
q.SetSMAP(!ka.Mitigations.DisableSmap) q.SetSMAP(!ka.Mitigations.DisableSmap)
q.SetKPTI(!ka.Mitigations.DisableKpti)
err = q.Start() err = q.Start()
if err != nil { if err != nil {
@ -336,6 +337,18 @@ func whatever(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact,
} }
defer q.Stop() defer q.Stop()
if verbose {
go func() {
for !q.Died {
time.Sleep(time.Minute)
log.Println(ka.Name, ki.DistroType,
ki.DistroRelease, ki.KernelRelease,
"still alive")
}
}()
}
usr, err := user.Current() usr, err := user.Current()
if err != nil { if err != nil {
return return
@ -394,7 +407,7 @@ func performCI(ka config.Artifact, kcfg config.KernelConfig, binaryPath,
testPath string, stop time.Time, testPath string, stop time.Time,
qemuTimeout, dockerTimeout time.Duration, qemuTimeout, dockerTimeout time.Duration,
max, runs int64, dist, tag string, threads int, max, runs int64, dist, tag string, threads int,
db *sql.DB) (err error) { db *sql.DB, verbose bool) (err error) {
found := false found := false
@ -420,7 +433,7 @@ func performCI(ka config.Artifact, kcfg config.KernelConfig, binaryPath,
swg.Add() swg.Add()
go whatever(&swg, ka, kernel, binaryPath, go whatever(&swg, ka, kernel, binaryPath,
testPath, qemuTimeout, dockerTimeout, testPath, qemuTimeout, dockerTimeout,
dist, tag, db) dist, tag, db, verbose)
} }
} }
} }
@ -477,7 +490,7 @@ func pewHandler(kcfg config.KernelConfig,
workPath, ovrrdKrnl, binary, test string, guess bool, workPath, ovrrdKrnl, binary, test string, guess bool,
stop time.Time, qemuTimeout, dockerTimeout time.Duration, stop time.Time, qemuTimeout, dockerTimeout time.Duration,
max, runs int64, dist, tag string, threads int, max, runs int64, dist, tag string, threads int,
db *sql.DB) (err error) { db *sql.DB, verbose bool) (err error) {
ka, err := config.ReadArtifactConfig(workPath + "/.out-of-tree.toml") ka, err := config.ReadArtifactConfig(workPath + "/.out-of-tree.toml")
if err != nil { if err != nil {
@ -507,7 +520,7 @@ func pewHandler(kcfg config.KernelConfig,
err = performCI(ka, kcfg, binary, test, err = performCI(ka, kcfg, binary, test,
stop, qemuTimeout, dockerTimeout, stop, qemuTimeout, dockerTimeout,
max, runs, dist, tag, threads, db) max, runs, dist, tag, threads, db, verbose)
if err != nil { if err != nil {
return return
} }

Wyświetl plik

@ -25,7 +25,8 @@ ENV RELEASE=trusty
RUN mkdir $IMAGEDIR RUN mkdir $IMAGEDIR
# Must be executed with --privileged because of /dev/loop # Must be executed with --privileged because of /dev/loop
CMD debootstrap --include=openssh-server $RELEASE $TMPDIR $REPOSITORY && \ CMD debootstrap --include=openssh-server,policykit-1 \
$RELEASE $TMPDIR $REPOSITORY && \
/shared/setup.sh $TMPDIR && \ /shared/setup.sh $TMPDIR && \
qemu-img create $IMAGE 2G && \ qemu-img create $IMAGE 2G && \
mkfs.ext4 -F $IMAGE && \ mkfs.ext4 -F $IMAGE && \

Wyświetl plik

@ -26,7 +26,8 @@ ENV RELEASE=bionic
RUN mkdir $IMAGEDIR RUN mkdir $IMAGEDIR
# Must be executed with --privileged because of /dev/loop # Must be executed with --privileged because of /dev/loop
CMD debootstrap --include=openssh-server $RELEASE $TMPDIR $REPOSITORY && \ CMD debootstrap --include=openssh-server,policykit-1 \
$RELEASE $TMPDIR $REPOSITORY && \
/shared/setup.sh $TMPDIR && \ /shared/setup.sh $TMPDIR && \
qemu-img create $IMAGE 2G && \ qemu-img create $IMAGE 2G && \
mkfs.ext4 -F $IMAGE && \ mkfs.ext4 -F $IMAGE && \