所见非所得 之 花一个小时学一下编码要死啊

之前想必大家都知道unicode和utf-8,这两个常常出现在我们的题目当中和我们学习的资料中,可是否清楚他们的关系到底是什么,本文就从unicode说起,并看看在hctf的admin一题的应用,如有问题欢迎讨论

简介

wiki:Unicode(中文:万国码、国际码、统一码、单一码)是计算机科学领域里的一项业界标准。它对世界上大部分的文字系统进行了整理、编码,使得计算机可以用更为简单的方式来呈现和处理文字.unicode 编码包含了不同写法的字,如“ɑ/a”、“強/强”、“戶/户/戸”。然而在汉字方面引起了一字多形的认定争议(详见中日韩统一表意文字主题)。

在文字处理方面,统一码为每一个字符而非字形定义唯一的代码(即一个整数)。换句话说,统一码以一种抽象的方式(即数字)来处理字符,并将视觉上的演绎工作(例如字体大小、外观形状、字体形态、文体等)留给其他软件来处理,例如网页浏览器或是文字处理器。

在表示一个 Unicode 的字符时,通常会用“U+”然后紧接着一组十六进制的数字来表示这一个字符。在基本多文种平面(英语:Basic Multilingual Plane,简写 BMP。又称为“零号平面”、plane 0)里的所有字符,要用四个数字(即两个byte,共16 bits,例如 U+4AE0,共支持六万多个字符);在零号平面以外的字符则需要使用五个或六个数字。旧版的 Unicode 标准使用相近的标记方法,但却有些微小差异:在 Unicode 3.0 里使用“U-”然后紧接着八个数字,而“U+”则必须随后紧接着四个数字。

在表示一个 Unicode 的字符时,通常会用“U+”然后紧接着一组十六进制的数字来表示这一个字符。在基本多文种平面(英语:Basic Multilingual Plane,简写 BMP。又称为“零号平面”、plane 0)里的所有字符,要用四个数字(即两个byte,共16 bits,例如 U+4AE0,共支持六万多个字符);在零号平面以外的字符则需要使用五个或六个数字。

Baidu:它为每种语言中的每个字符设定了统一并且唯一的二进制编码.

其中在百度百科里面提到,每一种语言的每一个字符都有一个唯一的二进制编码.这句话就是每一个字符即使可能看起来相似,但是计算机认为他们仍然是两个完全没有关系的字符.然后wiki后面一段的意思则说,它本来是啥样,我已经弄出来了,就看你计算机怎么看它.你是一个字节一个字节地看就是ascii编码方式,如果你要两个字节两个字节看就是utf-16编码方式,其中utf-8是字节可变的编码方式

Unicode 的编码和实现

大概来说,Unicode 编码系统可分为编码方式和实现方式两个层次。

编码方式

在基本多文种平面的字符的编码为 U+hhhh,其中每个 h 代表一个十六进制数字.一共可以包含六万多个字符,更多的字符在其他平面上,Unicode 到目前为止共十七个平面,在所定义的十七个平面中,第0平面(BMP)最为重要,包含

  • 0000-007F:C0控制符及基本拉丁文 (C0 Control and Basic Latin)
  • 0080-00FF:C1控制符及拉丁文补充-1 (C1 Control and Latin 1 Supplement)
  • ...
    注:中文范围 4E00-9FA5:CJK 统一表意符号 (CJK Unified Ideographs)

更多分布,在百度百科可以看到
https://baike.baidu.com/item/Unicode/750500?fr=aladdin#4

实现方式

Unicode 的实现方式不同于编码方式。一个字符的 Unicode 编码是确定的。但是在实际传输过程中,由于不同系统平台的设计不一定一致,以及出于节省空间的目的,对 Unicode 编码的实现方式有所不同。Unicode 的实现方式称为 Unicode转换格式(Unicode Transformation Format,简称为 UTF).

例如,如果一个仅包含基本 7 位 ASCII 字符的 Unicode 文件,如果每个字符都使用 2 字节的原 Unicode 编码传输,其第一字节的 8 位始终为 0。这就造成了比较大的浪费。对于这种情况,可以使用 UTF-8 编码,这是一种变长编码,它将基本 7 位 ASCII 字符仍用 7 位编码表示,占用一个字节(首位补 0)。而遇到与其他 Unicode 字符混合的情况,将按一定算法转换,每个字符使用 1-3 个字节编码,并利用首位为 0 或 1 进行识别。这样对以7位ASCII字符为主的西文文档就大幅节省了编码长度(具体方案参见 UTF-8)。类似的,对未来会出现的需要 4 个字节的辅助平面字符和其他 UCS-4 扩充字符,2 字节编码的 UTF-16 也需要通过一定的算法进行转换.

admin

所以理解了unicode后,再看看,在admin中怎么应用.因为在题目中有一个修改密码的功能,而且用户名没有加任何限制(支持unicode),除了不能与已注册用户同名,并且在源码中可以看到进行了用户名标准化(具体在buuctf-writeup看的到),所以我们可以注册一个以&#1040开头的西里尔文大写字母 A

QQ截图20190814090715.png

后面加上dmin,然后注册后修改密码,再以admin(拉丁文)登录就能得到flag了.

QQ截图20190814090856.png

这是出题人的考点:
QQ截图20190814091031.png

漏洞的原理比较有意思,主要的条件是用户的id支持unicode。比如两个ID:mike@example.org vs mıke@example.org
然而在一些业务逻辑中会对用户id做标准化的操作,比如重置密码的时候,mıke@example.org标准化之后变成了mike@example.org,从而重置了mike@example.org的密码。

所以关键的条件就是用户识别的ID(包括可以用来登录的邮箱)支持unicode。而在某些业务逻辑中有对unicode字符进行所谓标准化,转换成了对应的ascii。其实假如某些业务逻辑不支持unicode,直接丢掉了那部分unicode,应该也是一样的,目前没有看到类似的案例。导致在这部分业务逻辑中出现了越权的问题。典型的场景就是修改密码,导致可以修改他人的密码.

本文链接:

http://chrisyy.top:2000/index.php/archives/7/
1 + 1 =
快来做第一个评论的人吧~