Skip to content

Instantly share code, notes, and snippets.

@kidandcat
Last active September 19, 2018 11:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kidandcat/ea22fa356fcdbcf0ae14925643b6d671 to your computer and use it in GitHub Desktop.
Save kidandcat/ea22fa356fcdbcf0ae14925643b6d671 to your computer and use it in GitHub Desktop.
package main
import (
"bytes"
"context"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"strconv"
"strings"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/docker/docker/pkg/stdcopy"
"github.com/gliderlabs/ssh"
tb "gopkg.in/tucnak/telebot.v2"
)
const PORT = 22
var tuser *tb.User
var bot *tb.Bot
func main() {
k, err := ioutil.ReadFile("./key") // just pass the file name
if err != nil {
fmt.Println("cannot find key file")
panic(err)
}
key := string(k)
key = strings.TrimRight(key, "\r\n")
key = strings.Trim(key, " ")
ssh.Handle(func(sess ssh.Session) {
_, _, isTty := sess.Pty()
cfg := &container.Config{
Image: "ubuntu",
Cmd: sess.Command(),
Env: sess.Environ(),
Tty: isTty,
OpenStdin: true,
AttachStderr: true,
AttachStdin: true,
AttachStdout: true,
StdinOnce: true,
Volumes: make(map[string]struct{}),
}
status, cleanup, err := dockerRun(cfg, sess)
defer cleanup()
if err != nil {
fmt.Fprintln(sess, err)
log.Println(err)
}
sess.Exit(int(status))
})
// telegram bot
fmt.Println("bot key", ":"+key+":")
bot, err = tb.NewBot(tb.Settings{
Token: key,
Poller: &tb.LongPoller{Timeout: 10 * time.Second},
})
if err != nil {
fmt.Println("bot error")
log.Fatal(err)
return
}
bot.Handle(tb.OnText, func(m *tb.Message) {
tuser = m.Sender
h, _ := os.Hostname()
print("I'm " + h)
//bot.Send(m.Sender, "I'm "+h)
})
go bot.Start()
// server
log.Println("port " + strconv.Itoa(PORT) + " honeypotted")
log.Println("starting ssh server on port " + strconv.Itoa(PORT) + "...")
log.Fatal(ssh.ListenAndServe(":"+strconv.Itoa(PORT), nil))
}
func dockerRun(cfg *container.Config, sess ssh.Session) (status int64, cleanup func(), err error) {
docker, err := client.NewEnvClient()
if err != nil {
return 1, func() {}, err
}
status = 255
cleanup = func() {}
ctx := context.Background()
res, err := docker.ContainerCreate(ctx, cfg, nil, nil, "")
if err != nil {
return
}
cleanup = func() {
docker.ContainerRemove(ctx, res.ID, types.ContainerRemoveOptions{})
}
opts := types.ContainerAttachOptions{
Stdin: cfg.AttachStdin,
Stdout: cfg.AttachStdout,
Stderr: cfg.AttachStderr,
Stream: true,
}
stream, err := docker.ContainerAttach(ctx, res.ID, opts)
if err != nil {
return
}
cleanup = func() {
docker.ContainerRemove(ctx, res.ID, types.ContainerRemoveOptions{})
stream.Close()
}
outputErr := make(chan error)
var buf bytes.Buffer
tee := io.TeeReader(sess, &buf)
go func() {
buffer := ""
for {
line, _ := buf.ReadString('\r')
if line != "" {
if bytes.Compare([]byte(line), []byte{13}) == 0 {
print(sess.RemoteAddr().String() + "@" + buffer)
buffer = ""
} else {
buffer += line
}
}
}
}()
go func() {
var err error
if cfg.Tty {
_, err = io.Copy(sess, stream.Reader)
} else {
_, err = stdcopy.StdCopy(sess, sess.Stderr(), stream.Reader)
}
outputErr <- err
}()
go func() {
defer stream.CloseWrite()
io.Copy(stream.Conn, tee)
}()
err = docker.ContainerStart(ctx, res.ID, types.ContainerStartOptions{})
if err != nil {
return
}
if cfg.Tty {
_, winCh, _ := sess.Pty()
go func() {
for win := range winCh {
err := docker.ContainerResize(ctx, res.ID, types.ResizeOptions{
Height: uint(win.Height),
Width: uint(win.Width),
})
if err != nil {
log.Println(err)
break
}
}
}()
}
resultC, errC := docker.ContainerWait(ctx, res.ID, container.WaitConditionNotRunning)
select {
case err = <-errC:
return
case result := <-resultC:
status = result.StatusCode
}
err = <-outputErr
return
}
func print(text string) {
if tuser != nil {
bot.Send(tuser, text)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment