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 com.jsql.model.injection.strategy.blind.patch.Diff;
7   import com.jsql.model.injection.strategy.blind.patch.DiffMatchPatch;
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 BinRanges binRanges;
21  
22      private LinkedList<Diff> diffsWithReference = new LinkedList<>();  // List of differences found between the reference page, and the current page
23      private static final DiffMatchPatch DIFF_MATCH_PATCH = new DiffMatchPatch();
24      private final InjectionBlindBin injectionBlind;
25  
26      private final String metadataInjectionProcess;
27  
28      /**
29       * Constructor for preparation and blind confirmation.
30       */
31      public CallableBlindBin(
32          String sqlQuery,
33          InjectionModel injectionModel,
34          InjectionBlindBin injectionBlind,
35          BlindOperator blindOperator,
36          BinRanges binRanges,
37          String metadataInjectionProcess
38      ) {
39          this.isBinary = true;
40          this.binRanges = binRanges;
41          this.injectionBlind = injectionBlind;
42          this.metadataInjectionProcess = metadataInjectionProcess;
43          this.booleanUrl = injectionModel.getMediatorEngine().getEngine().instance().sqlTestBlindWithOperator(sqlQuery, blindOperator);
44      }
45  
46      /**
47       * Constructor for bits test.
48       */
49      public CallableBlindBin(
50          String sqlQuery,
51          int indexChar,
52          InjectionModel injectionModel,
53          InjectionBlindBin injectionBlind,
54          BlindOperator blindOperator,
55          BinRanges binRanges,
56          String metadataInjectionProcess
57      ) {
58          this(sqlQuery, injectionModel, injectionBlind, blindOperator, binRanges, metadataInjectionProcess);
59          this.booleanUrl = injectionModel.getMediatorEngine().getEngine().instance().sqlBlindBin(sqlQuery, indexChar, binRanges.mid(), blindOperator);
60          this.currentIndex = indexChar;
61      }
62  
63      /**
64       * Check if a result page means the SQL query is true,
65       * confirm that nothing in the resulting page is also defined
66       * in the pages from every FALSE SQL queries.
67       * @return true if the current SQL query is true
68       */
69      @Override
70      public boolean isTrue() {
71          // Fix #95426: ConcurrentModificationException on iterator.next()
72          List<Diff> falseDiffs = new CopyOnWriteArrayList<>(this.injectionBlind.getFalseDiffs());
73          for (Diff falseDiff: falseDiffs) {  // ignored when false OR false => falsy empty
74              // Fix #4386: NullPointerException on contains(), diffsWithReference initialized to new LinkedList<>()
75              if (this.diffsWithReference.contains(falseDiff)) {
76                  return false;
77              }
78          }
79          List<Diff> trueDiffs = new CopyOnWriteArrayList<>(this.injectionBlind.getTrueDiffs());
80          for (Diff trueDiff: trueDiffs) {
81              if (!this.diffsWithReference.contains(trueDiff)) {  // required, set to false when empty falseDiffs
82                  return false;
83              }
84          }
85          return true;  // not in falseDiffs and in trueDiffs
86      }
87  
88      /**
89       * Process the URL HTTP call, use function inject() from the model.
90       * Build the list of differences found between TRUE and the current page.
91       * @return Functional Blind Callable
92       */
93      @Override
94      public CallableBlindBin call() {
95          String result = this.injectionBlind.callUrl(this.booleanUrl, this.metadataInjectionProcess, this);
96          this.diffsWithReference = CallableBlindBin.DIFF_MATCH_PATCH.diffMain(this.injectionBlind.getSourceReferencePage(), result, true);
97          CallableBlindBin.DIFF_MATCH_PATCH.diffCleanupEfficiency(this.diffsWithReference);
98          return this;
99      }
100 
101     public List<Diff> getDiffsWithReference() {
102         return this.diffsWithReference;
103     }
104 
105     public BinRanges getBinRanges() {
106         return this.binRanges;
107     }
108 }