what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Telegram For Android Connection::onReceivedData Use-After-Free

Telegram For Android Connection::onReceivedData Use-After-Free
Posted Jul 29, 2024
Authored by Google Security Research, Mark Brand

Telegram for Android suffers from a use-after-free vulnerability in Connection::onReceivedData.

tags | advisory
SHA-256 | b50977499b859adec9bc55d49621466231a4ab00aa44223747f9839cecd9995e

Telegram For Android Connection::onReceivedData Use-After-Free

Change Mirror Download
Telegram for Android: Use-after-free in Connection::onReceivedData

Reporting this in collaboration with Mitch, who found crashes indicating this issue and brought it to my attention.

Related to https://bugs.chromium.org/p/project-zero/issues/detail?id=2505; there's another issue which I overlooked when reviewing the fix. If we look more closely at `Connection::onReceivedData`, there's another possibility that can invalidate `buffer`.

```
void Connection::onReceivedData(NativeByteBuffer *buffer) {
AES_ctr128_encrypt(buffer->bytes(), buffer->bytes(), buffer->limit(), &decryptKey, decryptIv, decryptCount, &decryptNum);

// snip...

NativeByteBuffer *reuseLater = nullptr;
while (buffer->hasRemaining()) {
// snip...

uint32_t old = buffer->limit();
buffer->limit(buffer->position() + currentPacketLength);

ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionDataReceived(this, buffer, currentPacketLength);
buffer->position(buffer->limit()); // <-- Use here
buffer->limit(old);

// snip...
```

We can see the call to `ConnectionsManager::onConnectionDataReceived`, and it should be the case that buffer etc. remain valid past this call. If we look at the implementation, we can see that (at least in the case where we aren't using a proxy) we call `connection->reconnect()`

```
void ConnectionsManager::onConnectionDataReceived(Connection *connection, NativeByteBuffer *data, uint32_t length) {
bool error = false;
if (length <= 24 + 32) {
int32_t code = data->readInt32(&error);
if (code == 0) {
// snip...
} else {
Datacenter *datacenter = connection->getDatacenter();
if (LOGS_ENABLED) DEBUG_W(\"mtproto error = %d\", code);
if (code == -444 && connection->getConnectionType() == ConnectionTypeGeneric && !proxyAddress.empty() && !proxySecret.empty()) {
// snip...
} else if (code == -404 && (datacenter->isCdnDatacenter || PFS_ENABLED)) {
// snip...
} else {
connection->reconnect();
}
}
return;
}

// snip...
```

`Connection::reconnect` calls down into `Connection::suspendConnection`, which releases `restOfTheData`, which may alias `buffer`.

```
void Connection::suspendConnection(bool idle) {
reconnectTimer->stop();
waitForReconnectTimer = false;
if (connectionState == TcpConnectionStageIdle || connectionState == TcpConnectionStageSuspended) {
return;
}
if (LOGS_ENABLED) DEBUG_D(\"connection(%p, account%u, dc%u, type %d) suspend\", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType);
connectionState = idle ? TcpConnectionStageIdle : TcpConnectionStageSuspended;
dropConnection();
ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionClosed(this, 0);
firstPacketSent = false;
if (restOfTheData != nullptr) {
restOfTheData->reuse(); // <-- Free here
restOfTheData = nullptr;
}
lastPacketLength = 0;
connectionToken = 0;
wasConnected = false;
}

This will then lead to a use-after-free on buffer after returning from `ConnectionsManager::onConnectionDataReceived`.

Crashes with a matching stack trace have been observed, so it is definitely possible for this to occur - since the simplest case requires that the client be connected directly to the datacenter instead of through a proxy, I haven't attempted to reproduce the issue yet.

It is however possible to reach `connection->reconnect()` in multiple ways inside `ConnectionsManager::onConnectionDataReceived`, so it's very likely that this is also reachable in a similar way to issue 2505.

This bug is subject to a 90-day disclosure deadline. If a fix for this
issue is made available to users before the end of the 90-day deadline,
this bug report will become public 30 days after the fix was made
available. Otherwise, this bug report will become public at the deadline.
The scheduled deadline is 2024-07-23.





Found by: markbrand@google.com

Login or Register to add favorites

File Archive:

September 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Sep 1st
    261 Files
  • 2
    Sep 2nd
    17 Files
  • 3
    Sep 3rd
    38 Files
  • 4
    Sep 4th
    52 Files
  • 5
    Sep 5th
    23 Files
  • 6
    Sep 6th
    0 Files
  • 7
    Sep 7th
    0 Files
  • 8
    Sep 8th
    0 Files
  • 9
    Sep 9th
    0 Files
  • 10
    Sep 10th
    0 Files
  • 11
    Sep 11th
    0 Files
  • 12
    Sep 12th
    0 Files
  • 13
    Sep 13th
    0 Files
  • 14
    Sep 14th
    0 Files
  • 15
    Sep 15th
    0 Files
  • 16
    Sep 16th
    0 Files
  • 17
    Sep 17th
    0 Files
  • 18
    Sep 18th
    0 Files
  • 19
    Sep 19th
    0 Files
  • 20
    Sep 20th
    0 Files
  • 21
    Sep 21st
    0 Files
  • 22
    Sep 22nd
    0 Files
  • 23
    Sep 23rd
    0 Files
  • 24
    Sep 24th
    0 Files
  • 25
    Sep 25th
    0 Files
  • 26
    Sep 26th
    0 Files
  • 27
    Sep 27th
    0 Files
  • 28
    Sep 28th
    0 Files
  • 29
    Sep 29th
    0 Files
  • 30
    Sep 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2024 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close