### Analysis  
Expected analysis steps

1\. Read scripts  
1\. You find `http://host:port/?<regexp search query>#<URL>` shows  
\- element with `background-image: <URL>`  
\- notes only matching regexp query  
1\. You will try to detect whether any note matches the regexp query, by
controling the content located at `<URL>`.  
1\. You notice that notes have "deletion button"  
\- Only when any note matches the regexp query, the image of "deletion button"
is fetched.  
\- Hence, you'll become eager to detect whether the image of "deletion button"
was fetched by the communication to `<URL>`.  
1\. You'll find "deletion button image" has URL with `https` scheme, and its
certificate was issued by *Let's Encrypt Authority X3*.  
\- Other HTTPS URLs (`https://cdnjs.cloudflare.com/...`,
`https://cdn.jsdelivr.net/...`, `https://use.fontawesome.com/...`) use
different certificates.  
1\. The Let's Encrypt certificate is an intermediate one, which is signed by
root CA *DST Root CA X3*.  
\- You can find the detail [here](https://letsencrypt.org/certificates/).  
1\. What if you present a certificate signed by Let's Encrypt without the
certificate for Let's Encrypt intermediate CA signed by Root CA...?  
\- Actually, Firefox has the cache for SSL certificates [citation needed] !
You can find it through experiments.

### Solution

1\. You should prepare  
\- one machine with a global IP such as VPS  
\- If testing locally, you can use `192.168.1.100` now.  
\- one DNS record that points to the global IP  
\- There are several free Dynamic DNS services.  
\- If testing locally, you can use `jfwioaw.hopto.org` now.  
1\. Get a certificate issued by *Let's Encrypt Authority X3*  
\- `docker run --rm -ti -v /tmp/cert/etc:/etc/letsencrypt -v
/tmp/cert/var:/var/lib/letsencrypt certbot/certbot certonly --manual
--preferred-challenges http --server
https://acme-v02.api.letsencrypt.org/directory -d 'example.jp'`  
\- If testing locally, I prepared a cert for `jfwioaw.hopto.org` in this
directory.  
1\. Insert a short delay before presenting the SSL certificate  
\- Because you want to detect whether the certificate for "deletion image" was
cached, "deletion image" fetch must precede the header image fetch.  
\- `socat tcp-listen:8001,bind=0.0.0.0,fork,reuseaddr system:'sleep 1; nc
127.0.0.1 5678'` (included in solver.rb)  
1\. Terminate TLS using only the leaf certificate (i.e. use `cert.pem` without
`chain.pem` and `fullchain.pem`)  
\- `socat openssl-
listen:5678,fork,reuseaddr,certificate=cert.pem,key=privkey.pem,verify=0
system:'nc 127.0.0.1 6789'` (included in solver.rb)  
1\. Now, you can derive the 1bit information, that is the existence of
preceding "deletion image" fetch, by detecting if Firefox continues HTTP
communication after SSL handshakes.

Original writeup (https://github.com/tsg-
ut/tsgctf2020/blob/master/web/note/writeup/writeup.md).