内容简介:I want to be able to inspect the traffic of programs running on my computer. I don’t really trust those programs and ideally I’d like to put nearly all of them into a high security jail.One of those programs is Oculus software. There are a few reasons why
I want to be able to inspect the traffic of programs running on my computer. I don’t really trust those programs and ideally I’d like to put nearly all of them into a high security jail.
One of those programs is Oculus software. There are a few reasons why I want to be cautious about Oculus software.
- Oculus is owned by Facebook, which means Facebook can dictate what Oculus software does with user’s data.
- Oculus servers run on Facebook’s infrastructure, which means that Facebook can have access to any data uploaded to those servers.
- Oculus Headset has cameras and software that builds a 3D map of my room, which can be uploaded to the servers.
- Oculus Privacy Policy explicitly states that Oculus automatically collects:
Information about your environment, physical movements, and dimensions when you use an XR device. For example, when you set up the Oculus Guardian System to alert you when you approach a boundary, we receive information about the play area that you have defined;
Fortunately, I can use programs such as Wireshark or tcpdump to inspect traffic sent to the servers.
Fortunately, Oculus is using TLS so that a third party cannot snoop on this data in transit.
Unfortunately, I am playing a role of “third party” in this case.
Fortunately, it’s possible to read process memory and extract secret keys and inspect TLS data.
Things that didn’t work
- Setting
SSLKEYLOGFILE
variable – Oculus Runtime is using a 1.0.2o version of OpenSSL where this is not supported. - Extracting OpenSSL keys using an automated debugger – Oculus Runtime is using statically linked OpenSSL with no debug symbols.
- Substituting OpenSSL library with one that can log secret keys – it’s statically linked.
- I didn’t want to add extra root certificates and proxies to inspect all TLS traffic going on the machine.
Doing this the hard way
So the plan forward was to:
- Figure out a code location where secret keys for the session are available
- Patch or debug the program so that we can inspect and log those keys
A bit of reverse engineering
To figure out the code location some reverse-engineering was necessary. The first step was to figure out which version does Oculus Runtime use. Looking for strings in OculusAppFramework.dll
, there was the following string: Stack part of OpenSSL 1.0.2o-fb10 27 Mar 2018
, which means I have a specific version that I work off.
After reading Introduction to OpenSSL programming on Linux Journal , I deduced that SSL_connect
(and later SSL_set_connect_state
) may be a good place to interject OpenSSL for key extraction.
I’ve loaded up Oculus Runtime into Ghidra, opened up source code that contains public interface of OpenSSL ssl_lib.c
and attempted to find common ground between those. The things of interest were integer and string constants which could be used as landmarks.
A particularly notable function is SSL_get_version
, which contains references to multiple strings. Looking for TLSv1.2
yielded a few locations, particularly this one:
It looks like SSL_get_version
got inlined. I suspected that this was not the only place where TLS connections were made, so I had to find a different place to work on. The next notable thing was that near one of the SSL version strings I’ve noticed code paths and assertion strings:
As it turns out, debug information such as source file names and assetion expressions, which can be used as landmarks too. Now we have more landmarks to navigate OpenSSL binary code.
I’ve continued to label function as I inspected nearby references to .\\ssl\ssl_lib.c
strings, and I’ve stumbled onto SSL_set_connect_state
function . Using the same code pattern, mov dword ptr [$register + 0x48], 0x5000
, I’ve found SSL_connect
as well. SSL_connect
had an inlined call to SSL_set_connect_state
. I’ve decided to be cautious and interject both of these functions.
Extracting the data
These functions already have pointers to ssl_st
struct, so let’s extract the data from there.
There were a few options to do this:
- Use/write a programmable debugger and breakpoint/inspect values on those functions
- Binary patch the DLL
- Use DLL injection and patching in-memory DLL code
Since I’ve had poor experience with controlling debuggers programmatically, I didn’t want to go use the first option. This is a potential thing that I might want to improve. Since I didn’t want to invalidate a signed DLL, I didn’t binary patch it. Last option it is.
DLL injection
To extract all TLS keys, we need to control the running process from the very beginning. One way to do this is to set gflags
to use DLL injector program as a debugger for the process. The program we want to debug is called OVRServer_x64.exe
, so let’s create HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\OVRServer_x64.exe
key in registry and set Debugger
string value to command line of our injector.
The injector doesn’t have to do any debugging, but it needs to start a program with DEBUG_ONLY_THIS_PROCESS
or DEBUG_PROCESS
flag. Otherwise, our debugger will bespawned recursively.
The CreateRemoteThread
DLL injection is itself a simple technique on Windows, it’s consicely described in a WikiLeaks article as well in other articles.
The code for injector.exe
is here .
Running from inside the process
After the DLL was injected, it can patch the code in-memory and log secret keys.
The architecture for injectee.dll
is pretty simple – patch the code, create a channel, create writer thread with the receiving end of the channel, send keys from different threads using the other end.
Patching was done in assembly. It can be approximately described like this:
There are several ways to extract the keys ginen a pointer to ssl_st
struct.
- Implementing a C library
- Walking the pointers manually
- Porting OpenSSL structs to the used language
Initially I’ve implemented walking the pointers by hand, but that is a very fragile approach. Porting OpenSSL structs to Rust is quite cumbersome, so I’ve implemented a miniature C library to read secret keys given an ssl_st
struct pointer.
The rest is plumbing, and we now can inspect TLS traffic in a running application:
The code for injectee.dll
is here .
If you’re interested, the entire code for the project is here: github.com/m1el/oculus-tls-extractor
Analysis of the data being sent by Oculus Runtime to the mothership is coming up in the follow-up post.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Test Driven Development
Kent Beck / Addison-Wesley Professional / 2002-11-18 / USD 49.99
Quite simply, test-driven development is meant to eliminate fear in application development. While some fear is healthy (often viewed as a conscience that tells programmers to "be careful!"), the auth......一起来看看 《Test Driven Development》 这本书的介绍吧!
CSS 压缩/解压工具
在线压缩/解压 CSS 代码
MD5 加密
MD5 加密工具