点入题目看见四个可购买的东西,但是都购买不了,最后一个价格大的脱俗,猜测成功买到后会得到flag,但是购买时提示操作失败只允许一个字符。查看源码发现在utf-8后面特意标注提示
涉及到了字符编码和字符集的概念:
UTF-8 是一种字符编码方案,它可以将 Unicode 中的字符以字节序列的形式进行存储和传输。在 UTF-8 编码中,一个字符可以由 1~4 个字节组成,其中 ASCII 码对应的字符只需要一个字节即可表示,而其他字符可能需要更多的字节来表示。因此,在传输过程中,如果遇到一个无法解析为 ASCII 码的 UTF-8 字符,那么会使用多个字节来表示该字符。
Unicode 则是一种字符集,它定义了字符的编码值和对应的字符形式。在 Unicode 中,每个字符都有一个唯一的编码值,通常用 U+XXXX 的形式表示,其中 XXXX 是一个 16 进制数。
在这个情况下,传入的 UTF-8 编码的字符无法解析为 ASCII 码,后端系统会将其解析为 Unicode 编码,这个 Unicode 编码的值为 50000。由于 Unicode 是一种字符集,它可以表示世界上几乎所有的书写系统中的字符,因此 Unicode 编码中的 50000 可以被解释为一个字符,并且该字符并不受到 ASCII 编码字符的限制。因此,可以通过构造特定的 UTF-8 编码字符串,绕过字符限制,成功购买并获得 flag。
通过这个网站寻找大于1337的字符https://www.compart.com/en/unicode/
里面查找thousand,出现一堆代表千相关的数字的字符,找到一个大于1337的,点进去复制utf-8那行,把0x改成%,删掉空格。
Payload:
id=4&price=%E2%86%81
传入UTF-8编码,在后端处理的过程中,发现该UTF-8编码无法解析为ASCII码,然后会将其解析为Unicode编码,而Unicode中的这个字符表示的值为罗马数字5000,且为一个字符,于是就绕过了一个字符的限制,数字大小也大于1337,于是成功购买,得到flag。
相关链接:
https://blog.lyle.ac.cn/2018/10/29/unicode-normalization/
https://blog.csdn.net/rfrder/article/details/109755403