[
  {
    "path": ".dockerignore",
    "content": "/web\n.gitignore\nREADME.md\nbuild.sh\n"
  },
  {
    "path": ".gitignore",
    "content": ".idea\nintheshell\nweb_deploy.sh\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM golang:1.19-buster as builder\n\nWORKDIR /src\n\nCOPY intheshell.go /src/\n\nRUN go build intheshell.go\n\nFROM ubuntu:18.04\n\nRUN apt-get update && apt-get install -y openssh-server && \\\n    mkdir /var/run/sshd && chmod -x /etc/update-motd.d/* && \\\n    useradd -m -s /usr/local/bin/intheshell ghost && \\\n    /etc/init.d/ssh stop && \\\n    sed -ri 's/ghost:(!)?:/ghost:U6aMy0wojraho:/' /etc/shadow && \\\n    sed -ri 's/#Port 22/Port 22222/' /etc/ssh/sshd_config &&\\\n    sed -ri 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config &&\\\n    sed -ri 's/#PermitEmptyPasswords no/PermitEmptyPasswords yes/' /etc/ssh/sshd_config &&\\\n    sed -ri 's@Subsystem sftp /usr/lib/openssh/sftp-server@@' /etc/ssh/sshd_config && \\\n    sed -ri 's/X11Forwarding no/X11Forwarding yes/' /etc/ssh/sshd_config && \\\n    echo \"AllowUsers ghost\" >> /etc/ssh/sshd_config && \\\n    echo \"AllowTcpForwarding no\" >> /etc/ssh/sshd_config && \\\n    sed 's@session\\s*required\\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd && \\\n    apt-get remove -y && apt-get autoclean -y\n\nEXPOSE 22222\n\nCOPY --from=builder /src/intheshell /usr/local/bin/\n\nCMD [\"/usr/sbin/sshd\", \"-D\"]\n"
  },
  {
    "path": "README.md",
    "content": "##### [UPD] 2018-12-01\nIt's a Docker time :)\n\nJust use command\n```sh\ndocker run -d --restart always --name intheshell -p 22:22222 es1n/intheshell\n```\n\nto run latest Docker image, boo! :ghost:\n\nDon't forget, that image will bind 22 port (ssh), so change your host machine port to something else, 2222 for example\n\n\n\n\n#### [Deprecated] Installation instruction\nUpload _intheshell_ into /usr/local/bin/\n\nCreate user *ghost*\n```sh\nuseradd -m -s /usr/local/bin/intheshell ghost\n```\nRemove password for _ghost_\n```sh\nsed -ri s/ghost:(!)?:/ghost:U6aMy0wojraho:/g /etc/shadow\n```\nAllow empty password in sshd and add allowed users (file /etc/ssh/sshd_config)\nand some security changes\n```sh\n..........\nPermitEmptyPasswords yes\nPasswordAuthentication yes\n..........\nAllowUsers ghost\n\n### Disable Subsystem\n#Subsystem sftp /usr/lib/openssh/sftp-server\n### X11 Forwarding\nX11Forwarding no\n\n# Adding chroot\nMatch User ghost\n    ChrootDirectory /chroot/ghost\n    AllowTcpForwarding no\n..........\n```\n\nAdding chroot for user ghost\n```sh\ndir=/chroot/ghost\nmkdir -p $dir\nmkdir -p $dir/{dev,lib64,lib,bin,etc}\nmkdir -p $dir/usr/local/bin\nmknod -m 666 $dir/dev/null c 1 3\nmknod -m 666 $dir/dev/tty c 5 0\nmknod -m 666 $dir/dev/zero c 1 5\nmknod -m 666 $dir/dev/random c 1 8\nchown root:root $dir\nchmod 0755 $dir\nmkdir -p $dir/lib/x86_64-linux-gnu/\ncp -v /lib/x86_64-linux-gnu/{libncurses.so.5,libtinfo.so.5,libdl.so.2,libc.so.6} $dir/lib/\ncp -v /lib64/ld-linux-x86-64.so.2 $dir/lib64/\ncat /etc/passwd | grep ghost > $dir/etc/passwd\ntouch $dir/etc/group\ncp -av /bin/stty $dir/bin\ncp -av /usr/local/bin/intheshell $dir/bin\ncp -av /usr/local/bin/intheshell $dir/usr/local/bin\n```\n\nDisable motd and other stuff on ssh login (not so beautyfull)\n```sh\nchmod -x /etc/update-motd.d/*\n```\n\nThen restart sshd\n```sh\n/etc/init.d/ssh restart\n```\n"
  },
  {
    "path": "build.sh",
    "content": "#!/bin/bash\n\ndt=$(date +%y%m%d%H%M)\ndocker build --load -t es1n/intheshell:latest -t es1n/intheshell:$dt -f Dockerfile .\nif [ $? -ne 0 ]; then\n  exit 1;\nfi\n\ndocker push es1n/intheshell:$dt\n\ndocker push es1n/intheshell:latest\n\nexit 0\n"
  },
  {
    "path": "go.mod",
    "content": "module theshell.xyz/ghost\n\ngo 1.19\n"
  },
  {
    "path": "intheshell.go",
    "content": "package main\n\nimport (\n\t\"os\"\n\t\"os/exec\"\n\t\"os/signal\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n)\n\n// Constants\nconst (\n\tOneMSec   = 1000 * 1000       // One milliseond\n\tOneSec    = 1000 * 1000 * 100 // One second\n\tTextSpeed = 50                // Text showing speed\n)\n\nvar abortOp bool\n\n// Return Ghost and his height\nfunc getGhost() string {\n\tghost := ps1str() + \" \\n\" +\n\t\tps1str() + Bold(\"    ___\\n\") +\n\t\tps1str() + Bold(\"  _/ @@\\\\\\n\") +\n\t\tps1str() + Bold(\" ( \\\\  0/__\\n\") +\n\t\tps1str() + Bold(\"  \\\\    \\\\__)\\n\") +\n\t\tps1str() + Bold(\"  /     \\\\\\n\") +\n\t\tps1str() + Bold(\" /       \\\\\\n\") +\n\t\tps1str() + Bold(\" ^^^^^^^^^\\n\") +\n\t\tps1str()\n\treturn ghost\n}\n\n// Show text from black to white\nfunc textShowSlow(inString string) {\n\tfor i := 232; i <= 255; i++ {\n\t\tif abortOp {\n\t\t\tbreak\n\t\t}\n\t\tos.Stdout.Write([]byte(\"\\033[38;5;\" + strconv.Itoa(i) + \"m\" + Bold(inString) + \"\\033[0m\\r\"))\n\t\ttime.Sleep(OneMSec * TextSpeed)\n\t\tos.Stdout.Sync()\n\t}\n}\n\n// Show text from white to black\nfunc textHideSlow(inString string) {\n\tfor i := 255; i >= 232; i-- {\n\t\tif abortOp {\n\t\t\tbreak\n\t\t}\n\t\tos.Stdout.Write([]byte(\"\\033[38;5;\" + strconv.Itoa(i) + \"m\" + Bold(inString) + \"\\033[0m\\r\"))\n\t\ttime.Sleep(OneMSec * TextSpeed)\n\t\tos.Stdout.Sync()\n\t}\n\n}\n\n// Clearing screen\nfunc clearScreen() {\n\tos.Stdout.Write([]byte(\"\\033[H\\033[2J\"))\n\tos.Stdout.Sync()\n}\n\n// Bold text\nfunc Bold(inString string) string {\n\treturn \"\\033[1m\" + inString + \"\\033[0m\"\n}\n\n// Creating PS1\nfunc ps1str() string {\n\treturn \"ghost@shell:~$ \"\n}\n\n// Show creds on exit\nfunc showCreds() {\n\tos.Stdout.Write([]byte(\"\\n\\n\"))\n\tos.Stdout.Write([]byte(centrifyText(\"Created\")))\n\tos.Stdout.Write([]byte(\"\\n\"))\n\tos.Stdout.Write([]byte(centrifyText(\" by\")))\n\tos.Stdout.Write([]byte(\"\\n\\n\"))\n\tos.Stdout.Write([]byte(Bold(centrifyText(\"Andrey Esin\"))))\n\tos.Stdout.Write([]byte(\"\\n\\n\"))\n\tos.Stdout.Write([]byte(centrifyText(\"[ https://hubzil.la/profile/andrey ] [ t.me/la_stik ] [ andrey@esin.email ]\")))\n\tos.Stdout.Write([]byte(\"\\n\\n\"))\n\tos.Stdout.Write([]byte(Bold(centrifyText(\"Sources\"))))\n\tos.Stdout.Write([]byte(\"\\n\"))\n\tos.Stdout.Write([]byte(centrifyText(\"[ github.com/esin/intheshell ]\")))\n\tos.Stdout.Write([]byte(\"\\n\"))\n\n\tos.Stdout.Sync()\n\n\ttime.Sleep(time.Second * 3)\n}\n\n// Get terminal count\nfunc getTTYSize() (int, int) {\n\tcmd := exec.Command(\"stty\", \"size\")\n\tcmd.Stdin = os.Stdin\n\tout, err := cmd.Output()\n\t//println(string(out))\n\tif err != nil {\n\t\t//log.Fatal(err)\n\t\tappExit()\n\t}\n\toutStr := strings.Replace(string(out), \"\\n\", \"\", -1)\n\tcols, err := strconv.Atoi(strings.Split(outStr, \" \")[1])\n\tif err != nil {\n\t\t//log.Fatal(err)\n\t\tappExit()\n\t}\n\trows, err := strconv.Atoi(strings.Split(outStr, \" \")[0])\n\tif err != nil {\n\t\t//log.Fatal(err)\n\t\tappExit()\n\t}\n\treturn cols, rows\n}\n\n// Return string, which can be showed in horizontal center of terminal\nfunc centrifyText(inText string) string {\n\tcols, _ := getTTYSize()\n\tresultString := \"\"\n\tspacesCount := (cols / 2) - (len(inText) / 2)\n\tfor i := 0; i < spacesCount; i++ {\n\t\tresultString = resultString + \" \"\n\t}\n\tresultString = resultString + inText\n\treturn resultString\n}\n\n// Right exiting from application\nfunc appExit() {\n\tabortOp = true\n\tclearScreen()\n\tshowCreds()\n\tos.Stdout.Write([]byte(\"\\033[?25h\"))\n\tos.Exit(0)\n}\n\nfunc centerVertical() string {\n\t_, rows := getTTYSize()\n\n\tresultString := \"\\n\"\n\tfor i := 0; i < rows/2; i++ {\n\t\tresultString += \"\\n\"\n\t}\n\treturn resultString\n}\n\nfunc main() {\n\t// Catch ctrl-c\n\tc := make(chan os.Signal)\n\tsignal.Notify(c, os.Interrupt, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)\n\tgo func() {\n\t\t<-c\n\t\tappExit()\n\t}()\n\n\t// 2 minutes enough to see the \"movie\"\n\tgo func() {\n\t\ttime.Sleep(time.Second * 120)\n\t\tappExit()\n\t}()\n\n\tabortOp = false\n\n\t// Don't allow using scp, ssh with params and similar\n\targs := os.Args\n\tif len(args) > 1 {\n\t\tos.Stdout.Write([]byte(\"Hey, just try:\" + Bold(\" ssh ghost@theshell.xyz\")))\n\t\tos.Stdout.Write([]byte(\"\\n\"))\n\t\tos.Stdout.Write([]byte(\"\\033[?25h\"))\n\t\tos.Exit(0)\n\t}\n\n\tclearScreen()\n\n\t// Hide cursor\n\tos.Stdout.Write([]byte(\"\\033[?25l\"))\n\n\t//1 scene\n\t//Andrey Esin\n\tos.Stdout.Write([]byte(centerVertical()))\n\ttextShowSlow(centrifyText(\"Andrey Esin\"))\n\ttime.Sleep(OneSec * 5)\n\ttextHideSlow(centrifyText(\"Andrey Esin\"))\n\ttime.Sleep(OneSec * 1)\n\tclearScreen()\n\t// 2 scene\n\t// PRESENTS\n\tos.Stdout.Write([]byte(centerVertical()))\n\ttextShowSlow(centrifyText(\"PRESENTS\"))\n\ttime.Sleep(OneSec * 5)\n\ttextHideSlow(centrifyText(\"PRESENTS\"))\n\ttime.Sleep(OneSec * 1)\n\tclearScreen()\n\n\t// 3 scene\n\t// GHOST IN THE SHELL (bash)\n\tos.Stdout.Write([]byte(centerVertical()))\n\ttextShowSlow(centrifyText(\"GHOST IN THE SHELL (bash)\"))\n\ttime.Sleep(OneSec * 5)\n\ttextHideSlow(centrifyText(\"GHOST IN THE SHELL (bash)\"))\n\ttime.Sleep(OneSec * 1)\n\tclearScreen()\n\n\tcols, _ := getTTYSize()\n\tghost := getGhost()\n\tspaces := \" \"\n\tfor i := 0; i < cols-15-len(ps1str()); i++ {\n\t\tclearScreen()\n\t\tspaces += \" \"\n\n\t\tresult := strings.Replace(ghost, ps1str(), ps1str()+spaces, -1)\n\t\t//println(result)\n\t\tos.Stdout.Write([]byte(result))\n\t\ttime.Sleep(OneMSec * 50)\n\t\tos.Stdout.Sync()\n\t}\n\n\tclearScreen()\n\n\t//GHOST IN THE SHELL (bash)\n\tos.Stdout.Write([]byte(centerVertical()))\n\ttextShowSlow(centrifyText(\"THE END\"))\n\ttime.Sleep(OneSec * 5)\n\ttextHideSlow(centrifyText(\"THE END\"))\n\ttime.Sleep(OneSec * 1)\n\n\tappExit()\n}\n"
  },
  {
    "path": "web/index.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n  <meta charset=\"UTF-8\">\n\n  <style type=\"text/css\">\n    body {\n      background-color: rgba(255, 255, 255, 1);\n    }\n\n    #footer {\n      position: absolute;\n      bottom: 0;\n      width: 100%;\n      height: 60px;\n      /* Height of the footer */\n      background: #6cf;\n      font-family: 'Rubik', sans-serif;\n    }\n  </style>\n  <link href=\"https://fonts.googleapis.com/css?family=Roboto:500|Rubik\" rel=\"stylesheet\">\n  <title>GHOST IN THE SHELL | remake</title>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1,\n      maximum-scale=2.2\" viewport=\"\">\n\n  <!-- Matomo -->\n  <script>\n    var _paq = window._paq = window._paq || [];\n    /* tracker methods like \"setCustomDimension\" should be called before \"trackPageView\" */\n    _paq.push(['trackPageView']);\n    _paq.push(['enableLinkTracking']);\n    (function () {\n      var u = \"//analytics.esin.name/\";\n      _paq.push(['setTrackerUrl', u + 'matomo.php']);\n      _paq.push(['setSiteId', '3']);\n      var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];\n      g.async = true; g.src = u + 'matomo.js'; s.parentNode.insertBefore(g, s);\n    })();\n  </script>\n  <!-- End Matomo Code -->\n</head>\n\n<body>\n\n  <div id=\"wrapper\" style=\"text-align: center\">\n\n    <div style=\"font-family: 'Rubik', sans-serif;\">\n      <font size=\"5\">GHOST IN THE SHELL</font>\n      <br>\n      <font size=\"4\">remake</font>\n      <br><br><br>\n      <font size=\"3\">open your terminal and type:</font>\n      <br><br>\n      <div style=\"font-family: 'Source Code Pro', monospace;\">\n\n        <font size=\"3\">ssh ghost@theshell.xyz</font>\n      </div>\n      <font size=\"1\">*user ghost has an empty password</font>\n    </div>\n  </div>\n\n</body>\n<footer>\n  Made with <span style=\"color: #e25555;\">&#9829;</span> by <a href=\"https://andrey.es\">Andrey Esin</a>\n</footer>\n\n</html>"
  }
]