ANSI转义序列

之前博主玩了玩wmctf2021的MISC题, 其中的logo题给人一个眼前一亮的感觉, 也是第一次接触ANSI转义序列, 这篇文章就来总结一下

定义

ANSI转义序列(ANSI escape sequences)是一种带内信号转义序列标准,用于控制视频文本终端上的光标位置、颜色和其他选项。在文本中嵌入确定的字节序列,大部分以ESC转义字符和""字符开始,终端会把这些字节序列解释为相应的指令,而不是普通的[字符编码

ANSI序列是在二十世纪七十年代引入的标准,用以取代特定于终端供应商的序列,并在二十世纪八十年代早期开始在计算机设备市场上广泛使用。与早期缺少光标移动功能的系统相比,新生的电子公告板系统使用ANSI序列改进其显示。正是因为这个原因,ANSI序列变成了所有制造商共同采用的标准。

在21世纪,尽管硬件文本终端已经越来越少了,但ANSI标准依然存在,因为大多数终端模拟器会对部分ANSI转义序列进行解释。一个值得注意的例外是,在微软Windows 10更新TH2之前,Windows操作系统Win32控制台是不支持ANSI转义序列的。( 引自wiki)

简而言之, ANSI转义是一种能把特定字符串转义成系统指令的转义序列, 它不像ASCII之类的只是转义不可见和可见字符, 他更多的是进行系统指令的转义,

案例

在bash中我们常常会遇到这么一种情况: 如果我们的bash界面因为打开了某些诸如socat之类的程序而被暂时"阻塞"的时候, 若这时我们按下了方向键, 如上下左右, 则会依次打印出

image-20210902233819084

^[[A^[[B^[[D^[[C 就是使用ANSI转义的方向键, 其中^[是一个字符: 0x1b, 也就是[ESC], 所有序列都以ASCII字符[ESC](27 / 0x1B)开头,第二个字节则是0x40–0x5F(ASCII @A–Z[\]^_)范围内的字符。

一些ANSI转义序列(不完整列表)

序列C1名称作用
ESC N0x8eSS2 – Single Shift Two从其中一个替代字符集中选择一个字符。在xterm中,SS2选择G2字符集,SS3选择G3字符集。
ESC O0x8fSS3 – Single Shift Three从其中一个替代字符集中选择一个字符。在xterm中,SS2选择G2字符集,SS3选择G3字符集。
ESC P0x90DCS – 设备控制字符串(Device Control String)控制设备。在xterm中,这个序列的使用包括定义用户自定义的密钥,以及请求或设置Termcap/Terminfo数据。
ESC [0x9bCSI - 控制序列导入器(Control Sequence Introducer)大部分有用的序列。结束于ASCII 64到126 (@~/十六进制0x40到0x7E).
ESC\0x9cST – 字符串终止(String Terminator)终止其他控件(包括APC,DCS,OSC,PM和SOS)中的字符串。
ESC ]0x9dOSC – 操作系统命令(Operating System Command)启动操作系统使用的控制字符串。OSC序列与CSI序列相似,但不限于整数参数。通常,这些控制序列由ST终止。在xterm中,它们也可能被BEL终止。例如,在xterm中,窗口标题可以这样设置:OSC 0;this is the window title BEL
ESC X0x98SOS – 字符串开始(Start of String)引用由ST终止的一串文本的参数。这些字符串控制序列的用途由应用程序或私有规则来定义。这些函数没有实现,参数被xterm忽略。
ESC ^0x9ePM – 私有消息(Privacy Message)将设备重置为原始状态。可能包括(如果适用的话):重置图形格式,清除制表符,重置为默认字体等等。
ESC _0x9fAPC – 应用程序命令(Application Program Command)将设备重置为原始状态。可能包括(如果适用的话):重置图形格式,清除制表符,重置为默认字体等等。
ESC c RIS – 重置为初始状态(Reset to Initial State)将设备重置为原始状态。可能包括(如果适用的话):重置图形格式,清除制表符,重置为默认字体等等。

由上表我们可以看到, 方向键是[ESC][开头的, 也就是CSI序列, 这里描述方向键, 一方面是因为wmctf的pvz题目中, 为了完成自动化刷分脚本, 需要向服务器发送方向键, 所以当时就研究了一下, 当然, pvz的方向键并不是[ESC][, 因为pvz程序是ncurses生成的界面, 不同于curses, 他的转义序列发生了改变. 另一方面, 主要还是引出颜色部分

24位颜色的ANSI

该题中, 多数wp均使用了nc xxxxxxxx > 1.txt重定向得到了类似[ESC][48;2;16;19;18m (注意有空格)的字符串, 首先[ESC][部分就是代表是CSI序列, 即 控制序列导入器(Control Sequence Introducer), 这里的48;2; 其实是固定格式:

ESC[ … 38;2;<r>;<g>;<b> … m选择RGB前景色
ESC[ … 48;2;<r>;<g>;<b> … m选择RGB背景色

即这里是使用了RGB背景色, 又由于后面的[空格] 故导致了后面一位体现出了纯色像素块的特征, 而在题目中, 我们可以看到, 对于每行而言, 总会重复一次像素块, 这是因为在bash中, 空格的面积大概是 █ 这么大, 故重复后 ██ 更像方形( 虽然这里看起来不像), 看着好看(这句纯猜测

然后为了好玩, 写了一个从图片生成bash图片的python脚本

from PIL import Image
import sys
import subprocess

img = Image.open(sys.argv[1]).convert('RGB')
contents = '\x1b[48;2;{};{};{}m  '
w, h = img.size
for y in range(h):
    res = ''
    for x in range(w):
        r, g, b = img.getpixel((x, y))
        res += contents.format(r, g, b)
    subprocess.run(f'printf "{res}\n"', shell=True)

这里值得注意的是, linux中似乎只有printf才能进行ANSI转义, 而echo不行

效果图如下

img

最后修改:2021 年 09 月 03 日 12 : 32 AM
如果觉得我的文章对你有用,请随意赞赏