diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0fb17cf --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.phar +composer.lock \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..89a3ba7 --- /dev/null +++ b/composer.json @@ -0,0 +1,6 @@ +{ + "require": { + "guzzlehttp/guzzle": "^7.2", + "wujunze/php-cli-color": "^2.4" + } +} diff --git a/params.json b/params.json new file mode 100644 index 0000000..cf52e44 --- /dev/null +++ b/params.json @@ -0,0 +1,41 @@ +[ + { + "url": "http://localhost/mysite/login", + "method": "POST", + "headers": null, + "body": "username=admin&password=s3cr3t", + "header-regexp": [ + { + "next_url": "/Location: (.+?)$/" + }, + { + "cookie": "/Set-Cookie: (.+?)$/" + } + ], + "body-regexp": null + }, + { + "url": "http://localhost§next_url§", + "method": "GET", + "headers": { + "Cookie": "§cookie§" + }, + "body": null, + "header-regexp": null, + "body-regexp": [ + { + "email": "/
Your email is: (.+?)<\\/p>/"
+ }
+ ]
+ },
+ {
+ "url": "http://localhost/mysite/sign-up",
+ "method": "POST",
+ "headers": {
+ "Cookie": "§cookie§"
+ },
+ "body": "op=signup&email=§email§",
+ "header-regexp": null,
+ "body-regexp": null
+ }
+]
\ No newline at end of file
diff --git a/request.php b/request.php
new file mode 100644
index 0000000..7be472c
--- /dev/null
+++ b/request.php
@@ -0,0 +1,189 @@
+getColoredString('
+File '.$argv[1].' does not exists or is not readable!
+
+', 'red', null);
+ exit();
+}
+
+$pointer = $colors->getColoredString('[*]', 'blue');
+
+// Reading JSON
+$requests = [];
+
+echo $pointer.' Parsing '.$colors->getColoredString($argv[1], 'yellow').'...';
+
+if( $requests = json_decode( file_get_contents($argv[1]), 1 ) ){
+ echo $colors->getColoredString("OK\n", 'green');
+} else {
+ echo $colors->getColoredString('ERR
+It does not seems a good JSON file!', 'green').'
+';
+ exit();
+}
+
+
+// Loop through URLs :-)
+echo $pointer." Found ".$colors->getColoredString( count($requests), 'yellow')." requests!\n\n";
+
+
+
+// Requests counter
+$s = 1;
+
+// Placeholder for values extracted by regexp
+$all_values = [];
+
+foreach ($requests as $request) {
+ $new_values = [];
+
+ // Apply regexp substitution on url, body and headers with previous values
+ $request['url'] = replace_values($request['url'], $all_values);
+ $request['body'] = replace_values($request['body'], $all_values);
+
+ $headers = [];
+
+ if( !empty($request['headers']) ){
+ foreach( $request['headers'] as $name => $values ){
+ $headers[$name] = replace_values($values, $all_values);
+ }
+ }
+
+ // Preview of the request
+ echo $colors->getColoredString('[>]', 'red').' '.$colors->getColoredString('REQUEST '.$s.'/'.count($requests), 'yellow').'
+'.$colors->getColoredString('[>]', 'red').' '.$colors->getColoredString('METHOD :', 'cyan').' '.$colors->getColoredString($request['method'], 'yellow').'
+'.$colors->getColoredString('[>]', 'red').' '.$colors->getColoredString('URL :', 'cyan').' '.$colors->getColoredString($request['url'], 'yellow').'
+'.$colors->getColoredString('[>]', 'red').' '.$colors->getColoredString('HEADERS :', 'cyan').'
+';
+
+ // Print all headers
+ foreach( $headers as $name => $value ){
+ echo ' '.$name.': '.$value."\n";
+ }
+
+ echo $colors->getColoredString('[>]', 'red').' '.$colors->getColoredString('BODY :', 'cyan').' '.$colors->getColoredString($request['body'], 'yellow').'
+';
+
+
+ // Execute the request!
+ $client = new \GuzzleHttp\Client();
+ $response = $client->request(
+ $request['method'],
+ replace_values($request['url'], $all_values),
+ [
+ 'body' => $request['body'],
+ 'headers' => $headers,
+ ]
+ );
+
+ // Get values from regexp on headers
+ foreach ($response->getHeaders() as $name => $values) {
+ $header = $name.': '.implode('; ', $values);
+
+ if( !empty($request['header-regexp']) ){
+ foreach( $request['header-regexp'] as $idx => $values ){
+ foreach( $values as $title => $regexp){
+ if (preg_match($regexp, $header, $m)) {
+ $new_values[$title] = $m[1];
+ }
+ }
+ }
+ }
+ }
+
+ if( $debug ){
+ echo $response->getBody();
+ }
+
+ // Get values from regexp on body
+ if( !empty($request['body-regexp']) ){
+ foreach( $request['body-regexp'] as $idx => $values ){
+ foreach( $values as $title => $regexp){
+ if (preg_match($regexp, $response->getBody(), $m)) {
+ $new_values[$title] = $m[1];
+ }
+ }
+ }
+ }
+
+ // Prints out found values with regexp!
+ if( !empty($request['header-regexp']) || !empty($request['body-regexp']) ){
+ foreach( $new_values as $name => $value ){
+ echo $colors->getColoredString('[<]', 'green').' '.$name.': '.$colors->getColoredString($value, 'yellow')."\n";
+ }
+ }
+
+ if( !empty($new_values) ){
+ $all_values = array_merge( $all_values, $new_values );
+ }
+
+ $s++;
+
+ echo "\n";
+}
+
+
+
+function usage(){
+ global $colors;
+
+ echo '
+#################
+# PHP AUTOMATOR #
+# by loviuz #
+#################
+
+A PHP script that automates a chain of HTTP requests to test '.$colors->getColoredString('web logic vulnerabilities', 'green').'.
+
+Usage: request.php