Tản mạn về lỗ hổng trong máy ATM

English version below….

Mở đầu

Câu chuyện được bắt đấu vào đầu năm 2019, nhóm mình “vô tình” truy cập được vào một máy ATM của hãng Diebold. Theo mình biết đây là một hãng khá nổi tiếng, chuyên cung cấp các máy ATM trên thế giới, chiếm thị phần khá lớn ở Việt Nam.

Ý tưởng của khá đơn giản, thử tìm xem có lỗ hổng nào có thể lợi dụng được không. Vậy thì bắt tay vào làm thôi.

Nội dung

Trước khi bắt tay vào làm, ATM trong tưởng tượng là một máy tính chạy hệ điều hành Windows. Tiến hành phân tích nhanh thì đúng là như thế thật :D. Một máy tính được cài hệ điều hành Windows, có thêm các services của hãng.

Việc đầu tiên cần xác định các attack surface có thể. Với mục tiêu tìm kiếm một lỗ hổng dạng “Remote”, cần xác định được port / dịch vụ nào đang listen public (0.0.0.0). Sử dụng lệnh netstat -ano và phân tích:

Chú ý đến port 8043. Port này đang được quản lý bởi dịch vụ: Spiservice (Binary spiservice.exe). Về cơ bản đây là một dịch vụ nằm trong bộ các dịch vụ XFS (nếu ai có nghiên cứu về ATM thì đây như là một platform cho ATM)

Aglis XFS for Opteva, phiên bản 4.1.61.1 (2/2/2018). Nằm trong Diebold XFS Services

Một cách thông thường, thử truy cập bằng http vào cổng này:

Một thông báo trông rất quen thuộc, của một dịch vụ xa lạ. Tiếp tục phân tích sâu hơn, file exe này gọi đến nhiều thư viện, trong đó có một thư viện là VDMXFS.dll:

Chương trình sử dụng hàm: RemotingConfiguration.Configure(“server.config”). Chắc là file config đây. Phân tích file này có một số “manh mối”, bao gồm cả 01 url khá là hay.

Nhận định nữa là chương trình sử dụng kỹ thuật lập trình .NET Remoting. Một chút “vô tình” nữa, nhóm tìm được một bài mô tả khá chi tiết về kỹ thuật này https://www.codeproject.com/Articles/14791/NET-Remoting-with-an-easy-example.

Dựa trên các mô tả, bên mình tiến hành lập trình hai ứng dụng để tạo tương tác qua mạng. Dự định của mình là bắt lấy traffic này để phân tích. Và kết quả khá hợp lý, giao thức giao tiếp là http soap (theo cấu hình trong file Server.config).

Đến đây có thể dẫn đến 2 lỗi: XXE và XML Deserialization. Tiếp tục phân tích, dịch ngược thì thấy rằng XXE là không khả thi (Ứng dụng sử dụng .Net >= 4, default đã disable dtd). Tập trung vào phân tích XML Deserialization.

RemotingConfiguration class thuộc thư viện System.Runtime.Remoting, theo tài liệu mô tả của M$ thư viện này gửi và nhận dữ liệu serialization.

Một chú ý nữa là file config đang để typeFilterLevel=”Full”

Time to debug:

Thực hiện debug, đặt breakpoint để verify việc gọi hàm deserialize soap ở thư viện .net, và đúng là chương trình có gọi desrialize:

Tiến hành tạo payload với (***censored***) và test:

“We get a bad excetion and our exploitation dreams go up in smoke”

Trace lại theo callstack, dễ thấy thêm 1 số hành động thực hiện trước khi deserialize:

Chương trình cần Resolve 1 method name để call, và payload của (***censored***) vốn chỉ có 1 class cho Dataset:

Thêm 1 methodname cho việc resolvemethod thnh công. Exploit run!

Thử với run calc.exe xem sao:

Xây dựng payload tạo reverse shell để backconnect:

Tổng kết

Bằng một số mối quan hệ cá nhân, nhóm có thể chạy thử exploit trên một số máy ATM thật. Và thật bất ngờ là gần như máy ATM nào (tại thời điểm đó) exploit đều run thành công. Hoàn toàn có thể chiếm quyền điều khiển một máy ATM từ xa.

