diff --git a/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/README.md b/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/README.md index 9c7037bac..698a7ec8a 100644 --- a/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/README.md +++ b/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/README.md @@ -2,21 +2,21 @@ {{#include ../../../banners/hacktricks-training.md}} -## Azure Kiracı +## Azure Tenant -### Kiracı Keşfi +### Tenant Enumeration -Bazı **herkese açık Azure API'leri** vardır; saldırgan sadece kiracının **alan adını** bilerek daha fazla bilgi toplamak için bu API'leri sorgulayabilir.\ +Bir saldırganın yalnızca **tenant domainini** bilerek daha fazla bilgi toplamak için sorgulayabileceği bazı **public Azure API'leri** vardır.\ API'yi doğrudan sorgulayabilir veya PowerShell kütüphanesi [**AADInternals**](https://github.com/Gerenios/AADInternals) (`Install-Module AADInternals`) kullanabilirsiniz: -- **Tenant ID dahil oturum açma bilgileri** -- `Get-AADIntTenantID -Domain ` (main API `login.microsoftonline.com//.well-known/openid-configuration`) -- **Kiracıdaki tüm geçerli alan adları** -- `Get-AADIntTenantDomains -Domain ` (main API `autodiscover-s.outlook.com/autodiscover/autodiscover.svc`) -- **Kullanıcının oturum bilgileri**. Eğer `NameSpaceType` `Managed` ise, bu EntraID kullanıldığı anlamına gelir -- `Get-AADIntLoginInformation -UserName ` (main API `login.microsoftonline.com/GetUserRealm.srf?login=`) +- **tenant ID dahil login bilgileri** +- `Get-AADIntTenantID -Domain ` (ana API `login.microsoftonline.com//.well-known/openid-configuration`) +- **tenant içindeki tüm geçerli domainler** +- `Get-AADIntTenantDomains -Domain ` (ana API `autodiscover-s.outlook.com/autodiscover/autodiscover.svc`) +- **kullanıcının login bilgileri**. Eğer `NameSpaceType` `Managed` ise, bu EntraID kullanıldığı anlamına gelir +- `Get-AADIntLoginInformation -UserName ` (ana API `login.microsoftonline.com/GetUserRealm.srf?login=`) -Bir Azure kiracısının tüm bilgilerini [**AADInternals**](https://github.com/Gerenios/AADInternals) içinden **sadece bir komutla** sorgulayabilirsiniz: +Bir Azure tenant'ına ait tüm bilgileri [**AADInternals**](https://github.com/Gerenios/AADInternals) ile **tek bir komutla** sorgulayabilirsiniz: ```bash # Doesn't work in macos because 'Resolve-DnsName' doesn't exist Invoke-AADIntReconAsOutsider -DomainName corp.onmicrosoft.com | Format-Table @@ -35,33 +35,39 @@ company.mail.onmicrosoft.com True True True Managed company.onmicrosoft.com True True True Managed int.company.com False False False Managed ``` -It's possible to observe details about the tenant's name, ID, and "brand" name. Additionally, the status of the Desktop Single Sign-On (SSO), also known as [**Seamless SSO**](https://docs.microsoft.com/en-us/azure/active-directory/hybrid/how-to-connect-sso), is displayed. When enabled, this feature facilitates the determination of the presence (enumeration) of a specific user within the target organization. +Tenant’in adı, ID’si ve "brand" adı hakkında detayları gözlemlemek mümkündür. Ayrıca, Desktop Single Sign-On (SSO), yani [**Seamless SSO**](https://docs.microsoft.com/en-us/azure/active-directory/hybrid/how-to-connect-sso) durum bilgisi de gösterilir. Etkinleştirildiğinde, bu özellik hedef organization içindeki belirli bir kullanıcının varlığının (enumeration) belirlenmesini kolaylaştırır. -Moreover, the output presents the names of all verified domains associated with the target tenant, along with their respective identity types. In the case of federated domains, the Fully Qualified Domain Name (FQDN) of the identity provider in use, typically an ADFS server, is also disclosed. The "MX" column specifies whether emails are routed to Exchange Online, while the "SPF" column denotes the listing of Exchange Online as an email sender. It is important to note that the current reconnaissance function does not parse the "include" statements within SPF records, which may result in false negatives. +Ayrıca, çıktı hedef tenant ile ilişkili tüm verified domain’lerin adlarını ve bunların ilgili identity type’larını sunar. Federated domain’ler söz konusu olduğunda, kullanımda olan identity provider’ın Fully Qualified Domain Name (FQDN) değeri, genellikle bir ADFS server, da ifşa edilir. "MX" sütunu, e-postaların Exchange Online’a yönlendirilip yönlendirilmediğini belirtirken, "SPF" sütunu Exchange Online’ın bir e-posta göndericisi olarak listelenip listelenmediğini gösterir. Mevcut reconnaissance fonksiyonunun SPF record’lar içindeki "include" ifadelerini ayrıştırmadığını, bunun da false negative’lere yol açabileceğini unutmamak önemlidir. ### User Enumeration > [!TIP] -> Note that even if a tenant is using several emails for the same user, the **kullanıcı adı benzersizdir**. This means that it'll only work with the domain the user has associated and not with the other domains. +> Bir tenant aynı user için birden fazla email kullanıyor olsa bile, **username unique**’dir. Bu nedenle, yalnızca user’ın ilişkilendirdiği domain ile çalışır, diğer domain’lerle çalışmaz. -It's possible to **bir tenant içinde bir kullanıcı adının mevcut olup olmadığını kontrol etmek**. This includes also **misafir kullanıcıları**, whose username is in the format: +Bir tenant içinde bir **username’in mevcut olup olmadığını kontrol etmek** mümkündür. Buna **guest users** da dahildir; bunların username formatı şöyledir: ``` #EXT#@.onmicrosoft.com ``` -E-posta, kullanıcı e-posta adresidir; “@” yerine alt çizgi “\_” kullanılır. +E-posta, “@” işareti yerine underscore “\_” kullanılan kullanıcının e-posta adresidir. -With [**AADInternals**](https://github.com/Gerenios/AADInternals), kullanıcının var olup olmadığını kolayca kontrol edebilirsiniz: +[**AADInternals**](https://github.com/Gerenios/AADInternals) ile, kullanıcının var olup olmadığını kolayca kontrol edebilirsiniz: ```bash # Check does the user exist Invoke-AADIntUserEnumerationAsOutsider -UserName "user@company.com" ``` -Çevirmemi istediğiniz README.md içeriğini buraya yapıştırın. Kod blokları, linkler, yollar, tag'ler ve teknik terimler (pentesting, leak, bulut/SaaS platform isimleri vb.) çevrilmeyecek; geri kalan metni Türkçeye çevirip orijinal markdown/html yapısını koruyacağım. +Azure Security Nedir? + +Hacking teknikleri iki ana kategoriye ayrılır: initial access ve post-exploitation. Azure Security, Cloud Security'nin bir alt kategorisi olarak, Azure bulut ortamlarının güvenliğini sağlamaya odaklanır. Azure ortamlarında güvenlik testleri yaparken, genellikle ilk amaç, hedef sisteme yetkisiz erişim elde etmektir. Bu, kimlik doğrulama veya yetkilendirme mekanizmalarındaki zayıflıkları kullanarak yapılabilir. Azure Security kapsamında, saldırganlar farklı teknikler kullanarak ortamı keşfedebilir, yapılandırma hatalarını bulabilir ve ayrıcalıkları yükseltebilir. + +Bu bölümde, Azure ortamlarında yetkisiz enum ve initial entry yöntemleri ele alınmaktadır. Amaç, açık kaynaklı bilgiler ve yanlış yapılandırmalar üzerinden bir Azure tenant içine nasıl erişim sağlanabileceğini anlamaktır. Bu süreçte genellikle tenant bilgileri, kullanıcı hesapları, servis principal'lar ve uygulamalar hakkında veri toplanır. Ardından, bu bilgiler kullanılarak daha derin erişim veya ek saldırı yüzeyleri aranır. + +Not: pentesting faaliyetleri yalnızca yetkili ve yasal çerçevede yapılmalıdır. ``` UserName Exists -------- ------ user@company.com True ``` -Ayrıca her satırda bir e-posta adresi bulunan bir metin dosyası da kullanabilirsiniz: +Ayrıca satır başına bir e-posta adresi içeren bir text file da kullanabilirsiniz: ``` user@company.com user2@company.com @@ -75,22 +81,22 @@ external.user_outlook.com#EXT#@company.onmicrosoft.com # Invoke user enumeration Get-Content .\users.txt | Invoke-AADIntUserEnumerationAsOutsider -Method Normal ``` -Şu anda seçilebilecek **4 farklı enumeration yöntemi** var. Bilgiyi `Get-Help Invoke-AADIntUserEnumerationAsOutsider` içinde bulabilirsiniz: +Şu anda seçebileceğiniz **4 farklı enumeration methodu** var. `Get-Help Invoke-AADIntUserEnumerationAsOutsider` içinde bilgi bulabilirsiniz: -Aşağıdaki enumeration yöntemlerini destekler: Normal, Login, Autologon ve RST2. +Şu enumeration methodlarını destekler: Normal, Login, Autologon ve RST2. -- **Normal** yöntemi şu anda görünüşe göre tüm tenant'larda çalışıyor. Önceden en az bir domain için Desktop SSO (aka Seamless SSO) etkinleştirilmiş olmasını gerektiriyordu. +- **Normal** methodu şu anda tüm tenantlarla çalışıyor gibi görünüyor. Daha önce en az bir domain için Desktop SSO (namıdiğer Seamless SSO) etkin olmasını gerektiriyordu. -- **Login** yöntemi herhangi bir tenant ile çalışır, ancak enumeration sorguları Azure AD sign-in log'una başarısız login olayları olarak kaydedilecektir! +- **Login** methodu herhangi bir tenant ile çalışır, ancak enumeration sorguları Azure AD sign-in log içinde failed login events olarak loglanır! -- **Autologon** yöntemi artık tüm tenant'larda çalışıyor gibi görünmüyor. Muhtemelen DesktopSSO veya directory sync'in etkinleştirilmiş olmasını gerektirir. +- **Autologon** methodunun artık tüm tenantlarla çalışmadığı görülüyor. Muhtemelen DesktopSSO veya directory sync etkin olmasını gerektirir. -Geçerli kullanıcı adlarını keşfettikten sonra bir kullanıcı hakkında **bilgi** almak için: +Valid usernames keşfettikten sonra bir kullanıcı hakkında **info** alabilirsiniz: ```bash Get-AADIntLoginInformation -UserName root@corp.onmicrosoft.com ``` -Bu script [**o365spray**](https://github.com/0xZDH/o365spray) ayrıca bir email'in geçerli olup olmadığını tespit etmenizi sağlar. +Script [**o365spray**](https://github.com/0xZDH/o365spray) ayrıca bir **e-postanın geçerli olup olmadığını** keşfetmenize olanak tanır. ```bash git clone https://github.com/0xZDH/o365spray cd o365spray @@ -101,15 +107,15 @@ python3 ./o365spray.py --enum -d carloshacktricks.onmicrosoft.com -u carlos # Check a list of emails python3 ./o365spray.py --enum -d carloshacktricks.onmicrosoft.com -U /tmp/users.txt ``` -**User Enumeration via Microsoft Teams** +**Microsoft Teams Üzerinden User Enumeration** -Başka iyi bir bilgi kaynağı Microsoft Teams. +Bir diğer iyi bilgi kaynağı da Microsoft Teams'tir. -Microsoft Teams'in API'si kullanıcı aramaya izin verir. Özellikle "user search" endpoint'leri **externalsearchv3** ve **searchUsers**, Teams'e kayıtlı kullanıcı hesapları hakkında genel bilgi talep etmek için kullanılabilir. +Microsoft Teams API'si kullanıcı aramak için kullanılabilir. Özellikle "user search" endpoint'leri **externalsearchv3** ve **searchUsers**, Teams'e kayıtlı user account'lar hakkında genel bilgi istemek için kullanılabilir. -API yanıtına bağlı olarak var olmayan kullanıcılar ile geçerli bir Teams aboneliğine sahip mevcut kullanıcılar ayırt edilebilir. +API response'una bağlı olarak, var olmayan users ile geçerli bir Teams subscription'a sahip mevcut users arasında ayrım yapmak mümkündür. -Script [**TeamsEnum**](https://github.com/lucidra-security/TeamsEnum) belirli bir kullanıcı adı setini Teams API'ye karşı doğrulamak için kullanılabilir; ancak bunu kullanmak için Teams erişimi olan bir kullanıcı hesabına erişiminiz olması gerekir. +[**TeamsEnum**](https://github.com/lucidra-security/TeamsEnum) script'i, verilen bir username kümesini Teams API'ye karşı doğrulamak için kullanılabilir; ancak bunu kullanmak için Teams access'i olan bir user'a erişiminiz gerekir. ```bash # Install git clone https://github.com/lucidra-security/TeamsEnum @@ -119,13 +125,32 @@ python3 -m pip install -r requirements.txt # Login and ask for password python3 ./TeamsEnum.py -a password -u -f inputlist.txt -o teamsenum-output.json ``` -Çevirmem için src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/README.md dosyasının içeriğini gönderin. +# yetkisiz enum ve initial entry + +`[Microsoft Azure](https://www.microsoft.com/en-us/azure)` ortamlarında, uygun güvenlik ayarları yoksa, bilgisayarı ve kullanıcıları keşfetmek, erişim elde etmek ve yanal hareket için faydalı olabilecek çeşitli bilgi parçaları sızdırılabilir. + +[Pentesting Azure](https://cloud.hacktricks.wiki/en/pentesting-cloud/azure-security/index.html) bu bilgileri toplamak için farklı yolları kapsar, bunlardan bazıları şunlardır: + +- [Unauthenticated enumeration](unauthenticated-enum.md) +- [Initial entry](initial-entry.md) +- [Improperly secured interfaces](improperly-secured-interfaces.md) +- [Pre-authentication SSRF](pre-auth-ssrf.md) +- [Resource-specific vulnerabilities](resource-specific-vulns.md) + +Ayrıca çeşitli türlerde leaked bilgiyi de kapsar: + +- [Storage accounts](storage-accounts.md) +- [Azure AD](azure-ad.md) +- [Recovery Services vault](recovery-services-vault.md) +- [APIs](apis.md) +- [Domain fronting](domain-fronting.md) +- [Miscellaneous](miscellaneous.md) ``` [-] user1@domain - Target user not found. Either the user does not exist, is not Teams-enrolled or is configured to not appear in search results (personal accounts only) [+] user2@domain - User2 | Company (Away, Mobile) [+] user3@domain - User3 | Company (Available, Desktop) ``` -Ayrıca mevcut kullanıcıların aşağıdaki gibi kullanılabilirlik bilgilerini listelemek mümkündür: +Ayrıca, aşağıdaki gibi mevcut kullanıcılar hakkında kullanılabilirlik bilgilerini enumerate etmek mümkündür: - Available - Away @@ -133,11 +158,56 @@ Ayrıca mevcut kullanıcıların aşağıdaki gibi kullanılabilirlik bilgilerin - Busy - Offline -Bir **ofis dışı mesajı** yapılandırılmışsa, mesajı TeamsEnum kullanarak almak da mümkündür. Bir çıktı dosyası belirtilmişse, ofis dışı mesajlar otomatik olarak JSON dosyasına kaydedilir: +Bir **out-of-office message** yapılandırılmışsa, TeamsEnum kullanarak mesajı almak da mümkündür. Bir output file belirtilmişse, out-of-office mesajları otomatik olarak JSON dosyası içinde saklanır: ``` jq . teamsenum-output.json ``` -Bu dosyanın içeriğine erişimim yok. Lütfen src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/README.md dosyasının içeriğini buraya yapıştırın; verilen kurallara uygun olarak Türkçeye çevireyim. +# Kimlik Doğrulaması Olmadan Enum ve Initial Entry + +Bu bölüm, Azure üzerinde kimlik doğrulaması olmadan enum ve initial entry için teknikleri kapsar. + +- [AAD / Entra ID](#aad--entra-id) +- [Storage Accounts](#storage-accounts) +- [Key Vault](#key-vault) +- [Resource and API enumeration](#resource-and-api-enumeration) +- [Azure Functions](#azure-functions) +- [App Service](#app-service) +- [Kudu](#kudu) +- [Static Websites](#static-websites) + +## AAD / Entra ID + +### Device code login + +### Enumerate users, groups, and applications + +### Guessing usernames + +### Custom domain takeover / subdomain takeover + +## Storage Accounts + +### Blob enumeration + +### Container enumeration + +### File share enumeration + +### Queue enumeration + +### Table enumeration + +## Key Vault + +## Resource and API enumeration + +## Azure Functions + +## App Service + +## Kudu + +## Static Websites ```json { "email": "user2@domain", @@ -192,10 +262,10 @@ Bu dosyanın içeriğine erişimim yok. Lütfen src/pentesting-cloud/azure-secur az-password-spraying.md {{#endref}} -## Domain kullanan Azure Servisleri +## Azure Services using domains Ayrıca, bu [post: -](https://www.netspi.com/blog/technical-blog/cloud-penetration-testing/enumerating-azure-services/) içinde belgelenenlere benzer yaygın azure alt alanlarında **Azure services exposed** aramayı deneyebilirsiniz. +](https://www.netspi.com/blog/technical-blog/cloud-penetration-testing/enumerating-azure-services/) içinde belgelenenlere benzer yaygın azure subdomain'lerinde **exposed** olan **Azure services** bulmayı denemek de mümkündür. - App Services: `azurewebsites.net` - App Services – Management: `scm.azurewebsites.net` @@ -216,7 +286,7 @@ Ayrıca, bu [post: - Search Appliance: `search.windows.net` - API Services: `azure-api.net` -Böyle bir amaç için [**MicroBurst**](https://github.com/NetSPI/MicroBurst) içindeki bir yöntemi kullanabilirsiniz. Bu fonksiyon, temel domain adını (ve birkaç permutasyonu) birkaç **azure domains:** içinde arayacaktır: +Böyle bir amaç için [**MicroBust**](https://github.com/NetSPI/MicroBurst) içindeki bir methodu kullanabilirsiniz. Bu function, base domain name'i (ve birkaç permutation) birkaç **azure domain** içinde arayacaktır: ```bash Import-Module .\MicroBurst\MicroBurst.psm1 -Verbose Invoke-EnumerateAzureSubDomains -Base corp -Verbose @@ -226,20 +296,59 @@ Invoke-EnumerateAzureSubDomains -Base corp -Verbose - [**Common Phishing**](https://book.hacktricks.wiki/en/generic-methodologies-and-resources/phishing-methodology/index.html) for credentials or via [OAuth Apps](az-oauth-apps-phishing.md) - [**Device Code Authentication** Phishing](az-device-code-authentication-phishing.md) -## Dosya Sistemi Credentials +### Exchange Online direct-to-tenant SMTP spoofing -**`az cli`** birçok ilginç bilgiyi **`/.Azure`** içinde saklar: -- **`azureProfile.json`** geçmişte oturum açmış kullanıcılar hakkında bilgi içerir -- **`clouds.config`** abonelikler hakkında bilgi içerir -- **`service_principal_entries.json`** uygulamaların **credentials** (tenant id, clients and secret) içerir -- **`msal_token_cache.json`** **access tokens and refresh tokens** içerir +Eğer bir hedef **Exchange Online / EOP** kullanıyor ama public **MX** kaydı **third-party mail gateway**’e (Mimecast, Proofpoint, Mailgun, on-prem filtering, vb.) işaret ediyorsa, Exchange Online’ın hâlâ tenant host’a `*.mail.protection.outlook.com` doğrudan gönderilen mailleri kabul edip etmediğini test edin. Bu durumda attacker, **external gateway**’i atlayabilir ve phishing mail’ini doğrudan EOP’ye iletebilir. -macOS ve linux'ta bu dosyalar **korunmasız** olarak düz metin halinde saklanır. +Bu, **initial access / phishing** için kullanışlıdır; çünkü spoofed sender **SPF**, **DKIM** ve **DMARC** başarısız olsa bile teslimat yine de gerçekleşebilir. Internal sender’lar için Outlook ayrıca spoofed sender’ı gerçek bir employee olarak resolve edebilir ve bu da güveni artırır. -## Referanslar +**Recon / triage:** +```bash +# If the MX already points to Microsoft, this specific path is usually not the issue +dig +short MX target.com + +# Typical vulnerable pattern: the MX points to a third-party filter +# 10 mxb.eu.mailgun.org. +``` +Doğrudan EOP host genellikle tenant'a özel `mail.protection.outlook.com` ismidir (örneğin `target-com.mail.protection.outlook.com`). Çoğu zaman tenant adlandırma kalıbını public tenant/domain enumeration ve Exchange ile ilgili autodiscover yanıtlarından geri kazanabilirsiniz. + +**Minimal PoC:** +```powershell +Send-MailMessage -SmtpServer target-com.mail.protection.outlook.com -To victim@target.com -From ceo@target.com -Subject "Urgent" -Body "Review the attached payment change" -BodyAsHTML +``` +**Validation signals:** +- Mail `*.mail.protection.outlook.com` adresine, public MX host yerine gönderilir. +- Mesaj, başlıklarda `spf=fail`, `dkim=none`, `dmarc=fail` veya `compauth=none` gibi hatalar görünse bile teslim edilir. +- Güvenli bir Partner connector genellikle `RCPT TO` aşamasında `5.7.51 TenantInboundAttribution; Rejecting.` ile reddeder. + +**Technical notes / defensive hunting:** +- **Enhanced Filtering for Connectors** Exchange'in orijinal göndericiyi doğru şekilde atamasına yardımcı olur, ancak tek başına doğrudan tenant teslimini engelleyen sınır değildir. +- Microsoft, Exchange Online önünde external MX kullanırken iki pratik control belgelendirir: +- Yalnızca onaylı gateway'in tenant'a teslim edebilmesi için `SenderDomains *` ve `RestrictDomainsToCertificate` veya `RestrictDomainsToIPAddresses` ile bir **Partner inbound connector** oluşturun. +- Gelen mail'i, gönderici IP onaylı gateway aralıklarına ait değilse **veya** `X-MS-Exchange-Organization-AuthAs` içinde `Internal` yoksa quarantine eden bir **priority 0 transport rule** oluşturun. +- **Received** satırında ilk Microsoft hop olarak `*.mail.protection.outlook.com` görünen ancak sender-authentication başlıklarında yine de **SPF/DKIM/DMARC failures** gösteren mail'leri avlayın. +- Hedef hâlâ **Direct Send**'e izin veriyorsa, bunu devre dışı bırakmak esasen **internal** sender spoofing'i azaltır; rastgele **external** spoofing için connector / transport-rule mitigation yerine geçmez. + +## Filesystem Credentials + +**`az cli`**, **`/.Azure`** içinde çok sayıda ilginç bilgi saklar: +- **`azureProfile.json`** geçmişte giriş yapılmış kullanıcılar hakkında bilgi içerir +- **`clouds.config`** subscriptions hakkında bilgi içerir +- **`service_principal_entries.json`** uygulama **credentials**'larını içerir (tenant id, clients ve secret) +- **`msal_token_cache.json`** **access tokens** ve refresh tokens içerir + +macOS ve linux'ta bu dosyaların **unprotected** durumda, clear text olarak saklandığını unutmayın. + + + +## References - [https://aadinternals.com/post/just-looking/](https://aadinternals.com/post/just-looking/) - [https://www.securesystems.de/blog/a-fresh-look-at-user-enumeration-in-microsoft-teams/](https://www.securesystems.de/blog/a-fresh-look-at-user-enumeration-in-microsoft-teams/) - [https://www.netspi.com/blog/technical-blog/cloud-penetration-testing/enumerating-azure-services/](https://www.netspi.com/blog/technical-blog/cloud-penetration-testing/enumerating-azure-services/) +- [https://labs.infoguard.ch/posts/ghost-sender/](https://labs.infoguard.ch/posts/ghost-sender/) +- [https://learn.microsoft.com/en-us/exchange/mail-flow-best-practices/manage-mail-flow-using-third-party-cloud](https://learn.microsoft.com/en-us/exchange/mail-flow-best-practices/manage-mail-flow-using-third-party-cloud) +- [https://learn.microsoft.com/en-us/defender-office-365/anti-phishing-policies-about](https://learn.microsoft.com/en-us/defender-office-365/anti-phishing-policies-about) +- [https://techcommunity.microsoft.com/blog/exchange/direct-send-vs-sending-directly-to-an-exchange-online-tenant/4439865](https://techcommunity.microsoft.com/blog/exchange/direct-send-vs-sending-directly-to-an-exchange-online-tenant/4439865) {{#include ../../../banners/hacktricks-training.md}}