Skip to content

Commit d2eb9c4

Browse files
committed
Upgrade v0.15
1 parent cbae89f commit d2eb9c4

16 files changed

+538
-22
lines changed

cmd/config.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ Mics Flags:
279279
--title string HTML report title
280280
--html string Enable generate HTML reports after the scan done
281281
--hh string Full help message
282-
--re Shortcut for disable replicate request (avoid sending many request to timeout)
282+
--dr Shortcut for disable replicate request (avoid sending many timeout requests)
283283
--at Enable Always True Detection for observe response
284284
--lc Shortcut for '--proxy http://127.0.0.1:8080'
285285
--ba Shortcut for take raw input as '{{.BaseURL}}'

cmd/root.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func init() {
9494
RootCmd.PersistentFlags().IntVar(&options.ChunkLimit, "chunk-limit", 200000, "Limit size to trigger chunk run")
9595
// some shortcuts
9696
RootCmd.PersistentFlags().StringVarP(&options.InlineDetection, "inline", "I", "", "Inline Detections")
97-
RootCmd.PersistentFlags().BoolVar(&options.Mics.DisableReplicate, "re", false, "Shortcut for disable replicate request (avoid sending many request to timeout)")
97+
RootCmd.PersistentFlags().BoolVar(&options.Mics.DisableReplicate, "dr", false, "Shortcut for disable replicate request (avoid sending many request to timeout)")
9898
RootCmd.PersistentFlags().BoolVar(&options.Mics.BaseRoot, "ba", false, "Shortcut for take raw input as {{.BaseURL}}'")
9999
RootCmd.PersistentFlags().BoolVar(&options.Mics.BurpProxy, "lc", false, "Shortcut for '--proxy http://127.0.0.1:8080'")
100100
RootCmd.PersistentFlags().BoolVar(&options.Mics.AlwaysTrue, "at", false, "Enable Always True Detection for observe response")

cmd/scan.go

+22-1
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,21 @@ func runScan(cmd *cobra.Command, _ []string) error {
145145
}
146146

147147
func CreateRunner(j interface{}) {
148+
var jobs []libs.Job
148149
job := j.(libs.Job)
149-
jobs := []libs.Job{job}
150+
151+
// auto append http and https prefix if not present
152+
if !strings.HasPrefix(job.URL, "http://") && !strings.HasPrefix(job.URL, "https://") {
153+
withPrefixJob := job
154+
job.URL = "http://" + job.URL
155+
jobs = append(jobs, withPrefixJob)
156+
157+
withPrefixJob = job
158+
job.URL = "https://" + job.URL
159+
jobs = append(jobs, withPrefixJob)
160+
} else {
161+
jobs = append(jobs, job)
162+
}
150163

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

161174
for _, job := range jobs {
175+
if job.Sign.Type == "routine" {
176+
routine, err := core.InitRoutine(job.URL, job.Sign, options)
177+
if err != nil {
178+
utils.ErrorF("Error create new routine: %v", err)
179+
}
180+
routine.Start()
181+
continue
182+
}
162183
runner, err := core.InitRunner(job.URL, job.Sign, options)
163184
if err != nil {
164185
utils.ErrorF("Error create new runner: %v", err)

core/output.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ func (r *Record) Output() string {
1818
if !r.IsVulnerable {
1919
return ""
2020
}
21-
2221
utils.InforF("[Found] %v", color.MagentaString(r.DetectString))
2322

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

84+
//// do passive analyze if got called from detector
85+
//if strings.Contains(strings.ToLower(r.DetectString), "invokesign") {
86+
// r.InvokeSign()
87+
// options.SignFolder/sign-name.yaml
88+
//}
89+
8590
return "stop"
8691
}
8792

8893
// StoreOutput store vulnerable request to a file
8994
func (r *Record) StoreOutput() {
95+
// disable out
96+
if r.NoOutput {
97+
return
98+
}
9099
// store output to a file
91100
if r.Request.URL == "" {
92101
r.Request.URL = r.Request.Target["URL"]

core/parser.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"io/ioutil"
99
"net/http"
1010
"net/url"
11+
"path"
1112
"path/filepath"
1213
"strings"
1314

@@ -18,6 +19,7 @@ import (
1819

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

204206
// more options
205207
realTarget["Root"] = options.RootFolder
206-
realTarget["Version"] = fmt.Sprintf("Jaeles - %v", libs.VERSION)
208+
realTarget["BaseSign"] = strings.TrimRight(options.SignFolder, "/")
209+
realTarget["SignPwd"] = strings.TrimRight(path.Dir(sign.RawPath), "/")
207210
realTarget["Resources"] = options.ResourcesFolder
208211
realTarget["ThirdParty"] = options.ThirdPartyFolder
209212
realTarget["proxy"] = options.Proxy
210213
realTarget["output"] = options.Output
214+
realTarget["Version"] = fmt.Sprintf("Jaeles - %v", libs.VERSION)
211215

212216
// default params in signature
213217
signParams := sign.Params

core/routine.go

+154
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
package core
2+
3+
import (
4+
"github.com/jaeles-project/jaeles/libs"
5+
"github.com/jaeles-project/jaeles/utils"
6+
"github.com/robertkrimen/otto"
7+
)
8+
9+
// RoutineRunner runner struct
10+
type RoutineRunner struct {
11+
Input string
12+
SendingType string
13+
Opt libs.Options
14+
Sign libs.Signature
15+
Routines []libs.Routine
16+
Results map[string]bool
17+
Target map[string]string
18+
}
19+
20+
// InitRoutine init routine task
21+
func InitRoutine(url string, sign libs.Signature, opt libs.Options) (RoutineRunner, error) {
22+
var routine RoutineRunner
23+
routine.Input = url
24+
routine.Opt = opt
25+
routine.Sign = sign
26+
27+
routine.Results = make(map[string]bool)
28+
routine.Target = MoreVariables(ParseTarget(routine.Input), routine.Sign, routine.Opt)
29+
routine.ParseRoutines(&sign)
30+
31+
return routine, nil
32+
}
33+
34+
// ParseRoutines parse routine
35+
func (r *RoutineRunner) ParseRoutines(sign *libs.Signature) {
36+
var routines []libs.Routine
37+
38+
for _, rawRoutine := range sign.Routines {
39+
var routine libs.Routine
40+
routine.Signs = ResolveHeader(rawRoutine.Signs, r.Target)
41+
for _, logic := range rawRoutine.Logics {
42+
logic.Expression = ResolveVariable(logic.Expression, r.Target)
43+
logic.Invokes = ResolveDetection(logic.Invokes, r.Target)
44+
routine.Logics = append(routine.Logics, logic)
45+
}
46+
routines = append(routines, routine)
47+
}
48+
49+
r.Routines = routines
50+
}
51+
52+
// Start start the routine
53+
func (r *RoutineRunner) Start() {
54+
for _, routine := range r.Routines {
55+
r.StartRunner(routine)
56+
if len(r.Results) == 0 {
57+
continue
58+
}
59+
60+
for _, logic := range routine.Logics {
61+
IsPassed := r.DoExpression(logic.Expression)
62+
utils.DebugF("Expression: %s -- %v", logic.Expression, IsPassed)
63+
64+
if IsPassed {
65+
r.DoInvokes(logic.Invokes)
66+
}
67+
}
68+
}
69+
}
70+
71+
// Start start the routine
72+
func (r *RoutineRunner) StartRunner(routine libs.Routine) {
73+
74+
for _, Signs := range routine.Signs {
75+
for key, signFile := range Signs {
76+
utils.DebugF("Start runner for: %s", key)
77+
sign, err := ParseSign(signFile)
78+
if err != nil {
79+
utils.ErrorF("Error parsing YAML sign: %v", signFile)
80+
continue
81+
}
82+
83+
// Forced to send sign as serial
84+
//sign.Single = true
85+
86+
job := libs.Job{
87+
URL: r.Input,
88+
Sign: sign,
89+
}
90+
91+
runner, err := InitRunner(job.URL, job.Sign, r.Opt)
92+
if err != nil {
93+
utils.ErrorF("Error create new runner: %v", err)
94+
}
95+
runner.InRoutine = true
96+
runner.Sending()
97+
utils.DebugF("Done runner for: %s", key)
98+
99+
// set result here
100+
for _, rec := range runner.Records {
101+
if rec.IsVulnerable {
102+
_, exist := r.Results[key]
103+
if exist {
104+
continue
105+
}
106+
r.Results[key] = true
107+
}
108+
}
109+
}
110+
}
111+
112+
}
113+
114+
// DoExpression start the routine
115+
func (r *RoutineRunner) DoExpression(expression string) bool {
116+
vm := otto.New()
117+
// export value
118+
for k, v := range r.Results {
119+
vm.Set(k, func(call otto.FunctionCall) otto.Value {
120+
result, _ := vm.ToValue(v)
121+
return result
122+
})
123+
}
124+
125+
result, _ := vm.Run(expression)
126+
analyzeResult, err := result.Export()
127+
128+
if err != nil || analyzeResult == nil {
129+
return false
130+
}
131+
return analyzeResult.(bool)
132+
}
133+
134+
// DoExpression start the routine
135+
func (r *RoutineRunner) DoInvokes(invokes []string) {
136+
for _, signFile := range invokes {
137+
sign, err := ParseSign(signFile)
138+
if err != nil {
139+
utils.ErrorF("Error parsing YAML sign: %v", signFile)
140+
continue
141+
}
142+
job := libs.Job{
143+
URL: r.Input,
144+
Sign: sign,
145+
}
146+
147+
runner, err := InitRunner(job.URL, job.Sign, r.Opt)
148+
if err != nil {
149+
utils.ErrorF("Error create new runner: %v", err)
150+
}
151+
runner.Sending()
152+
}
153+
154+
}

core/runner.go

+74-3
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,13 @@ type Runner struct {
1515
Opt libs.Options
1616
Sign libs.Signature
1717
Origin Record
18-
Target map[string]string
19-
Records []Record
18+
19+
CRecords []Record
20+
CMatched bool
21+
InRoutine bool
22+
23+
Target map[string]string
24+
Records []Record
2025
}
2126

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

2934
// passive check
35+
NoOutput bool
3036
DoPassive bool
3137
SelectPassive string
3238
IsVulnerablePassive bool
@@ -71,6 +77,10 @@ func InitRunner(url string, sign libs.Signature, opt libs.Options) (Runner, erro
7177
runner.PrePareOrigin()
7278
}
7379

80+
if len(runner.Sign.CRequests) > 0 {
81+
runner.GenCRequests()
82+
}
83+
7484
// generate requests
7585
runner.GetRequests()
7686
return runner, nil
@@ -156,6 +166,7 @@ func (r *Runner) GenRequests() []libs.Request {
156166
return realReqs
157167
}
158168

169+
// PrePareOrigin parsing origin request
159170
func (r *Runner) PrePareOrigin() {
160171
var originRec libs.Record
161172
var origin libs.Origin
@@ -185,7 +196,7 @@ func (r *Runner) PrePareOrigin() {
185196
r.Target = Target
186197
}
187198

188-
// sending origin request
199+
// SendOrigin sending origin request
189200
func (r *Runner) SendOrigin(originReq libs.Request) (libs.Origin, map[string]string) {
190201
var origin libs.Origin
191202
var err error
@@ -229,3 +240,63 @@ func (r *Runner) SendOrigin(originReq libs.Request) (libs.Origin, map[string]str
229240
r.Origin = originRec
230241
return origin, r.Target
231242
}
243+
244+
// GenCRequests generate condition requests
245+
func (r *Runner) GenCRequests() {
246+
// quick param for calling resource
247+
r.Sign.Target = MoreVariables(r.Sign.Target, r.Sign, r.Opt)
248+
249+
var realReqs []libs.Request
250+
globalVariables := ParseVariable(r.Sign)
251+
if len(globalVariables) > 0 {
252+
for _, globalVariable := range globalVariables {
253+
r.Sign.Target = r.Target
254+
for k, v := range globalVariable {
255+
r.Sign.Target[k] = v
256+
}
257+
// start to send stuff
258+
for _, req := range r.Sign.CRequests {
259+
// receive request from "-r req.txt"
260+
if r.Sign.RawRequest != "" {
261+
req.Raw = r.Sign.RawRequest
262+
}
263+
// gen bunch of request to send
264+
realReqs = append(realReqs, ParseRequest(req, r.Sign, r.Opt)...)
265+
}
266+
}
267+
} else {
268+
r.Sign.Target = r.Target
269+
// start to send stuff
270+
for _, req := range r.Sign.CRequests {
271+
// receive request from "-r req.txt"
272+
if r.Sign.RawRequest != "" {
273+
req.Raw = r.Sign.RawRequest
274+
}
275+
// gen bunch of request to send
276+
realReqs = append(realReqs, ParseRequest(req, r.Sign, r.Opt)...)
277+
}
278+
}
279+
280+
if len(realReqs) > 0 {
281+
for _, req := range realReqs {
282+
var rec Record
283+
284+
rec.NoOutput = true
285+
if r.Sign.COutput {
286+
rec.NoOutput = false
287+
}
288+
289+
// set somethings in record
290+
rec.Request = req
291+
rec.Request.Target = r.Target
292+
rec.Sign = r.Sign
293+
rec.Opt = r.Opt
294+
// assign origins here
295+
rec.OriginReq = r.Origin.Request
296+
rec.OriginRes = r.Origin.Response
297+
298+
r.CRecords = append(r.CRecords, rec)
299+
}
300+
}
301+
302+
}

0 commit comments

Comments
 (0)