Skip to content

Commit d815615

Browse files
committed
deploy: 2ca2b56
1 parent ed1cac9 commit d815615

File tree

131 files changed

+9170
-175
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+9170
-175
lines changed

2023/08/28/Playing Dominos with Moodle's Security 2/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ <h1 id="OAuth-Authentication-Flows"><a href="#OAuth-Authentication-Flows" class=
249249

250250
<h1 id="Exploitation"><a href="#Exploitation" class="headerlink" title="Exploitation"></a>Exploitation</h1><p>Here are the specific number of steps an attacker would need to do to craft an account takeover attack:</p>
251251
<ol>
252-
<li><p>The attacker has an account with a controlled email same as the OAuth provider (for example, if Moodle has Google’s OAuth then the email should be a Gmail address). In this demonstration, let’s say an attacker is logged in with <a href="mailto:&#x61;&#x74;&#x74;&#97;&#x63;&#x6b;&#x65;&#x72;&#x40;&#x67;&#109;&#x61;&#x69;&#108;&#x2e;&#99;&#111;&#x6d;">&#x61;&#x74;&#x74;&#97;&#x63;&#x6b;&#x65;&#x72;&#x40;&#x67;&#109;&#x61;&#x69;&#108;&#x2e;&#99;&#111;&#x6d;</a>. </p>
252+
<li><p>The attacker has an account with a controlled email same as the OAuth provider (for example, if Moodle has Google’s OAuth then the email should be a Gmail address). In this demonstration, let’s say an attacker is logged in with <a href="mailto:&#97;&#116;&#116;&#x61;&#99;&#107;&#101;&#114;&#x40;&#x67;&#109;&#x61;&#x69;&#108;&#46;&#99;&#x6f;&#x6d;">&#97;&#116;&#116;&#x61;&#99;&#107;&#101;&#114;&#x40;&#x67;&#109;&#x61;&#x69;&#108;&#46;&#99;&#x6f;&#x6d;</a>. </p>
253253
</li>
254254
<li><p>The attacker’s account shouldn’t be linked to OAuth (can be unlinked in the user options in case it’s already linked).</p>
255255
</li>
@@ -259,7 +259,7 @@ <h1 id="Exploitation"><a href="#Exploitation" class="headerlink" title="Exploita
259259
</li>
260260
<li><p>Attacker logs out.</p>
261261
</li>
262-
<li><p>The attacker logs in with <strong>OAuth</strong> (using <a href="mailto:&#97;&#116;&#116;&#97;&#x63;&#107;&#x65;&#114;&#64;&#x67;&#109;&#x61;&#x69;&#108;&#x2e;&#x63;&#x6f;&#x6d;">&#97;&#116;&#116;&#97;&#x63;&#107;&#x65;&#114;&#64;&#x67;&#109;&#x61;&#x69;&#108;&#x2e;&#x63;&#x6f;&#x6d;</a>). Moodle will see that there is already an account with the same email address and will generate a confirmation URL that links the Moodle account to the OAuth. That URL will be sent by email. </p>
262+
<li><p>The attacker logs in with <strong>OAuth</strong> (using <a href="mailto:&#97;&#116;&#x74;&#x61;&#x63;&#107;&#101;&#114;&#x40;&#103;&#109;&#x61;&#105;&#x6c;&#x2e;&#99;&#x6f;&#x6d;">&#97;&#116;&#x74;&#x61;&#x63;&#107;&#101;&#114;&#x40;&#103;&#109;&#x61;&#105;&#x6c;&#x2e;&#99;&#x6f;&#x6d;</a>). Moodle will see that there is already an account with the same email address and will generate a confirmation URL that links the Moodle account to the OAuth. That URL will be sent by email. </p>
263263
</li>
264264
<li><p>Attacker adds the <code>redirect</code> parameter to the URL that will point to the self-XSS containing page: <code>http://moodle-domain/auth/oauth2/confirm-linkedlogin.php?token=...&amp;userid=11&amp;username=...&amp;issuerid=...&amp;redirect=http://moodle-domain/user/edit.php?id=11%231</code></p>
265265
</li>

2025/01/11/MacOS Binary Debugging/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@
197197

198198
<span class="attr">Tags:/
199199

200+
<a class="tag" href="/tags/#macos" title="macos">macos</a>
201+
<span>/</span>
202+
200203
<a class="tag" href="/tags/#lldb" title="lldb">lldb</a>
201204
<span>/</span>
202205

@@ -206,9 +209,6 @@
206209
<a class="tag" href="/tags/#debugging" title="debugging">debugging</a>
207210
<span>/</span>
208211

209-
<a class="tag" href="/tags/#macos" title="macos">macos</a>
210-
<span>/</span>
211-
212212
</span>
213213

214214

Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
<!DOCTYPE html>
2+
<html lang=en>
3+
<head>
4+
5+
<meta charset="utf-8">
6+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
7+
<meta name="viewport" content="width=device-width, initial-scale=1">
8+
<meta property="og:type" content="website">
9+
<meta name="author" content="Yaniv Nizry">
10+
<meta name="description" content="Security research blog">
11+
<meta name="keyword" content="security,research,vulnerability,blog,vulnerabilites">
12+
<link rel="shortcut icon" href="/img/favicon.ico">
13+
<title>
14+
15+
Apache httpd XSS Using Multiple Extensions - YNizry
16+
17+
</title>
18+
19+
<!-- Custom CSS -->
20+
21+
<link rel="stylesheet" href="/css/aircloud.css">
22+
23+
24+
<link rel="stylesheet" href="/css/gitment.css">
25+
26+
<!--<link rel="stylesheet" href="https://imsun.github.io/gitment/style/default.css">-->
27+
<link href="//at.alicdn.com/t/font_620856_28hi1hpxx24.css" rel="stylesheet" type="text/css">
28+
29+
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
30+
<style>
31+
.googleicon {
32+
vertical-align: middle;
33+
font-size: 20px;
34+
font-style: normal;
35+
-webkit-font-smoothing: antialiased;
36+
-moz-osx-font-smoothing: grayscale;
37+
color: #999999;
38+
}
39+
</style>
40+
41+
<!-- ga & ba script hoook -->
42+
<script></script>
43+
44+
45+
46+
47+
<script async src="https://www.googletagmanager.com/gtag/js?id=G-SCK9223GY8"></script>
48+
<script>
49+
window.dataLayer = window.dataLayer || []
50+
function gtag() {
51+
dataLayer.push(arguments)
52+
}
53+
gtag('js', new Date())
54+
gtag('config', 'G-SCK9223GY8')
55+
</script>
56+
57+
58+
59+
60+
61+
62+
63+
64+
65+
66+
67+
<meta name="generator" content="Hexo 6.3.0"><link rel="alternate" href="/atom.xml" title="Yaniv Nizry Blogs" type="application/atom+xml">
68+
</head>
69+
70+
<body>
71+
72+
<div class="site-nav-toggle" id="site-nav-toggle">
73+
<button>
74+
<span class="btn-bar"></span>
75+
<span class="btn-bar"></span>
76+
<span class="btn-bar"></span>
77+
</button>
78+
</div>
79+
80+
<div class="index-about">
81+
<i> </i>
82+
</div>
83+
84+
<div class="index-container">
85+
86+
<div class="index-left">
87+
88+
<div class="nav" id="nav">
89+
<div class="avatar-name">
90+
<div class="avatar radius">
91+
<img src="/img/avatar.webp" />
92+
</div>
93+
<div class="name">
94+
<i>Yaniv Nizry</i>
95+
</div>
96+
</div>
97+
<div class="contents" id="nav-content">
98+
<ul>
99+
<li >
100+
<a href="/">
101+
<i class="material-icons googleicon">home</i>
102+
<span>Blogs</span>
103+
</a>
104+
</li>
105+
<li >
106+
<a href="/talks">
107+
<i class="material-icons googleicon">co_present</i>
108+
<span>Talks</span>
109+
</a>
110+
</li>
111+
<li >
112+
<a href="/advisories">
113+
<i class="material-icons googleicon">speaker_notes</i>
114+
<span>Advisories</span>
115+
</a>
116+
</li>
117+
<li >
118+
<a href="/tags">
119+
<i class="material-icons googleicon">label</i>
120+
<span>Tags</span>
121+
</a>
122+
</li>
123+
<li >
124+
<a href="/archive">
125+
<i class="material-icons googleicon">archive</i>
126+
<span>Archives</span>
127+
</a>
128+
</li>
129+
<li >
130+
<a href="/about/">
131+
<i class="material-icons googleicon">person</i>
132+
<span>About</span>
133+
</a>
134+
</li>
135+
136+
<li>
137+
<a id="search">
138+
<i class="material-icons googleicon">search</i>
139+
<span>Search</span>
140+
</a>
141+
</li>
142+
143+
</ul>
144+
</div>
145+
146+
<div id="toc" class="toc-article">
147+
<ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#Introduction"><span class="toc-text">Introduction</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Details"><span class="toc-text">Details</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#The-Attack-Scenario"><span class="toc-text">The Attack Scenario</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#References"><span class="toc-text">References</span></a></li></ol>
148+
</div>
149+
150+
</div>
151+
152+
153+
<div class="search-field" id="search-field">
154+
<div class="search-bg" id="search-bg"></div>
155+
<div class="search-container">
156+
<div class="search-input">
157+
<span id="esc-search"> <i class="icon-fanhui iconfont"></i></span>
158+
<input id="search-input"/>
159+
<span id="begin-search">search</span>
160+
</div>
161+
<div class="search-result-container" id="search-result-container">
162+
163+
</div>
164+
</div>
165+
</div>
166+
167+
<div class="index-about-mobile">
168+
<i> </i>
169+
</div>
170+
</div>
171+
172+
<div class="index-middle">
173+
<!-- Main Content -->
174+
<div class="post-container">
175+
<div class="post-title">
176+
Apache httpd XSS Using Multiple Extensions
177+
</div>
178+
179+
<div class="post-meta">
180+
<span class="attr">Post:<span>2025-07-07 22:00:00</span></span>
181+
182+
183+
<span class="attr">Tags:/
184+
185+
<a class="tag" href="/tags/#apache" title="apache">apache</a>
186+
<span>/</span>
187+
188+
<a class="tag" href="/tags/#content-type" title="content-type">content-type</a>
189+
<span>/</span>
190+
191+
<a class="tag" href="/tags/#xss" title="xss">xss</a>
192+
<span>/</span>
193+
194+
</span>
195+
196+
197+
198+
199+
200+
201+
202+
<!--<span class="attr">Visit:<span id="busuanzi_value_page_pv"></span>-->
203+
</span>
204+
</span>
205+
</div>
206+
207+
<div class="post-source-meta post-meta">
208+
209+
</div>
210+
<div class="post-content no-indent">
211+
<h1 id="Introduction"><a href="#Introduction" class="headerlink" title="Introduction"></a>Introduction</h1><p>This post dives into a stored Cross-Site Scripting (XSS) technique I discovered while researching Fortinet’s endpoint protection solution. It builds on previous work, specifically <a href="https://yaniv-git.github.io/2025/06/29/Caught%20in%20the%20FortiNet:%20How%20Attackers%20Can%20Exploit%20FortiClient%20to%20Compromise%20Organizations%202/#From-Limited-File-Write-to-XSS-CVE-2025-22859">part two</a> of my series (CVE-2025-22859), where I detailed an <code>httpd</code> stored XSS vulnerability using a files with a predefined extensions.</p>
212+
<p>I have already <a href="https://yaniv-git.github.io/2023/11/04/Apache%20httpd%20XSS%20by%20design/">covered</a> a small technique of achieving XSS on <code>httpd</code> when the attacker can’t control the file extension. However, unlike that prior method, which involved creating files with no name or only dots to bypass extension assignage, this new trick doesn’t depend on the absense of the <code>X-Content-Type-Options: nosniff</code> header. Complicating the other writeup, making these nice to add to our toolbox.</p>
213+
<h1 id="Details"><a href="#Details" class="headerlink" title="Details"></a>Details</h1><p>The core of this technique lies in how <a target="_blank" rel="noopener" href="https://httpd.apache.org/">Apache httpd’s</a> <a target="_blank" rel="noopener" href="https://httpd.apache.org/docs/2.4/mod/mod_mime.html">mod_mime</a> module determines a file’s <code>Content-Type</code>. Typically, <code>mod_mime</code> guesses the content type based on the file’s extension. If the <code>X-Content-Type-Options: nosniff</code> header is present, browsers are instructed not to “sniff” the content type and will default to <code>text/plain</code> when an <code>Content-Type</code> isn’t set. However, a closer look at the <code>mod_mime</code> documentation reveals an interesting behavior: </p>
214+
<img src="/img/blogs/fortinet/2/mod_mime_doc.png" style="width: 100%;"/>
215+
216+
<p>Files can have <a target="_blank" rel="noopener" href="https://httpd.apache.org/docs/2.4/mod/mod_mime.html#multipleext" title="multiple extensions">multiple extensions</a>, with a priority given to the last one. For example, these file extensions will correspond to the following content-types:</p>
217+
<table>
218+
<thead>
219+
<tr>
220+
<th>File Extension</th>
221+
<th>mod_mime Content-Type</th>
222+
</tr>
223+
</thead>
224+
<tbody><tr>
225+
<td>Filename.<strong>html</strong></td>
226+
<td>text&#x2F;html</td>
227+
</tr>
228+
<tr>
229+
<td>Filename.<strong>gif</strong></td>
230+
<td>image&#x2F;gif</td>
231+
</tr>
232+
<tr>
233+
<td>Filename.gif.<strong>html</strong></td>
234+
<td>text&#x2F;html</td>
235+
</tr>
236+
<tr>
237+
<td>Filename.<strong>unknown</strong></td>
238+
<td></td>
239+
</tr>
240+
<tr>
241+
<td>Filename.unknown.<strong>html</strong></td>
242+
<td>text&#x2F;html</td>
243+
</tr>
244+
<tr>
245+
<td>Filename.<strong>html</strong>.unknown</td>
246+
<td>text&#x2F;html</td>
247+
</tr>
248+
</tbody></table>
249+
<h1 id="The-Attack-Scenario"><a href="#The-Attack-Scenario" class="headerlink" title="The Attack Scenario"></a>The Attack Scenario</h1><p>Armed with this knowledge, in a scenario where an attacker has the ability to upload a file, but can’t control the extension. If the extension doesn’t correlate to any content type in <code>mod_mime</code> (for example <code>.abc</code>), all the attacker would need to do is to add <code>.html</code> to the filename (<code>filename.html.abc</code>). When Apache serves this file, <code>mod_mime</code> will process the multiple extensions, recognize <code>.html</code> as the last and most significant one since <code>.abc</code> doesnt cererlate ot anything, and serve the file with <code>Content-Type: text/html</code>, resulting in stored XSS. This technique might also be used to bypass some server-side validation that only permits specific file types.</p>
250+
<h1 id="References"><a href="#References" class="headerlink" title="References"></a>References</h1><ul>
251+
<li><a href="https://yaniv-git.github.io/2025/06/29/Caught%20in%20the%20FortiNet:%20How%20Attackers%20Can%20Exploit%20FortiClient%20to%20Compromise%20Organizations%202/#From-Limited-File-Write-to-XSS-CVE-2025-22859">CVE-2025-22859 blog</a></li>
252+
<li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options">X-Content-Type-Options</a></li>
253+
<li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type">Content-Type</a></li>
254+
<li><a target="_blank" rel="noopener" href="https://httpd.apache.org/docs/2.4/mod/mod_mime.html">mod_mime</a></li>
255+
<li><a target="_blank" rel="noopener" href="https://x.com/YNizry/status/1940053407127007587">Tweet</a></li>
256+
</ul>
257+
258+
259+
<br />
260+
<div id="comment-container">
261+
</div>
262+
<div id="disqus_thread"></div>
263+
<div id="lv-container"></div>
264+
<div class="giscus"></div>
265+
</div>
266+
</div>
267+
268+
</div>
269+
</div>
270+
271+
272+
<footer class="footer">
273+
<ul class="list-inline text-center">
274+
275+
<li>
276+
<a target="_blank" href="https://twitter.com/YNizry">
277+
<span class="fa-stack fa-lg">
278+
<i class="iconfont icon-twitter"></i>
279+
</span>
280+
</a>
281+
</li>
282+
283+
284+
285+
286+
287+
288+
289+
290+
<li>
291+
<a target="_blank" href="https://github.com/yaniv-git">
292+
<span class="fa-stack fa-lg">
293+
<i class="iconfont icon-github"></i>
294+
</span>
295+
</a>
296+
</li>
297+
298+
299+
300+
<li>
301+
<a target="_blank" href="https://www.linkedin.com/in/yaniv-n-8b4a76193">
302+
<span class="fa-stack fa-lg">
303+
<i class="iconfont icon-linkedin"></i>
304+
</span>
305+
</a>
306+
</li>
307+
308+
309+
</ul>
310+
311+
<p>
312+
Theme <a target="_blank" rel="noopener" href="https://github.com/aircloud/hexo-theme-aircloud">AirCloud</a></p>
313+
</footer>
314+
315+
316+
317+
318+
</body>
319+
320+
<script>
321+
// We expose some of the variables needed by the front end
322+
window.hexo_search_path = "search.json"
323+
window.hexo_root = "/"
324+
window.isPost = true
325+
</script>
326+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
327+
328+
<script src="/js/index.js"></script>
329+
330+
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
331+
332+
333+
334+
335+
336+
337+
</html>

0 commit comments

Comments
 (0)