├── img └── bot.png ├── release └── trsh ├── setup └── trsh.service ├── Dockerfile ├── LICENSE ├── install.sh ├── README.md └── trsh.go /img/bot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fnzv/trsh-go/HEAD/img/bot.png -------------------------------------------------------------------------------- /release/trsh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fnzv/trsh-go/HEAD/release/trsh -------------------------------------------------------------------------------- /setup/trsh.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=trshbot service 3 | After=network.target 4 | 5 | [Service] 6 | Type=simple 7 | User=root 8 | ExecStart=/usr/bin/trsh 9 | EnvironmentFile=/etc/trsh.env 10 | Restart=on-failure 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.13 2 | 3 | RUN mkdir -p /app 4 | 5 | WORKDIR /app 6 | 7 | RUN go get -u "gopkg.in/telegram-bot-api.v4" 8 | RUN apt update -y 9 | RUN apt install -y mtr dnsutils nmap net-tools 10 | 11 | ADD . /app 12 | 13 | RUN go build ./trsh.go 14 | 15 | CMD ["./trsh"] 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Sami 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | echo "############## Starting trsh setup ################" 2 | 3 | echo "Installing the last trsh-go binary release from github...." 4 | cp release/trsh /usr/bin/trsh 5 | 6 | echo "Installing requirements...jq" 7 | if [ -f /etc/redhat-release ]; then 8 | yum install jq -y 9 | fi 10 | 11 | if [ -f /etc/lsb-release ]; then 12 | apt-get install jq -y 13 | fi 14 | 15 | echo "Type your Telegram BOT Token, followed by [ENTER]:" 16 | 17 | read TGBOT_TOKEN 18 | 19 | echo "To find out your Telegram Chat ID send a message to the configured BOT and then confirm here with [ENTER]" 20 | read tmpvar 21 | 22 | chat_id=$(curl -ss https://api.telegram.org/bot$TGBOT_TOKEN/getUpdates | jq .result[0].message.from.id) 23 | 24 | 25 | if [ $chat_id != "null" ]; then 26 | echo "Your chat id is "$chat_id 27 | else 28 | echo "Chat id is null, enter manually your chat id or CTRL+Z this script and re-run after sending a message to the bot, [ENTER]:" 29 | read chat_id 30 | fi 31 | 32 | 33 | echo 'TGBOT_TOKEN="'$TGBOT_TOKEN'"' >> /etc/trsh.env 34 | echo 'TGBOT_CHATID="'$chat_id'"' >> /etc/trsh.env 35 | 36 | echo "Configuring trsh service.." 37 | cp setup/trsh.service /etc/systemd/system/trsh.service 38 | systemctl daemon-reload 39 | systemctl start trsh 40 | echo "Your Telegram bot is now ready to receive commands! Send /help for more information" 41 | 42 | 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## trsh-go 2 | 3 | Telegram Remote-Shell is a Golang script that let you comunicate with your Linux server using a Telegram Bot
4 | This repo is a re-make of my original Python script created a few years ago [here](https://github.com/fnzv/trsh) 5 | 6 | ----------------- 7 | ![](img/bot.png?raw=true) 8 |
9 | 10 | ------------------------------- 11 | ## Requirements 12 | - Linux OS (tested on Ubuntu 20.04 and Centos 7) 13 | - Telegram Bot created using @BotFather 14 | - Packages required: jq 15 | - (Optional packages used): nmap, dig, mtr, net-tools (netstat) 16 | 17 | ## Quick setup 18 | 19 | Before setup:
20 | 21 | * Chat with BotFather in order to create a Bot ( https://telegram.me/botfather ), just launch the command /newbot and get your Telegram Token.
22 | Open the bot chat and send some messages to activate the bot.
23 | 24 | * Launch this oneliner+script on your Linux system (where the bot will be running as a service):
25 | 26 | ``` 27 | git clone https://github.com/fnzv/trsh-go /home/trsh/ && cd /home/trsh/ && bash install.sh 28 | ``` 29 | 30 | ##### WARNING: this command will install the required/missing packages ( dnsutils, nmap, mtr, net-tools ) 31 | 32 | ##### NOTES: 33 | 34 | - You will be asked to insert your Telegram Bot Token acquired on the first step and then follow the quick installation wizard.
35 | 36 | - The script will gather your chat-id based on the last unread message you send to the bot on the first step.
37 | 38 | After you finished the installation the Golang script binary will run as a system service with systemd (trsh.service). 39 | 40 | ## Usage 41 | 42 | - /dig - Resolve the given domain, supports RR.. example /dig A google.com or /dig MX google.com 43 | - /mtr - Execute a mtr with a following report 44 | - /nmap - Execute a nmap -Pn -A 45 | - /curl - Execute a curl request 46 | - /whois - Whois lookup 47 | - /sysinfo - Display generic system information (disk usage, network & memory) 48 | - /sh - Execute a command with Bash.. example /sh cat namefile , /sh ps auxf | grep ssh 49 | 50 | ## Tests 51 | 52 | The following scripts are tested on Ubuntu 20.04 LTS, Centos 7 and marked as working. 53 | 54 | 55 | ## Run using docker 56 | 57 | Inside this repo you will find a prepared Docker image to build and use in order to run trsh-go: 58 | 59 | 1) Build the image: 60 | 61 | ``` 62 | docker build -t trsh . 63 | ``` 64 | 65 | 2) Run the docker image and specify your ENV vars (below an example): 66 | 67 | ``` 68 | docker run -d -e TGBOT_TOKEN="123456789:qwertyuiopasdfghjklzxcb" -e TGBOT_CHATID="12345678" trsh-go 69 | ``` 70 | 71 | 3) Chat with your Bot 72 | 73 | 74 | ## Contributors 75 | 76 | Feel free to open issues or contact me directly 77 | 78 | ## License 79 | 80 | Code distributed under MIT licence. 81 | 82 | -------------------------------------------------------------------------------- /trsh.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os" 6 | "strconv" 7 | "strings" 8 | "os/exec" 9 | "gopkg.in/telegram-bot-api.v4" 10 | 11 | ) 12 | // System dependencies if used: net-tools (netstat), mtr, nmap, dig 13 | 14 | // ENV variables required: TGBOT_TOKEN and TGBOT_CHATID 15 | 16 | // Global variables 17 | var clean_domain string 18 | var tgbot_token string 19 | var tgbot_chatid string 20 | var chat_id string 21 | 22 | func checkErr(err error) { 23 | if err != nil { 24 | log.Println("Error while running cmd",err ) 25 | } 26 | } 27 | 28 | func removeCharacters(input string, characters string) string { 29 | filter := func(r rune) rune { 30 | if strings.IndexRune(characters, r) < 0 { 31 | return r 32 | } 33 | return -1 34 | } 35 | 36 | return strings.Map(filter, input) 37 | 38 | } 39 | 40 | 41 | func exec_shell(command string) string { 42 | 43 | 44 | log.Println("/bin/bash -c",command) 45 | out, err := exec.Command("/bin/bash","-c",command).Output() 46 | checkErr(err) 47 | return string(out) 48 | } 49 | 50 | func main() { 51 | 52 | f, err := os.OpenFile("bot.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) 53 | if err != nil { 54 | log.Fatal(err) 55 | } 56 | defer f.Close() 57 | log.SetOutput(f) 58 | if os.Getenv("TGBOT_TOKEN") != "" && os.Getenv("TGBOT_CHATID") != "" { 59 | tgbot_token = os.Getenv("TGBOT_TOKEN") 60 | tgbot_chatid = os.Getenv("TGBOT_CHATID") 61 | } else { 62 | log.Println("Telegram env vars are not set... skipping notification") 63 | } 64 | bot, err := tgbotapi.NewBotAPI(tgbot_token) 65 | if err != nil { 66 | log.Panic(err) 67 | } 68 | //bot.Debug = true 69 | log.Printf("Authorized on account %s", bot.Self.UserName) 70 | 71 | u := tgbotapi.NewUpdate(0) 72 | u.Timeout = 60 73 | updates, err := bot.GetUpdatesChan(u) 74 | 75 | for update := range updates { 76 | if update.Message == nil { 77 | continue 78 | } 79 | // chat_id := update.Message.Chat.ID 80 | chat_id:= strconv.Itoa(int(update.Message.Chat.ID)) 81 | 82 | if strings.Contains(chat_id , tgbot_chatid) { 83 | 84 | log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text) 85 | if strings.Contains(update.Message.Text,"/sh") { 86 | 87 | cmd_raw:=update.Message.Text 88 | words := strings.Fields(cmd_raw) 89 | if len(words) == 1 { 90 | log.Println("Bot missing parameter") 91 | } 92 | if len(words) >= 2 { 93 | 94 | cmd_clean:= strings.Replace(cmd_raw, "/sh", "", 1) 95 | log.Println("Rimmed cmd ",cmd_clean) 96 | output:=exec_shell(cmd_clean) 97 | msg := tgbotapi.NewMessage(update.Message.Chat.ID, output) 98 | bot.Send(msg) 99 | } 100 | 101 | } 102 | 103 | if strings.Contains(update.Message.Text,"/sysinfo") { 104 | 105 | output:=exec_shell("df -h && free -m && netstat -tunlp") 106 | msg := tgbotapi.NewMessage(update.Message.Chat.ID, output) 107 | bot.Send(msg) 108 | 109 | 110 | } 111 | if strings.Contains(update.Message.Text,"/dig") { 112 | 113 | cmd_raw:=update.Message.Text 114 | 115 | words:= strings.Fields(cmd_raw) 116 | 117 | if len(words) == 2 { 118 | 119 | 120 | cmd_clean:= words[1] 121 | 122 | output:=exec_shell("dig +short "+cmd_clean) 123 | msg := tgbotapi.NewMessage(update.Message.Chat.ID, output) 124 | bot.Send(msg) 125 | 126 | } 127 | } 128 | 129 | if strings.Contains(update.Message.Text,"/nmap") { 130 | cmd_raw:=update.Message.Text 131 | 132 | words := strings.Fields(cmd_raw) 133 | 134 | if len(words) == 2 { 135 | 136 | 137 | cmd_clean:= words[1] 138 | 139 | output:=exec_shell("nmap -Pn -A "+cmd_clean) 140 | msg := tgbotapi.NewMessage(update.Message.Chat.ID, output) 141 | bot.Send(msg) 142 | 143 | } 144 | } 145 | 146 | if strings.Contains(update.Message.Text,"/whois") { 147 | cmd_raw:=update.Message.Text 148 | 149 | words := strings.Fields(cmd_raw) 150 | 151 | if len(words) == 2 { 152 | 153 | 154 | cmd_clean:= words[1] 155 | 156 | output:=exec_shell("whois "+cmd_clean) 157 | msg := tgbotapi.NewMessage(update.Message.Chat.ID, output) 158 | bot.Send(msg) 159 | 160 | } 161 | } 162 | 163 | if strings.Contains(update.Message.Text,"/curl") { 164 | cmd_raw:=update.Message.Text 165 | 166 | words := strings.Fields(cmd_raw) 167 | 168 | if len(words) == 2 { 169 | 170 | 171 | cmd_clean:=words[1] 172 | 173 | output:=exec_shell("curl "+cmd_clean) 174 | msg := tgbotapi.NewMessage(update.Message.Chat.ID, output) 175 | bot.Send(msg) 176 | 177 | } 178 | } 179 | 180 | 181 | if update.Message.Text == "/help" { 182 | msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Usage: \n /sh - Executes a command on the shell of the remote system \n/sysinfo - Display generic troubleshoot system information (disk usage, network, memory)\n/dig - Resolve the given domain, supports RR.. example /dig A google.com or /dig MX google.com\n /mtr - prints reachability report to a specific hosts using the tool MTR\n /nmap - runs the command NMAP \n /curl executes a curl request and shows status code") 183 | 184 | bot.Send(msg) 185 | 186 | 187 | } 188 | 189 | } 190 | 191 | } // for range updates 192 | 193 | 194 | 195 | } //main 196 | --------------------------------------------------------------------------------