Skip to content

Commit

Permalink
Upgrade v0.15
Browse files Browse the repository at this point in the history
  • Loading branch information
j3ssie committed Nov 22, 2020
1 parent cbae89f commit d2eb9c4
Show file tree
Hide file tree
Showing 16 changed files with 538 additions and 22 deletions.
2 changes: 1 addition & 1 deletion cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ Mics Flags:
--title string HTML report title
--html string Enable generate HTML reports after the scan done
--hh string Full help message
--re Shortcut for disable replicate request (avoid sending many request to timeout)
--dr Shortcut for disable replicate request (avoid sending many timeout requests)
--at Enable Always True Detection for observe response
--lc Shortcut for '--proxy http://127.0.0.1:8080'
--ba Shortcut for take raw input as '{{.BaseURL}}'
Expand Down
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func init() {
RootCmd.PersistentFlags().IntVar(&options.ChunkLimit, "chunk-limit", 200000, "Limit size to trigger chunk run")
// some shortcuts
RootCmd.PersistentFlags().StringVarP(&options.InlineDetection, "inline", "I", "", "Inline Detections")
RootCmd.PersistentFlags().BoolVar(&options.Mics.DisableReplicate, "re", false, "Shortcut for disable replicate request (avoid sending many request to timeout)")
RootCmd.PersistentFlags().BoolVar(&options.Mics.DisableReplicate, "dr", false, "Shortcut for disable replicate request (avoid sending many request to timeout)")
RootCmd.PersistentFlags().BoolVar(&options.Mics.BaseRoot, "ba", false, "Shortcut for take raw input as {{.BaseURL}}'")
RootCmd.PersistentFlags().BoolVar(&options.Mics.BurpProxy, "lc", false, "Shortcut for '--proxy http://127.0.0.1:8080'")
RootCmd.PersistentFlags().BoolVar(&options.Mics.AlwaysTrue, "at", false, "Enable Always True Detection for observe response")
Expand Down
23 changes: 22 additions & 1 deletion cmd/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,21 @@ func runScan(cmd *cobra.Command, _ []string) error {
}

func CreateRunner(j interface{}) {
var jobs []libs.Job
job := j.(libs.Job)
jobs := []libs.Job{job}

// auto append http and https prefix if not present
if !strings.HasPrefix(job.URL, "http://") && !strings.HasPrefix(job.URL, "https://") {
withPrefixJob := job
job.URL = "http://" + job.URL
jobs = append(jobs, withPrefixJob)

withPrefixJob = job
job.URL = "https://" + job.URL
jobs = append(jobs, withPrefixJob)
} else {
jobs = append(jobs, job)
}

if (job.Sign.Replicate.Ports != "" || job.Sign.Replicate.Prefixes != "") && !options.Mics.DisableReplicate {
if options.Mics.BaseRoot {
Expand All @@ -159,6 +172,14 @@ func CreateRunner(j interface{}) {
}

for _, job := range jobs {
if job.Sign.Type == "routine" {
routine, err := core.InitRoutine(job.URL, job.Sign, options)
if err != nil {
utils.ErrorF("Error create new routine: %v", err)
}
routine.Start()
continue
}
runner, err := core.InitRunner(job.URL, job.Sign, options)
if err != nil {
utils.ErrorF("Error create new runner: %v", err)
Expand Down
11 changes: 10 additions & 1 deletion core/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ func (r *Record) Output() string {
if !r.IsVulnerable {
return ""
}

utils.InforF("[Found] %v", color.MagentaString(r.DetectString))

// do passive analyze if got called from detector
Expand Down Expand Up @@ -82,11 +81,21 @@ func (r *Record) Output() string {
Execution(r.Opt.FoundCmd)
}

//// do passive analyze if got called from detector
//if strings.Contains(strings.ToLower(r.DetectString), "invokesign") {
// r.InvokeSign()
// options.SignFolder/sign-name.yaml
//}

return "stop"
}

// StoreOutput store vulnerable request to a file
func (r *Record) StoreOutput() {
// disable out
if r.NoOutput {
return
}
// store output to a file
if r.Request.URL == "" {
r.Request.URL = r.Request.Target["URL"]
Expand Down
6 changes: 5 additions & 1 deletion core/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"io/ioutil"
"net/http"
"net/url"
"path"
"path/filepath"
"strings"

Expand All @@ -18,6 +19,7 @@ import (

// ParseSign parsing YAML signature file
func ParseSign(signFile string) (sign libs.Signature, err error) {
signFile = utils.NormalizePath(signFile)
yamlFile, err := ioutil.ReadFile(signFile)
if err != nil {
utils.ErrorF("Error parsing Signature: #%v - %v", err, signFile)
Expand Down Expand Up @@ -203,11 +205,13 @@ func MoreVariables(target map[string]string, sign libs.Signature, options libs.O

// more options
realTarget["Root"] = options.RootFolder
realTarget["Version"] = fmt.Sprintf("Jaeles - %v", libs.VERSION)
realTarget["BaseSign"] = strings.TrimRight(options.SignFolder, "/")
realTarget["SignPwd"] = strings.TrimRight(path.Dir(sign.RawPath), "/")
realTarget["Resources"] = options.ResourcesFolder
realTarget["ThirdParty"] = options.ThirdPartyFolder
realTarget["proxy"] = options.Proxy
realTarget["output"] = options.Output
realTarget["Version"] = fmt.Sprintf("Jaeles - %v", libs.VERSION)

// default params in signature
signParams := sign.Params
Expand Down
154 changes: 154 additions & 0 deletions core/routine.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package core

import (
"github.com/jaeles-project/jaeles/libs"
"github.com/jaeles-project/jaeles/utils"
"github.com/robertkrimen/otto"
)

// RoutineRunner runner struct
type RoutineRunner struct {
Input string
SendingType string
Opt libs.Options
Sign libs.Signature
Routines []libs.Routine
Results map[string]bool
Target map[string]string
}

// InitRoutine init routine task
func InitRoutine(url string, sign libs.Signature, opt libs.Options) (RoutineRunner, error) {
var routine RoutineRunner
routine.Input = url
routine.Opt = opt
routine.Sign = sign

routine.Results = make(map[string]bool)
routine.Target = MoreVariables(ParseTarget(routine.Input), routine.Sign, routine.Opt)
routine.ParseRoutines(&sign)

return routine, nil
}

// ParseRoutines parse routine
func (r *RoutineRunner) ParseRoutines(sign *libs.Signature) {
var routines []libs.Routine

for _, rawRoutine := range sign.Routines {
var routine libs.Routine
routine.Signs = ResolveHeader(rawRoutine.Signs, r.Target)
for _, logic := range rawRoutine.Logics {
logic.Expression = ResolveVariable(logic.Expression, r.Target)
logic.Invokes = ResolveDetection(logic.Invokes, r.Target)
routine.Logics = append(routine.Logics, logic)
}
routines = append(routines, routine)
}

r.Routines = routines
}

// Start start the routine
func (r *RoutineRunner) Start() {
for _, routine := range r.Routines {
r.StartRunner(routine)
if len(r.Results) == 0 {
continue
}

for _, logic := range routine.Logics {
IsPassed := r.DoExpression(logic.Expression)
utils.DebugF("Expression: %s -- %v", logic.Expression, IsPassed)

if IsPassed {
r.DoInvokes(logic.Invokes)
}
}
}
}

// Start start the routine
func (r *RoutineRunner) StartRunner(routine libs.Routine) {

for _, Signs := range routine.Signs {
for key, signFile := range Signs {
utils.DebugF("Start runner for: %s", key)
sign, err := ParseSign(signFile)
if err != nil {
utils.ErrorF("Error parsing YAML sign: %v", signFile)
continue
}

// Forced to send sign as serial
//sign.Single = true

job := libs.Job{
URL: r.Input,
Sign: sign,
}

runner, err := InitRunner(job.URL, job.Sign, r.Opt)
if err != nil {
utils.ErrorF("Error create new runner: %v", err)
}
runner.InRoutine = true
runner.Sending()
utils.DebugF("Done runner for: %s", key)

// set result here
for _, rec := range runner.Records {
if rec.IsVulnerable {
_, exist := r.Results[key]
if exist {
continue
}
r.Results[key] = true
}
}
}
}

}

// DoExpression start the routine
func (r *RoutineRunner) DoExpression(expression string) bool {
vm := otto.New()
// export value
for k, v := range r.Results {
vm.Set(k, func(call otto.FunctionCall) otto.Value {
result, _ := vm.ToValue(v)
return result
})
}

result, _ := vm.Run(expression)
analyzeResult, err := result.Export()

if err != nil || analyzeResult == nil {
return false
}
return analyzeResult.(bool)
}

// DoExpression start the routine
func (r *RoutineRunner) DoInvokes(invokes []string) {
for _, signFile := range invokes {
sign, err := ParseSign(signFile)
if err != nil {
utils.ErrorF("Error parsing YAML sign: %v", signFile)
continue
}
job := libs.Job{
URL: r.Input,
Sign: sign,
}

runner, err := InitRunner(job.URL, job.Sign, r.Opt)
if err != nil {
utils.ErrorF("Error create new runner: %v", err)
}
runner.Sending()
}

}
77 changes: 74 additions & 3 deletions core/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,13 @@ type Runner struct {
Opt libs.Options
Sign libs.Signature
Origin Record
Target map[string]string
Records []Record

CRecords []Record
CMatched bool
InRoutine bool

Target map[string]string
Records []Record
}

// Record all information about request
Expand All @@ -27,6 +32,7 @@ type Record struct {
Sign libs.Signature

// passive check
NoOutput bool
DoPassive bool
SelectPassive string
IsVulnerablePassive bool
Expand Down Expand Up @@ -71,6 +77,10 @@ func InitRunner(url string, sign libs.Signature, opt libs.Options) (Runner, erro
runner.PrePareOrigin()
}

if len(runner.Sign.CRequests) > 0 {
runner.GenCRequests()
}

// generate requests
runner.GetRequests()
return runner, nil
Expand Down Expand Up @@ -156,6 +166,7 @@ func (r *Runner) GenRequests() []libs.Request {
return realReqs
}

// PrePareOrigin parsing origin request
func (r *Runner) PrePareOrigin() {
var originRec libs.Record
var origin libs.Origin
Expand Down Expand Up @@ -185,7 +196,7 @@ func (r *Runner) PrePareOrigin() {
r.Target = Target
}

// sending origin request
// SendOrigin sending origin request
func (r *Runner) SendOrigin(originReq libs.Request) (libs.Origin, map[string]string) {
var origin libs.Origin
var err error
Expand Down Expand Up @@ -229,3 +240,63 @@ func (r *Runner) SendOrigin(originReq libs.Request) (libs.Origin, map[string]str
r.Origin = originRec
return origin, r.Target
}

// GenCRequests generate condition requests
func (r *Runner) GenCRequests() {
// quick param for calling resource
r.Sign.Target = MoreVariables(r.Sign.Target, r.Sign, r.Opt)

var realReqs []libs.Request
globalVariables := ParseVariable(r.Sign)
if len(globalVariables) > 0 {
for _, globalVariable := range globalVariables {
r.Sign.Target = r.Target
for k, v := range globalVariable {
r.Sign.Target[k] = v
}
// start to send stuff
for _, req := range r.Sign.CRequests {
// receive request from "-r req.txt"
if r.Sign.RawRequest != "" {
req.Raw = r.Sign.RawRequest
}
// gen bunch of request to send
realReqs = append(realReqs, ParseRequest(req, r.Sign, r.Opt)...)
}
}
} else {
r.Sign.Target = r.Target
// start to send stuff
for _, req := range r.Sign.CRequests {
// receive request from "-r req.txt"
if r.Sign.RawRequest != "" {
req.Raw = r.Sign.RawRequest
}
// gen bunch of request to send
realReqs = append(realReqs, ParseRequest(req, r.Sign, r.Opt)...)
}
}

if len(realReqs) > 0 {
for _, req := range realReqs {
var rec Record

rec.NoOutput = true
if r.Sign.COutput {
rec.NoOutput = false
}

// set somethings in record
rec.Request = req
rec.Request.Target = r.Target
rec.Sign = r.Sign
rec.Opt = r.Opt
// assign origins here
rec.OriginReq = r.Origin.Request
rec.OriginRes = r.Origin.Response

r.CRecords = append(r.CRecords, rec)
}
}

}
Loading

0 comments on commit d2eb9c4

Please sign in to comment.