View Javadoc
1   package com.jsql.model.injection.strategy.blind.callable;
2   
3   import com.jsql.model.injection.strategy.blind.InjectionCharInsertion;
4   import com.jsql.model.injection.strategy.blind.patch.Diff;
5   import com.jsql.model.injection.strategy.blind.patch.DiffMatchPatch;
6   import com.jsql.util.LogLevelUtil;
7   import org.apache.logging.log4j.LogManager;
8   import org.apache.logging.log4j.Logger;
9   
10  import java.util.LinkedList;
11  import java.util.List;
12  import java.util.concurrent.CopyOnWriteArrayList;
13  
14  /**
15   * Define a call HTTP to the server, require the associated url, character
16   * position and bit. Opcodes represent the differences between
17   * the reference page, and the resulting page.
18   */
19  public class CallableCharInsertion extends AbstractCallableBit<CallableCharInsertion> {
20  
21      private static final Logger LOGGER = LogManager.getRootLogger();
22  
23      private LinkedList<Diff> opcodes = new LinkedList<>();  // List of differences found between the reference page, and the present page
24  
25      private static final DiffMatchPatch DIFF_MATCH_PATCH = new DiffMatchPatch();
26  
27      private final InjectionCharInsertion injectionCharInsertion;
28  
29      private final String metadataInjectionProcess;
30  
31      /**
32       * Constructor for preparation and blind confirmation.
33       */
34      public CallableCharInsertion(String booleanUrl, InjectionCharInsertion injectionCharInsertion, String metadataInjectionProcess) {
35          this.booleanUrl = booleanUrl;
36          this.injectionCharInsertion = injectionCharInsertion;
37          this.metadataInjectionProcess = metadataInjectionProcess;
38      }
39  
40      /**
41       * Check if a result page means the SQL query is true,
42       * confirm that nothing in the resulting page is also defined
43       * in the pages from every FALSE SQL queries.
44       * @return true if the current SQL query is true
45       */
46      @Override
47      public boolean isTrue() {
48          // Fix #95422: ConcurrentModificationException on iterator.next()
49          List<Diff> copyTrueMarks = new CopyOnWriteArrayList<>(this.injectionCharInsertion.getConstantTrueMark());
50          for (Diff trueDiff: copyTrueMarks) {
51              try {  // Fix #96229: NullPointerException on contains()
52                  if (!this.opcodes.contains(trueDiff)) {
53                      return false;
54                  }
55              } catch (NullPointerException e) {
56                  LOGGER.log(LogLevelUtil.CONSOLE_JAVA, "Unexpected opcodes failure during char insertion", e);
57                  return false;
58              }
59          }
60          return true;
61      }
62  
63      /**
64       * Process the URL HTTP call, use function inject() from the model.
65       * Build the list of differences found between TRUE and the current page.
66       * @return Functional Blind Callable
67       */
68      @Override
69      public CallableCharInsertion call() {
70          String source = this.injectionCharInsertion.callUrl(this.booleanUrl, this.metadataInjectionProcess, this);
71  
72          this.opcodes = CallableCharInsertion.DIFF_MATCH_PATCH.diffMain(
73              this.injectionCharInsertion.getBlankFalseMark(),
74              source,
75              false
76          );
77  
78          CallableCharInsertion.DIFF_MATCH_PATCH.diffCleanupEfficiency(this.opcodes);
79          return this;
80      }
81  
82      public List<Diff> getOpcodes() {
83          return this.opcodes;
84      }
85  }