Skip to content

Commit

Permalink
Merge pull request #118 from rmaksimov/misc-changes
Browse files Browse the repository at this point in the history
Misc changes
  • Loading branch information
staaldraad authored May 3, 2020
2 parents 9d5b041 + bc7fa08 commit a832fd8
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 30 deletions.
7 changes: 7 additions & 0 deletions autodiscover/autodiscover.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,16 @@ func GetRPCHTTP(email, autoURLPtr string, resp *utils.AutodiscoverResp) (*utils.
if resp.Response.Account.MicrosoftOnline == true {
lindex := strings.LastIndex(resp.Response.Account.Protocol[0].MailStore.ExternalUrl, "=")
user = resp.Response.Account.Protocol[0].MailStore.ExternalUrl[lindex+1:]
if user == "" {
return nil, "", "", "", false, fmt.Errorf("The user is undefined")
}

url = "https://outlook.office365.com"
}

return nil, "", "", "", false, fmt.Errorf("The user is undefined")
}

RPCURL := fmt.Sprintf("%s/rpc/rpcproxy.dll?%s:6001", url, user)

utils.Trace.Printf("RPC URL set: %s\n", RPCURL)
Expand Down
11 changes: 9 additions & 2 deletions mapi/mapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,16 @@ func sendMapiRequest(mapi ExecuteRequest) (*ExecuteResponse, error) {
var err error
if AuthSession.Transport == HTTP { //this is always going to be an "Execute" request
if rawResp, err = mapiRequestHTTP(AuthSession.URL.String(), "Execute", mapi.Marshal()); err != nil {
utils.Debug.Printf("%s\n", hex.Dump(rawResp))
if rawResp != nil {
utils.Debug.Printf("%s\n", hex.Dump(rawResp))
}
return nil, err
}
} else {
if rawResp, err = mapiRequestRPC(mapi); err != nil {
utils.Debug.Printf("%s\n", hex.Dump(rawResp))
if rawResp != nil {
utils.Debug.Printf("%s\n", hex.Dump(rawResp))
}
return nil, err
}
}
Expand Down Expand Up @@ -371,6 +375,9 @@ func specialFolders(folderResponse []byte) {
func readResponse(headers http.Header, body []byte) ([]byte, error) {
//check to see that the response code was 0, which indicates protocol success
if headers.Get("X-ResponseCode") != "0" {
if headers.Get("X-ResponseCode") == "10" {
utils.Error.Println("This is a server-side issue. See details at https://github.com/sensepost/ruler/issues/75")
}
return nil, fmt.Errorf("Got a protocol error response: %s", headers.Get("X-ResponseCode"))
}
//We need to parse out the body to get rid of the meta-tags and additional headers (if any)
Expand Down
11 changes: 4 additions & 7 deletions rpc-http/rpctransport.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,17 +172,17 @@ func setupHTTP(rpctype string, URL string, ntlmAuth bool, full bool) (net.Conn,
}

//RPCOpen opens HTTP for RPC_IN_DATA and RPC_OUT_DATA
func RPCOpen(URL string, readySignal chan bool, errOccurred chan error) (err error) {
func RPCOpen(URL string, readySignal chan bool, errOccurred chan error) {
//I'm so damn frustrated at not being able to use the http client here
//can't find a way to keep the write channel open (other than going over to http/2, which isn't valid here)
//so this is some damn messy code, but screw it

var err error
rpcInConn, err = setupHTTP("RPC_IN_DATA", URL, AuthSession.RPCNtlm, true)

if err != nil {
readySignal <- false
errOccurred <- err
return err
}

//open the RPC_OUT_DATA channel, receive a "ready" signal when this is setup
Expand All @@ -195,7 +195,6 @@ func RPCOpen(URL string, readySignal chan bool, errOccurred chan error) (err err
readySignal <- true
} else {
readySignal <- false
return err
}
case <-time.After(time.Second * 5): // call timed out
readySignal <- true
Expand All @@ -212,19 +211,18 @@ func RPCOpen(URL string, readySignal chan bool, errOccurred chan error) (err err
break
}
}
return nil
}

//RPCOpenOut function opens the RPC_OUT_DATA channel
//starts our listening "loop" which scans for new responses and pushes
//these to our list of recieved responses
func RPCOpenOut(URL string, readySignal chan<- bool, errOccurred chan<- error) (err error) {
func RPCOpenOut(URL string, readySignal chan<- bool, errOccurred chan<- error) {

var err error
rpcOutConn, err = setupHTTP("RPC_OUT_DATA", URL, AuthSession.RPCNtlm, true)
if err != nil {
readySignal <- false
errOccurred <- err
return err
}

scanner := bufio.NewScanner(rpcOutConn)
Expand Down Expand Up @@ -260,7 +258,6 @@ func RPCOpenOut(URL string, readySignal chan<- bool, errOccurred chan<- error) (
}
}

return nil
}

//RPCBind function establishes our session
Expand Down
40 changes: 19 additions & 21 deletions ruler.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ func exit(err error) {

//function to perform an autodiscover
func discover(c *cli.Context) error {

if c.GlobalString("domain") == "" {
return fmt.Errorf("Required param --domain is missing")
}
Expand Down Expand Up @@ -112,7 +111,6 @@ func discover(c *cli.Context) error {

//var resp *utils.AutodiscoverResp
var domain string

if c.Bool("mapi") == true {
_, domain, err = autodiscover.MAPIDiscover(url)
} else {
Expand Down Expand Up @@ -183,6 +181,7 @@ func brute(c *cli.Context) error {
} else {
autodiscover.UserPassBruteForce()
}

return nil
}

Expand All @@ -196,7 +195,6 @@ func addRule(c *cli.Context) error {
}

utils.Info.Println("Rule Added. Fetching list of rules...")

printRules()

if c.Bool("send") {
Expand Down Expand Up @@ -270,13 +268,13 @@ func deleteRule(c *cli.Context) error {
func displayRules(c *cli.Context) error {
utils.Info.Println("Retrieving Rules")
er := printRules()

return er
}

//sendMessage sends a message to the user, using their own Account
//uses supplied subject and body
func sendMessage(subject, body string) error {

propertyTags := make([]mapi.PropertyTag, 1)
propertyTags[0] = mapi.PidTagDisplayName

Expand All @@ -296,6 +294,7 @@ func sendMessage(subject, body string) error {
//Function to connect to the Exchange server
func connect(c *cli.Context) error {
var err error

//if no password or hash was supplied, read from stdin
if c.GlobalString("password") == "" && c.GlobalString("hash") == "" && c.GlobalString("config") == "" {
fmt.Printf("Password: ")
Expand All @@ -312,6 +311,7 @@ func connect(c *cli.Context) error {
return fmt.Errorf("Invalid hash provided. Hex decode failed")
}
}

//setup our autodiscover service
config.Domain = c.GlobalString("domain")
config.User = c.GlobalString("username")
Expand Down Expand Up @@ -371,14 +371,13 @@ func connect(c *cli.Context) error {

autodiscover.SessionConfig = &config

//try connect to MAPI/HTTP first -- this is faster and the code-base is more stable
//unless of course the global "RPC" flag has been set, which specifies we should just use
//RPC/HTTP from the get-go
var resp *utils.AutodiscoverResp
var rawAutodiscover string

var mapiURL, abkURL, userDN string

//try connect to MAPI/HTTP first -- this is faster and the code-base is more stable
//unless of course the global "RPC" flag has been set, which specifies we should just use
//RPC/HTTP from the get-go
if c.GlobalString("config") != "" {
var yamlConfig utils.YamlConfig
if yamlConfig, err = utils.ReadYml(c.GlobalString("config")); err != nil {
Expand Down Expand Up @@ -425,10 +424,9 @@ func connect(c *cli.Context) error {
} else {
mapiURL = fmt.Sprintf("%s?MailboxId=%s", yamlConfig.MapiURL, yamlConfig.Mailbox)
}
userDN = yamlConfig.UserDN

userDN = yamlConfig.UserDN
} else if !c.GlobalBool("rpc") {

if config.User == "" && config.Email == "" {
return fmt.Errorf("Missing username and/or email argument. Use --domain (if needed), --username and --email or the --config")
}
Expand Down Expand Up @@ -465,7 +463,6 @@ func connect(c *cli.Context) error {
autodiscover.CreateCache(config.Email, rawAutodiscover) //store the autodiscover for future use
}
} else {

utils.Trace.Println("MAPI URL found: ", mapiURL)
utils.Trace.Println("MAPI AddressBook URL found: ", abkURL)

Expand All @@ -474,9 +471,7 @@ func connect(c *cli.Context) error {
autodiscover.CreateCache(config.Email, rawAutodiscover) //store the autodiscover for future use
}
}

} else {

if config.User == "" && config.Email == "" {
return fmt.Errorf("Missing username and/or email argument. Use --domain (if needed), --username and --email or the --config")
}
Expand Down Expand Up @@ -519,6 +514,7 @@ func connect(c *cli.Context) error {
propertyTags[1] = mapi.PidTagSubfolders
mapi.GetFolder(mapi.INBOX, propertyTags) //Open Inbox
}

return nil
}

Expand All @@ -530,7 +526,6 @@ func printRules() error {
//cols[2] = mapi.PidTagRuleActions

rows, er := mapi.FetchRules(cols)

if er != nil {
return er
}
Expand Down Expand Up @@ -573,8 +568,9 @@ func printRules() error {
}
utils.Info.Println()
} else {
utils.Info.Printf("No Rules Found\n")
utils.Info.Println("No Rules Found")
}

return nil
}

Expand Down Expand Up @@ -621,6 +617,7 @@ func abkList(c *cli.Context) error {
}
}
}

return nil
}

Expand Down Expand Up @@ -667,6 +664,7 @@ func abkDump(c *cli.Context) error {
}
}
}

return nil
}

Expand Down Expand Up @@ -768,6 +766,7 @@ func triggerForm(c *cli.Context) error {
return err
}
utils.Info.Println("Email sent! Hopefully you will have a shell soon.")

return nil
}

Expand All @@ -790,6 +789,7 @@ func displayForms(c *cli.Context) error {
utils.Error.Println("Failed to find any forms.")
return err
}

return nil
}

Expand Down Expand Up @@ -844,6 +844,7 @@ func displayHomePage() error {
utils.Info.Println("Webview is set as ENABLED")
}
}

return e
}

Expand Down Expand Up @@ -891,7 +892,6 @@ func deleteHomePage() error {
}

func searchFolders(c *cli.Context) error {

utils.Info.Println("Checking if a search folder exists")

searchFolderName := "searcher"
Expand Down Expand Up @@ -990,7 +990,6 @@ func searchFolders(c *cli.Context) error {
}

func checkFolder(folderName string) ([]byte, error) {

var folderID []byte
propertyTags := make([]mapi.PropertyTag, 2)
propertyTags[0] = mapi.PidTagDisplayName
Expand Down Expand Up @@ -1190,7 +1189,7 @@ A tool by @_staaldraad from @sensepost to abuse Exchange Services.`
Usage: "If you need to use an upstream proxy. Works with https://user:pass@ip:port or https://ip:port",
},
cli.StringFlag{
Name: "useragent",
Name: "useragent,ua",
Value: "ruler",
Usage: "Custom User-Agent string",
},
Expand Down Expand Up @@ -1225,7 +1224,7 @@ A tool by @_staaldraad from @sensepost to abuse Exchange Services.`
},
cli.BoolFlag{
Name: "verbose",
Usage: "Be verbose and show some of thei inner workings",
Usage: "Be verbose and show some of the inner workings",
},
cli.BoolFlag{
Name: "debug",
Expand Down Expand Up @@ -1762,7 +1761,7 @@ A tool by @_staaldraad from @sensepost to abuse Exchange Services.`
},
Action: func(c *cli.Context) error {
if c.String("term") == "" {
return cli.NewExitError("You need to supply a valid search term. Use --term ", 1)
return cli.NewExitError("You need to supply a valid search term. Use --term", 1)
}
err := connect(c)
if err != nil {
Expand All @@ -1782,5 +1781,4 @@ A tool by @_staaldraad from @sensepost to abuse Exchange Services.`
}

app.Run(os.Args)

}

0 comments on commit a832fd8

Please sign in to comment.