Skip to content

Instantly share code, notes, and snippets.

@ytoku
Last active September 30, 2020 20:42
Show Gist options
  • Save ytoku/ffd67666953d707040b391e17218dccb to your computer and use it in GitHub Desktop.
Save ytoku/ffd67666953d707040b391e17218dccb to your computer and use it in GitHub Desktop.

TWCTF 6th 2020 "Does Linux Dream of Windows?" intended solution: Nightmare

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

Flag 1

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.

Flag 2

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.

@jskimm
Copy link

jskimm commented Sep 30, 2020

not \u226E, but \u0338

zip "`sh<\u0338a>\u0338b`.zip" "`sh<\u0338a>\u0338b`"

1

btw it was great challenge, thank you!

@ytoku
Copy link
Author

ytoku commented Sep 30, 2020

oops, thanks!
I fixed it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment