Primer paso de la investigacion. Se aportan el .apk, las carpetas con el apk extraido y el apk descompilado. El archivo API_DOCUMENTATION.md es un archivo donde se anotaran los descubrimientos del funcionamiento de la API, y los .py son scripts para probar la funcionalidad de la API con los métodos que vayamos encontrando. Finalmente, los archivos .js son scripts de Frida para extraer informacion de la APP durante la ejecucion.

This commit is contained in:
2025-12-04 13:59:54 +01:00
parent f2fd1c3bf5
commit e0133d2ca2
10432 changed files with 1019085 additions and 1 deletions

247
API_DOCUMENTATION.md Normal file
View File

@@ -0,0 +1,247 @@
# Adif Elcano API - Ingeniería Reversa
Documentación de la API de Adif (Elcano) obtenida mediante ingeniería reversa de la aplicación móvil.
## URLs Base
```
BASE_URL_STATIONS = https://estaciones.api.adif.es
BASE_URL_CIRCULATION = https://circulacion.api.adif.es
BASE_URL_ELCANOWEB = https://elcanoweb.adif.es/api/
BASE_URL_AVISA = https://avisa.adif.es/avisa-ws/api/
```
## Headers de Autenticación
### Para API de Circulaciones y Composiciones
```
Content-Type: application/json;charset=utf-8
User-key: f4ce9fbfa9d721e39b8984805901b5df
```
### Para API de Estaciones
```
Content-Type: application/json;charset=utf-8
User-key: 0d021447a2fd2ac64553674d5a0c1a6f
```
### Para Avisa Login
```
Authorization: Basic YXZpc3RhX2NsaWVudF9hbmRyb2lkOjh5WzZKNyFmSjwhXypmYXE1NyNnOSohNElwa2MjWC1BTg==
```
### Para Suscripciones
```
Authorization: Basic ZGVpbW9zOmRlaW1vc3R0
X-CanalMovil-Authentication: <token>
X-CanalMovil-deviceID: <device_id>
X-CanalMovil-pushID: <push_id>
```
## Tokens
```
REGISTRATION_TOKEN = Bearer b9034774-c6e4-4663-a1a8-74bf7102651b
```
## Endpoints
### Estaciones
#### Obtener todas las estaciones
```
GET /portroyalmanager/secure/stations/allstations/reducedinfo/{token}/
Base: https://estaciones.api.adif.es
Headers: User-key para estaciones
```
#### Obtener detalles de una estación
```
POST /portroyalmanager/secure/stations/onestation/
Base: https://estaciones.api.adif.es
Headers: User-key para estaciones
Body:
{
"stationCode": "string"
}
```
#### Observaciones de estación
```
POST /portroyalmanager/secure/stationsobservations/
Base: https://estaciones.api.adif.es
Headers: User-key para estaciones
```
### Circulaciones (Trenes)
#### Salidas (Departures)
```
POST /portroyalmanager/secure/circulationpaths/departures/traffictype/
Base: https://circulacion.api.adif.es
Headers: User-key para circulaciones
Body:
{
"commercialService": "YES|NO|ALL",
"commercialStopType": "YES|NO|ALL",
"destinationStationCode": "string|null",
"originStationCode": "string|null",
"page": {
"page": number,
"size": number
},
"stationCode": "string|null",
"trafficType": "CERCANIAS|MEDIA_DISTANCIA|LARGA_DISTANCIA|ALL"
}
```
#### Llegadas (Arrivals)
```
POST /portroyalmanager/secure/circulationpaths/arrivals/traffictype/
Base: https://circulacion.api.adif.es
Headers: User-key para circulaciones
Body: Same as departures
```
#### Entre estaciones
```
POST /portroyalmanager/secure/circulationpaths/betweenstations/traffictype/
Base: https://circulacion.api.adif.es
Headers: User-key para circulaciones
Body: Same as departures
```
#### Una ruta específica
```
POST /portroyalmanager/secure/circulationpathdetails/onepaths/
Base: https://circulacion.api.adif.es
Headers: User-key para circulaciones
Body:
{
"allControlPoints": boolean|null,
"commercialNumber": "string|null",
"destinationStationCode": "string|null",
"launchingDate": timestamp|null,
"originStationCode": "string|null"
}
```
#### Varias rutas
```
POST /portroyalmanager/secure/circulationpathdetails/severalpaths/
Base: https://circulacion.api.adif.es
Headers: User-key para circulaciones
Body: Same as onepaths
```
### Composiciones
#### Composición de tren
```
POST /portroyalmanager/secure/circulationpaths/compositions/path/
Base: https://circulacion.api.adif.es
Headers: User-key para circulaciones
Body: Same as onepaths request
```
### Avisa (Sistema de incidencias)
#### Login
```
POST /avisa-ws/api/token
Base: https://avisa.adif.es
Headers: Basic auth token para Avisa
Query params:
- grant_type: "password"
- username: <username>
- password: <password>
```
#### Registrar cliente
```
POST /avisa-ws/api/v1/client
Base: https://avisa.adif.es
```
#### Estaciones Avisa
```
GET /avisa-ws/api/v1/station
Base: https://avisa.adif.es
```
#### Categorías de estación
```
GET /avisa-ws/api/v1/category
Base: https://avisa.adif.es
```
#### Incidencias
```
GET /avisa-ws/api/v1/incidence
POST /avisa-ws/api/v1/incidence
GET /avisa-ws/api/v1/incidence/{incidenceId}
Base: https://avisa.adif.es
```
### Suscripciones
#### Listar suscripciones
```
GET /api/subscriptions?platform=300
Base: https://elcanoweb.adif.es
Headers: Basic auth + X-CanalMovil headers
```
#### Crear suscripción
```
POST /api/subscriptions
Base: https://elcanoweb.adif.es
Headers: Basic auth + X-CanalMovil headers
```
#### Silenciar suscripción
```
PUT /api/subscriptions/{id}/mute
Base: https://elcanoweb.adif.es
Headers: Basic auth + X-CanalMovil headers
```
## Tipos de Datos
### TrafficType (Tipos de tráfico)
- `CERCANIAS` - Trenes de cercanías
- `MEDIA_DISTANCIA` - Media distancia
- `LARGA_DISTANCIA` - Larga distancia
- `ALL` - Todos los tipos
### State (Estados)
- `YES` - Sí
- `NO` - No
- `ALL` - Todos
### PageInfoDTO
```json
{
"page": 0,
"size": 20
}
```
## Notas de Seguridad
- La app usa certificate pinning con claves públicas específicas
- Los tokens están hardcodeados en la aplicación
- Las User-keys son diferentes para cada servicio (estaciones vs circulaciones)
- El token de registro `b9034774-c6e4-4663-a1a8-74bf7102651b` está en el código
[CODE] 200
[METHOD] POST
[URL] https://circulacion.api.adif.es/portroyalmanager/secure/circulationpathdetails/onepaths/
[URL] https://circulacion.api.adif.es/portroyalmanager/secure/circulationpaths/betweenstations/traffictype/
[URL] https://circulacion.api.adif.es/portroyalmanager/secure/circulationpaths/departures/traffictype/
[URL] https://estaciones.api.adif.es/portroyalmanager/secure/stationsobservations/