View Javadoc
1   package com.jsql.model.injection.strategy.blind.callable;
2   
3   import com.jsql.model.InjectionModel;
4   import com.jsql.model.injection.strategy.blind.AbstractInjectionBit.BlindOperator;
5   import com.jsql.model.injection.strategy.blind.InjectionBlindBin;
6   import name.fraser.neil.plaintext.diff_match_patch;
7   import static name.fraser.neil.plaintext.diff_match_patch.Diff;
8   
9   import java.util.LinkedList;
10  import java.util.List;
11  import java.util.concurrent.CopyOnWriteArrayList;
12  
13  /**
14   * Define a call HTTP to the server, require the associated url, character
15   * position and bit. Diffs represent the differences between
16   * the reference page, and the current page.
17   */
18  public class CallableBlindBin extends AbstractCallableBit<CallableBlindBin> {
19  
20      private final int low;
21      private final int mid;
22      private final int high;
23  
24      private LinkedList<Diff> diffsWithReference = new LinkedList<>();  // List of differences found between the reference page, and the current page
25      private static final diff_match_patch DIFF_MATCH_PATCH = new diff_match_patch();
26      private final InjectionBlindBin injectionBlind;
27  
28      private final String metadataInjectionProcess;
29  
30      /**
31       * Constructor for preparation and blind confirmation.
32       */
33      public CallableBlindBin(
34          String sqlQuery,
35          InjectionModel injectionModel,
36          InjectionBlindBin injectionBlind,
37          BlindOperator blindOperator,
38          int low, int mid, int high,
39          String metadataInjectionProcess
40      ) {
41          this.isBinary = true;
42          this.low = low;
43          this.mid = mid;
44          this.high = high;
45          this.injectionBlind = injectionBlind;
46          this.metadataInjectionProcess = metadataInjectionProcess;
47          this.booleanUrl = injectionModel.getMediatorVendor().getVendor().instance().sqlTestBlindWithOperator(sqlQuery, blindOperator);
48      }
49  
50      /**
51       * Constructor for bits test.
52       */
53      public CallableBlindBin(
54          String sqlQuery,
55          int indexChar,
56          InjectionModel injectionModel,
57          InjectionBlindBin injectionBlind,
58          BlindOperator blindOperator,
59          int low, int mid, int high,
60          String metadataInjectionProcess
61      ) {
62          this(sqlQuery, injectionModel, injectionBlind, blindOperator, low, mid, high, metadataInjectionProcess);
63          this.booleanUrl = injectionModel.getMediatorVendor().getVendor().instance().sqlBlindBin(sqlQuery, indexChar, mid, blindOperator);
64          this.currentIndex = indexChar;
65      }
66  
67      /**
68       * Check if a result page means the SQL query is true,
69       * confirm that nothing in the resulting page is also defined
70       * in the pages from every FALSE SQL queries.
71       * @return true if the current SQL query is true
72       */
73      @Override
74      public boolean isTrue() {
75          // Fix #95426: ConcurrentModificationException on iterator.next()
76          List<Diff> falseDiffs = new CopyOnWriteArrayList<>(this.injectionBlind.getFalseDiffs());
77          for (Diff falseDiff: falseDiffs) {  // ignored when false OR false => falsy empty
78              // Fix #4386: NullPointerException on contains(), diffsWithReference initialized to new LinkedList<>()
79              if (this.diffsWithReference.contains(falseDiff)) {
80                  return false;
81              }
82          }
83          List<Diff> trueDiffs = new CopyOnWriteArrayList<>(this.injectionBlind.getTrueDiffs());
84          for (Diff trueDiff: trueDiffs) {
85              if (!this.diffsWithReference.contains(trueDiff)) {  // required, set to false when empty falseDiffs
86                  return false;
87              }
88          }
89          return true;  // not in falseDiffs and in trueDiffs
90      }
91  
92      /**
93       * Process the URL HTTP call, use function inject() from the model.
94       * Build the list of differences found between TRUE and the current page.
95       * @return Functional Blind Callable
96       */
97      @Override
98      public CallableBlindBin call() {
99          String result = this.injectionBlind.callUrl(this.booleanUrl, this.metadataInjectionProcess, this);
100         this.diffsWithReference = CallableBlindBin.DIFF_MATCH_PATCH.diff_main(this.injectionBlind.getSourceReferencePage(), result, true);
101         CallableBlindBin.DIFF_MATCH_PATCH.diff_cleanupEfficiency(this.diffsWithReference);
102         return this;
103     }
104     
105     public List<Diff> getDiffsWithReference() {
106         return this.diffsWithReference;
107     }
108 
109     public int getLow() {
110         return this.low;
111     }
112 
113     public int getMid() {
114         return this.mid;
115     }
116 
117     public int getHigh() {
118         return this.high;
119     }
120 }