@@ -19,6 +19,8 @@ package filesystem
1919
2020import (
2121 "context"
22+ "fmt"
23+ "strconv"
2224 "time"
2325
2426 "github.com/bishopfox/sliver/client/console"
@@ -28,48 +30,113 @@ import (
2830 "google.golang.org/protobuf/proto"
2931)
3032
33+ const chtimesDefaultLayout = "2006-01-02 15:04:05"
34+
35+ type chtimesTimeFormat struct {
36+ name string
37+ parse func (string ) (int64 , error )
38+ }
39+
40+ func chtimesParseUnixSeconds (value string ) (int64 , error ) {
41+ parsed , err := strconv .ParseInt (value , 10 , 64 )
42+ if err != nil {
43+ return 0 , err
44+ }
45+ return parsed , nil
46+ }
47+
48+ func chtimesParseUnixMillis (value string ) (int64 , error ) {
49+ parsed , err := strconv .ParseInt (value , 10 , 64 )
50+ if err != nil {
51+ return 0 , err
52+ }
53+ return time .UnixMilli (parsed ).Unix (), nil
54+ }
55+
56+ func chtimesParseLayout (layout string ) func (string ) (int64 , error ) {
57+ return func (value string ) (int64 , error ) {
58+ parsed , err := time .Parse (layout , value )
59+ if err != nil {
60+ return 0 , err
61+ }
62+ return parsed .Unix (), nil
63+ }
64+ }
65+
66+ func chtimesFormatFromFlags (cmd * cobra.Command ) (chtimesTimeFormat , error ) {
67+ formatFlags := []struct {
68+ flag string
69+ format chtimesTimeFormat
70+ }{
71+ {flag : "unix" , format : chtimesTimeFormat {name : "unix" , parse : chtimesParseUnixSeconds }},
72+ {flag : "unix-ms" , format : chtimesTimeFormat {name : "unix-ms" , parse : chtimesParseUnixMillis }},
73+ {flag : "rfc3339" , format : chtimesTimeFormat {name : "rfc3339" , parse : chtimesParseLayout (time .RFC3339 )}},
74+ {flag : "rfc1123" , format : chtimesTimeFormat {name : "rfc1123" , parse : chtimesParseLayout (time .RFC1123 )}},
75+ }
76+
77+ var selected * chtimesTimeFormat
78+ selectedFlag := ""
79+ for _ , candidate := range formatFlags {
80+ enabled , _ := cmd .Flags ().GetBool (candidate .flag )
81+ if ! enabled {
82+ continue
83+ }
84+ if selected != nil {
85+ return chtimesTimeFormat {}, fmt .Errorf ("only one time format flag can be used (--%s and --%s are both set)" , selectedFlag , candidate .flag )
86+ }
87+ selected = & candidate .format
88+ selectedFlag = candidate .flag
89+ }
90+
91+ if selected == nil {
92+ return chtimesTimeFormat {name : "datetime" , parse : chtimesParseLayout (chtimesDefaultLayout )}, nil
93+ }
94+
95+ return * selected , nil
96+ }
97+
3198// ChtimesCmd - Change the access and modified time of a file on the remote file system.
3299func ChtimesCmd (cmd * cobra.Command , con * console.SliverClient , args []string ) {
33100 session , beacon := con .ActiveTarget .GetInteractive ()
34101 if session == nil && beacon == nil {
35102 return
36103 }
37- // DateTime layout (https://pkg.go.dev/time)
38- layout := "2006-01-02 15:04:05"
39104 filePath := args [0 ]
40105
41106 if filePath == "" {
42107 con .PrintErrorf ("Missing parameter: file or directory name\n " )
43108 return
44109 }
45110
46- atime := args [1 ]
111+ format , err := chtimesFormatFromFlags (cmd )
112+ if err != nil {
113+ con .PrintErrorf ("%s\n " , err )
114+ return
115+ }
47116
117+ atime := args [1 ]
48118 if atime == "" {
49119 con .PrintErrorf ("Missing parameter: Last accessed time id\n " )
50120 return
51121 }
52122
53- t_a , err := time . Parse ( layout , atime )
123+ unixAtime , err := format . parse ( atime )
54124 if err != nil {
55- con .PrintErrorf ("%s \n " , err )
125+ con .PrintErrorf ("Invalid access time (%s): %s \n " , format . name , err )
56126 return
57127 }
58- unixAtime := t_a .Unix ()
59128
60129 mtime := args [2 ]
61-
62130 if mtime == "" {
63131 con .PrintErrorf ("Missing parameter: Last modified time id\n " )
64132 return
65133 }
66134
67- t_b , err := time . Parse ( layout , mtime )
135+ unixMtime , err := format . parse ( mtime )
68136 if err != nil {
69- con .PrintErrorf ("%s \n " , err )
137+ con .PrintErrorf ("Invalid modified time (%s): %s \n " , format . name , err )
70138 return
71139 }
72- unixMtime := t_b .Unix ()
73140
74141 chtimes , err := con .Rpc .Chtimes (context .Background (), & sliverpb.ChtimesReq {
75142 Request : con .ActiveTarget .Request (cmd ),
0 commit comments