-
Notifications
You must be signed in to change notification settings - Fork 83
/
Copy pathutils.rs
258 lines (245 loc) · 10.9 KB
/
utils.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
use crate::scan::active::http_client::auth::Authorization;
use crate::scan::active::http_client::QuePay;
use crate::scan::active::http_client::{AttackRequest, RequestParameter};
use cherrybomb_oas::legacy::legacy_oas::Server;
use cherrybomb_oas::legacy::path::Operation;
use cherrybomb_oas::legacy::utils::Method;
use serde_json::Value;
use std::collections::HashMap;
pub fn create_payload(
// this function needs to calls the create hash func from here try to get the value from the hash
// then if success build requestParameter else then use the get regular function
swagger: &Value,
op: &Operation,
hash_map: &HashMap<String, String>,
placeholder: Option<String>,
) -> Vec<RequestParameter> {
let mut params_vec: Vec<RequestParameter> = vec![];
for i in op.params() {
let parameter = i.inner(swagger);
let in_var = parameter.param_in;
let param_name = parameter.name.to_string();
if in_var.trim().eq("path") {
// if param is in path
if let Some(the_key) = hash_map.iter().find_map(|(key, _val)| {
//if is match the hashmap
if key.to_lowercase().eq(¶m_name.to_lowercase()) {
Some(key)
} else {
None
}
}) {
let param_value = hash_map.get(the_key).unwrap();
let mut params_vec = vec![];
params_vec.push(RequestParameter {
//push the parameter in the req vec
name: param_name,
value: param_value.to_string(),
dm: QuePay::Path,
});
if placeholder.is_some() && placeholder.clone().unwrap().eq("") {
// println!("The placeholder is empty ");
// if there is a empty placeholder and it's match with hashmap so return the vec param
return params_vec;
}
}
}
}
if placeholder.as_ref().is_some() {
// println!("THe placeholder is some");
// if there is a placeholder value, used in ssrf or redirection for example
if !placeholder.clone().unwrap().eq("") {
//empty quote in placeholder are used only to create a path parameter payload.
//if there is placeholder and the value exist in the hashmap so let's call the second method for paylaod redirection or pollution.
return create_payload_for_get(swagger, op, placeholder, &mut params_vec);
}
} else {
//The placeholder is none for pollution
return create_payload_for_get(swagger, op, placeholder, &mut params_vec);
}
//println!("END");
params_vec
}
pub async fn send_req(
//send request and check the value of specific key, return vec of values
path: String,
element: &String,
auth: &Authorization,
server: &Option<Vec<Server>>,
) -> Vec<String> {
let mut collection_of_values: Vec<String> = Vec::new();
let req = AttackRequest::builder()
.uri(server, &path)
.parameters(vec![])
.auth(auth.clone())
.method(Method::GET)
.headers(vec![])
.auth(auth.clone())
.build();
let res = req.send_request_with_response().await;
if res.1 {
let object: Value = serde_json::from_str(&res.0).unwrap_or_default();
if let Some(i) = object.as_array() {
for x in i.iter() {
// println!("x: {x:?}");
read_json_func(x, element, &mut collection_of_values);
}
}
}
collection_of_values
}
pub fn read_json_func(obj: &Value, element: &String, vector: &mut Vec<String>) -> Vec<String> {
let st = obj.as_object();
if let Some(hashmap) = st {
for (key, value) in hashmap {
if key.eq(&element.to_lowercase()) {
if let Some(array) = value.as_array() {
for i in array {
if let Some(val) = i.as_str() {
vector.push(val.to_string());
}
if let Some(val) = i.as_u64() {
vector.push(val.to_string());
}
}
}
if let Some(val) = value.as_str() {
vector.push(val.to_string());
}
if let Some(val) = value.as_u64() {
vector.push(val.to_string());
}
}
read_json_func(value, element, vector);
}
}
vector.to_vec()
}
pub fn create_payload_for_get(
swagger: &Value,
op: &Operation,
test_value: Option<String>,
params_vec: &mut Vec<RequestParameter>,
) -> Vec<RequestParameter> {
// let mut params_vec = vec![];
let mut final_value = "blstparamtopollute".to_string(); //random string use to parameter pollution
for i in op.params() {
let parameter = i.inner(swagger);
let in_var = parameter.param_in;
let param_name = parameter.name.to_string();
match in_var.as_str().to_lowercase().trim() {
"path" => {
// if the param is in the path
if !params_vec.iter().any(|s| s.name == param_name) {
// check if there is not a path parameter already configured so
//we check if param_name is not exist in the params_vec
let mut option_example_value = None;
if let Some(value) = parameter.examples {
// if there is an example
if let Some((_ex, val)) = value.into_iter().next() {
option_example_value = Some(val.inner(swagger).value.to_string());
}
}
if let Some(schema_ref) = parameter.schema {
// dbg!(&schema_ref);
if let Some(schema_type) = schema_ref.inner(swagger).schema_type {
// let val_to_path:String;
match schema_type.as_str().as_str() {
"string" => {
let mut example_value = "randomString".to_string();
if let Some(val) = option_example_value {
example_value = val;
}
params_vec.push(RequestParameter {
name: param_name,
value: example_value,
dm: QuePay::Path,
});
}
"integer" => {
let mut example_value = "123".to_string();
if let Some(val) = option_example_value {
example_value = val;
}
params_vec.push(RequestParameter {
name: param_name,
value: example_value,
dm: QuePay::Path,
});
}
"boolean" => {
let mut example_value = "true".to_string();
if let Some(val) = option_example_value {
example_value = val;
}
params_vec.push(RequestParameter {
name: param_name,
value: example_value,
dm: QuePay::Path,
});
}
_ => (),
};
} else {
let mut example_value = "randomString".to_string();
if let Some(val) = option_example_value {
example_value = val;
}
params_vec.push(RequestParameter {
name: param_name,
value: example_value,
dm: QuePay::Path,
});
}
}
}
}
"query" => {
if let Some(ref value) = test_value {
// Here in case of ssrf of redirection there is Some(value)
if !value.eq(&"".to_string()) {
//
// if test_value.as_ref().is_none() {
params_vec.push(RequestParameter {
name: param_name,
dm: QuePay::Query,
value: value.to_string(),
});
} else {
//if the placeholder is empty string means that we want to insert example of default values
if parameter.required.unwrap_or(false) {
//check if the query parameter is mandatory
if let Some(values) = parameter.examples {
if let Some((_ex, val)) = values.into_iter().next() {
//take example as value
final_value = val.inner(swagger).value.to_string();
params_vec.push(RequestParameter {
name: param_name,
dm: QuePay::Query,
value:final_value.clone(),
});
} else {
//if no examples insert randonstring
params_vec.push(RequestParameter {
name: param_name,
dm: QuePay::Query,
value: "randomString".to_string(),
});
}
}
} // if no mandatory continue
}
} else {
//if value to test is none, meaning test for pollution
params_vec.push(RequestParameter {
name: param_name,
dm: QuePay::Query,
value: final_value.clone(),
});
}
}
_ => (),
};
}
params_vec.to_vec()
}