5 | #include "zend.h"
6 | #include "php_embed_ex.h"
7 | #include "php_cfg.h"
8 | #include "php_dfg.h"
9 | #include "php_ssa.h"
10 |
11 | void zend_accel_move_user_functions (HashTable *src, HashTable *dst);
12 |
13 | static bool generate_function_object (const char *class_name,
14 | const char *function_name,
15 | const zend_op_array *op_array,
16 | zend_file_handle *file_handle,
17 | PyObject *fn_pobject);
18 |
19 | static bool generate_basic_info (const zend_op_array *op_array,
20 | PyObject *fn_pobject);
21 |
22 | static bool generate_extra_info (const zend_op_array *op_array,
23 | PyObject *fn_pobject);
24 |
25 | static bool generate_instructions_info (const zend_op_array *op_array,
26 | PyObject *fn_pobject);
27 |
28 | static bool generate_cfg_info (const zend_op_array *op_array,
29 | zend_file_handle *file_handle,
30 | PyObject *fn_pobject);
31 |
32 | static bool generate_dfg_info (const zend_op_array *op_array, zend_cfg *cfg,
33 | PyObject *fn_pobject);
34 |
35 | static bool generate_ssa_info (const zend_op_array *op_array, zend_cfg *cfg,
36 | zend_file_handle *file_handle,
37 | PyObject *fn_pobject);
38 |
39 | static PyObject *zval_to_python_object (zval *val);
40 |
41 | static PyObject *
42 | method_convert (PyObject *self, PyObject *args)
43 | {
44 | char *filename = NULL;
45 | PyObject *zend_functions_pyobject = PyList_New (0);
46 |
47 | /* Parse arguments */
48 | if (!PyArg_ParseTuple (args, "s", &filename))
49 | {
50 | return zend_functions_pyobject;
51 | }
52 |
53 | zend_script script;
54 | zend_op_array *op_array = NULL;
55 | int php_embed_argc = 0;
56 | char **php_embed_argv = NULL;
57 |
58 | PHP_EMBED_START_BLOCK (php_embed_argc, php_embed_argv);
59 |
60 | zend_file_handle file_handle;
61 | file_handle.filename = filename;
62 | file_handle.free_filename = 0;
63 | file_handle.type = ZEND_HANDLE_FILENAME;
64 | file_handle.opened_path = NULL;
65 |
66 | // initialize function_table & class_table
67 | zend_hash_init (&script.function_table, 128, NULL, ZEND_FUNCTION_DTOR, 0);
68 | zend_hash_init (&script.class_table, 16, NULL, ZEND_CLASS_DTOR, 0);
69 |
70 | op_array = zend_compile_file (&file_handle, ZEND_INCLUDE TSRMLS_CC);
71 | if (!op_array)
72 | {
73 | printf ("Error parsing php script file: %s\n", filename);
74 | goto cleanup_e;
75 | }
76 |
77 | PyObject *fn_pobject = PyDict_New ();
78 | bool status = generate_function_object ("", "main", op_array, &file_handle,
79 | fn_pobject);
80 | if (status == true)
81 | {
82 | PyList_Append (zend_functions_pyobject, fn_pobject);
83 | }
84 |
85 | zend_accel_move_user_functions (CG (function_table),
86 | &script.function_table);
87 | zend_op_array *iter_op_array;
88 | ZEND_HASH_FOREACH_PTR (&script.function_table, iter_op_array)
89 | {
90 | PyObject *fn_pobject = PyDict_New ();
91 | bool status = generate_function_object (
92 | "", ZSTR_VAL (iter_op_array->function_name), iter_op_array,
93 | &file_handle, fn_pobject);
94 | if (status == true)
95 | {
96 | PyList_Append (zend_functions_pyobject, fn_pobject);
97 | }
98 | }
99 | ZEND_HASH_FOREACH_END ();
100 |
101 | EG (class_table) = CG (class_table);
102 | zend_class_entry *ce;
103 | zend_string *name;
104 | ZEND_HASH_FOREACH_PTR (EG (class_table), ce)
105 | {
106 | if (ce->type == ZEND_USER_CLASS)
107 | {
108 | ZEND_HASH_FOREACH_STR_KEY_PTR (&ce->function_table, name,
109 | iter_op_array)
110 | {
111 | if (iter_op_array->scope == ce)
112 | {
113 | PyObject *fn_pobject = PyDict_New ();
114 | bool status = generate_function_object (
115 | ZSTR_VAL (ce->name),
116 | ZSTR_VAL (iter_op_array->function_name),
117 | iter_op_array, &file_handle, fn_pobject);
118 | if (status == true)
119 | {
120 | PyList_Append (zend_functions_pyobject,
121 | fn_pobject);
122 | }
123 | }
124 | }
125 | ZEND_HASH_FOREACH_END ();
126 | }
127 | }
128 | ZEND_HASH_FOREACH_END ();
129 |
130 | cleanup_e:
131 | zend_hash_destroy (&script.function_table);
132 | zend_hash_destroy (&script.class_table);
133 |
134 | if (op_array)
135 | {
136 | destroy_op_array (op_array TSRMLS_CC);
137 | efree (op_array);
138 | }
139 |
140 | PHP_EMBED_END_BLOCK ();
141 | return zend_functions_pyobject;
142 | }
143 |
144 | void
145 | zend_accel_move_user_functions (HashTable *src, HashTable *dst)
146 | {
147 | Bucket *p;
148 | dtor_func_t orig_dtor = src->pDestructor;
149 |
150 | src->pDestructor = NULL;
151 | zend_hash_extend (dst, dst->nNumUsed + src->nNumUsed, 0);
152 | ZEND_HASH_REVERSE_FOREACH_BUCKET (src, p)
153 | {
154 | zend_function *function = Z_PTR (p->val);
155 |
156 | if (EXPECTED (function->type == ZEND_USER_FUNCTION))
157 | {
158 | _zend_hash_append_ptr (dst, p->key, function);
159 | zend_hash_del_bucket (src, p);
160 | }
161 | else
162 | {
163 | break;
164 | }
165 | }
166 | ZEND_HASH_FOREACH_END ();
167 | src->pDestructor = orig_dtor;
168 | }
169 |
170 | static bool
171 | generate_function_object (const char *class_name, const char *function_name,
172 | const zend_op_array *op_array,
173 | zend_file_handle *file_handle, PyObject *fn_pobject)
174 | {
175 | bool status = true;
176 |
177 | PyDict_SetItem (fn_pobject, Py_BuildValue ("s", "class_name"),
178 | Py_BuildValue ("s", class_name));
179 |
180 | PyDict_SetItem (fn_pobject, Py_BuildValue ("s", "function_name"),
181 | Py_BuildValue ("s", function_name));
182 |
183 | status = generate_basic_info (op_array, fn_pobject);
184 | if (status == false)
185 | {
186 | return false;
187 | }
188 |
189 | status = generate_extra_info (op_array, fn_pobject);
190 | if (status == false)
191 | {
192 | return false;
193 | }
194 |
195 | status = generate_instructions_info (op_array, fn_pobject);
196 | if (status == false)
197 | {
198 | return false;
199 | }
200 |
201 | // printf("\n");
202 | status = generate_cfg_info (op_array, file_handle, fn_pobject);
203 | if (status == false)
204 | {
205 | return false;
206 | }
207 | return status;
208 | }
209 |
210 | static bool
211 | generate_basic_info (const zend_op_array *op_array, PyObject *fn_pobject)
212 | {
213 | // op_array->num_args
214 | PyDict_SetItem (fn_pobject, Py_BuildValue ("s", "num_args"),
215 | Py_BuildValue ("i", op_array->num_args));
216 |
217 | // op_array->required_num_args
218 | PyDict_SetItem (fn_pobject, Py_BuildValue ("s", "required_num_args"),
219 | Py_BuildValue ("i", op_array->required_num_args));
220 |
221 | // op_array->last
222 | PyDict_SetItem (fn_pobject, Py_BuildValue ("s", "number_of_instructions"),
223 | Py_BuildValue ("i", op_array->last));
224 |
225 | // op_array->filename
226 | if (op_array->filename)
227 | PyDict_SetItem (fn_pobject, Py_BuildValue ("s", "filename"),
228 | Py_BuildValue ("s", ZSTR_VAL (op_array->filename)));
229 | else
230 | PyDict_SetItem (fn_pobject, Py_BuildValue ("s", "filename"),
231 | Py_BuildValue ("s", ""));
232 | return true;
233 | }
234 |
235 | static bool
236 | generate_extra_info (const zend_op_array *op_array, PyObject *fn_pobject)
237 | {
238 | PyObject *fn_extra_pobject = PyDict_New ();
239 |
240 | // op_array->type
241 | PyDict_SetItem (fn_extra_pobject, Py_BuildValue ("s", "type"),
242 | Py_BuildValue ("i", op_array->type));
243 |
244 | // op_array->cache_size
245 | PyDict_SetItem (fn_extra_pobject, Py_BuildValue ("s", "cache_size"),
246 | Py_BuildValue ("i", op_array->cache_size));
247 |
248 | // op_array->last_var
249 | PyDict_SetItem (fn_extra_pobject,
250 | Py_BuildValue ("s", "number_of_cv_variables"),
251 | Py_BuildValue ("i", op_array->last_var));
252 |
253 | // op_array->T
254 | PyDict_SetItem (fn_extra_pobject,
255 | Py_BuildValue ("s", "number_of_tmp_variables"),
256 | Py_BuildValue ("i", op_array->T));
257 |
258 | // op_array->last_live_range
259 | PyDict_SetItem (fn_extra_pobject, Py_BuildValue ("s", "last_live_range"),
260 | Py_BuildValue ("i", op_array->last_live_range));
261 |
262 | // op_array->last_try_catch
263 | PyDict_SetItem (fn_extra_pobject, Py_BuildValue ("s", "last_try_catch"),
264 | Py_BuildValue ("i", op_array->last_try_catch));
265 |
266 | // op_array->arg_flags
267 | PyObject *arg_flags = PyList_New (0);
268 | PyList_Append (arg_flags, Py_BuildValue ("i", op_array->arg_flags[0]));
269 |
270 | PyList_Append (arg_flags, Py_BuildValue ("i", op_array->arg_flags[1]));
271 |
272 | PyList_Append (arg_flags, Py_BuildValue ("i", op_array->arg_flags[2]));
273 |
274 | PyDict_SetItem (fn_extra_pobject, Py_BuildValue ("s", "arg_flags"),
275 | arg_flags);
276 |
277 | // op_array->last_literal
278 | PyDict_SetItem (fn_extra_pobject, Py_BuildValue ("s", "last_literal"),
279 | Py_BuildValue ("i", op_array->last_literal));
280 |
281 | // op_array->literals
282 | PyObject *literals_array_pyobject = PyList_New (0);
283 | if (op_array->literals)
284 | {
285 | int j;
286 | for (j = 0; j < op_array->last_literal; j++)
287 | {
288 | zval *literal_val = &op_array->literals[j];
289 | PyList_Append (literals_array_pyobject,
290 | zval_to_python_object (literal_val));
291 | }
292 | }
293 | PyDict_SetItem (fn_extra_pobject, Py_BuildValue ("s", "literals"),
294 | literals_array_pyobject);
295 |
296 | PyDict_SetItem (fn_pobject, Py_BuildValue ("s", "extra"), fn_extra_pobject);
297 | return true;
298 | }
299 |
300 | static int
301 | zval_string_is_ascii (zval *val)
302 | {
303 | int status = 1;
304 | for (int i = 0; i < Z_STRLEN_P (val); ++i)
305 | {
306 | if ((!isascii (Z_STRVAL_P (val)[i])
307 | && (!isprint (Z_STRVAL_P (val)[i]))))
308 | {
309 | status = 0;
310 | break;
311 | }
312 | }
313 | return status;
314 | }
315 |
316 | static PyObject *
317 | zval_to_python_object (zval *val)
318 | {
319 | PyObject *zval_pyobject = PyDict_New ();
320 | char *decode = NULL;
321 |
322 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "type"),
323 | Py_BuildValue ("s", "unknown"));
324 |
325 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "value"),
326 | Py_BuildValue ("s", ""));
327 |
328 | // types defined in Zend/zend_types.h
329 | switch (Z_TYPE_P (val))
330 | {
331 | case IS_STRING:
332 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "type"),
333 | Py_BuildValue ("s", "string"));
334 |
335 | // printf("==== %ld, %s %d\n",
336 | // Z_STRLEN_P(val),
337 | // Z_STRVAL_P(val),
338 | // zval_string_is_ascii(val));
339 |
340 | if (zval_string_is_ascii (val))
341 | {
342 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "value"),
343 | Py_BuildValue ("s", Z_STRVAL_P (val)));
344 | }
345 | else
346 | {
347 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "value"),
348 | Py_BuildValue ("s", ""));
349 | }
350 |
351 | break;
352 | case IS_DOUBLE:
353 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "type"),
354 | Py_BuildValue ("s", "integer"));
355 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "value"),
356 | Py_BuildValue ("i", Z_DVAL_P (val)));
357 | break;
358 | case IS_LONG:
359 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "type"),
360 | Py_BuildValue ("s", "integer"));
361 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "value"),
362 | Py_BuildValue ("i", Z_LVAL_P (val)));
363 | break;
364 | case IS_TRUE:
365 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "type"),
366 | Py_BuildValue ("s", "boolean"));
367 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "value"),
368 | Py_BuildValue ("s", "true"));
369 | break;
370 | case IS_FALSE:
371 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "type"),
372 | Py_BuildValue ("s", "boolean"));
373 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "value"),
374 | Py_BuildValue ("s", "false"));
375 | break;
376 | case IS_UNDEF:
377 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "type"),
378 | Py_BuildValue ("s", "undef"));
379 | break;
380 | case IS_RESOURCE:
381 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "type"),
382 | Py_BuildValue ("s", "resource"));
383 |
384 | spprintf (&decode, 0, "Rsrc #%d", Z_RES_HANDLE_P (val));
385 |
386 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "value"),
387 | Py_BuildValue ("s", decode));
388 | break;
389 | case IS_REFERENCE:
390 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "type"),
391 | Py_BuildValue ("s", "reference"));
392 | break;
393 | case IS_OBJECT:
394 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "type"),
395 | Py_BuildValue ("s", "object"));
396 |
397 | zend_string *str = Z_OBJCE_P (val)->name;
398 | spprintf (&decode, 0, "%s", ZSTR_VAL (str));
399 |
400 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "value"),
401 | Py_BuildValue ("s", decode));
402 | break;
403 | case IS_ARRAY:
404 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "type"),
405 | Py_BuildValue ("s", "array"));
406 |
407 | spprintf (&decode, 0, "array(%d)",
408 | zend_hash_num_elements (Z_ARR_P (val)));
409 |
410 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "value"),
411 | Py_BuildValue ("s", decode));
412 | break;
413 | case IS_NULL:
414 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "type"),
415 | Py_BuildValue ("s", "null"));
416 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "value"),
417 | Py_BuildValue ("s", estrdup ("null")));
418 | break;
419 | default:
420 | spprintf (&decode, 0, "unknown type: %d", Z_TYPE_P (val));
421 |
422 | PyDict_SetItem (zval_pyobject, Py_BuildValue ("s", "value"),
423 | Py_BuildValue ("s", decode));
424 | break;
425 | }
426 | return zval_pyobject;
427 | }
428 |
429 | static PyObject *
430 | get_znode_operand (const zend_op_array *op_array, const zend_op *opline,
431 | znode_op op, zend_uchar op_type, uint32_t flags)
432 | {
433 | /***************************************
434 | typedef union _znode_op {
435 | uint32_t constant;
436 | uint32_t var;
437 | uint32_t num;
438 | uint32_t opline_num;
439 | #if ZEND_USE_ABS_JMP_ADDR
440 | zend_op *jmp_addr;
441 | #else
442 | uint32_t jmp_offset;
443 | #endif
444 | #if ZEND_USE_ABS_CONST_ADDR
445 | zval *zv;
446 | #endif
447 | } znode_op;
448 | ***************************************/
449 |
450 | PyObject *znode_pyobject = PyDict_New ();
451 |
452 | PyDict_SetItem (znode_pyobject, Py_BuildValue ("s", "type"),
453 | Py_BuildValue ("s", "UNKNOWN"));
454 |
455 | PyDict_SetItem (znode_pyobject, Py_BuildValue ("s", "value"),
456 | Py_BuildValue ("s", ""));
457 |
458 | PyDict_SetItem (znode_pyobject, Py_BuildValue ("s", "variable_number"),
459 | Py_BuildValue ("i", EX_VAR_TO_NUM (op.var)));
460 |
461 | if (op_type == IS_UNUSED)
462 | {
463 | char *decode = NULL;
464 |
465 | if (ZEND_VM_OP_JMP_ADDR == (flags & ZEND_VM_OP_MASK))
466 | {
467 | // spprintf(&decode, 0, "J%td", OP_JMP_ADDR(opline, op) -
468 | // op_array->opcodes);
469 | }
470 | else if (ZEND_VM_OP_NUM == (flags & ZEND_VM_OP_MASK))
471 | {
472 | spprintf (&decode, 0, "%" PRIu32, op.num);
473 | }
474 | else if (ZEND_VM_OP_TRY_CATCH == (flags & ZEND_VM_OP_MASK))
475 | {
476 | if (op.num != (uint32_t)-1)
477 | {
478 | spprintf (&decode, 0, "try-catch(%" PRIu32 ")",
479 | op.num);
480 | }
481 | }
482 | else if (ZEND_VM_OP_THIS == (flags & ZEND_VM_OP_MASK))
483 | {
484 | decode = estrdup ("THIS");
485 | }
486 | else if (ZEND_VM_OP_NEXT == (flags & ZEND_VM_OP_MASK))
487 | {
488 | decode = estrdup ("NEXT");
489 | }
490 | else if (ZEND_VM_OP_CLASS_FETCH == (flags & ZEND_VM_OP_MASK))
491 | {
492 | }
493 | else if (ZEND_VM_OP_CONSTRUCTOR == (flags & ZEND_VM_OP_MASK))
494 | {
495 | decode = estrdup ("CONSTRUCTOR");
496 | }
497 |
498 | PyDict_SetItem (znode_pyobject, Py_BuildValue ("s", "type"),
499 | Py_BuildValue ("s", "IS_UNUSED"));
500 |
501 | PyDict_SetItem (znode_pyobject, Py_BuildValue ("s", "value"),
502 | Py_BuildValue ("s", decode));
503 | }
504 |
505 | if (op_type == IS_CONST)
506 | {
507 | PyDict_SetItem (znode_pyobject, Py_BuildValue ("s", "type"),
508 | Py_BuildValue ("s", "IS_CONST"));
509 |
510 | PyDict_SetItem (znode_pyobject, Py_BuildValue ("s", "value"),
511 | Py_BuildValue ("s", ""));
512 |
513 | zval *const_literal = RT_CONSTANT (opline, op);
514 | if (const_literal)
515 | {
516 | PyObject *const_literal_pyobject
517 | = zval_to_python_object (const_literal);
518 |
519 | PyDict_SetItem (
520 | znode_pyobject, Py_BuildValue ("s", "value"),
521 | PyDict_GetItem (const_literal_pyobject,
522 | Py_BuildValue ("s", "value")));
523 | }
524 | }
525 |
526 | if (op_type == IS_TMP_VAR)
527 | {
528 | char *decode = NULL;
529 | spprintf (&decode, 0, "T%u", EX_VAR_TO_NUM (op.var));
530 |
531 | PyDict_SetItem (znode_pyobject, Py_BuildValue ("s", "type"),
532 | Py_BuildValue ("s", "IS_TMP_VAR"));
533 |
534 | PyDict_SetItem (znode_pyobject, Py_BuildValue ("s", "value"),
535 | Py_BuildValue ("s", decode));
536 | }
537 |
538 | if (op_type == IS_VAR)
539 | {
540 | char *decode = NULL;
541 | spprintf (&decode, 0, "@%u", EX_VAR_TO_NUM (op.var));
542 |
543 | PyDict_SetItem (znode_pyobject, Py_BuildValue ("s", "type"),
544 | Py_BuildValue ("s", "IS_VAR"));
545 |
546 | PyDict_SetItem (znode_pyobject, Py_BuildValue ("s", "value"),
547 | Py_BuildValue ("s", decode));
548 | }
549 |
550 | if (op_type == IS_CV)
551 | {
552 | char *decode = NULL;
553 | zend_string *var = op_array->vars[EX_VAR_TO_NUM (op.var)];
554 |
555 | spprintf (&decode, 0, "$%.*s%c",
556 | ZSTR_LEN (var) <= 19 ? (int)ZSTR_LEN (var) : 18,
557 | ZSTR_VAL (var), ZSTR_LEN (var) <= 19 ? 0 : '+');
558 |
559 | PyDict_SetItem (znode_pyobject, Py_BuildValue ("s", "type"),
560 | Py_BuildValue ("s", "IS_CV"));
561 |
562 | PyDict_SetItem (znode_pyobject, Py_BuildValue ("s", "value"),
563 | Py_BuildValue ("s", decode));
564 | }
565 |
566 | return znode_pyobject;
567 | }
568 |
569 | static bool
570 | generate_instructions_info (const zend_op_array *op_array, PyObject *fn_pobject)
571 | {
572 | PyObject *insns_pyobject = PyList_New (0);
573 | for (int i = 0; i < op_array->last; i++)
574 | {
575 | zend_op *op = &op_array->opcodes[i];
576 | uint32_t flags = zend_get_opcode_flags (op->opcode);
577 |
578 | /***************************************************************************
579 | // php-7.3.31
580 | struct _zend_op {
581 | const void *handler;
582 | znode_op op1; // input operand
583 | znode_op op2; // input operand
584 | znode_op result; // one output operand result
585 | uint32_t extended_value;
586 | uint32_t lineno;
587 | zend_uchar opcode; // determining the instruction type
588 | zend_uchar op1_type;
589 | zend_uchar op2_type;
590 | zend_uchar result_type;
591 | };
592 | *****************************************************************************/
593 | PyObject *dict = PyDict_New ();
594 |
595 | // op->op1
596 | PyDict_SetItem (dict, Py_BuildValue ("s", "op1"),
597 | get_znode_operand (op_array, op, op->op1,
598 | op->op1_type,
599 | ZEND_VM_OP1_FLAGS (flags)));
600 |
601 | // op->op2
602 | PyDict_SetItem (dict, Py_BuildValue ("s", "op2"),
603 | get_znode_operand (op_array, op, op->op2,
604 | op->op2_type,
605 | ZEND_VM_OP2_FLAGS (flags)));
606 |
607 | // op->result
608 | switch (op->opcode)
609 | {
610 | case ZEND_CATCH:
611 | if (op->extended_value & ZEND_LAST_CATCH)
612 | {
613 | PyObject *znode_pyobject = PyDict_New ();
614 | PyDict_SetItem (dict, Py_BuildValue ("s", "op2"),
615 | znode_pyobject);
616 | }
617 | PyDict_SetItem (dict, Py_BuildValue ("s", "result"),
618 | get_znode_operand (op_array, op, op->result,
619 | op->result_type, -1));
620 | break;
621 | default:
622 | PyDict_SetItem (dict, Py_BuildValue ("s", "result"),
623 | get_znode_operand (op_array, op, op->result,
624 | op->result_type, -1));
625 | break;
626 | }
627 |
628 | // num
629 | PyDict_SetItem (dict, Py_BuildValue ("s", "num"),
630 | Py_BuildValue ("i", i));
631 |
632 | // op->extended_value
633 | PyDict_SetItem (dict, Py_BuildValue ("s", "extended_value"),
634 | Py_BuildValue ("i", op->extended_value));
635 |
636 | // op->lineno
637 | PyDict_SetItem (dict, Py_BuildValue ("s", "lineno"),
638 | Py_BuildValue ("i", op->lineno));
639 |
640 | // op->opcode
641 | PyDict_SetItem (dict, Py_BuildValue ("s", "opcode"),
642 | Py_BuildValue ("i", op->opcode));
643 |
644 | // op->opcode_name
645 | const char *opcode_name = zend_get_opcode_name (op->opcode);
646 | PyDict_SetItem (dict, Py_BuildValue ("s", "opcode_name"),
647 | Py_BuildValue ("s", ""));
648 |
649 | if (opcode_name)
650 | {
651 | PyDict_SetItem (dict, Py_BuildValue ("s", "opcode_name"),
652 | Py_BuildValue ("s", opcode_name));
653 | }
654 |
655 | // op->opcode_flags
656 | PyDict_SetItem (
657 | dict, Py_BuildValue ("s", "opcode_flags"),
658 | Py_BuildValue ("i", zend_get_opcode_flags (op->opcode)));
659 |
660 | // op->op1_type
661 | PyDict_SetItem (dict, Py_BuildValue ("s", "op1_type"),
662 | Py_BuildValue ("i", op->op1_type));
663 |
664 | // op->op2_type
665 | PyDict_SetItem (dict, Py_BuildValue ("s", "op2_type"),
666 | Py_BuildValue ("i", op->op2_type));
667 |
668 | // op->result_type
669 | PyDict_SetItem (dict, Py_BuildValue ("s", "result_type"),
670 | Py_BuildValue ("i", op->result_type));
671 |
672 | PyList_Append (insns_pyobject, dict);
673 | }
674 |
675 | PyDict_SetItem (fn_pobject, Py_BuildValue ("s", "instructions"),
676 | insns_pyobject);
677 | return true;
678 | }
679 |
680 | static bool
681 | generate_cfg_info (const zend_op_array *op_array, zend_file_handle *file_handle,
682 | PyObject *fn_pobject)
683 | {
684 | PyObject *cfg_pyobject = PyDict_New ();
685 |
686 | zend_cfg cfg;
687 | zend_arena *arena = zend_arena_create (64 * 1024);
688 | void *checkpoint = zend_arena_checkpoint (arena);
689 |
690 | if (zend_build_cfg (&arena, op_array, ZEND_CFG_SPLIT_AT_LIVE_RANGES, &cfg)
691 | != SUCCESS)
692 | {
693 | zend_arena_release (&arena, checkpoint);
694 | printf ("Error building cfg\n");
695 | return false;
696 | }
697 |
698 | if (zend_cfg_build_predecessors (&arena, &cfg) != SUCCESS)
699 | {
700 | printf ("Error building cfg predecessors\n");
701 | return false;
702 | }
703 |
704 | PyDict_SetItem (cfg_pyobject, Py_BuildValue ("s", "blocks_count"),
705 | Py_BuildValue ("i", cfg.blocks_count));
706 |
707 | PyDict_SetItem (cfg_pyobject, Py_BuildValue ("s", "edges_count"),
708 | Py_BuildValue ("i", cfg.edges_count));
709 |
710 | PyObject *cfg_blocks_pyobject = PyList_New (0);
711 | if (cfg.blocks)
712 | {
713 | int k;
714 | for (k = 0; k < cfg.blocks_count; k++)
715 | {
716 | PyObject *block_pyobject = PyDict_New ();
717 | zend_basic_block *block = &cfg.blocks[k];
718 |
719 | // first opcode number
720 | PyDict_SetItem (block_pyobject,
721 | Py_BuildValue ("s", "start"),
722 | Py_BuildValue ("i", block->start));
723 |
724 | // number of opcodes
725 | PyDict_SetItem (block_pyobject, Py_BuildValue ("s", "len"),
726 | Py_BuildValue ("i", block->len));
727 |
728 | // number of successors
729 | PyDict_SetItem (
730 | block_pyobject, Py_BuildValue ("s", "successors_count"),
731 | Py_BuildValue ("i", block->successors_count));
732 |
733 | // number of predecessors
734 | PyDict_SetItem (
735 | block_pyobject,
736 | Py_BuildValue ("s", "predecessors_count"),
737 | Py_BuildValue ("i", block->predecessors_count));
738 |
739 | // offset of 1-st predecessor
740 | PyDict_SetItem (
741 | block_pyobject,
742 | Py_BuildValue ("s", "predecessor_offset"),
743 | Py_BuildValue ("i", block->predecessor_offset));
744 |
745 | // immediate dominator block
746 | PyDict_SetItem (block_pyobject, Py_BuildValue ("s", "idom"),
747 | Py_BuildValue ("i", block->idom));
748 |
749 | // closest loop header, or -1
750 | PyDict_SetItem (block_pyobject,
751 | Py_BuildValue ("s", "loop_header"),
752 | Py_BuildValue ("i", block->loop_header));
753 |
754 | // steps away from the entry in the dom. tree
755 | PyDict_SetItem (block_pyobject,
756 | Py_BuildValue ("s", "level"),
757 | Py_BuildValue ("i", block->level));
758 |
759 | // list of dominated blocks
760 | PyDict_SetItem (block_pyobject,
761 | Py_BuildValue ("s", "children"),
762 | Py_BuildValue ("i", block->children));
763 |
764 | // next dominated block
765 | PyDict_SetItem (block_pyobject,
766 | Py_BuildValue ("s", "next_child"),
767 | Py_BuildValue ("i", block->next_child));
768 |
769 | // up to 2 successor blocks
770 | PyObject *sstorage_pyobject = PyList_New (0);
771 | PyList_Append (
772 | sstorage_pyobject,
773 | Py_BuildValue ("i", block->successors_storage[0]));
774 | PyList_Append (
775 | sstorage_pyobject,
776 | Py_BuildValue ("i", block->successors_storage[1]));
777 | PyDict_SetItem (block_pyobject,
778 | Py_BuildValue ("s", "successors_storage"),
779 | sstorage_pyobject);
780 |
781 | // successor block indices
782 | PyObject *successor_block_indices_pyobject = PyList_New (0);
783 | if (block->successors_count > 0)
784 | {
785 | for (int i = 0; i < block->successors_count; i++)
786 | {
787 | PyList_Append (
788 | successor_block_indices_pyobject,
789 | Py_BuildValue ("i",
790 | block->successors[i]));
791 | }
792 | }
793 | PyDict_SetItem (block_pyobject,
794 | Py_BuildValue ("s", "successors"),
795 | successor_block_indices_pyobject);
796 | PyList_Append (cfg_blocks_pyobject, block_pyobject);
797 | }
798 | }
799 | PyDict_SetItem (cfg_pyobject, Py_BuildValue ("s", "blocks"),
800 | cfg_blocks_pyobject);
801 |
802 | PyObject *predecessors_pyobject = PyList_New (0);
803 | if (cfg.predecessors)
804 | {
805 | int k;
806 | for (k = 0; k < cfg.edges_count; k++)
807 | {
808 | int predecessor = cfg.predecessors[k];
809 | PyList_Append (predecessors_pyobject,
810 | Py_BuildValue ("i", predecessor));
811 | }
812 | }
813 | PyDict_SetItem (cfg_pyobject, Py_BuildValue ("s", "predecessors"),
814 | predecessors_pyobject);
815 |
816 | PyDict_SetItem (fn_pobject, Py_BuildValue ("s", "cfg"), cfg_pyobject);
817 |
818 | bool dfg_status = generate_dfg_info (op_array, &cfg, fn_pobject);
819 | if (dfg_status == false)
820 | {
821 | return false;
822 | }
823 |
824 | bool ssa_status
825 | = generate_ssa_info (op_array, &cfg, file_handle, fn_pobject);
826 | if (ssa_status == false)
827 | {
828 | return false;
829 | }
830 |
831 | zend_arena_release (&arena, checkpoint);
832 | zend_arena_destroy (arena);
833 | return true;
834 | }
835 |
836 | static void
837 | zend_dump_variable (const zend_op_array *op_array, int var_num,
838 | PyObject *var_pyobject)
839 | {
840 | PyDict_SetItem (var_pyobject, Py_BuildValue ("s", "var_num"),
841 | Py_BuildValue ("i", var_num));
842 |
843 | if (var_num < op_array->last_var)
844 | {
845 | PyDict_SetItem (var_pyobject, Py_BuildValue ("s", "var_name"),
846 | Py_BuildValue ("s", op_array->vars[var_num]->val));
847 | }
848 | else
849 | {
850 | PyDict_SetItem (var_pyobject, Py_BuildValue ("s", "var_name"),
851 | Py_BuildValue ("s", ""));
852 | }
853 | }
854 |
855 | static PyObject *
856 | zend_dump_var_set (const zend_op_array *op_array, const char *name,
857 | zend_bitset set)
858 | {
859 | int first = 1;
860 | uint32_t i;
861 | PyObject *var_set_pyobject_vars = PyList_New (0);
862 |
863 | for (i = 0; i < op_array->last_var + op_array->T; i++)
864 | {
865 | if (zend_bitset_in (set, i))
866 | {
867 | if (first)
868 | {
869 | first = 0;
870 | }
871 | PyObject *var_value = PyDict_New ();
872 | zend_dump_variable (op_array, i, var_value);
873 | PyList_Append (var_set_pyobject_vars, var_value);
874 | }
875 | }
876 | return var_set_pyobject_vars;
877 | }
878 |
879 | static bool
880 | generate_dfg_info (const zend_op_array *op_array, zend_cfg *cfg,
881 | PyObject *fn_pobject)
882 | {
883 | zend_dfg dfg;
884 | int blocks_count = cfg->blocks_count;
885 | uint32_t set_size;
886 | uint32_t build_flags = 0;
887 | ALLOCA_FLAG (dfg_use_heap)
888 |
889 | dfg.vars = op_array->last_var + op_array->T;
890 | dfg.size = set_size = zend_bitset_len (dfg.vars);
891 | dfg.tmp
892 | = do_alloca ((set_size * sizeof (zend_ulong)) * (blocks_count * 4 + 1),
893 | dfg_use_heap);
894 | memset (dfg.tmp, 0,
895 | (set_size * sizeof (zend_ulong)) * (blocks_count * 4 + 1));
896 | dfg.def = dfg.tmp + set_size;
897 | dfg.use = dfg.def + set_size * blocks_count;
898 | dfg.in = dfg.use + set_size * blocks_count;
899 | dfg.out = dfg.in + set_size * blocks_count;
900 |
901 | if (zend_build_dfg (op_array, cfg, &dfg, build_flags) != SUCCESS)
902 | {
903 | free_alloca (dfg.tmp, dfg_use_heap);
904 | return false;
905 | }
906 |
907 | PyObject *dfg_pyobject = PyList_New (0);
908 | if (cfg->blocks)
909 | {
910 | for (int j = 0; j < cfg->blocks_count; j++)
911 | {
912 |
913 | PyObject *var_set_value_def = zend_dump_var_set (
914 | op_array, "def", DFG_BITSET (dfg.def, dfg.size, j));
915 | PyObject *var_set_value_use = zend_dump_var_set (
916 | op_array, "use", DFG_BITSET (dfg.use, dfg.size, j));
917 | PyObject *var_set_value_in = zend_dump_var_set (
918 | op_array, "in ", DFG_BITSET (dfg.in, dfg.size, j));
919 | PyObject *var_set_value_out = zend_dump_var_set (
920 | op_array, "out", DFG_BITSET (dfg.out, dfg.size, j));
921 | PyObject *var_set_value_tmp = zend_dump_var_set (
922 | op_array, "tmp", DFG_BITSET (dfg.tmp, dfg.size, j));
923 |
924 | PyObject *var_set_values_pyobject = PyDict_New ();
925 |
926 | PyDict_SetItem (var_set_values_pyobject,
927 | Py_BuildValue ("s", "block_index"),
928 | Py_BuildValue ("i", j));
929 |
930 | PyDict_SetItem (var_set_values_pyobject,
931 | Py_BuildValue ("s", "var_def"),
932 | var_set_value_def);
933 |
934 | PyDict_SetItem (var_set_values_pyobject,
935 | Py_BuildValue ("s", "var_use"),
936 | var_set_value_use);
937 |
938 | PyDict_SetItem (var_set_values_pyobject,
939 | Py_BuildValue ("s", "var_in"),
940 | var_set_value_in);
941 |
942 | PyDict_SetItem (var_set_values_pyobject,
943 | Py_BuildValue ("s", "var_out"),
944 | var_set_value_out);
945 |
946 | PyDict_SetItem (var_set_values_pyobject,
947 | Py_BuildValue ("s", "var_tmp"),
948 | var_set_value_tmp);
949 |
950 | PyList_Append (dfg_pyobject, var_set_values_pyobject);
951 | }
952 | }
953 |
954 | PyDict_SetItem (fn_pobject, Py_BuildValue ("s", "dfg"), dfg_pyobject);
955 | return true;
956 | }
957 |
958 | static void
959 | zend_ssa_pi_constraint_to_pyobject (zend_ssa_pi_constraint *constraint,
960 | PyObject *constraint_pyobject)
961 | {
962 | PyDict_SetItem (constraint_pyobject, Py_BuildValue ("s", "range_range_min"),
963 | Py_BuildValue ("i", constraint->range.range.min));
964 |
965 | PyDict_SetItem (constraint_pyobject, Py_BuildValue ("s", "range_range_max"),
966 | Py_BuildValue ("i", constraint->range.range.max));
967 |
968 | PyDict_SetItem (constraint_pyobject,
969 | Py_BuildValue ("s", "range_range_underflow"),
970 | Py_BuildValue ("i", constraint->range.range.underflow));
971 |
972 | PyDict_SetItem (constraint_pyobject,
973 | Py_BuildValue ("s", "range_range_overflow"),
974 | Py_BuildValue ("i", constraint->range.range.overflow));
975 |
976 | PyDict_SetItem (constraint_pyobject, Py_BuildValue ("s", "range_min_var"),
977 | Py_BuildValue ("i", constraint->range.min_var));
978 |
979 | PyDict_SetItem (constraint_pyobject, Py_BuildValue ("s", "range_max_var"),
980 | Py_BuildValue ("i", constraint->range.max_var));
981 |
982 | // ((min_var>0) ? MIN(ssa_var) : 0) + range.min
983 | PyDict_SetItem (constraint_pyobject,
984 | Py_BuildValue ("s", "range_min_ssa_var"),
985 | Py_BuildValue ("i", constraint->range.min_ssa_var));
986 |
987 | // ((max_var>0) ? MAX(ssa_var) : 0) + range.max
988 | PyDict_SetItem (constraint_pyobject,
989 | Py_BuildValue ("s", "range_max_ssa_var"),
990 | Py_BuildValue ("i", constraint->range.max_ssa_var));
991 |
992 | // zend_ssa_negative_lat check = POS_INF;
993 | switch (constraint->range.negative)
994 | {
995 | case NEG_NONE:
996 | PyDict_SetItem (constraint_pyobject,
997 | Py_BuildValue ("s", "range_negative"),
998 | Py_BuildValue ("s", "NEG_NONE"));
999 | break;
1000 | case NEG_INIT:
1001 | PyDict_SetItem (constraint_pyobject,
1002 | Py_BuildValue ("s", "range_negative"),
1003 | Py_BuildValue ("s", "NEG_INIT"));
1004 | break;
1005 | case NEG_INVARIANT:
1006 | PyDict_SetItem (constraint_pyobject,
1007 | Py_BuildValue ("s", "range_negative"),
1008 | Py_BuildValue ("s", "NEG_INVARIANT"));
1009 | break;
1010 | case NEG_USE_LT:
1011 | PyDict_SetItem (constraint_pyobject,
1012 | Py_BuildValue ("s", "range_negative"),
1013 | Py_BuildValue ("s", "NEG_USE_LT"));
1014 | break;
1015 | case NEG_USE_GT:
1016 | PyDict_SetItem (constraint_pyobject,
1017 | Py_BuildValue ("s", "range_negative"),
1018 | Py_BuildValue ("s", "NEG_USE_GT"));
1019 | break;
1020 | default:
1021 | PyDict_SetItem (constraint_pyobject,
1022 | Py_BuildValue ("s", "range_negative"),
1023 | Py_BuildValue ("s", "NEG_UNKNOWN"));
1024 | break;
1025 | }
1026 | }
1027 |
1028 | static void
1029 | zend_ssa_phi_to_pyobject (const zend_op_array *op_array, const zend_ssa *ssa,
1030 | zend_ssa_phi *phi, PyObject *phi_pyobject)
1031 | {
1032 | // if >= 0 this is actually a e-SSA Pi
1033 | PyDict_SetItem (phi_pyobject, Py_BuildValue ("s", "pi"),
1034 | Py_BuildValue ("i", phi->pi));
1035 |
1036 | // Original CV, VAR or TMP variable index
1037 | PyDict_SetItem (phi_pyobject, Py_BuildValue ("s", "variable_index"),
1038 | Py_BuildValue ("i", phi->var));
1039 |
1040 | PyObject *var_pyobject = PyDict_New ();
1041 | if (phi->var >= 0)
1042 | {
1043 | zend_dump_variable (op_array, phi->var, var_pyobject);
1044 | }
1045 | PyDict_SetItem (phi_pyobject, Py_BuildValue ("s", "variable"),
1046 | var_pyobject);
1047 |
1048 | // SSA variable index
1049 | PyDict_SetItem (phi_pyobject, Py_BuildValue ("s", "ssa_variable_index"),
1050 | Py_BuildValue ("i", phi->ssa_var));
1051 |
1052 | // current BB index
1053 | PyDict_SetItem (phi_pyobject, Py_BuildValue ("s", "current_block_index"),
1054 | Py_BuildValue ("i", phi->block));
1055 |
1056 | // flag to avoid recursive processing
1057 | PyDict_SetItem (phi_pyobject, Py_BuildValue ("s", "visited"),
1058 | Py_BuildValue ("i", phi->visited));
1059 |
1060 | PyDict_SetItem (phi_pyobject, Py_BuildValue ("s", "has_range_constraint"),
1061 | Py_BuildValue ("i", phi->has_range_constraint));
1062 |
1063 | PyObject *constraint_pyobject = PyDict_New ();
1064 | if (phi->has_range_constraint)
1065 | {
1066 | zend_ssa_pi_constraint_to_pyobject (&phi->constraint,
1067 | constraint_pyobject);
1068 | }
1069 | PyDict_SetItem (phi_pyobject, Py_BuildValue ("s", "constraint"),
1070 | constraint_pyobject);
1071 |
1072 | PyObject *sources_pyobject = PyList_New (0);
1073 | if (phi->sources)
1074 | {
1075 | int current_block_index = phi->block;
1076 | for (int i = 0;
1077 | i < ssa->cfg.blocks[current_block_index].predecessors_count;
1078 | ++i)
1079 | {
1080 | PyList_Append (sources_pyobject,
1081 | Py_BuildValue ("i", phi->sources[i]));
1082 | }
1083 | }
1084 | PyDict_SetItem (phi_pyobject, Py_BuildValue ("s", "sources"),
1085 | sources_pyobject);
1086 | }
1087 |
1088 | static void
1089 | zend_dump_ssa_variable (const zend_op_array *op_array, const zend_ssa *ssa,
1090 | int ssa_var_num, int var_num, PyObject *var_pyobject)
1091 | {
1092 | PyDict_SetItem (var_pyobject, Py_BuildValue ("s", "ssa_var_num"),
1093 | Py_BuildValue ("i", -1));
1094 |
1095 | if (ssa_var_num >= 0)
1096 | PyDict_SetItem (var_pyobject, Py_BuildValue ("s", "ssa_var_num"),
1097 | Py_BuildValue ("i", ssa_var_num));
1098 |
1099 | zend_dump_variable (op_array, var_num, var_pyobject);
1100 |
1101 | // opcode that defines this value
1102 | PyDict_SetItem (var_pyobject, Py_BuildValue ("s", "definition"),
1103 | Py_BuildValue ("i", ssa->vars[ssa_var_num].definition));
1104 |
1105 | // phi that defines this value
1106 | PyObject *definition_phi_pyobject = PyDict_New ();
1107 | if (ssa->vars[ssa_var_num].definition_phi)
1108 | {
1109 | zend_ssa_phi *phi = ssa->vars[ssa_var_num].definition_phi;
1110 | zend_ssa_phi_to_pyobject (op_array, ssa, phi,
1111 | definition_phi_pyobject);
1112 | }
1113 | PyDict_SetItem (var_pyobject, Py_BuildValue ("s", "definition_phi"),
1114 | definition_phi_pyobject);
1115 |
1116 | // value doesn't mater (used as op1 in ZEND_ASSIGN)
1117 | PyDict_SetItem (var_pyobject, Py_BuildValue ("s", "no_val"),
1118 | Py_BuildValue ("i", ssa->vars[ssa_var_num].no_val));
1119 |
1120 | // uses of this value, linked through opN_use_chain
1121 | PyDict_SetItem (var_pyobject, Py_BuildValue ("s", "use_chain"),
1122 | Py_BuildValue ("i", ssa->vars[ssa_var_num].use_chain));
1123 |
1124 | PyDict_SetItem (var_pyobject, Py_BuildValue ("s", "escape_state"),
1125 | Py_BuildValue ("i", ssa->vars[ssa_var_num].escape_state));
1126 | }
1127 |
1128 | static PyObject *
1129 | zend_dump_ssa_variables (const zend_op_array *op_array, const zend_ssa *ssa)
1130 | {
1131 | PyObject *ssa_variables_pyobject = PyList_New (0);
1132 |
1133 | if (ssa->vars)
1134 | {
1135 | for (int ssa_var_num = 0; ssa_var_num < ssa->vars_count;
1136 | ssa_var_num++)
1137 | {
1138 | PyObject *var_pyobject = PyDict_New ();
1139 | zend_dump_ssa_variable (op_array, ssa, ssa_var_num,
1140 | ssa->vars[ssa_var_num].var,
1141 | var_pyobject);
1142 |
1143 | // set scc
1144 | PyDict_SetItem (
1145 | var_pyobject,
1146 | Py_BuildValue ("s", "strongly_connected_component"),
1147 | Py_BuildValue ("i", ssa->vars[ssa_var_num].scc));
1148 |
1149 | // set default to false
1150 | PyDict_SetItem (
1151 | var_pyobject,
1152 | Py_BuildValue ("s",
1153 | "strongly_connected_component_entry"),
1154 | Py_BuildValue ("i", 1));
1155 |
1156 | if (ssa->vars[ssa_var_num].scc >= 0)
1157 | {
1158 | if (ssa->vars[ssa_var_num].scc_entry)
1159 | {
1160 | // set to true
1161 | PyDict_SetItem (
1162 | var_pyobject,
1163 | Py_BuildValue ("s",
1164 | "strongly_connected_"
1165 | "component_entry"),
1166 | Py_BuildValue ("i", 0));
1167 | }
1168 | }
1169 |
1170 | PyList_Append (ssa_variables_pyobject, var_pyobject);
1171 | }
1172 | }
1173 | return ssa_variables_pyobject;
1174 | }
1175 |
1176 | static PyObject *
1177 | zend_dump_ssa_instructions (const zend_op_array *op_array, const zend_ssa *ssa)
1178 | {
1179 | PyObject *ssa_instructions_pyobject = PyList_New (0);
1180 |
1181 | /*
1182 | op1_use -> op1_def
1183 | op2_use -> op2_def
1184 | result_use -> result_def
1185 |
1186 | takes *_use
1187 | *_def: maps to def if greater than -1. creates a def of that variable stored
1188 | in _def
1189 |
1190 | */
1191 |
1192 | if (ssa->ops)
1193 | {
1194 | for (int i = op_array->last - 1; i >= 0; i--)
1195 | {
1196 | zend_ssa_op *op = ssa->ops + i;
1197 | PyObject *op_pyobject = PyDict_New ();
1198 |
1199 | PyDict_SetItem (op_pyobject, Py_BuildValue ("s", "op1_use"),
1200 | Py_BuildValue ("i", op->op1_use));
1201 |
1202 | PyDict_SetItem (op_pyobject, Py_BuildValue ("s", "op2_use"),
1203 | Py_BuildValue ("i", op->op2_use));
1204 |
1205 | PyDict_SetItem (op_pyobject,
1206 | Py_BuildValue ("s", "result_use"),
1207 | Py_BuildValue ("i", op->result_use));
1208 |
1209 | PyDict_SetItem (op_pyobject, Py_BuildValue ("s", "op1_def"),
1210 | Py_BuildValue ("i", op->op1_def));
1211 |
1212 | PyDict_SetItem (op_pyobject, Py_BuildValue ("s", "op2_def"),
1213 | Py_BuildValue ("i", op->op2_def));
1214 |
1215 | PyDict_SetItem (op_pyobject,
1216 | Py_BuildValue ("s", "result_def"),
1217 | Py_BuildValue ("i", op->result_def));
1218 |
1219 | PyDict_SetItem (op_pyobject,
1220 | Py_BuildValue ("s", "op1_use_chain"),
1221 | Py_BuildValue ("i", op->op1_use_chain));
1222 |
1223 | PyDict_SetItem (op_pyobject,
1224 | Py_BuildValue ("s", "op2_use_chain"),
1225 | Py_BuildValue ("i", op->op2_use_chain));
1226 |
1227 | PyDict_SetItem (op_pyobject,
1228 | Py_BuildValue ("s", "res_use_chain"),
1229 | Py_BuildValue ("i", op->res_use_chain));
1230 |
1231 | PyList_Append (ssa_instructions_pyobject, op_pyobject);
1232 | }
1233 | }
1234 | return ssa_instructions_pyobject;
1235 | }
1236 |
1237 | static PyObject *
1238 | zend_dump_ssa_blocks (const zend_op_array *op_array, const zend_ssa *ssa)
1239 | {
1240 | PyObject *ssa_blocks_pyobject = PyList_New (0);
1241 |
1242 | if (ssa->blocks)
1243 | {
1244 | for (int i = 0; i < ssa->cfg.blocks_count; i++)
1245 | {
1246 | PyObject *block_pyobject = PyDict_New ();
1247 |
1248 | PyDict_SetItem (block_pyobject,
1249 | Py_BuildValue ("s", "block_index"),
1250 | Py_BuildValue ("i", i));
1251 |
1252 | PyObject *phis_pyobject = PyList_New (0);
1253 | zend_ssa_phi *phi = ssa->blocks[i].phis;
1254 | while (phi)
1255 | {
1256 | PyObject *phi_pyobject = PyDict_New ();
1257 | zend_ssa_phi_to_pyobject (op_array, ssa, phi,
1258 | phi_pyobject);
1259 |
1260 | PyDict_SetItem (block_pyobject,
1261 | Py_BuildValue ("s", "phis"),
1262 | phi_pyobject);
1263 |
1264 | PyList_Append (phis_pyobject, phi_pyobject);
1265 | phi = phi->next;
1266 | }
1267 |
1268 | PyDict_SetItem (block_pyobject, Py_BuildValue ("s", "phis"),
1269 | phis_pyobject);
1270 |
1271 | PyList_Append (ssa_blocks_pyobject, block_pyobject);
1272 | }
1273 | }
1274 | return ssa_blocks_pyobject;
1275 | }
1276 |
1277 | static PyObject *
1278 | zend_dump_zend_ssa (const zend_op_array *op_array, const zend_ssa *ssa)
1279 | {
1280 | PyObject *ssa_pyobject = PyDict_New ();
1281 |
1282 | // number of SCCs
1283 | PyDict_SetItem (ssa_pyobject, Py_BuildValue ("s", "number_of_sccs"),
1284 | Py_BuildValue ("i", ssa->sccs));
1285 |
1286 | // number of SSA variables
1287 | PyDict_SetItem (ssa_pyobject,
1288 | Py_BuildValue ("s", "number_of_ssa_variables"),
1289 | Py_BuildValue ("i", ssa->vars_count));
1290 |
1291 | // dump ssa vars (ssa->vars)
1292 | PyDict_SetItem (ssa_pyobject, Py_BuildValue ("s", "ssa_variables"),
1293 | zend_dump_ssa_variables (op_array, ssa));
1294 |
1295 | // dump array of SSA instructions (ssa->ops)
1296 | PyDict_SetItem (ssa_pyobject, Py_BuildValue ("s", "ssa_instructions"),
1297 | zend_dump_ssa_instructions (op_array, ssa));
1298 |
1299 | // dump array of SSA blocks (ssa->blocks)
1300 | PyDict_SetItem (ssa_pyobject, Py_BuildValue ("s", "ssa_blocks"),
1301 | zend_dump_ssa_blocks (op_array, ssa));
1302 |
1303 | return ssa_pyobject;
1304 | }
1305 |
1306 | static bool
1307 | generate_ssa_info (const zend_op_array *op_array, zend_cfg *cfg,
1308 | zend_file_handle *file_handle, PyObject *fn_pobject)
1309 | {
1310 | zend_ssa ssa;
1311 | zend_script script;
1312 | uint32_t build_flags = 0;
1313 |
1314 | script.first_early_binding_opline
1315 | = (op_array->fn_flags & ZEND_ACC_EARLY_BINDING)
1316 | ? zend_build_delayed_early_binding_list (op_array)
1317 | : (uint32_t)-1;
1318 | script.main_op_array = *op_array;
1319 |
1320 | if (file_handle->opened_path)
1321 | {
1322 | script.filename = zend_string_copy (file_handle->opened_path);
1323 | }
1324 | else
1325 | {
1326 | script.filename = zend_string_init (
1327 | file_handle->filename, strlen (file_handle->filename), 0);
1328 | }
1329 | zend_string_hash_val (script.filename);
1330 |
1331 | /* Build SSA */
1332 | memset (&ssa, 0, sizeof (zend_ssa));
1333 |
1334 | zend_arena *arena = zend_arena_create (64 * 1024);
1335 | void *checkpoint = zend_arena_checkpoint (arena);
1336 |
1337 | if (zend_build_cfg (&arena, op_array, ZEND_CFG_SPLIT_AT_LIVE_RANGES,
1338 | &ssa.cfg)
1339 | != SUCCESS)
1340 | {
1341 | printf ("Error building ssa cfg\n");
1342 | zend_arena_release (&arena, checkpoint);
1343 | return false;
1344 | }
1345 |
1346 | if (zend_cfg_build_predecessors (&arena, &ssa.cfg) != SUCCESS)
1347 | {
1348 | printf ("Error building ssa cfg predecessors\n");
1349 | return false;
1350 | }
1351 |
1352 | if (zend_cfg_compute_dominators_tree (op_array, &ssa.cfg) != SUCCESS)
1353 | {
1354 | printf ("Error building ssa cfg dominators tree\n");
1355 | zend_arena_release (&arena, checkpoint);
1356 | return false;
1357 | }
1358 |
1359 | if (zend_build_ssa (&arena, &script, op_array, build_flags, &ssa)
1360 | != SUCCESS)
1361 | {
1362 | printf ("Error building ssa\n");
1363 | zend_arena_release (&arena, checkpoint);
1364 | return false;
1365 | }
1366 |
1367 | if (zend_ssa_compute_use_def_chains (&arena, op_array, &ssa) != SUCCESS)
1368 | {
1369 | printf ("Error building ssa cfg use_def_chains\n");
1370 | zend_arena_release (&arena, checkpoint);
1371 | return false;
1372 | }
1373 |
1374 | PyObject *ssa_pyobject = zend_dump_zend_ssa (op_array, &ssa);
1375 | PyDict_SetItem (fn_pobject, Py_BuildValue ("s", "ssa"), ssa_pyobject);
1376 |
1377 | zend_arena_release (&arena, checkpoint);
1378 | zend_arena_destroy (arena);
1379 | return true;
1380 | }
1381 |
1382 | static PyMethodDef OpArrayMethods[]
1383 | = { { "convert", method_convert, METH_VARARGS,
1384 | "Compile and Converts PHP code/script to Bytecode, CFG, DFG, SSA" },
1385 | { NULL, NULL, 0, NULL } };
1386 |
1387 |
1388 | static struct PyModuleDef OpArrayDefinition
1389 | = { PyModuleDef_HEAD_INIT, "convert",
1390 | "Compile and Convert PHP code/script to Bytecode, CFG, DFG, SSA", -1,
1391 | OpArrayMethods };
1392 |
1393 | PyMODINIT_FUNC
1394 | PyInit_php_to_bytecode_converter (void)
1395 | {
1396 | Py_Initialize ();
1397 | return PyModule_Create (&OpArrayDefinition);
1398 | }
--------------------------------------------------------------------------------
/vulnerabilities/vulnerable_web_apps.md:
--------------------------------------------------------------------------------
1 | # List of vulnerabilties for `Vulnerable Web applications Test cases`
2 | Before running any of the test cases below, you need to set the docker container by following the [Setup In README.md](README.md#setting-up)
3 |
4 | ## Testing with `DVWA`
5 | `Damn Vulnerable Web Application (DVWA)`
6 |
7 | ### Testing
8 | ```sh
9 | cd /app
10 | git clone https://github.com/digininja/DVWA targets/DVWA
11 | python3 detectors/code_injection.py
12 | ```
13 |
14 | ### Reports
15 | ```sh
16 | [*] ----------------------------------------------------------------------------------------------------
17 | [*] ----------------------------------------------------------------------------------------------------
18 | [*] TOTAL_VULNS = 21
19 | [*]
20 | [*] ----------------------------------------------------------------------------------------------------
21 | [*] ----------------------------------------------------------------------------------------------------
22 | [*] INDEX = 1
23 | [*] IMPACT = HIGH
24 | [*] VULNERABILTY TYPE = code_injection
25 | [*] VISITED FUNCTION CALLS =
26 | [*] FILE = /app/targets/DVWA/vulnerabilities/view_help.php::main
27 | [*]
28 | [*] --- SOURCE PATH TO VULNERABILTY ---
29 | [*] lineno=14 ------ $id = $_GET[ 'id' ];
30 | [*] lineno=20 ------ eval( '?>' . file_get_contents( DVWA_WEB_PAGE_TO_ROOT . "vulnerabilities/{$id}/help/help.php" ) . '
83 | [*] lineno=32 ------
84 | [*]
85 | [*]
86 | [*] ----------------------------------------------------------------------------------------------------
87 | [*] ----------------------------------------------------------------------------------------------------
88 | [*] INDEX = 6
89 | [*] IMPACT = HIGH
90 | [*] VULNERABILTY TYPE = code_injection
91 | [*] VISITED FUNCTION CALLS =
92 | [*] FILE = /app/targets/DVWA/vulnerabilities/captcha/source/low.php::main
93 | [*]
94 | [*] --- SOURCE PATH TO VULNERABILTY ---
95 | [*] lineno=51 ------ $pass_conf = $_POST[ 'password_conf' ];
96 | [*] lineno=33 ------
97 | [*]
98 | [*]
99 | [*] ----------------------------------------------------------------------------------------------------
100 | [*] ----------------------------------------------------------------------------------------------------
101 | [*] INDEX = 7
102 | [*] IMPACT = HIGH
103 | [*] VULNERABILTY TYPE = code_injection
104 | [*] VISITED FUNCTION CALLS =
105 | [*] FILE = /app/targets/DVWA/vulnerabilities/captcha/source/medium.php::main
106 | [*]
107 | [*] --- SOURCE PATH TO VULNERABILTY ---
108 | [*] lineno=52 ------ $pass_conf = $_POST[ 'password_conf' ];
109 | [*] lineno=33 ------
110 | [*] lineno=32 ------
111 | [*]
112 | [*]
113 | [*] ----------------------------------------------------------------------------------------------------
114 | [*] ----------------------------------------------------------------------------------------------------
115 | [*] INDEX = 8
116 | [*] IMPACT = HIGH
117 | [*] VULNERABILTY TYPE = code_injection
118 | [*] VISITED FUNCTION CALLS =
119 | [*] FILE = /app/targets/DVWA/vulnerabilities/captcha/source/medium.php::main
120 | [*]
121 | [*] --- SOURCE PATH TO VULNERABILTY ---
122 | [*] lineno=52 ------ $pass_conf = $_POST[ 'password_conf' ];
123 | [*] lineno=33 ------
124 | [*]
125 | [*]
126 | [*] ----------------------------------------------------------------------------------------------------
127 | [*] ----------------------------------------------------------------------------------------------------
128 | [*] INDEX = 9
129 | [*] IMPACT = HIGH
130 | [*] VULNERABILTY TYPE = code_injection
131 | [*] VISITED FUNCTION CALLS =
132 | [*] FILE = /app/targets/DVWA/vulnerabilities/csp/source/high.php::main
133 | [*]
134 | [*] --- SOURCE PATH TO VULNERABILTY ---
135 | [*] lineno=10 ------ " . $_POST['include'] . "
136 | [*]
137 | [*]
138 | [*] ----------------------------------------------------------------------------------------------------
139 | [*] ----------------------------------------------------------------------------------------------------
140 | [*] INDEX = 10
141 | [*] IMPACT = HIGH
142 | [*] VULNERABILTY TYPE = code_injection
143 | [*] VISITED FUNCTION CALLS =
144 | [*] FILE = /app/targets/DVWA/vulnerabilities/csp/source/impossible.php::main
145 | [*]
146 | [*] --- SOURCE PATH TO VULNERABILTY ---
147 | [*] lineno=11 ------ " . $_POST['include'] . "
148 | [*]
149 | [*]
150 | [*] ----------------------------------------------------------------------------------------------------
151 | [*] ----------------------------------------------------------------------------------------------------
152 | [*] INDEX = 11
153 | [*] IMPACT = HIGH
154 | [*] VULNERABILTY TYPE = code_injection
155 | [*] VISITED FUNCTION CALLS =
156 | [*] FILE = /app/targets/DVWA/vulnerabilities/csp/source/jsonp.php::main
157 | [*]
158 | [*] --- SOURCE PATH TO VULNERABILTY ---
159 | [*] lineno=5 ------ $callback = $_GET['callback'];
160 | [*] lineno=12 ------ echo $callback . "(".json_encode($outp).")";
161 | [*]
162 | [*]
163 | [*] ----------------------------------------------------------------------------------------------------
164 | [*] ----------------------------------------------------------------------------------------------------
165 | [*] INDEX = 12
166 | [*] IMPACT = HIGH
167 | [*] VULNERABILTY TYPE = code_injection
168 | [*] VISITED FUNCTION CALLS =
169 | [*] FILE = /app/targets/DVWA/vulnerabilities/csp/source/low.php::main
170 | [*]
171 | [*] --- SOURCE PATH TO VULNERABILTY ---
172 | [*] lineno=15 ------
173 | [*]
174 | [*]
175 | [*] ----------------------------------------------------------------------------------------------------
176 | [*] ----------------------------------------------------------------------------------------------------
177 | [*] INDEX = 13
178 | [*] IMPACT = HIGH
179 | [*] VULNERABILTY TYPE = code_injection
180 | [*] VISITED FUNCTION CALLS =
181 | [*] FILE = /app/targets/DVWA/vulnerabilities/csp/source/medium.php::main
182 | [*]
183 | [*] --- SOURCE PATH TO VULNERABILTY ---
184 | [*] lineno=16 ------ " . $_POST['include'] . "
185 | [*]
186 | [*]
187 | [*] ----------------------------------------------------------------------------------------------------
188 | [*] ----------------------------------------------------------------------------------------------------
189 | [*] INDEX = 14
190 | [*] IMPACT = HIGH
191 | [*] VULNERABILTY TYPE = code_injection
192 | [*] VISITED FUNCTION CALLS =
193 | [*] FILE = /app/targets/DVWA/vulnerabilities/exec/source/low.php::main
194 | [*]
195 | [*] --- SOURCE PATH TO VULNERABILTY ---
196 | [*] lineno=5 ------ $target = $_REQUEST[ 'ip' ];
197 | [*] lineno=10 ------ $cmd = shell_exec( 'ping ' . $target );
198 | [*]
199 | [*]
200 | [*] ----------------------------------------------------------------------------------------------------
201 | [*] ----------------------------------------------------------------------------------------------------
202 | [*] INDEX = 15
203 | [*] IMPACT = HIGH
204 | [*] VULNERABILTY TYPE = code_injection
205 | [*] VISITED FUNCTION CALLS =
206 | [*] FILE = /app/targets/DVWA/vulnerabilities/open_redirect/source/high.php::main
207 | [*]
208 | [*] --- SOURCE PATH TO VULNERABILTY ---
209 | [*] lineno=5 ------ header ("location: " . $_GET['redirect']);
210 | [*]
211 | [*]
212 | [*] ----------------------------------------------------------------------------------------------------
213 | [*] ----------------------------------------------------------------------------------------------------
214 | [*] INDEX = 16
215 | [*] IMPACT = HIGH
216 | [*] VULNERABILTY TYPE = code_injection
217 | [*] VISITED FUNCTION CALLS =
218 | [*] FILE = /app/targets/DVWA/vulnerabilities/open_redirect/source/low.php::main
219 | [*]
220 | [*] --- SOURCE PATH TO VULNERABILTY ---
221 | [*] lineno=4 ------ header ("location: " . $_GET['redirect']);
222 | [*]
223 | [*]
224 | [*] ----------------------------------------------------------------------------------------------------
225 | [*] ----------------------------------------------------------------------------------------------------
226 | [*] INDEX = 17
227 | [*] IMPACT = HIGH
228 | [*] VULNERABILTY TYPE = code_injection
229 | [*] VISITED FUNCTION CALLS =
230 | [*] FILE = /app/targets/DVWA/vulnerabilities/open_redirect/source/medium.php::main
231 | [*]
232 | [*] --- SOURCE PATH TO VULNERABILTY ---
233 | [*] lineno=11 ------ header ("location: " . $_GET['redirect']);
234 | [*]
235 | [*]
236 | [*] ----------------------------------------------------------------------------------------------------
237 | [*] ----------------------------------------------------------------------------------------------------
238 | [*] INDEX = 18
239 | [*] IMPACT = HIGH
240 | [*] VULNERABILTY TYPE = code_injection
241 | [*] VISITED FUNCTION CALLS =
242 | [*] FILE = /app/targets/DVWA/vulnerabilities/sqli/source/low.php::main
243 | [*]
244 | [*] --- SOURCE PATH TO VULNERABILTY ---
245 | [*] lineno=5 ------ $id = $_REQUEST[ 'id' ];
246 | [*] lineno=10 ------ $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
247 | [*]
248 | [*]
249 | [*] ----------------------------------------------------------------------------------------------------
250 | [*] ----------------------------------------------------------------------------------------------------
251 | [*] INDEX = 19
252 | [*] IMPACT = HIGH
253 | [*] VULNERABILTY TYPE = code_injection
254 | [*] VISITED FUNCTION CALLS =
255 | [*] FILE = /app/targets/DVWA/vulnerabilities/sqli_blind/source/high.php::main
256 | [*]
257 | [*] --- SOURCE PATH TO VULNERABILTY ---
258 | [*] lineno=5 ------ $id = $_COOKIE[ 'id' ];
259 | [*] lineno=11 ------ $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
260 | [*]
261 | [*]
262 | [*] ----------------------------------------------------------------------------------------------------
263 | [*] ----------------------------------------------------------------------------------------------------
264 | [*] INDEX = 20
265 | [*] IMPACT = HIGH
266 | [*] VULNERABILTY TYPE = code_injection
267 | [*] VISITED FUNCTION CALLS =
268 | [*] FILE = /app/targets/DVWA/vulnerabilities/sqli_blind/source/low.php::main
269 | [*]
270 | [*] --- SOURCE PATH TO VULNERABILTY ---
271 | [*] lineno=5 ------ $id = $_GET[ 'id' ];
272 | [*] lineno=11 ------ $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
273 | [*]
274 | [*]
275 | [*] ----------------------------------------------------------------------------------------------------
276 | [*] ----------------------------------------------------------------------------------------------------
277 | [*] INDEX = 21
278 | [*] IMPACT = HIGH
279 | [*] VULNERABILTY TYPE = code_injection
280 | [*] VISITED FUNCTION CALLS =
281 | [*] FILE = /app/targets/DVWA/vulnerabilities/xss_r/source/low.php::main
282 | [*]
283 | [*] --- SOURCE PATH TO VULNERABILTY ---
284 | [*] lineno=8 ------ $html .= 'Hello ' . $_GET[ 'name' ] . '
';
285 | [*]
286 | [*]
287 | [*] ----------------------------------------------------------------------------------------------------
288 | [*] ----------------------------------------------------------------------------------------------------
289 | [*] TOTAL_VULNS = 21
290 | [*]
291 | ```
292 |
293 | ### Fixes
294 | ```
295 | N/A
296 | ```
297 |
298 | ---
299 |
300 | ## Testing with `OWASP-vuln-web-app`
301 | `OWASP Vulnerable Web Application Project`
302 |
303 | ### Testing
304 | ```sh
305 | cd /app
306 | git clone https://github.com/OWASP/Vulnerable-Web-Application targets/Vulnerable-Web-Application
307 | python3 detectors/code_injection.py
308 | ```
309 |
310 | ### Reports
311 | ```sh
312 | [*] ----------------------------------------------------------------------------------------------------
313 | [*] ----------------------------------------------------------------------------------------------------
314 | [*] TOTAL_VULNS = 10
315 | [*]
316 | [*] ----------------------------------------------------------------------------------------------------
317 | [*] ----------------------------------------------------------------------------------------------------
318 | [*] INDEX = 1
319 | [*] IMPACT = HIGH
320 | [*] VULNERABILTY TYPE = code_injection
321 | [*] VISITED FUNCTION CALLS =
322 | [*] FILE = /app/targets/Vulnerable-Web-Application/FileInclusion/pages/lvl1.php::main
323 | [*]
324 | [*] --- SOURCE PATH TO VULNERABILTY ---
325 | [*] lineno=25 ------ @include($_GET[ 'file' ]);
326 | [*]
327 | [*]
328 | [*] ----------------------------------------------------------------------------------------------------
329 | [*] ----------------------------------------------------------------------------------------------------
330 | [*] INDEX = 2
331 | [*] IMPACT = HIGH
332 | [*] VULNERABILTY TYPE = code_injection
333 | [*] VISITED FUNCTION CALLS =
334 | [*] FILE = /app/targets/Vulnerable-Web-Application/FileInclusion/pages/lvl1.php::main
335 | [*]
336 | [*] --- SOURCE PATH TO VULNERABILTY ---
337 | [*] lineno=26 ------ echo"".$_GET[ 'file' ]."
";
338 | [*]
339 | [*]
340 | [*] ----------------------------------------------------------------------------------------------------
341 | [*] ----------------------------------------------------------------------------------------------------
342 | [*] INDEX = 3
343 | [*] IMPACT = HIGH
344 | [*] VULNERABILTY TYPE = code_injection
345 | [*] VISITED FUNCTION CALLS =
346 | [*] FILE = /app/targets/Vulnerable-Web-Application/FileUpload/fileupload1.php::main
347 | [*]
348 | [*] --- SOURCE PATH TO VULNERABILTY ---
349 | [*] lineno=28 ------ echo "File uploaded /uploads/".$_FILES["file"]["name"];
350 | [*]
351 | [*]
352 | [*] ----------------------------------------------------------------------------------------------------
353 | [*] ----------------------------------------------------------------------------------------------------
354 | [*] INDEX = 4
355 | [*] IMPACT = HIGH
356 | [*] VULNERABILTY TYPE = code_injection
357 | [*] VISITED FUNCTION CALLS =
358 | [*] FILE = /app/targets/Vulnerable-Web-Application/FileUpload/fileupload2.php::main
359 | [*]
360 | [*] --- SOURCE PATH TO VULNERABILTY ---
361 | [*] lineno=37 ------ echo "File uploaded /uploads/".$_FILES["file"]["name"];
362 | [*]
363 | [*]
364 | [*] ----------------------------------------------------------------------------------------------------
365 | [*] ----------------------------------------------------------------------------------------------------
366 | [*] INDEX = 5
367 | [*] IMPACT = HIGH
368 | [*] VULNERABILTY TYPE = code_injection
369 | [*] VISITED FUNCTION CALLS =
370 | [*] FILE = /app/targets/Vulnerable-Web-Application/FileUpload/fileupload3.php::main
371 | [*]
372 | [*] --- SOURCE PATH TO VULNERABILTY ---
373 | [*] lineno=39 ------ echo "File uploaded /uploads/".$_FILES["file"]["name"];
374 | [*]
375 | [*]
376 | [*] ----------------------------------------------------------------------------------------------------
377 | [*] ----------------------------------------------------------------------------------------------------
378 | [*] INDEX = 6
379 | [*] IMPACT = HIGH
380 | [*] VULNERABILTY TYPE = code_injection
381 | [*] VISITED FUNCTION CALLS =
382 | [*] FILE = /app/targets/Vulnerable-Web-Application/SQL/sql1.php::main
383 | [*]
384 | [*] --- SOURCE PATH TO VULNERABILTY ---
385 | [*] lineno=39 ------ $firstname = $_POST["firstname"];
386 | [*] lineno=40 ------ $sql = "SELECT lastname FROM users WHERE firstname='$firstname'";//String
387 | [*]
388 | [*]
389 | [*] ----------------------------------------------------------------------------------------------------
390 | [*] ----------------------------------------------------------------------------------------------------
391 | [*] INDEX = 7
392 | [*] IMPACT = HIGH
393 | [*] VULNERABILTY TYPE = code_injection
394 | [*] VISITED FUNCTION CALLS =
395 | [*] FILE = /app/targets/Vulnerable-Web-Application/SQL/sql2.php::main
396 | [*]
397 | [*] --- SOURCE PATH TO VULNERABILTY ---
398 | [*] lineno=37 ------ $number = $_POST['number'];
399 | [*] lineno=38 ------ $query = "SELECT bookname,authorname FROM books WHERE number = $number"; //Int
400 | [*]
401 | [*]
402 | [*] ----------------------------------------------------------------------------------------------------
403 | [*] ----------------------------------------------------------------------------------------------------
404 | [*] INDEX = 8
405 | [*] IMPACT = HIGH
406 | [*] VULNERABILTY TYPE = code_injection
407 | [*] VISITED FUNCTION CALLS =
408 | [*] FILE = /app/targets/Vulnerable-Web-Application/SQL/sql3.php::main
409 | [*]
410 | [*] --- SOURCE PATH TO VULNERABILTY ---
411 | [*] lineno=38 ------ $number = $_POST['number'];
412 | [*] lineno=39 ------ $query = "SELECT bookname,authorname FROM books WHERE number = '$number'"; //Is this same with the level 2?
413 | [*]
414 | [*]
415 | [*] ----------------------------------------------------------------------------------------------------
416 | [*] ----------------------------------------------------------------------------------------------------
417 | [*] INDEX = 9
418 | [*] IMPACT = HIGH
419 | [*] VULNERABILTY TYPE = code_injection
420 | [*] VISITED FUNCTION CALLS =
421 | [*] FILE = /app/targets/Vulnerable-Web-Application/SQL/sql6.php::main
422 | [*]
423 | [*] --- SOURCE PATH TO VULNERABILTY ---
424 | [*] lineno=35 ------ $number = $_GET['number'];
425 | [*] lineno=36 ------ $query = "SELECT bookname,authorname FROM books WHERE number = '$number'";
426 | [*]
427 | [*]
428 | [*] ----------------------------------------------------------------------------------------------------
429 | [*] ----------------------------------------------------------------------------------------------------
430 | [*] INDEX = 10
431 | [*] IMPACT = HIGH
432 | [*] VULNERABILTY TYPE = code_injection
433 | [*] VISITED FUNCTION CALLS =
434 | [*] FILE = /app/targets/Vulnerable-Web-Application/XSS/XSS_level1.php::main
435 | [*]
436 | [*] --- SOURCE PATH TO VULNERABILTY ---
437 | [*] lineno=22 ------ echo("Your name is ".$_GET["username"])?>
438 | [*]
439 | [*]
440 | [*] ----------------------------------------------------------------------------------------------------
441 | [*] ----------------------------------------------------------------------------------------------------
442 | [*] TOTAL_VULNS = 10
443 | [*]
444 | ```
445 |
446 | ### Fixes
447 | ```
448 | N/A
449 | ```
450 |
451 | ---
452 |
453 | ## Testing with `sqlinjection-training-app`
454 | `Simple SQL Injection Training App`
455 |
456 | ### Testing
457 | ```sh
458 | cd /app
459 | git clone https://github.com/appsecco/sqlinjection-training-app targets/sqlinjection-training-app
460 | python3 detectors/code_injection.py
461 | ```
462 |
463 | ### Reports
464 | ```sh
465 | [*] ----------------------------------------------------------------------------------------------------
466 | [*] ----------------------------------------------------------------------------------------------------
467 | [*] TOTAL_VULNS = 15
468 | [*]
469 | [*] ----------------------------------------------------------------------------------------------------
470 | [*] ----------------------------------------------------------------------------------------------------
471 | [*] INDEX = 1
472 | [*] IMPACT = HIGH
473 | [*] VULNERABILTY TYPE = code_injection
474 | [*] VISITED FUNCTION CALLS =
475 | [*] FILE = /app/targets/sqlinjection-training-app/www/blindsqli.php::main
476 | [*]
477 | [*] --- SOURCE PATH TO VULNERABILTY ---
478 | [*] lineno=29 ------ $user = $_GET["user"];
479 | [*] lineno=30 ------ $q = "Select * from users where username = '".$user."'";
480 | [*]
481 | [*]
482 | [*] ----------------------------------------------------------------------------------------------------
483 | [*] ----------------------------------------------------------------------------------------------------
484 | [*] INDEX = 2
485 | [*] IMPACT = HIGH
486 | [*] VULNERABILTY TYPE = code_injection
487 | [*] VISITED FUNCTION CALLS =
488 | [*] FILE = /app/targets/sqlinjection-training-app/www/login1.php::main
489 | [*]
490 | [*] --- SOURCE PATH TO VULNERABILTY ---
491 | [*] lineno=64 ------ $username = ($_REQUEST['uid']);
492 | [*] lineno=67 ------ $q = "SELECT * FROM users where username='".$username."' AND password = '".md5($pass)."'" ;
493 | [*]
494 | [*]
495 | [*] ----------------------------------------------------------------------------------------------------
496 | [*] ----------------------------------------------------------------------------------------------------
497 | [*] INDEX = 3
498 | [*] IMPACT = HIGH
499 | [*] VULNERABILTY TYPE = code_injection
500 | [*] VISITED FUNCTION CALLS =
501 | [*] FILE = /app/targets/sqlinjection-training-app/www/login2.php::main
502 | [*]
503 | [*] --- SOURCE PATH TO VULNERABILTY ---
504 | [*] lineno=65 ------ $username = ($_REQUEST['uid']);
505 | [*] lineno=68 ------ $q = "SELECT * FROM users where (username='".$username."') AND (password = '".md5($pass)."')" ;
506 | [*]
507 | [*]
508 | [*] ----------------------------------------------------------------------------------------------------
509 | [*] ----------------------------------------------------------------------------------------------------
510 | [*] INDEX = 4
511 | [*] IMPACT = HIGH
512 | [*] VULNERABILTY TYPE = code_injection
513 | [*] VISITED FUNCTION CALLS =
514 | [*] FILE = /app/targets/sqlinjection-training-app/www/os_sqli.php::main
515 | [*]
516 | [*] --- SOURCE PATH TO VULNERABILTY ---
517 | [*] lineno=30 ------ $user = $_GET["user"];
518 | [*] lineno=31 ------ $q = "Select * from users where username = '".$user."'";
519 | [*]
520 | [*]
521 | [*] ----------------------------------------------------------------------------------------------------
522 | [*] ----------------------------------------------------------------------------------------------------
523 | [*] INDEX = 5
524 | [*] IMPACT = HIGH
525 | [*] VULNERABILTY TYPE = code_injection
526 | [*] VISITED FUNCTION CALLS =
527 | [*] FILE = /app/targets/sqlinjection-training-app/www/register.php::main
528 | [*]
529 | [*] --- SOURCE PATH TO VULNERABILTY ---
530 | [*] lineno=93 ------ $username = $_REQUEST['uid'];
531 | [*] lineno=98 ------ $q = "INSERT INTO users (username, password, fname, description) values ('".$username."','".md5($pass)."','".$fname."','".$descr."')" ;
532 | [*]
533 | [*]
534 | [*] ----------------------------------------------------------------------------------------------------
535 | [*] ----------------------------------------------------------------------------------------------------
536 | [*] INDEX = 6
537 | [*] IMPACT = HIGH
538 | [*] VULNERABILTY TYPE = code_injection
539 | [*] VISITED FUNCTION CALLS =
540 | [*] FILE = /app/targets/sqlinjection-training-app/www/register.php::main
541 | [*]
542 | [*] --- SOURCE PATH TO VULNERABILTY ---
543 | [*] lineno=95 ------ $fname = $_REQUEST['name'];
544 | [*] lineno=98 ------ $q = "INSERT INTO users (username, password, fname, description) values ('".$username."','".md5($pass)."','".$fname."','".$descr."')" ;
545 | [*]
546 | [*]
547 | [*] ----------------------------------------------------------------------------------------------------
548 | [*] ----------------------------------------------------------------------------------------------------
549 | [*] INDEX = 7
550 | [*] IMPACT = HIGH
551 | [*] VULNERABILTY TYPE = code_injection
552 | [*] VISITED FUNCTION CALLS = md5
553 | [*] FILE = /app/targets/sqlinjection-training-app/www/register.php::main
554 | [*]
555 | [*] --- SOURCE PATH TO VULNERABILTY ---
556 | [*] lineno=95 ------ $fname = $_REQUEST['name'];
557 | [*] lineno=98 ------ $q = "INSERT INTO users (username, password, fname, description) values ('".$username."','".md5($pass)."','".$fname."','".$descr."')" ;
558 | [*] lineno=93 ------ $username = $_REQUEST['uid'];
559 | [*]
560 | [*]
561 | [*] ----------------------------------------------------------------------------------------------------
562 | [*] ----------------------------------------------------------------------------------------------------
563 | [*] INDEX = 8
564 | [*] IMPACT = HIGH
565 | [*] VULNERABILTY TYPE = code_injection
566 | [*] VISITED FUNCTION CALLS =
567 | [*] FILE = /app/targets/sqlinjection-training-app/www/register.php::main
568 | [*]
569 | [*] --- SOURCE PATH TO VULNERABILTY ---
570 | [*] lineno=96 ------ $descr = $_REQUEST['descr'];
571 | [*] lineno=98 ------ $q = "INSERT INTO users (username, password, fname, description) values ('".$username."','".md5($pass)."','".$fname."','".$descr."')" ;
572 | [*]
573 | [*]
574 | [*] ----------------------------------------------------------------------------------------------------
575 | [*] ----------------------------------------------------------------------------------------------------
576 | [*] INDEX = 9
577 | [*] IMPACT = HIGH
578 | [*] VULNERABILTY TYPE = code_injection
579 | [*] VISITED FUNCTION CALLS = md5
580 | [*] FILE = /app/targets/sqlinjection-training-app/www/register.php::main
581 | [*]
582 | [*] --- SOURCE PATH TO VULNERABILTY ---
583 | [*] lineno=96 ------ $descr = $_REQUEST['descr'];
584 | [*] lineno=95 ------ $fname = $_REQUEST['name'];
585 | [*] lineno=98 ------ $q = "INSERT INTO users (username, password, fname, description) values ('".$username."','".md5($pass)."','".$fname."','".$descr."')" ;
586 | [*] lineno=93 ------ $username = $_REQUEST['uid'];
587 | [*]
588 | [*]
589 | [*] ----------------------------------------------------------------------------------------------------
590 | [*] ----------------------------------------------------------------------------------------------------
591 | [*] INDEX = 10
592 | [*] IMPACT = HIGH
593 | [*] VULNERABILTY TYPE = code_injection
594 | [*] VISITED FUNCTION CALLS =
595 | [*] FILE = /app/targets/sqlinjection-training-app/www/searchproducts.php::main
596 | [*]
597 | [*] --- SOURCE PATH TO VULNERABILTY ---
598 | [*] lineno=56 ------ $q = "Select * from products where product_name like '".$_POST["searchitem"]."%'";
599 | [*]
600 | [*]
601 | [*] ----------------------------------------------------------------------------------------------------
602 | [*] ----------------------------------------------------------------------------------------------------
603 | [*] INDEX = 11
604 | [*] IMPACT = HIGH
605 | [*] VULNERABILTY TYPE = code_injection
606 | [*] VISITED FUNCTION CALLS =
607 | [*] FILE = /app/targets/sqlinjection-training-app/www/secondorder_home.php::main
608 | [*]
609 | [*] --- SOURCE PATH TO VULNERABILTY ---
610 | [*] lineno=117 ------ $username = $_REQUEST['uid'];
611 | [*] lineno=122 ------ $q = "INSERT INTO users (username, password, fname, description) values ('".$username."','".md5($pass)."','".$fname."','".$descr."')" ;
612 | [*]
613 | [*]
614 | [*] ----------------------------------------------------------------------------------------------------
615 | [*] ----------------------------------------------------------------------------------------------------
616 | [*] INDEX = 12
617 | [*] IMPACT = HIGH
618 | [*] VULNERABILTY TYPE = code_injection
619 | [*] VISITED FUNCTION CALLS =
620 | [*] FILE = /app/targets/sqlinjection-training-app/www/secondorder_home.php::main
621 | [*]
622 | [*] --- SOURCE PATH TO VULNERABILTY ---
623 | [*] lineno=119 ------ $fname = $_REQUEST['name'];
624 | [*] lineno=122 ------ $q = "INSERT INTO users (username, password, fname, description) values ('".$username."','".md5($pass)."','".$fname."','".$descr."')" ;
625 | [*]
626 | [*]
627 | [*] ----------------------------------------------------------------------------------------------------
628 | [*] ----------------------------------------------------------------------------------------------------
629 | [*] INDEX = 13
630 | [*] IMPACT = HIGH
631 | [*] VULNERABILTY TYPE = code_injection
632 | [*] VISITED FUNCTION CALLS = md5
633 | [*] FILE = /app/targets/sqlinjection-training-app/www/secondorder_home.php::main
634 | [*]
635 | [*] --- SOURCE PATH TO VULNERABILTY ---
636 | [*] lineno=119 ------ $fname = $_REQUEST['name'];
637 | [*] lineno=122 ------ $q = "INSERT INTO users (username, password, fname, description) values ('".$username."','".md5($pass)."','".$fname."','".$descr."')" ;
638 | [*] lineno=117 ------ $username = $_REQUEST['uid'];
639 | [*]
640 | [*]
641 | [*] ----------------------------------------------------------------------------------------------------
642 | [*] ----------------------------------------------------------------------------------------------------
643 | [*] INDEX = 14
644 | [*] IMPACT = HIGH
645 | [*] VULNERABILTY TYPE = code_injection
646 | [*] VISITED FUNCTION CALLS =
647 | [*] FILE = /app/targets/sqlinjection-training-app/www/secondorder_home.php::main
648 | [*]
649 | [*] --- SOURCE PATH TO VULNERABILTY ---
650 | [*] lineno=120 ------ $descr = $_REQUEST['descr'];
651 | [*] lineno=122 ------ $q = "INSERT INTO users (username, password, fname, description) values ('".$username."','".md5($pass)."','".$fname."','".$descr."')" ;
652 | [*]
653 | [*]
654 | [*] ----------------------------------------------------------------------------------------------------
655 | [*] ----------------------------------------------------------------------------------------------------
656 | [*] INDEX = 15
657 | [*] IMPACT = HIGH
658 | [*] VULNERABILTY TYPE = code_injection
659 | [*] VISITED FUNCTION CALLS = md5
660 | [*] FILE = /app/targets/sqlinjection-training-app/www/secondorder_home.php::main
661 | [*]
662 | [*] --- SOURCE PATH TO VULNERABILTY ---
663 | [*] lineno=120 ------ $descr = $_REQUEST['descr'];
664 | [*] lineno=119 ------ $fname = $_REQUEST['name'];
665 | [*] lineno=122 ------ $q = "INSERT INTO users (username, password, fname, description) values ('".$username."','".md5($pass)."','".$fname."','".$descr."')" ;
666 | [*] lineno=117 ------ $username = $_REQUEST['uid'];
667 | [*]
668 | [*]
669 | [*] ----------------------------------------------------------------------------------------------------
670 | [*] ----------------------------------------------------------------------------------------------------
671 | [*] TOTAL_VULNS = 15
672 | [*]
673 |
674 | ```
675 |
676 | ### Fixes
677 | ```
678 | N/A
679 | ```
680 |
681 | ---
682 |
683 | ## Testing with `OSTE-Vulnerable-Web-Application`
684 | `Vulnerable Web application made with PHP/SQL designed to help new web testers gain some experience and test DAST tools for identifying web vulnerabilities.`
685 |
686 | ### Testing
687 | ```sh
688 | cd /app
689 | git clone https://github.com/OSTEsayed/OSTE-Vulnerable-Web-Application targets/OSTE-Vulnerable-Web-Application
690 | python3 detectors/code_injection.py
691 | ```
692 |
693 | ### Reports
694 | ```sh
695 | [*] ----------------------------------------------------------------------------------------------------
696 | [*] ----------------------------------------------------------------------------------------------------
697 | [*] TOTAL_VULNS = 6
698 | [*]
699 | [*] ----------------------------------------------------------------------------------------------------
700 | [*] ----------------------------------------------------------------------------------------------------
701 | [*] INDEX = 1
702 | [*] IMPACT = HIGH
703 | [*] VULNERABILTY TYPE = code_injection
704 | [*] VISITED FUNCTION CALLS =
705 | [*] FILE = /app/targets/OSTE-Vulnerable-Web-Application/SQL/page1.php::main
706 | [*]
707 | [*] --- SOURCE PATH TO VULNERABILTY ---
708 | [*] lineno=210 ------ $passe=$_POST["pswd"];
709 | [*] lineno=212 ------ $sql = "INSERT INTO user (name,password) VALUES ('$namee','$passe')";
710 | [*]
711 | [*]
712 | [*] ----------------------------------------------------------------------------------------------------
713 | [*] ----------------------------------------------------------------------------------------------------
714 | [*] INDEX = 2
715 | [*] IMPACT = HIGH
716 | [*] VULNERABILTY TYPE = code_injection
717 | [*] VISITED FUNCTION CALLS =
718 | [*] FILE = /app/targets/OSTE-Vulnerable-Web-Application/SQL/page1.php::main
719 | [*]
720 | [*] --- SOURCE PATH TO VULNERABILTY ---
721 | [*] lineno=209 ------ $namee=$_POST["username"];
722 | [*] lineno=212 ------ $sql = "INSERT INTO user (name,password) VALUES ('$namee','$passe')";
723 | [*]
724 | [*]
725 | [*] ----------------------------------------------------------------------------------------------------
726 | [*] ----------------------------------------------------------------------------------------------------
727 | [*] INDEX = 3
728 | [*] IMPACT = HIGH
729 | [*] VULNERABILTY TYPE = code_injection
730 | [*] VISITED FUNCTION CALLS =
731 | [*] FILE = /app/targets/OSTE-Vulnerable-Web-Application/SQL/page4.php::main
732 | [*]
733 | [*] --- SOURCE PATH TO VULNERABILTY ---
734 | [*] lineno=212 ------ $namee=$_POST["username"];
735 | [*] lineno=215 ------ $sql3 = "SELECT * FROM books WHERE author='$namee'";//String
736 | [*]
737 | [*]
738 | [*] ----------------------------------------------------------------------------------------------------
739 | [*] ----------------------------------------------------------------------------------------------------
740 | [*] INDEX = 4
741 | [*] IMPACT = HIGH
742 | [*] VULNERABILTY TYPE = code_injection
743 | [*] VISITED FUNCTION CALLS =
744 | [*] FILE = /app/targets/OSTE-Vulnerable-Web-Application/SQL/page5.php::main
745 | [*]
746 | [*] --- SOURCE PATH TO VULNERABILTY ---
747 | [*] lineno=212 ------ $namee=$_POST["username"];
748 | [*] lineno=215 ------ $sql3 = "SELECT * FROM sport WHERE id='$namee'";//String
749 | [*]
750 | [*]
751 | [*] ----------------------------------------------------------------------------------------------------
752 | [*] ----------------------------------------------------------------------------------------------------
753 | [*] INDEX = 5
754 | [*] IMPACT = HIGH
755 | [*] VULNERABILTY TYPE = code_injection
756 | [*] VISITED FUNCTION CALLS =
757 | [*] FILE = /app/targets/OSTE-Vulnerable-Web-Application/SQL/page6.php::main
758 | [*]
759 | [*] --- SOURCE PATH TO VULNERABILTY ---
760 | [*] lineno=212 ------ $namee=$_GET["username"];
761 | [*] lineno=215 ------ $sql3 = "SELECT * FROM sport WHERE id='$namee'";//String
762 | [*]
763 | [*]
764 | [*] ----------------------------------------------------------------------------------------------------
765 | [*] ----------------------------------------------------------------------------------------------------
766 | [*] INDEX = 6
767 | [*] IMPACT = HIGH
768 | [*] VULNERABILTY TYPE = code_injection
769 | [*] VISITED FUNCTION CALLS =
770 | [*] FILE = /app/targets/OSTE-Vulnerable-Web-Application/XSS/page1.php::main
771 | [*]
772 | [*] --- SOURCE PATH TO VULNERABILTY ---
773 | [*] lineno=197 ------ echo$_POST['username'];
774 | [*]
775 | [*]
776 | [*] ----------------------------------------------------------------------------------------------------
777 | [*] ----------------------------------------------------------------------------------------------------
778 | [*] TOTAL_VULNS = 6
779 | [*]
780 | ```
781 |
782 | ### Fixes
783 | ```
784 | N/A
785 | ```
786 |
787 | ---
788 |
789 | ## Testing with `InsecureTrust_Bank`
790 | `"InsecureTrust_Bank: Educational repo demonstrating web app vulnerabilities like SQL injection & XSS for security awareness. Use responsibly.`
791 |
792 | ### Testing
793 | ```sh
794 | cd /app
795 | git clone https://github.com/Hritikpatel/InsecureTrust_Bank targets/InsecureTrust_Bank
796 | python3 detectors/code_injection.py
797 | ```
798 |
799 | ### Reports
800 | ```sh
801 | [*] ----------------------------------------------------------------------------------------------------
802 | [*] ----------------------------------------------------------------------------------------------------
803 | [*] TOTAL_VULNS = 5
804 | [*]
805 | [*] ----------------------------------------------------------------------------------------------------
806 | [*] ----------------------------------------------------------------------------------------------------
807 | [*] INDEX = 1
808 | [*] IMPACT = HIGH
809 | [*] VULNERABILTY TYPE = code_injection
810 | [*] VISITED FUNCTION CALLS =
811 | [*] FILE = /app/targets/InsecureTrust_Bank/assets/php_process/login_process.php::main
812 | [*]
813 | [*] --- SOURCE PATH TO VULNERABILTY ---
814 | [*] lineno=9 ------ $entered_password = $_POST["password"];
815 | [*] lineno=27 ------ $sql = "SELECT * FROM logininfo WHERE username = '$entered_username' AND password = '$entered_password'";
816 | [*]
817 | [*]
818 | [*] ----------------------------------------------------------------------------------------------------
819 | [*] ----------------------------------------------------------------------------------------------------
820 | [*] INDEX = 2
821 | [*] IMPACT = HIGH
822 | [*] VULNERABILTY TYPE = code_injection
823 | [*] VISITED FUNCTION CALLS =
824 | [*] FILE = /app/targets/InsecureTrust_Bank/assets/php_process/login_process.php::main
825 | [*]
826 | [*] --- SOURCE PATH TO VULNERABILTY ---
827 | [*] lineno=8 ------ $entered_username = $_POST["username"];
828 | [*] lineno=27 ------ $sql = "SELECT * FROM logininfo WHERE username = '$entered_username' AND password = '$entered_password'";
829 | [*]
830 | [*]
831 | [*] ----------------------------------------------------------------------------------------------------
832 | [*] ----------------------------------------------------------------------------------------------------
833 | [*] INDEX = 3
834 | [*] IMPACT = HIGH
835 | [*] VULNERABILTY TYPE = code_injection
836 | [*] VISITED FUNCTION CALLS =
837 | [*] FILE = /app/targets/InsecureTrust_Bank/public/faq.php::main
838 | [*]
839 | [*] --- SOURCE PATH TO VULNERABILTY ---
840 | [*] lineno=50 ------ $searchQuery = $_GET[ 'search' ];
841 | [*] lineno=53 ------ $out = ' Looking for ' . $searchQuery . '
';
842 | [*]
843 | [*]
844 | [*] ----------------------------------------------------------------------------------------------------
845 | [*] ----------------------------------------------------------------------------------------------------
846 | [*] INDEX = 4
847 | [*] IMPACT = HIGH
848 | [*] VULNERABILTY TYPE = code_injection
849 | [*] VISITED FUNCTION CALLS =
850 | [*] FILE = /app/targets/InsecureTrust_Bank/public/faq.php::main
851 | [*]
852 | [*] --- SOURCE PATH TO VULNERABILTY ---
853 | [*] lineno=50 ------ $searchQuery = $_GET[ 'search' ];
854 | [*] lineno=53 ------ $out = ' Looking for ' . $searchQuery . '
';
855 | [*] lineno=54 ------ echo $out;
856 | [*]
857 | [*]
858 | [*] ----------------------------------------------------------------------------------------------------
859 | [*] ----------------------------------------------------------------------------------------------------
860 | [*] INDEX = 5
861 | [*] IMPACT = HIGH
862 | [*] VULNERABILTY TYPE = code_injection
863 | [*] VISITED FUNCTION CALLS =
864 | [*] FILE = /app/targets/InsecureTrust_Bank/toolPvt/supportApi.php::main
865 | [*]
866 | [*] --- SOURCE PATH TO VULNERABILTY ---
867 | [*] lineno=69 ------ $number = $_GET["number"];
868 | [*] lineno=72 ------ $stmt = $pdo->prepare("SELECT * FROM account WHERE Phone == $number");
869 | [*]
870 | [*]
871 | [*] ----------------------------------------------------------------------------------------------------
872 | [*] ----------------------------------------------------------------------------------------------------
873 | [*] TOTAL_VULNS = 5
874 | [*]
875 | ```
876 |
877 | ### Fixes
878 | ```
879 | N/A
880 | ```
881 |
882 | ---
--------------------------------------------------------------------------------