Phương án khắc phục lỗ hổng:

- Bản chất nằm ở dịch vụ quản lý các thành phần của máy ATM. Về lý thuyết việc này không cần phải publish dịch vụ (chỉ cần listen 127.0.0.1). Giới hạn các dải mạng, cô lập mạng ATM cũng là một giải pháp.

- Lập trình an toàn xử lý HTTP SOAP

- Fix theo bản vá của hãng. Theo mình được biết hãng đã có bản vá. Tuy nhiên nội dung và cách fix bên mình không nắm được.

Trong một diễn biến khác: Nhóm đã thử cố gắng liên hệ với Diebold, ít nhất qua 2 kênh. Tuy nhiên không nhận được phản hồi. Cũng đã quá hạn 90 ngày khá lâu nên nhóm quyết định sẽ publish lỗ hổng này.

Cuối cùng, thay lời của một thành viên trong nhóm: “Tất cả quá trình đều rất đơn giản, với 1 vài ngày làm việc, 1 2 người có thể tạo ra một mã khai thác ảnh hưởng rất lớn!”

Bài viết không kèm mã tấn công (POC)

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

English version:

Summary:

The story begins at early 2019 when my team can access to an ATM of Diebold vendor. Diebold is a big producer which provide ATM for many banks in the world. In Vietnam, they are also suppliers with a large market share. I have never worked with ATM services, so we would try to find out if it could be exploited. Let’s start.

Content:

In my opinion, ATM is a PC with Windows OS and some services provide by ATM provider. Now, I can sure that it is true =))

First step, I try to determine the attack surfaces. With the goal of finding a Remote Code Execution bug, I use “netstat -anbo” command to list all services and ports which expose to public.

Look at the output of command, there is a service (Spiservice) which running on port 8043. The SpiService.exe is associated with XFS, the Extension for Financial Services DLL library (MSXFS.dll) that is specifically used by ATMs. The library provides a special API for the communication with the ATM’s PIN pad and the cash dispenser.

This ATM which I accessed are running Aglis XFS for Opteva version 4.1.61.1, this product in Diebold XFS Service

Try to connect to service using web browser:

This service calls to many libraries, including a library called VDMXFS.dll:

You can see the program use RemotingConfiguration.Configure with a parameter is “server.config” to load config. Look at this file, I found a URL and some others interesting evidence. Also, I am sure that the program uses .NET Remoting technique. I found a great article about this technique when search about the technique on Google,: https://www.codeproject.com/Articles/14791/NET-Remoting-with-an-easy-example.

Following the descriptions, I created two applications to interactive remote through network as example. Then, I captured the network to debug and found that they use HTTP SOAP protocol to communicate.

With XML, there are two exploits here: XXE and XML Deserialization. Continue to analyse, I cannot exploit the program via XXE because the program running on .NET framework version >=4 which disabled DTD by default. Therefore, I will focus on XML Deserialization attack.

The RemotingConfiguration class is in the System.Runtime.Remoting library, which used to send and receive serialization data:

Look at the config of this library, you can see the typeFilterLevel=”Full” by default.

Back to debug the program, I put a breakpoint at deserialize function:

Create a payload with *REDACTED* then send to the program:

I get a bad exception returned and our exploitation dreams go up in smoke. Trace the call stack, I found they call some another function before deserialize the payload.

The program need resolve a method name to call and my payload has only one class for Dataset. Add a method name to pass the resolve step and re-run the program:

Boommmmmmmmmmmmmmmmmmmmmmmmmmmm!

Time to create a payload with reverse shell to back connect:

Conclusion:

I have successfully tested the exploit with some other ATMs. I think banks should update patch for this vulnerability as soon as possible.

Some suggestion from my team:

· The Spiservice is an internal service, so we don’t need to public the service (should 127.0.0.1 only).

· Follow the secure code guideline for HTTP SOAP.

· Upgrade to latest version.

My team also try to contact with Diebold via some channels but got no response. Therefore, my team public this article after 90 days, follow the Google Project Zero. This is simple vulnerability but has large impact, hope this article can help banks aware about this vulnerability.