Files on the server (except .aspx, .cs, .config) are case-insensitive. But the server is Linux based. What's happening? The answer is ext4 casefold feature.
settings:
mkfs.ext4 -O casefold /srv/www.img
mount /var/www
chattr +F /var/www/html
ext4 casefold uses Unicode casefold mechanism to compare filenames. https://www.unicode.org/Public/12.1.0/ucd/CaseFolding.txt
This mechanism contains some Unicode-character-to-ASCII-character(s) mappings. For example, s=ſ(U+017F), fi=fi(U+FB01), etc
0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE # depends on language
017F; C; 0073; # LATIN SMALL LETTER LONG S
1E9E; S; 00DF; # LATIN CAPITAL LETTER SHARP S
212A; C; 006B; # KELVIN SIGN
FB00; F; 0066 0066; # LATIN SMALL LIGATURE FF
FB01; F; 0066 0069; # LATIN SMALL LIGATURE FI
FB02; F; 0066 006C; # LATIN SMALL LIGATURE FL
FB03; F; 0066 0066 0069; # LATIN SMALL LIGATURE FFI
FB04; F; 0066 0066 006C; # LATIN SMALL LIGATURE FFL
FB05; F; 0073 0074; # LATIN SMALL LIGATURE LONG S T
On the other hand, on Apache2, AddType
directive is also case-insensitive but it provides only ASCII level equivalence.
So now if you access to upload.a\u017Fpx
, BasePage.c\u017F
, or Web.con\uFB01g
,
mod_mono handler is not executed and you can see the source code.
ext4 casefold feature uses not only Unicode casefold but also Unicode normalization (NFD).
For example, caf\u00E9
and cafe\u0301
are equivalent.
https://www.unicode.org/Public/12.1.0/ucd/NormalizationTest.txt
This normalization contains some remarkable Unicode-to-ASCII mappings: semicolon, backquote, less than, and greater than.
037E;003B;003B;003B;003B; # (;; ;; ;; ;; ;; ) GREEK QUESTION MARK
1FEF;0060;0060;0060;0060; # (`; `; `; `; `; ) GREEK VARIA
226E;226E;003C 0338;226E;003C 0338; # (≮; ≮; <◌̸; ≮; <◌̸; ) NOT LESS-THAN
226F;226F;003E 0338;226F;003E 0338; # (≯; ≯; >◌̸; ≯; >◌̸; ) NOT GREATER-THAN
If you upload a file \u1FEFsh\u226Ea\u226Fb\u1FEF
, the file is also accessed as `sh<\u0338a>\u0338b`
.
So by modifying uploadedFilename
(and uploadedFilenameTag
), you can compress `sh<\u0338a>\u0338b`
and
file-compressor will embed the filename to shell command:
zip "`sh<\u0338a>\u0338b`.zip" "`sh<\u0338a>\u0338b`"
By uploading a shell script as \u0338a
previously, you can get the result as \u0338b
. That's all.
not
\u226E
, but\u0338
btw it was great challenge, thank you!