├── .gitignore
├── LICENSE
├── README.md
├── ansible
├── README.md
├── attack.sh
├── cleanup.yml
├── crawl.sh
├── main.yml
├── webgoat-container-7.0.1-war-exec.jar
└── webgoat.sh
├── dist
└── sheepdog-1.0-SNAPSHOT.jar
├── pom.xml
└── src
└── main
└── java
└── com
└── contrastsecurity
└── sheepdog
├── AttackThread.java
├── ServerThread.java
├── Sheepdog.java
├── StreamGobbler.java
└── sheepdog.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | .settings
3 | .classpath
4 | .project
5 | *retry
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Contrast Security OSS
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Sheepdog
2 | ========
3 |
4 |
5 |
6 | Sheepdog is a simple tool to generate normal and attack traffic for OWASP WebGoat. It can be used with security technologies like WAF and RASP in demonstrations and to verify that they are doing a tiny piece of what they are supposed to do. Sheepdog is not intended to be an exhaustive set of security tests. It has some basic SQL injection, XSS, path traversal, and that kind of thing.
7 |
8 | Simply start WebGoat with:
9 |
10 | > java -jar webgoat-container-7.0.1-war-exec.jar
11 |
12 | Then in another window start sheepdog with:
13 |
14 | > java -jar sheepdog-1.0.jar
15 |
16 | There are several configurable properties that you can use to simulate a variety of crawls/attacks. Note that SheepDog sends an X-Forwarded-For header with random IP address for each attack thread.
17 |
18 | > Usage: java -jar sheepdog.jar
19 | >
20 | > -t threads (default 3)
21 | >
22 | > -s seconds (default 60)
23 | >
24 | > -d delay milliseconds between requests (default -1)
25 | >
26 | > -a attack percentage (default 50)
27 | >
28 | > -p port for WebGoat (default 8080)
29 | >
30 | > -v verbose
31 |
32 |
33 | ## Sample usage
34 |
35 | $ java -jar target/sheepdog-1.0-SNAPSHOT.jar -t 3 -s 3600 -d 1000 -a 50
36 | Usage: java -jar sheepdog.jar [-t -s -d -a -p -v]
37 | Using default value for flag 'p', using 8080
38 | Starting 3 attack threads, each with:
39 | 3600 seconds
40 | 1000ms delay between requests
41 | 50% attack parameters
42 | target: http://localhost:8080/WebGoat/
43 |
44 | Starting AttackThread (110.104.52.59)
45 | Starting AttackThread (93.65.24.224)
46 | Starting AttackThread (161.144.64.146)
47 |
48 | POST from 238.20.254.102 to http://localhost:8080/WebGoat/j_spring_security_check
49 | [username=guest, password=guest]
50 | HTTP/1.1 302 Found
51 |
52 | POST from 93.65.24.224 to http://localhost:8080/WebGoat/j_spring_security_check
53 | [username=guest, password=guest]
54 | HTTP/1.1 302 Found
55 |
56 | POST from 161.144.64.146 to http://localhost:8080/WebGoat/j_spring_security_check
57 | [username=guest, password=guest]
58 | HTTP/1.1 302 Found
59 |
60 | POST from 161.144.64.146 to http://localhost:8080/WebGoat/attack?Screen=733&menu=1200
61 | [SUBMIT=zoees822]
62 | HTTP/1.1 200 OK
63 |
64 | POST from 93.65.24.224 to http://localhost:8080/WebGoat/attack?Screen=534&menu=1900
65 | [id=sztol903, SUBMIT=rjeee272]
66 | HTTP/1.1 200 OK
67 |
68 | POST from 161.144.64.146 to http://localhost:8080/WebGoat/attack?Screen=726&menu=200&stage=1
69 | [action=' or 112=112--]
70 | HTTP/1.1 200 OK
71 |
72 | POST from 161.144.64.146 to http://localhost:8080/WebGoat/attack?Screen=737&menu=1100&stage=3
73 | [action=' or 1+2=3 --]
74 | HTTP/1.1 200 OK
75 |
76 | POST from 93.65.24.224 to http://localhost:8080/WebGoat/attack?Screen=498&menu=1300
77 | [clear_user=>, clear_pass=>, Submit=ctyna446]
78 | HTTP/1.1 200 OK
79 |
80 |
81 |
82 | ## Who made this?
83 | This project is sponsored by [Contrast Security](http://www.contrastsecurity.com/) and released under the MIT license.
84 |
85 | 
86 |
--------------------------------------------------------------------------------
/ansible/README.md:
--------------------------------------------------------------------------------
1 | # Ansible Playbooks to Deploy Sheepdog with WebGoat7
2 |
3 | These two ansible playbooks automate the deployment and cleanup of Sheepdog and WebGoat7 to quickly setup a demo environment using the Contrast Security Secure DevOps Platform.
4 |
5 | ## To use this playbook, follow the instructions below
6 |
7 | ### Create a '~.contrast.cfg file'
8 | The playbook relies on API credentials in this file.
9 | ```
10 | username: [username]
11 | service_key: [service_key]
12 | teamserver_url: [teamserver_url]
13 | teamserver_organization: [teamserver_organization]
14 | teamserver_url: [teamserver_url]
15 | api_key: [api_key]
16 |
17 | #These might not be required for the playbook to work.
18 | #@todo Validate the need for these fields
19 | agent_username: [agent_username]
20 | agent_service_key: [agent_service_key]
21 | ```
22 |
23 | ### Clone this github repo.
24 | ```
25 | $ git clone git@github.com:Contrast-Security-OSS/sheepdog.git
26 | ```
27 | ### Run the ansible playbook
28 | ```
29 | $ ansible-playbook ./sheepdog/ansible/main.yml
30 | ```
31 |
32 | ### Execute attack.sh
33 | **Note:** ```attack.sh``` will take approximatley 30 minutes to run
34 |
35 | ```
36 | $ cd ~/webgoat7
37 | $ ./attack.sh
38 | ```
39 |
40 |
41 | ### Demo: Start webgoat7 attack is done
42 | ```
43 | $ ./webgoat.sh
44 | ```
45 |
46 | Then browse to webgoat at http://localhost:8080/WebGoat/
47 |
48 | ## Cleanup
49 | ```
50 | ansible-playbook ./sheepdog/ansible/cleanup.yml
51 | ```
52 |
--------------------------------------------------------------------------------
/ansible/attack.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | # The port which webgoat will use
4 | wgport=${SHEEPDOG_WG_PORT:-8080}
5 |
6 | # Try to verify the webgoat port is open
7 | nc=/usr/bin/nc
8 |
9 | if test -x "$nc"; then
10 | if "$nc" -z localhost $wgport; then
11 | echo PORT $wgport is in use!
12 | echo Try setting \$SHEEPDOG_WG_PORT
13 | exit 1
14 | fi
15 | else
16 | echo ''
17 | echo '###################################'
18 | echo 'WARNING WARNING WARNING WARNING'
19 | echo '###################################'
20 | echo 'Unable to determine if there is a port confict.'
21 | echo ''
22 | echo "Webgoat will run on port $wgport"
23 | echo ''
24 | echo 'If you see no route coverage after sheepdog runs, you may need to'
25 | echo 'specify a different port with $SHEEPDOG_WG_PORT.'
26 | echo ''
27 | fi
28 |
29 | # trap ctrl-c and call ctrl_c()
30 | trap ctrl_c INT
31 |
32 | function ctrl_c() {
33 | echo "** Trapped CTRL-C"
34 | if [ -n $pid1 ]; then kill $pid1; fi
35 | if [ -n $pid2 ]; then kill $pid2; fi
36 | exit 1
37 | }
38 |
39 | function webgoat {
40 | java -javaagent:contrast.jar -Dcontrast.dir=working -Dcontrast.standalone.appname=$app -Dcontrast.override.appname="$app" -Dcontrast.path="/$path" -Dcontrast.server="$server" -Dcontrast.log.daily=true -jar webgoat-container-7.0.1-war-exec.jar -httpPort=$wgport > /dev/null 2>&1 &
41 | }
42 |
43 | function sheepdog {
44 | java -jar sheepdog-1.0-SNAPSHOT.jar -t 3 -s 3600 -d 1500 250 -a 90 -p $wgport > /dev/null 2>&1 &
45 |
46 | }
47 |
48 | declare -a configs=(
49 | "WebGoat7|DEV-WG7|TEST-WG7|STAGE-WG7|PROD-WG7"
50 | "OracleFS|DEV-OFS|TEST-OFS|PROD-OFS"
51 | "CustomerCare|DEV-CCB|TEST-CCB|PROD-CCB"
52 | "WebStore|DEV-WS|STAGE-WS|PROD-WS"
53 | "MedicalRecords|DEV-EMR|STAGE-EMR|PROD-EMR"
54 | "WebPOS|DEV-WPOS|STAGE-WPOS|PROD-WPOS"
55 | "TradingFloor|DEV-TF|TEST-TF|PROD-TF" )
56 |
57 | for config in "${configs[@]}"
58 | do
59 | IFS='|' read -a item <<<"$config"
60 | app=${item[0]}
61 |
62 | for ((i = 1; i < ${#item[@]}; i++))
63 | do
64 | server=${item[i]}
65 | path=$(echo "/$app" | tr '[:upper:]' '[:lower:]')
66 | echo "Starting $app on $server using $path"
67 | webgoat
68 | pid1=$!
69 | sleep 60
70 | echo "Attacking $app on $server using $path"
71 | sheepdog
72 | pid2=$!
73 | sleep 120
74 | kill -KILL $pid1
75 | kill -KILL $pid2
76 | echo "----------------"
77 | done
78 |
79 | done
80 |
--------------------------------------------------------------------------------
/ansible/cleanup.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Cleanup WebGoat7 and Sheepdog
4 | hosts: localhost
5 | gather_facts: false
6 | vars:
7 | wg7_destination: ~/webgoat7
8 | tasks:
9 | - name: Remove Webgoat7 destination directory if it exists
10 | file:
11 | path: '{{wg7_destination}}'
12 | state: absent
13 | - name: Remove cron job for WebGoat7 attack
14 | cron:
15 | name: "Attack WwebGoat7"
16 | state: absent
17 |
--------------------------------------------------------------------------------
/ansible/crawl.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | # The port which webgoat will use
4 | wgport=${SHEEPDOG_WG_PORT:-8080}
5 |
6 | # Try to verify the webgoat port is open
7 | nc=/usr/bin/nc
8 |
9 | if test -x "$nc"; then
10 | if "$nc" -z localhost $wgport; then
11 | echo PORT $wgport is in use!
12 | echo Try setting \$SHEEPDOG_WG_PORT
13 | exit 1
14 | fi
15 | else
16 | echo ''
17 | echo '###################################'
18 | echo 'WARNING WARNING WARNING WARNING'
19 | echo '###################################'
20 | echo 'Unable to determine if there is a port confict.'
21 | echo ''
22 | echo "Webgoat will run on port $wgport"
23 | echo ''
24 | echo 'If you see no route coverage after sheepdog runs, you may need to'
25 | echo 'specify a different port with $SHEEPDOG_WG_PORT.'
26 | echo ''
27 | fi
28 |
29 | # trap ctrl-c and call ctrl_c()
30 | trap ctrl_c INT
31 |
32 | function ctrl_c() {
33 | echo "** Trapped CTRL-C"
34 | if [ -n $pid1 ]; then kill $pid1; fi
35 | if [ -n $pid2 ]; then kill $pid2; fi
36 | exit 1
37 | }
38 |
39 | function webgoat {
40 | java -javaagent:contrast.jar -Dcontrast.dir=working -Dcontrast.standalone.appname=$app -Dcontrast.override.appname="$app" -Dcontrast.path="/$path" -Dcontrast.server="$server" -Dcontrast.log.daily=true -jar webgoat-container-7.0.1-war-exec.jar -httpPort=$wgport > /dev/null 2>&1 &
41 | }
42 |
43 | function sheepdog {
44 | java -jar sheepdog-1.0-SNAPSHOT.jar -t 3 -s 3600 -d 1500 250 -a 0 -p $wgport > /dev/null 2>&1 &
45 |
46 | }
47 |
48 | declare -a configs=(
49 | "WebGoat7|DEV-WG7|TEST-WG7|STAGE-WG7|PROD-WG7"
50 | "OracleFS|DEV-OFS|TEST-OFS|PROD-OFS"
51 | "CustomerCare|DEV-CCB|TEST-CCB|PROD-CCB"
52 | "WebStore|DEV-WS|STAGE-WS|PROD-WS"
53 | "MedicalRecords|DEV-EMR|STAGE-EMR|PROD-EMR"
54 | "WebPOS|DEV-WPOS|STAGE-WPOS|PROD-WPOS"
55 | "TradingFloor|DEV-TF|TEST-TF|PROD-TF" )
56 |
57 | for config in "${configs[@]}"
58 | do
59 | IFS='|' read -a item <<<"$config"
60 | app=${item[0]}
61 |
62 | for ((i = 1; i < ${#item[@]}; i++))
63 | do
64 | server=${item[i]}
65 | path=$(echo "/$app" | tr '[:upper:]' '[:lower:]')
66 | echo "Starting $app on $server using $path"
67 | webgoat
68 | pid1=$!
69 | sleep 60
70 | echo "Attacking $app on $server using $path"
71 | sheepdog
72 | pid2=$!
73 | sleep 120
74 | kill -KILL $pid1
75 | kill -KILL $pid2
76 | echo "----------------"
77 | done
78 |
79 | done
80 |
--------------------------------------------------------------------------------
/ansible/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: WebGoat7 Demo With Sheepdog
3 | hosts: localhost
4 | vars:
5 | wg7_destination: ~/webgoat7
6 | agent_type: java
7 |
8 | #@todo: gracefully fail if there is no file and produce a message.
9 | gather_facts: false
10 | tasks:
11 | - name: Include vars from .contrast.cfg
12 | include_vars:
13 | file: ~/.contrast.cfg
14 | name: contrast
15 |
16 | - name: Create Webgoat7 destination directory if it does not exist
17 | file:
18 | path: '{{wg7_destination}}'
19 | state: directory
20 | mode: 0755
21 | - name: Deploy scripts
22 | copy:
23 | src: '{{item}}'
24 | dest: '{{wg7_destination}}'
25 | mode: 0755
26 | with_items:
27 | - attack.sh
28 | - crawl.sh
29 | - webgoat.sh
30 | - name: Deploy sheepdog container
31 | copy:
32 | src: ../dist/sheepdog-1.0-SNAPSHOT.jar
33 | dest: '{{wg7_destination}}'
34 | - name: Copy webgoat container from our local source
35 | # get_url:
36 | # url: https://github.com/WebGoat/WebGoat/releases/download/7.0.1/webgoat-container-7.0.1-war-exec.jar
37 | # Changed this to include the file contained herein as the md5 of the static jar vs. the one in github are differeht.
38 | # Changed by Vihar on Apr 9.
39 | # Working with Jeff to determine pkgdiff between the two snapshots.
40 | copy:
41 | src: webgoat-container-7.0.1-war-exec.jar
42 | dest: '{{wg7_destination}}'
43 |
44 |
45 | #Download contrast.jar file from Teamserver
46 | - name: Create Authorization
47 | set_fact:
48 | authorization_key: "{{ contrast.username }}:{{ contrast.service_key }}"
49 |
50 | - name: Download Agent from TeamServer
51 | get_url:
52 | url: "{{ contrast.teamserver_url }}/Contrast/api/ng/{{ contrast.teamserver_organization }}/agents/default/{{ agent_type }}"
53 | dest: "{{wg7_destination}}/contrast.jar"
54 | headers: 'Accept:application/json,API-Key:{{ contrast.api_key }},Authorization:{{ authorization_key | b64encode }}'
55 |
56 | # - name: Setup cron job
57 | # cron:
58 | # name: "Attack WwebGoat7"
59 | # minute: "0"
60 | # hour: "0"
61 | # job: "{{wg7_destination}}/attack.sh"
62 |
--------------------------------------------------------------------------------
/ansible/webgoat-container-7.0.1-war-exec.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Contrast-Security-OSS/sheepdog/07522bff2ebe844ff261184b48cd749c67cf638d/ansible/webgoat-container-7.0.1-war-exec.jar
--------------------------------------------------------------------------------
/ansible/webgoat.sh:
--------------------------------------------------------------------------------
1 | java -javaagent:contrast.jar -Dcontrast.path=~/webgoat7 -Dcontrast.dir=working -Dcontrast.server=PROD-DEMO -Dcontrast.server.activity.period=5000 -Dcontrast.log.daily=true -jar webgoat-container-7.0.1-war-exec.jar -httpPort=8080
2 |
--------------------------------------------------------------------------------
/dist/sheepdog-1.0-SNAPSHOT.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Contrast-Security-OSS/sheepdog/07522bff2ebe844ff261184b48cd749c67cf638d/dist/sheepdog-1.0-SNAPSHOT.jar
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 | 4.0.0
5 | com.contrastsecurity
6 | sheepdog
7 | jar
8 |
9 | Contrast Sheepdog
10 |
11 | Contrast Sheepdog Project
12 |
13 |
14 |
15 | Contrast Security
16 | http://contrastsecurity.com
17 |
18 |
19 | 1.0-SNAPSHOT
20 |
21 |
22 |
23 | Jeff Williams
24 | Contrast Security
25 | jeff.williams@contrastsecurity.com
26 |
27 | Developer
28 |
29 |
30 |
31 |
32 | http://maven.apache.org
33 |
34 |
35 | junit
36 | junit
37 | 3.8.1
38 | test
39 |
40 |
41 | org.apache.httpcomponents
42 | httpclient
43 | 4.5.2
44 |
45 |
46 | commons-cli
47 | commons-cli
48 | 1.3.1
49 |
50 |
51 | commons-lang
52 | commons-lang
53 | 2.5
54 |
55 |
56 | commons-io
57 | commons-io
58 | 2.2
59 |
60 |
61 | com.google.code.gson
62 | gson
63 | 2.4
64 |
65 |
66 |
67 |
68 |
69 |
70 | org.apache.maven.plugins
71 | maven-dependency-plugin
72 |
73 |
74 | copy-dependencies
75 | prepare-package
76 |
77 | copy-dependencies
78 |
79 |
80 | ${project.build.directory}/lib
81 | false
82 | false
83 | true
84 |
85 |
86 |
87 |
88 |
89 | org.apache.maven.plugins
90 | maven-jar-plugin
91 | 3.0.2
92 |
93 |
94 |
95 | true
96 | lib/
97 | com.contrastsecurity.sheepdog.Sheepdog
98 |
99 |
100 |
101 |
102 |
103 | org.apache.maven.plugins
104 | maven-shade-plugin
105 | 2.3
106 |
107 |
108 | package
109 |
110 | shade
111 |
112 |
113 |
114 |
115 | com.contrastsecurity.sheepdog.Sheepdog
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/src/main/java/com/contrastsecurity/sheepdog/AttackThread.java:
--------------------------------------------------------------------------------
1 | package com.contrastsecurity.sheepdog;
2 |
3 | import java.security.SecureRandom;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 | import java.util.regex.Matcher;
7 | import java.util.regex.Pattern;
8 |
9 | import org.apache.commons.lang.time.StopWatch;
10 | import org.apache.http.Consts;
11 | import org.apache.http.HttpEntity;
12 | import org.apache.http.NameValuePair;
13 | import org.apache.http.client.CookieStore;
14 | import org.apache.http.client.config.CookieSpecs;
15 | import org.apache.http.client.config.RequestConfig;
16 | import org.apache.http.client.entity.UrlEncodedFormEntity;
17 | import org.apache.http.client.methods.CloseableHttpResponse;
18 | import org.apache.http.client.methods.HttpGet;
19 | import org.apache.http.client.methods.HttpPost;
20 | import org.apache.http.impl.client.BasicCookieStore;
21 | import org.apache.http.impl.client.CloseableHttpClient;
22 | import org.apache.http.impl.client.HttpClients;
23 | import org.apache.http.message.BasicNameValuePair;
24 | import org.apache.http.util.EntityUtils;
25 |
26 | public class AttackThread extends Thread {
27 |
28 | private CloseableHttpClient httpclient;
29 | private CookieStore cookieStore;
30 | private StopWatch watch;
31 |
32 | /* Scan settings */
33 | private String baseUrl;
34 | private String address;
35 | private List lessons;
36 | private int scanDuration;
37 | private int attackPercent;
38 | private long requestDelay;
39 | private boolean verbose;
40 |
41 | /* Statistics */
42 | private int requestCount;
43 | private long totalScanTime;
44 | private double highest;
45 | private double lowest;
46 |
47 | public AttackThread( String baseUrl, String address, int scanDuration, long requestDelay, int attackPercent, boolean verbose ) {
48 | this.baseUrl = baseUrl;
49 | this.address = address;
50 | this.scanDuration = scanDuration;
51 | this.requestDelay = requestDelay;
52 | this.attackPercent = attackPercent;
53 | this.verbose = verbose;
54 |
55 | this.highest = -1;
56 | this.lowest = -1;
57 |
58 | this.watch = new StopWatch();
59 |
60 | try {
61 | cookieStore = new BasicCookieStore();
62 | RequestConfig globalConfig = RequestConfig.custom()
63 | .setCookieSpec(CookieSpecs.DEFAULT)
64 | .build();
65 | httpclient = HttpClients.custom()
66 | .setDefaultCookieStore(cookieStore)
67 | .setDefaultRequestConfig(globalConfig)
68 | .build();
69 |
70 | // login and get list of lessons
71 | List credentials = new ArrayList();
72 | credentials.add(new BasicNameValuePair("username", "guest"));
73 | credentials.add(new BasicNameValuePair("password", "guest"));
74 |
75 | sendPost( "j_spring_security_check", credentials );
76 | sendGet( "welcome.mvc", false );
77 |
78 | String json = sendGet( "service/lessonmenu.mvc", false );
79 | lessons = parseLessons( json );
80 |
81 | } catch (Exception e ) {
82 | e.printStackTrace();
83 | }
84 | }
85 |
86 | public void run() {
87 | long start = System.currentTimeMillis();
88 | while( System.currentTimeMillis() - start < scanDuration * 1000 ) {
89 | try {
90 | long delay = this.requestDelay != -1 ? this.requestDelay : RANDOM.nextInt(1000);
91 | if(delay > 0) {
92 | Thread.sleep( delay );
93 | }
94 | String page = lessons.get( RANDOM.nextInt( lessons.size() ) );
95 | String[] parts = page.split( "/" );
96 | String lesson = "attack?Screen=" + parts[1] + "&menu=" + parts[2];
97 | if ( parts.length > 3 ) {
98 | lesson += "&stage=" + parts[3];
99 | }
100 | String form = sendGet( lesson, false );
101 | scan( lesson, form, attackPercent );
102 | } catch( Exception e ) {
103 | e.printStackTrace();
104 | }
105 | }
106 | }
107 |
108 | private void scan(String lesson, String form, int attackPercent ) throws Exception {
109 | List fields = parseForm( form );
110 | boolean attack = RANDOM.nextBoolean();
111 | permute( fields, attack, attackPercent );
112 | sendPost( lesson, fields );
113 | }
114 |
115 | private void permute(List fields, boolean attack, int attackPercent ) {
116 | for ( int i=0; i parseLessons(String lessons) {
132 | List allMatches = new ArrayList();
133 | Matcher m = Pattern.compile("#(attack.*?)\"").matcher(lessons);
134 | while (m.find()) {
135 | String page = m.group();
136 | if(verbose) {
137 | System.out.println(">>>>" + page );
138 | }
139 | allMatches.add(page.substring(1,page.length()-1));
140 | }
141 | return allMatches;
142 | }
143 |
144 |
145 |
146 | public String sendGet(String url, boolean xhr ) throws Exception {
147 | HttpGet httpGet = new HttpGet(baseUrl + url);
148 | // System.out.println( "SENDING: " + httpGet.getURI() );
149 | httpGet.addHeader("X-Forwarded-For", address );
150 | if ( xhr ) {
151 | httpGet.addHeader("X-Requested-With","XMLHttpRequest");
152 | }
153 | watch.reset();
154 | watch.start();
155 | CloseableHttpResponse response = httpclient.execute(httpGet);
156 | HttpEntity entity = response.getEntity();
157 | String content = EntityUtils.toString(entity);
158 | watch.stop();
159 | long elapsed = watch.getTime();
160 | checkHighestLowest(elapsed);
161 | this.totalScanTime += elapsed;
162 | this.requestCount++;
163 | response.close();
164 | return content;
165 | }
166 |
167 |
168 |
169 | public String sendPost(String url, List fields ) throws Exception {
170 | UrlEncodedFormEntity entity = new UrlEncodedFormEntity(fields, Consts.UTF_8);
171 | HttpPost httpPost = new HttpPost(baseUrl + url);
172 | if(verbose) {
173 | System.out.println( "POST from " + address + " to " + httpPost.getURI() );
174 | System.out.println( " " + fields );
175 | }
176 | httpPost.addHeader("X-Forwarded-For", address );
177 | httpPost.setEntity(entity);
178 |
179 | watch.reset();
180 | watch.start();
181 | CloseableHttpResponse response = httpclient.execute(httpPost);
182 | String content = EntityUtils.toString(response.getEntity());
183 | watch.stop();
184 | long elapsed = watch.getTime();
185 | checkHighestLowest(elapsed);
186 | totalScanTime += elapsed;
187 | response.close();
188 | if(verbose) {
189 | System.out.println( " " + response.getStatusLine() );
190 | System.out.println();
191 | }
192 | requestCount++;
193 | return content;
194 | }
195 |
196 | private void checkHighestLowest(long elapsed) {
197 | if(highest == -1 || elapsed > highest) {
198 | highest = elapsed;
199 | }
200 | if(lowest == -1 || elapsed < lowest) {
201 | lowest = elapsed;
202 | }
203 | }
204 |
205 | public long getTotalScanTime() {
206 | return totalScanTime;
207 | }
208 |
209 | public int getRequestCount() {
210 | return requestCount;
211 | }
212 |
213 | private static String getAttack() {
214 | return FRAGS[ RANDOM.nextInt(FRAGS.length) ];
215 | }
216 |
217 | private static List parseForm( String content ) {
218 | List fields = new ArrayList();
219 | int formStart = content.indexOf( "