├── 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 | 
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 |
--------------------------------------------------------------------------------