From fd22be622380f841b8428e19f37815437b478f96 Mon Sep 17 00:00:00 2001 From: Tristan Granier Date: Sat, 27 Apr 2019 19:46:59 +0200 Subject: [PATCH 1/6] update: operative framework reborn --- config/config.go | 1 + config/parse.go | 5 + engine/command.go | 23 ++++ .../module_base/session_help/session_help.go | 1 + modules/modules.go | 2 + modules/twitter/twitter_followers.go | 115 ++++++++++++++++++ session/session_readline.go | 1 + 7 files changed, 148 insertions(+) create mode 100644 modules/twitter/twitter_followers.go diff --git a/config/config.go b/config/config.go index 1844d72..5a06e32 100644 --- a/config/config.go +++ b/config/config.go @@ -5,6 +5,7 @@ type Config struct{ Database DataBase Common Common Instagram Network + Twitter Network } type Network struct{ diff --git a/config/parse.go b/config/parse.go index 008974d..33f6bb5 100644 --- a/config/parse.go +++ b/config/parse.go @@ -17,6 +17,11 @@ func ParseConfig() (Config, error){ conf.Instagram.Login = os.Getenv("INSTAGRAM_LOGIN") conf.Instagram.Password = os.Getenv("INSTAGRAM_PASSWORD") + conf.Twitter.Api.Key = os.Getenv("TWITTER_CONSUMER_SECRET") + conf.Twitter.Login = os.Getenv("TWITTER_CONSUMER") + conf.Twitter.Password = os.Getenv("TWITTER_ACCESS_TOKEN") + conf.Twitter.Api.SKey = os.Getenv("TWITTER_ACCESS_TOKEN_SECRET") + conf.Api.Host = os.Getenv("API_HOST") conf.Api.Port = os.Getenv("API_PORT") conf.Api.Verbose = os.Getenv("API_VERBOSE") diff --git a/engine/command.go b/engine/command.go index d7a9f50..1815b4d 100644 --- a/engine/command.go +++ b/engine/command.go @@ -5,6 +5,7 @@ import ( "github.com/graniet/go-pretty/table" "github.com/graniet/operative-framework/api" "github.com/graniet/operative-framework/session" + "github.com/joho/godotenv" "github.com/labstack/gommon/color" "os" ) @@ -16,10 +17,32 @@ func CommandBase(line string, s *session.Session) bool{ } else if line== "info api"{ ViewApiInformation(s) return true + } else if line == "env"{ + viewEnvironment(s) + return true } return false } +func viewEnvironment(s *session.Session){ + t := s.Stream.GenerateTable() + t.SetOutputMirror(os.Stdout) + t.AppendHeader(table.Row{ + "Name", + "Value", + }) + mp, err := godotenv.Read(".env") + if err == nil{ + for name, value := range mp{ + t.AppendRow(table.Row{ + name, + value, + }) + } + } + s.Stream.Render(t) +} + func ViewInformation(s *session.Session){ t := s.Stream.GenerateTable() t.SetOutputMirror(os.Stdout) diff --git a/modules/module_base/session_help/session_help.go b/modules/module_base/session_help/session_help.go index 72756da..f6b57bc 100644 --- a/modules/module_base/session_help/session_help.go +++ b/modules/module_base/session_help/session_help.go @@ -56,6 +56,7 @@ func (module *HelpModule) Start(){ t.AppendRows([]table.Row{ {"info session", "Print current session information"}, {"info api", "Print api rest endpoints information"}, + {"env", "Print environment variable"}, {"help", "Print help information"}, {"api ", "(Run/Stop) restful API"}, }) diff --git a/modules/modules.go b/modules/modules.go index 90c8c8d..98b8bae 100644 --- a/modules/modules.go +++ b/modules/modules.go @@ -9,6 +9,7 @@ import ( "github.com/graniet/operative-framework/modules/module_base/session_help" "github.com/graniet/operative-framework/modules/module_base/session_stream" "github.com/graniet/operative-framework/modules/phone_generator" + "github.com/graniet/operative-framework/modules/twitter" "github.com/graniet/operative-framework/modules/viewdns_search" "github.com/graniet/operative-framework/modules/whatsapp" "github.com/graniet/operative-framework/session" @@ -25,6 +26,7 @@ func LoadModules(s *session.Session){ s.Modules = append(s.Modules, phone_generator.PushPhoneGeneratorModule(s)) s.Modules = append(s.Modules, whatsapp.PushWhatsappExtractorModule(s)) s.Modules = append(s.Modules, instagram.PushInstagramFollowersModule(s)) + s.Modules = append(s.Modules, twitter.PushTwitterFollowerModule(s)) for _, mod := range s.Modules{ mod.CreateNewParam("FILTER", "Use module filter after execution", "",false, session.STRING) diff --git a/modules/twitter/twitter_followers.go b/modules/twitter/twitter_followers.go new file mode 100644 index 0000000..398641d --- /dev/null +++ b/modules/twitter/twitter_followers.go @@ -0,0 +1,115 @@ +package twitter + +import ( + "github.com/ChimeraCoder/anaconda" + "github.com/graniet/go-pretty/table" + "github.com/graniet/operative-framework/session" + "net/url" + "os" + "strconv" +) +type TwitterFollower struct{ + session.SessionModule + Sess *session.Session +} + +func PushTwitterFollowerModule(s *session.Session) *TwitterFollower{ + mod := TwitterFollower{ + Sess: s, + } + + mod.CreateNewParam("TARGET", "TWITTER USER SCREEN NAME", "", true, session.STRING) + return &mod +} + +func (module *TwitterFollower) Name() string{ + return "twitter_followers" +} + +func (module *TwitterFollower) Description() string{ + return "Get followers for target user twitter account" +} + +func (module *TwitterFollower) Author() string{ + return "Tristan Granier" +} + +func (module *TwitterFollower) GetType() string{ + return "twitter" +} + +func (module *TwitterFollower) GetInformation() session.ModuleInformation{ + information := session.ModuleInformation{ + Name: module.Name(), + Description: module.Description(), + Author: module.Author(), + Type: module.GetType(), + Parameters: module.Parameters, + } + return information +} + +func (module *TwitterFollower) Start(){ + + var followerIds []int64 + + trg, err := module.GetParameter("TARGET") + if err != nil{ + module.Sess.Stream.Error(err.Error()) + return + } + + target, err := module.Sess.GetTarget(trg.Value) + if err != nil{ + module.Sess.Stream.Error(err.Error()) + return + } + + + api := anaconda.NewTwitterApiWithCredentials(module.Sess.Config.Twitter.Password, module.Sess.Config.Twitter.Api.SKey, module.Sess.Config.Twitter.Login, module.Sess.Config.Twitter.Api.Key) + v := url.Values{} + user, err := api.GetUserSearch(target.Name, v) + if err != nil{ + module.Sess.Stream.Error(err.Error()) + return + } + followers, err := api.GetFollowersUser(user[0].Id, v) + if err != nil{ + module.Sess.Stream.Error(err.Error()) + return + } + if followers.Next_cursor_str == "0"{ + for _, ids := range followers.Ids{ + followerIds = append(followerIds, ids) + } + } + for followers.Next_cursor_str != "0"{ + for _, ids := range followers.Ids{ + followerIds = append(followerIds, ids) + } + v.Set("cursor", followers.Next_cursor_str) + followers, err = api.GetFollowersUser(user[0].Id, v) + if err != nil{ + module.Sess.Stream.Error(err.Error()) + break + } + } + + t := module.Sess.Stream.GenerateTable() + t.SetOutputMirror(os.Stdout) + t.AppendHeader(table.Row{ + "Twitter ID", + }) + separator := target.GetSeparator() + for _, ids := range followerIds{ + t.AppendRow(table.Row{ + ids, + }) + result := session.TargetResults{ + Header: "Twitter ID" + separator, + Value: strconv.Itoa(int(ids)) + separator, + } + target.Save(module, result) + } + module.Sess.Stream.Render(t) +} \ No newline at end of file diff --git a/session/session_readline.go b/session/session_readline.go index 6007abc..9fa4f13 100644 --- a/session/session_readline.go +++ b/session/session_readline.go @@ -119,6 +119,7 @@ func (s *Session) PushPrompt(){ readline.PcItem("run"), ), readline.PcItem("help"), + readline.PcItem("env"), readline.PcItem("info", readline.PcItem("session"), readline.PcItem("api")), From 9aea0ff556f15e45077936f93c50779beb9cfdde Mon Sep 17 00:00:00 2001 From: Tristan Granier Date: Sun, 28 Apr 2019 13:07:36 +0200 Subject: [PATCH 2/6] update: operative framework reborn --- engine/command.go | 3 + main.go | 1 + modules/diagram/diagram.go | 61 ++++++++ .../module_base/session_help/session_help.go | 1 + modules/modules.go | 2 + modules/twitter/twitter_followers.go | 2 +- modules/twitter/twitter_tweet.go | 130 ++++++++++++++++++ session/session.go | 19 +-- session/session_readline.go | 20 ++- session/session_target.go | 17 ++- 10 files changed, 244 insertions(+), 12 deletions(-) create mode 100644 modules/diagram/diagram.go create mode 100644 modules/twitter/twitter_tweet.go diff --git a/engine/command.go b/engine/command.go index 1815b4d..929ea20 100644 --- a/engine/command.go +++ b/engine/command.go @@ -20,6 +20,9 @@ func CommandBase(line string, s *session.Session) bool{ } else if line == "env"{ viewEnvironment(s) return true + } else if line == "clear"{ + s.ClearScreen() + return true } return false } diff --git a/main.go b/main.go index 2adb8b4..a5c93c1 100644 --- a/main.go +++ b/main.go @@ -104,6 +104,7 @@ func main(){ line = strings.TrimSpace(line) if line == "api run"{ + sess.Stream.Success("API Rest as been started at http://" + sess.Config.Api.Host + ":" + sess.Config.Api.Port) go apiRest.Start() sess.Information.SetApi(true) } else if line == "api stop"{ diff --git a/modules/diagram/diagram.go b/modules/diagram/diagram.go new file mode 100644 index 0000000..32d836f --- /dev/null +++ b/modules/diagram/diagram.go @@ -0,0 +1,61 @@ +package diagram + +import ( + "fmt" + "github.com/awalterschulze/gographviz" + "github.com/graniet/operative-framework/session" +) + +type DiagramModule struct{ + session.SessionModule + sess *session.Session + Stream *session.Stream +} + +func PushDiagramModuleRetrieval(s *session.Session) *DiagramModule{ + mod := DiagramModule{ + sess: s, + Stream: &s.Stream, + } + return &mod +} + +func (module *DiagramModule) Name() string{ + return "diagram" +} + +func (module *DiagramModule) Author() string{ + return "Tristan Granier" +} + +func (module *DiagramModule) Description() string{ + return "Generate a diagram of project" +} + +func (module *DiagramModule) GetType() string{ + return "" +} + +func (module *DiagramModule) GetInformation() session.ModuleInformation{ + information := session.ModuleInformation{ + Name: module.Name(), + Description: module.Description(), + Author: module.Author(), + Type: module.GetType(), + Parameters: module.Parameters, + } + return information +} + +func (module *DiagramModule) Start(){ + graphAst, _ := gographviz.ParseString(`digraph Project {}`) + graph := gographviz.NewGraph() + if err := gographviz.Analyse(graphAst, graph); err != nil { + panic(err) + } + _ = graph.AddNode("Project", "a", nil) + _ = graph.AddNode("Project", "b", nil) + _ = graph.AddEdge("a", "b", true, nil) + output := graph.String() + fmt.Println(output) +} diff --git a/modules/module_base/session_help/session_help.go b/modules/module_base/session_help/session_help.go index f6b57bc..304153d 100644 --- a/modules/module_base/session_help/session_help.go +++ b/modules/module_base/session_help/session_help.go @@ -58,6 +58,7 @@ func (module *HelpModule) Start(){ {"info api", "Print api rest endpoints information"}, {"env", "Print environment variable"}, {"help", "Print help information"}, + {"clear", "Clear current screen"}, {"api ", "(Run/Stop) restful API"}, }) module.sess.Stream.Render(t) diff --git a/modules/modules.go b/modules/modules.go index 98b8bae..9000459 100644 --- a/modules/modules.go +++ b/modules/modules.go @@ -27,8 +27,10 @@ func LoadModules(s *session.Session){ s.Modules = append(s.Modules, whatsapp.PushWhatsappExtractorModule(s)) s.Modules = append(s.Modules, instagram.PushInstagramFollowersModule(s)) s.Modules = append(s.Modules, twitter.PushTwitterFollowerModule(s)) + s.Modules = append(s.Modules, twitter.PushTwitterRetweetModule(s)) for _, mod := range s.Modules{ + s.PushType(mod.GetType()) mod.CreateNewParam("FILTER", "Use module filter after execution", "",false, session.STRING) } } diff --git a/modules/twitter/twitter_followers.go b/modules/twitter/twitter_followers.go index 398641d..93c35fb 100644 --- a/modules/twitter/twitter_followers.go +++ b/modules/twitter/twitter_followers.go @@ -27,7 +27,7 @@ func (module *TwitterFollower) Name() string{ } func (module *TwitterFollower) Description() string{ - return "Get followers for target user twitter account" + return "Get followers from target user twitter account" } func (module *TwitterFollower) Author() string{ diff --git a/modules/twitter/twitter_tweet.go b/modules/twitter/twitter_tweet.go new file mode 100644 index 0000000..0390acb --- /dev/null +++ b/modules/twitter/twitter_tweet.go @@ -0,0 +1,130 @@ +package twitter + +import ( + "github.com/ChimeraCoder/anaconda" + "github.com/graniet/go-pretty/table" + "github.com/graniet/operative-framework/session" + "net/url" + "os" + "strings" +) + +type TwitterRetweet struct{ + session.SessionModule + Sess *session.Session +} + +func PushTwitterRetweetModule(s *session.Session) *TwitterRetweet{ + mod := TwitterRetweet{ + Sess: s, + } + + mod.CreateNewParam("TARGET", "TWITTER USER SCREEN NAME", "", true, session.STRING) + mod.CreateNewParam("WITHRETWEET", "Include RT ?", "true", false, session.STRING) + mod.CreateNewParam("COUNT", "Number of tweets", "100", false, session.STRING) + return &mod +} + +func (module *TwitterRetweet) Name() string{ + return "twitter_tweets" +} + +func (module *TwitterRetweet) Description() string{ + return "Get (re)tweets from target user twitter account" +} + +func (module *TwitterRetweet) Author() string{ + return "Tristan Granier" +} + +func (module *TwitterRetweet) GetType() string{ + return "twitter" +} + +func (module *TwitterRetweet) GetInformation() session.ModuleInformation{ + information := session.ModuleInformation{ + Name: module.Name(), + Description: module.Description(), + Author: module.Author(), + Type: module.GetType(), + Parameters: module.Parameters, + } + return information +} + +func (module *TwitterRetweet) Start(){ + + trg, err := module.GetParameter("TARGET") + if err != nil{ + module.Sess.Stream.Error(err.Error()) + return + } + + target, err := module.Sess.GetTarget(trg.Value) + if err != nil{ + module.Sess.Stream.Error(err.Error()) + return + } + + argumentRT, err := module.GetParameter("WITHRETWEET") + if err != nil{ + module.Sess.Stream.Error(err.Error()) + return + } + + if argumentRT.Value != "false" && argumentRT.Value != "true"{ + module.Sess.Stream.Error("Please set correct value for 'WithRetweet' argument.") + return + } + + argumentCount, err := module.GetParameter("COUNT") + if err != nil{ + module.Sess.Stream.Error(err.Error()) + return + } + + + api := anaconda.NewTwitterApiWithCredentials(module.Sess.Config.Twitter.Password, module.Sess.Config.Twitter.Api.SKey, module.Sess.Config.Twitter.Login, module.Sess.Config.Twitter.Api.Key) + v := url.Values{} + user, err := api.GetUserSearch(target.Name, v) + if err != nil{ + module.Sess.Stream.Error(err.Error()) + return + } + u := user[0] + v.Set("screen_name", u.ScreenName) + v.Set("include_rts", argumentRT.Value) + v.Set("count", argumentCount.Value) + retweets, err := api.GetUserTimeline(v) + + t := module.Sess.Stream.GenerateTable() + t.SetOutputMirror(os.Stdout) + t.AppendHeader(table.Row{ + "text", + "Date", + }) + t.SetAllowedColumnLengths([]int{40, 0,}) + separator := target.GetSeparator() + for _, tweet := range retweets{ + var text string + if strings.Contains(tweet.Text, "RT @"){ + text = strings.TrimSpace(strings.Split(tweet.FullText, ":")[1]) + t := text[:len(text) - 3] + text = t + } else{ + text = strings.TrimSpace(tweet.FullText) + } + t.AppendRow(table.Row{ + text, + tweet.CreatedAt, + }) + + result := session.TargetResults{ + Header: "Text" + separator, + Value: text + separator, + } + target.Save(module, result) + } + module.Sess.Stream.Render(t) + +} \ No newline at end of file diff --git a/session/session.go b/session/session.go index 8f994b9..7847632 100644 --- a/session/session.go +++ b/session/session.go @@ -18,6 +18,7 @@ type Session struct{ Filters []ModuleFilter `json:"filters" sql:"-"` Prompt *readline.Config `json:"-" sql:"-"` Stream Stream `json:"-" sql:"-"` + TypeLists []string `json:"type_lists" sql:"-"` } type Information struct{ @@ -51,14 +52,14 @@ func (s *Session) GetId() int{ } func (s *Session) ListType() []string{ - return []string{ - "enterprise", - "ip_address", - "email", - "website", - "url", - "person", - "instagram", - "twitter", + return s.TypeLists +} + +func (s *Session) PushType(t string){ + for _, tp := range s.TypeLists{ + if tp == t{ + return + } } + s.TypeLists = append(s.TypeLists, t) } diff --git a/session/session_readline.go b/session/session_readline.go index 9fa4f13..dbeff63 100644 --- a/session/session_readline.go +++ b/session/session_readline.go @@ -4,9 +4,26 @@ import ( "github.com/chzyer/readline" "github.com/graniet/go-pretty/table" "os" + "os/exec" + "runtime" "strings" ) +func (s *Session) ClearScreen(){ + switch runtime.GOOS { + case "linux", "darwin", "freebsd", "dragonfly", "netbsd", "openbsd", "solaris": + cmd := exec.Command("clear") + cmd.Stdout = os.Stdout + cmd.Run() + case "windows": + cmd := exec.Command("cls") + cmd.Stdout = os.Stdout + cmd.Run() + default: + // do nothing + } +} + func (s *Session) ReadLineAutoCompleteType() func(string) []string{ return func(line string) []string{ return s.ListType() @@ -205,7 +222,7 @@ func (s *Session) ParseCommand(line string){ t := s.Stream.GenerateTable() t.SetOutputMirror(os.Stdout) - t.SetAllowedColumnLengths([]int{0, 30, 30, 30}) + t.SetAllowedColumnLengths([]int{40, 30, 30, 30}) headerRow := table.Row{} for _, result := range results{ resRow := table.Row{} @@ -242,6 +259,7 @@ func (s *Session) ParseCommand(line string){ } t := s.Stream.GenerateTable() t.SetOutputMirror(os.Stdout) + t.SetAllowedColumnLengths([]int{40, 30, 30, 30}) separator := trg.GetSeparator() header := strings.Split(result.Header, separator) res := strings.Split(result.Value, separator) diff --git a/session/session_target.go b/session/session_target.go index 3648a7a..ec97d29 100644 --- a/session/session_target.go +++ b/session/session_target.go @@ -113,7 +113,22 @@ func (s *Session) FindLinked(m string, res TargetResults) ([]string, error){ targetId := t.GetId() for _, targetRes := range t.Results[m]{ if res.Header == targetRes.Header && res.Value == targetRes.Value{ - targets = append(targets, targetId) + if len(targetRes.Value) > 5 { + targets = append(targets, targetId) + } + } else{ + valueParsed := strings.Replace(res.Value,t.GetSeparator(), "", -1) + targetResParsed := strings.Replace(targetRes.Value,t.GetSeparator(), "", -1) + + if res.Header == targetRes.Header && strings.Contains(valueParsed, targetResParsed){ + if len(targetResParsed) > 5 && len(valueParsed) > 5{ + targets = append(targets, targetId) + } + } else if res.Header == targetRes.Header && strings.Contains(targetResParsed, valueParsed){ + if len(targetResParsed) > 5 && len(valueParsed) > 5{ + targets = append(targets, targetId) + } + } } } } From eba1935bbebaf1b1484a4cfd3060398568975b5d Mon Sep 17 00:00:00 2001 From: Tristan Granier Date: Sun, 28 Apr 2019 13:41:38 +0200 Subject: [PATCH 3/6] update: operative framework reborn --- main.go | 24 ++++++++++++++++++++++++ scripts/exemple.opf | 5 +++++ 2 files changed, 29 insertions(+) create mode 100644 scripts/exemple.opf diff --git a/main.go b/main.go index a5c93c1..206ad64 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "bufio" "fmt" "github.com/akamensky/argparse" "github.com/chzyer/readline" @@ -45,6 +46,11 @@ func main(){ Help: "Print help", }) + scripts := parser.String("f", "opf", &argparse.Options{ + Required: false, + Help: "Run script before prompt starting", + }) + err = parser.Parse(os.Args) if err != nil{ fmt.Print(parser.Usage(err)) @@ -83,6 +89,24 @@ func main(){ _, _ = c.Println("OPERATIVE FRAMEWORK - DIGITAL INVESTIGATION FRAMEWORK") } + if *scripts != ""{ + file, err := os.Open(*scripts) + defer file.Close() + + if err != nil { + fmt.Println(err.Error()) + return + } + + fscanner := bufio.NewScanner(file) + for fscanner.Scan() { + line := strings.TrimSpace(fscanner.Text()) + if !strings.Contains(line, "//"){ + sess.ParseCommand(line) + } + } + } + l, err := readline.NewEx(sess.Prompt) if err != nil { diff --git a/scripts/exemple.opf b/scripts/exemple.opf new file mode 100644 index 0000000..65c64ac --- /dev/null +++ b/scripts/exemple.opf @@ -0,0 +1,5 @@ +session_stream set VERBOSE false +session_stream run +target add twitter graniet75 +session_stream set VERBOSE true +session_stream run \ No newline at end of file From e2409dd22f171677069c03b5bd0534f3cd5d8884 Mon Sep 17 00:00:00 2001 From: Tristan Granier Date: Sun, 28 Apr 2019 13:46:00 +0200 Subject: [PATCH 4/6] update: operative framework reborn --- .env.example | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index 59ae5c2..2e2308f 100644 --- a/.env.example +++ b/.env.example @@ -10,5 +10,10 @@ DB_PASS= OPERATIVE_HISTORY="/tmp/operative_framework.tmp" -INSTAGRAM_LOGIN=Usern4m3 -INSTAGRAM_PASSWORD=P4ssw0rd \ No newline at end of file +INSTAGRAM_LOGIN= +INSTAGRAM_PASSWORD= + +TWITTER_CONSUMER= +TWITTER_CONSUMER_SECRET= +TWITTER_ACCESS_TOKEN= +TWITTER_ACCESS_TOKEN_SECRET= \ No newline at end of file From caf6e47082246e118a9511191ea1292907d746c2 Mon Sep 17 00:00:00 2001 From: Tristan Granier Date: Sun, 28 Apr 2019 15:00:44 +0200 Subject: [PATCH 5/6] update: operative framework reborn --- filters/filters.go | 2 + .../follower_to_screenname.go | 61 +++++++++++++++++++ modules/twitter/twitter_followers.go | 27 ++++++++ session/session_readline.go | 26 +++++++- 4 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 filters/follower_to_screenName/follower_to_screenname.go diff --git a/filters/filters.go b/filters/filters.go index 692bafb..11abfa5 100644 --- a/filters/filters.go +++ b/filters/filters.go @@ -1,6 +1,7 @@ package filters import ( + "github.com/graniet/operative-framework/filters/follower_to_screenName" "github.com/graniet/operative-framework/filters/phone_to_instagram" "github.com/graniet/operative-framework/filters/say_hello" "github.com/graniet/operative-framework/session" @@ -9,4 +10,5 @@ import ( func LoadFilters(s *session.Session){ s.Filters = append(s.Filters, say_hello.PushSayHelloFilter(s)) s.Filters = append(s.Filters, phone_to_instagram.PushPhoneToInstagramFilter(s)) + s.Filters = append(s.Filters, follower_to_screenName.PushFollowerScreenNameFilter(s)) } diff --git a/filters/follower_to_screenName/follower_to_screenname.go b/filters/follower_to_screenName/follower_to_screenname.go new file mode 100644 index 0000000..5a5aca7 --- /dev/null +++ b/filters/follower_to_screenName/follower_to_screenname.go @@ -0,0 +1,61 @@ +package follower_to_screenName + +import ( + "github.com/ChimeraCoder/anaconda" + "github.com/graniet/go-pretty/table" + "github.com/graniet/operative-framework/session" + "net/url" + "os" + "strconv" +) + +type FollowerScreenName struct{ + session.SessionFilter + Sess *session.Session +} + +func PushFollowerScreenNameFilter(s *session.Session) *FollowerScreenName{ + mod := FollowerScreenName{ + Sess: s, + } + mod.AddModule("twitter_followers") + return &mod +} + +func (filter *FollowerScreenName) Name() string{ + return "follower_to_screen" +} + +func (filter *FollowerScreenName) Description() string{ + return "Find screen name from twitter ID list" +} + +func (filter *FollowerScreenName) Author() string{ + return "Tristan Granier" +} + +func (filter *FollowerScreenName) Start(mod session.Module){ + api := anaconda.NewTwitterApiWithCredentials(filter.Sess.Config.Twitter.Password, filter.Sess.Config.Twitter.Api.SKey, filter.Sess.Config.Twitter.Login, filter.Sess.Config.Twitter.Api.Key) + v := url.Values{} + + t := filter.Sess.Stream.GenerateTable() + t.SetOutputMirror(os.Stdout) + t.AppendHeader(table.Row{ + "id", + "screen_name", + }) + for _, id := range mod.GetResults(){ + id64, err := strconv.ParseInt(id, 10, 64) + if err == nil { + user, errU := api.GetUsersShowById(id64,v) + if errU == nil{ + t.AppendRow(table.Row{ + id, + user.ScreenName, + + }) + } + } + } + filter.Sess.Stream.Render(t) +} diff --git a/modules/twitter/twitter_followers.go b/modules/twitter/twitter_followers.go index 93c35fb..e772882 100644 --- a/modules/twitter/twitter_followers.go +++ b/modules/twitter/twitter_followers.go @@ -1,6 +1,7 @@ package twitter import ( + "fmt" "github.com/ChimeraCoder/anaconda" "github.com/graniet/go-pretty/table" "github.com/graniet/operative-framework/session" @@ -19,6 +20,7 @@ func PushTwitterFollowerModule(s *session.Session) *TwitterFollower{ } mod.CreateNewParam("TARGET", "TWITTER USER SCREEN NAME", "", true, session.STRING) + mod.CreateNewParam("COUNT", "FOLLOWER LIMIT", "50", false, session.INT) return &mod } @@ -78,14 +80,38 @@ func (module *TwitterFollower) Start(){ module.Sess.Stream.Error(err.Error()) return } + + + argumentCount, errCount := module.GetParameter("COUNT") + if errCount != nil{ + module.Sess.Stream.Error("Count parameters as not listed.") + return + } + + maxCount, errConv := strconv.Atoi(argumentCount.Value) + if errConv != nil{ + module.Sess.Stream.Error("Error as occured with parameter 'COUNT'") + return + } + current := 0 if followers.Next_cursor_str == "0"{ + fmt.Println(current) for _, ids := range followers.Ids{ + if current >= maxCount{ + break + } followerIds = append(followerIds, ids) + current = current + 1 } } for followers.Next_cursor_str != "0"{ for _, ids := range followers.Ids{ + fmt.Println(current) + if current >= maxCount{ + break + } followerIds = append(followerIds, ids) + current = current + 1 } v.Set("cursor", followers.Next_cursor_str) followers, err = api.GetFollowersUser(user[0].Id, v) @@ -102,6 +128,7 @@ func (module *TwitterFollower) Start(){ }) separator := target.GetSeparator() for _, ids := range followerIds{ + module.Results = append(module.Results, strconv.Itoa(int(ids))) t.AppendRow(table.Row{ ids, }) diff --git a/session/session_readline.go b/session/session_readline.go index dbeff63..bb0e9ea 100644 --- a/session/session_readline.go +++ b/session/session_readline.go @@ -114,6 +114,9 @@ func (s *Session) PushPrompt(){ readline.PcItem("update", readline.PcItemDynamic(s.ReadLineAutoCompleteTargets())), readline.PcItem("list"), + readline.PcItem("link", + readline.PcItemDynamic(s.ReadLineAutoCompleteTargets(), + readline.PcItemDynamic(s.ReadLineAutoCompleteTargets()))), readline.PcItem("links", readline.PcItemDynamic(s.ReadLineAutoCompleteTargets())), readline.PcItem("modules",readline.PcItemDynamic(s.ReadLineAutoCompleteTargets())), @@ -184,10 +187,31 @@ func (s *Session) ParseCommand(line string){ s.Stream.Success("target '" + value[3] + "' as successfully added with id '"+id+"'") case "list": s.ListTargets() + case "link": + value := strings.SplitN(strings.TrimSpace(line), " ", 4) + if len(arguments) < 3{ + s.Stream.Error("Please use subject add ") + return + } + trg, err := s.GetTarget(value[2]) + if err != nil{ + s.Stream.Error(err.Error()) + return + } + trg2, err := s.GetTarget(value[3]) + if err != nil{ + s.Stream.Error(err.Error()) + return + } + trg.Link(Linking{ + TargetId: trg2.GetId(), + }) + s.Stream.Success("target '"+trg.GetId()+"' as linked to '"+trg2.GetId()+"'") + return case "links": value := strings.SplitN(strings.TrimSpace(line), " ", 3) if len(arguments) < 3{ - s.Stream.Error("Please use subject add ") + s.Stream.Error("Please use subject links ") return } trg, err := s.GetTarget(value[2]) From 05bf01e94ade5c7e78196d28c068741262daf511 Mon Sep 17 00:00:00 2001 From: Tristan Granier Date: Sun, 28 Apr 2019 15:05:21 +0200 Subject: [PATCH 6/6] update: operative framework reborn --- main.go | 25 +++++++++++++++++-------- scripts/exemple.opf | 8 ++++++++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/main.go b/main.go index 206ad64..83de931 100644 --- a/main.go +++ b/main.go @@ -5,11 +5,11 @@ import ( "fmt" "github.com/akamensky/argparse" "github.com/chzyer/readline" - "github.com/fatih/color" "github.com/graniet/operative-framework/api" "github.com/graniet/operative-framework/engine" "github.com/graniet/operative-framework/session" "github.com/joho/godotenv" + "github.com/fatih/color" "io" "os" "strings" @@ -51,6 +51,11 @@ func main(){ Help: "Run script before prompt starting", }) + quiet := parser.Flag("q", "quiet", &argparse.Options{ + Required: false, + Help: "Don't prompt operative shell", + }) + err = parser.Parse(os.Args) if err != nil{ fmt.Print(parser.Usage(err)) @@ -82,13 +87,6 @@ func main(){ } } - if *verbose{ - sess.Stream.Verbose = false - } else{ - c := color.New(color.FgYellow) - _, _ = c.Println("OPERATIVE FRAMEWORK - DIGITAL INVESTIGATION FRAMEWORK") - } - if *scripts != ""{ file, err := os.Open(*scripts) defer file.Close() @@ -107,6 +105,17 @@ func main(){ } } + if *quiet{ + return + } + + if *verbose{ + sess.Stream.Verbose = false + } else{ + c := color.New(color.FgYellow) + _, _ = c.Println("OPERATIVE FRAMEWORK - DIGITAL INVESTIGATION FRAMEWORK") + } + l, err := readline.NewEx(sess.Prompt) if err != nil { diff --git a/scripts/exemple.opf b/scripts/exemple.opf index 65c64ac..fd9371c 100644 --- a/scripts/exemple.opf +++ b/scripts/exemple.opf @@ -1,5 +1,13 @@ +// Disallow event text session_stream set VERBOSE false session_stream run + +// Add target to session target add twitter graniet75 + +// Running API +api run + +// Allow event text session_stream set VERBOSE true session_stream run \ No newline at end of file