解题思路 追踪流量到和打印机交互的数据
可以看到一共分了两部分,第一部分是两个bitmap,第二步是BAR bitmap格式定义
https://www.mediaform.de/fileadmin/support/handbuecher/Armilla/Handbuecher/TSC_TSPL_TSPL2_Programming.pdf 由格式可知道第一个bitmap宽26 Byte, 高48 dot,第二个bitmap宽29 Byte, 高32 dot 把wireshark里的hex拉出来手动转换为0x格式,丢到py里生成二进制
#!/usr/bin/env python
a = [
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xc3,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xe7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xe7,0xff,0xe3,0xff,0xfe,0x1f,0xff,0xff,0xff,0xff,0xf8,0x07,
0xc0,0x3c,0x60,0x3f,0xc0,0x7c,0x07,0xe0,0x00,0x7f,0x7f,0xf0,0x1f,0x80,0x67,0xff,
0x00,0x7f,0xf8,0x03,0xfc,0x07,0xc0,0x3f,0xff,0x1f,0xf1,0xf0,0x4f,0x8f,0xf1,0xff,
0x1f,0xff,0x1f,0xff,0x3f,0xfc,0xff,0x1f,0x27,0xfc,0x7f,0x1f,0xf3,0xe1,0xff,0x1f,
0xf9,0xff,0xff,0x1f,0xf1,0xfc,0x1f,0xcf,0xf8,0xff,0x1f,0xff,0x1f,0xff,0x3f,0xfe,
0xfe,0x3f,0x87,0xf8,0xff,0x9f,0xef,0xf8,0xff,0x1f,0xf9,0xff,0xff,0x8f,0xf1,0xfc,
0x3f,0xc7,0xfc,0xff,0x1f,0xff,0x1f,0xff,0x1f,0xfe,0xfc,0x7f,0xc7,0xf9,0xff,0x8f,
0xdf,0xfc,0x7f,0x1f,0xf9,0xff,0xff,0x8f,0xf1,0xfc,0x7f,0xe3,0xfc,0x7f,0x1f,0xff,
0x1f,0xff,0x1f,0xfe,0xfc,0xff,0xe7,0xf1,0xff,0x8f,0x9f,0xfc,0x3f,0x1f,0xf9,0xff,
0xff,0xc7,0xf1,0xfc,0x7f,0xe3,0xfe,0x3f,0x1f,0xff,0x1f,0xff,0x0f,0xfe,0xf8,0xff,
0xe7,0xf1,0xff,0x0f,0xbf,0xfe,0x3f,0x1f,0xf9,0xff,0xff,0xc7,0xf1,0xfc,0x7f,0xe3,
0xfe,0x3f,0x1f,0xff,0x1f,0xff,0x0f,0xfe,0xf8,0xff,0xe7,0xe1,0xff,0x8f,0x3f,0xfe,
0x3f,0x1f,0xf9,0xff,0xff,0xe3,0xf1,0xfc,0x7f,0xe3,0xff,0x1f,0x1f,0xff,0x1f,0xff,
0x47,0xfe,0xf8,0xff,0xe7,0xe3,0xff,0x9f,0x7f,0xfe,0x1f,0x1f,0xf9,0xff,0xff,0xe3,
0xf1,0xfc,0x7f,0xf3,0xff,0x8e,0x1f,0xff,0x1f,0xff,0x47,0xfe,0xf9,0xff,0xe7,0xe3,
0xff,0xff,0xff,0xff,0x1f,0x1f,0xf9,0xff,0xff,0xf1,0xf1,0xfc,0x7f,0xf3,0xff,0x8c,
0x1f,0xff,0x1f,0xff,0x63,0xfe,0xf9,0xff,0xe7,0xf1,0xff,0xff,0xff,0xff,0x1f,0x1f,
0xf9,0xff,0xff,0xf1,0xf1,0xfc,0x7f,0xf3,0xff,0xc1,0x1f,0xff,0x1f,0xff,0x63,0xfe,
0xf9,0xff,0xe7,0xf1,0xff,0xff,0xff,0xff,0x1f,0x1f,0xf9,0xff,0xff,0xf1,0xf1,0xfc,
0x7f,0xe3,0xff,0xe3,0x1f,0xff,0x1f,0xff,0x71,0xfe,0xf9,0xff,0xe7,0xf1,0xff,0xff,
0xff,0xff,0x1f,0x1f,0xf9,0xff,0xff,0xf8,0xf1,0xfc,0x7f,0xe3,0xff,0xe7,0x1f,0xff,
0x1f,0xff,0x71,0xfe,0xf8,0xff,0xe7,0xf8,0xff,0xff,0xff,0xff,0x0f,0x1f,0xf9,0xff,
0xff,0xf8,0xf1,0xfc,0x7f,0xe3,0xff,0xcf,0x1f,0xff,0x1f,0xff,0x78,0xfe,0xf8,0xff,
0xe7,0xfc,0xff,0xff,0xff,0xff,0x0f,0x1f,0xf9,0xff,0xff,0xfc,0x61,0xfc,0x7f,0xe7,
0xff,0x9f,0x1f,0xff,0x1f,0xff,0x78,0xfe,0xf8,0xff,0xc7,0xfe,0x3f,0xff,0xff,0xff,
0x0f,0x1f,0xf9,0xff,0xff,0xfc,0x41,0xfc,0x7f,0xc7,0xff,0x3f,0x1f,0xff,0x1f,0xff,
0x7c,0x7e,0xfc,0xff,0xc7,0xff,0x83,0xff,0xff,0xff,0x0f,0x9f,0xf1,0xff,0xff,0xfe,
0x11,0xfc,0x3f,0x8f,0xff,0x7f,0x1f,0xff,0x1f,0xff,0x7c,0x7e,0xfc,0x7f,0xa7,0xff,
0x87,0xff,0xff,0xff,0x0f,0x9f,0xe9,0xff,0xff,0xfe,0x31,0xfc,0x1f,0x1f,0xfe,0x7f,
0x1f,0xff,0x1f,0xff,0x7e,0x3e,0xfe,0x3e,0x67,0xfe,0x3f,0xff,0xff,0xff,0x1f,0x8f,
0x99,0xff,0xff,0xff,0x31,0xfc,0x40,0x3f,0xe0,0x1f,0x1f,0xff,0x1f,0xff,0x7e,0x3e,
0xff,0x80,0xe0,0xfc,0x7f,0xff,0xff,0xff,0x1f,0xc0,0x39,0xff,0xff,0xfe,0x71,0xfc,
0x79,0xff,0xff,0xff,0x1f,0xff,0x1f,0xff,0x7f,0x1e,0xff,0xf3,0xef,0xf8,0xff,0xff,
0xff,0xff,0x1f,0xf0,0xf9,0xff,0xff,0xfe,0xf1,0xfc,0x7f,0xff,0xff,0xff,0x1f,0xff,
0x1f,0xff,0x7f,0x0e,0xff,0xff,0xff,0xf8,0xff,0xff,0xff,0xff,0x1f,0xff,0xf9,0xff,
0xff,0xfc,0xf1,0xfc,0x7f,0xff,0xff,0xff,0x1f,0xff,0x1f,0xff,0x7f,0x8e,0xff,0xff,
0xff,0xf8,0xff,0xff,0xff,0xfe,0x1f,0xff,0xf9,0xff,0xff,0xf9,0xf1,0xfc,0x7f,0xff,
0xff,0xff,0x1f,0xff,0x1f,0xff,0x7f,0x86,0xff,0xff,0xff,0xf8,0xff,0x9f,0x7f,0xfe,
0x3f,0xff,0xf9,0xff,0xff,0xfb,0xf1,0xfc,0x7f,0xff,0xff,0xff,0x1f,0xff,0x1f,0xff,
0x7f,0xc6,0xff,0xff,0xff,0xf8,0xff,0x0f,0x3f,0xfe,0x3f,0xff,0xf9,0xff,0xff,0xf7,
0xf1,0xfc,0x7f,0xff,0xff,0xff,0x1f,0xff,0x1f,0xff,0x7f,0xc2,0xff,0xff,0xff,0xf8,
0xff,0x8f,0xbf,0xfc,0x7f,0xff,0xf9,0xff,0xff,0xe7,0xf1,0xfc,0x7f,0xff,0xff,0xff,
0x1f,0xff,0x1f,0xff,0x7f,0xe2,0xff,0xff,0xff,0xf8,0xff,0x8f,0x9f,0xfc,0x7f,0xff,
0xf9,0xff,0xff,0xcf,0xf1,0xfc,0x7f,0xff,0xff,0xff,0x1f,0xff,0x1f,0xff,0x7f,0xf0,
0xff,0xff,0xff,0xfc,0xff,0x9f,0x9f,0xf8,0xff,0xff,0xf9,0xff,0xff,0x8f,0xf1,0xfc,
0x7f,0xff,0xff,0xff,0x1f,0xff,0x1f,0xff,0x7f,0xf0,0xff,0xff,0xff,0xfc,0x7f,0x9f,
0x8f,0xf1,0xff,0xff,0xf9,0xff,0xff,0x0f,0xf0,0xfc,0x3f,0xff,0xff,0xff,0x1f,0xff,
0x0f,0xfe,0x7f,0xf8,0xff,0xff,0xff,0xfe,0x1e,0x7f,0x83,0xe3,0xff,0xff,0xf8,0xff,
0xfc,0x03,0xc0,0x3c,0x0f,0xff,0xff,0xff,0x03,0xe0,0x00,0x78,0x0f,0xf8,0x3f,0xff,
0xff,0xff,0x80,0xff,0xf8,0x0f,0xff,0xff,0xf8,0x3f,0xff,0xff,0xff,0xfd,0xff,0xff,
0xff,0xff,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
]
b = [
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc7,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x38,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xf9,0xff,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xf9,0xff,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0x9f,0xfe,0xfb,0xff,0xc7,0xff,0xff,
0xff,0xe1,0xff,0xf8,0xff,0xff,0xff,0xfc,0x3f,0xff,0xff,0xff,0xff,0xf9,0xff,0x3f,
0xf8,0xff,0xff,0xff,0xff,0xff,0x0f,0xfe,0xfb,0xff,0x39,0xff,0x00,0x7f,0x9c,0x7f,
0xe7,0x2f,0xff,0xff,0xf3,0xc3,0xfc,0x07,0xff,0xff,0xf8,0x7e,0x78,0x46,0x3f,0x80,
0x3f,0xf0,0x1f,0x0f,0xfe,0x7b,0xfe,0xfe,0xff,0xf7,0xff,0x3f,0x3f,0x9f,0x8f,0xff,
0xff,0xef,0xf3,0xff,0xbf,0xff,0xff,0xfc,0x01,0xfa,0x3f,0x9f,0xfb,0xff,0xfe,0x7f,
0x9f,0xfe,0x71,0xfc,0xfe,0x7f,0xf7,0xff,0x7f,0x9f,0x9f,0xcf,0xff,0xff,0xef,0xfb,
0xff,0xbf,0xff,0xff,0xff,0xc0,0x7e,0x7f,0x9f,0xfb,0xff,0xfe,0x7f,0xff,0xfc,0x71,
0xf9,0xff,0x3f,0xf7,0xfe,0xff,0x9f,0x3f,0xcf,0xff,0xff,0xef,0xfb,0xff,0xbf,0xff,
0xff,0xff,0xfe,0x7e,0x7f,0x8f,0xfb,0xff,0xfe,0x7f,0xff,0xfd,0x75,0xf9,0xff,0x3f,
0xf7,0xff,0xff,0xcf,0x3f,0xcf,0xff,0xff,0xe7,0xff,0xff,0xbf,0xff,0xff,0xff,0xfe,
0x7e,0x7f,0x9f,0xfb,0xff,0xfe,0x7f,0xff,0xfd,0x35,0xf9,0xff,0x3f,0xf7,0xff,0xff,
0xcf,0x3f,0xcf,0xff,0xff,0xe3,0xff,0xff,0xbf,0xff,0xff,0xff,0x80,0xfe,0x7f,0x9f,
0xfb,0xff,0xfe,0x7f,0xff,0xfd,0x2c,0xf9,0xff,0x3f,0xf7,0xff,0xff,0xcf,0x3f,0xcf,
0xff,0xff,0xf0,0x7f,0xff,0xbf,0xff,0xff,0xff,0x7c,0xfe,0x7f,0x3f,0xfb,0xff,0xfe,
0x7f,0xff,0xfb,0x2c,0xf9,0xff,0x3f,0xf7,0xfe,0x00,0x0f,0x3f,0xcf,0xff,0xff,0xfc,
0x1f,0xff,0xbf,0xff,0xff,0xfe,0x7e,0x7e,0x7c,0x7f,0xfb,0xff,0xfe,0x7f,0xff,0xfb,
0xac,0xf9,0xff,0x3f,0xf7,0xfe,0x7f,0xcf,0x3f,0xcf,0xff,0xff,0xff,0x87,0xff,0xbf,
0xff,0xff,0xfe,0x7e,0x7e,0x03,0xff,0xfb,0xff,0xfe,0x7f,0xff,0xfb,0x9e,0xf9,0xff,
0x3f,0xf7,0xfe,0x7f,0xcf,0x3f,0xcf,0xff,0xff,0xff,0xe7,0xff,0xbf,0xff,0xff,0xfe,
0xfe,0x7e,0x7f,0xff,0xfb,0xff,0xfe,0x7f,0xff,0xfb,0x9e,0x79,0xff,0x3f,0xf7,0xfe,
0x7f,0x9f,0x3f,0xcf,0xff,0xff,0xef,0xf3,0xff,0xbf,0xff,0xff,0xfe,0xfe,0x7e,0x7f,
0x9f,0xfb,0xff,0xfe,0x7f,0xff,0xf7,0x9e,0x7c,0xfe,0x7f,0xf7,0xff,0x3f,0x9f,0x9f,
0x8f,0xff,0xff,0xef,0xf3,0xff,0xbf,0xff,0xff,0xfe,0x7e,0x7f,0x7f,0x1f,0xfb,0xff,
0xfe,0x7f,0x1f,0xf7,0x9e,0x7e,0xfc,0xff,0xf7,0xff,0x3f,0x3f,0x9f,0x0f,0xff,0xff,
0xe7,0xf7,0xff,0xbf,0xff,0xff,0xf2,0x7e,0xff,0x3f,0x3f,0xfb,0xff,0xfe,0x7f,0x0f,
0xe3,0x8e,0x3f,0x39,0xff,0xf7,0xff,0xce,0x7f,0xc0,0x4f,0xff,0xff,0xe1,0xcf,0xff,
0x9f,0xff,0xff,0xf0,0x19,0xff,0x9e,0x7f,0xfb,0xff,0xfe,0x7f,0x1f,0xff,0xff,0xff,
0xc7,0xff,0xf7,0xff,0xf1,0xff,0xfb,0xcf,0xff,0xff,0xee,0x3f,0xff,0x87,0xff,0xff,
0xfb,0xe7,0xff,0xe1,0xff,0xfb,0xff,0xe0,0x0f,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,
0xff,0xff,0xff,0xff,0xcf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xfb,0xff,0xfe,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,
0xff,0xcf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,
0xff,0xfe,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xff,0xcf,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0xff,0xfe,0x7f,
0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xff,0xcf,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0xfe,0x7e,0x7f,0xff,0xff,0xff,
0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xff,0xcf,0xff,0xff,0xff,0xff,0xff,0x3f,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0xfe,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xf7,0xff,0xff,0xff,0xff,0xcf,0xff,0xff,0xff,0xff,0xff,0x1f,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xfb,0xfe,0x7c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x3f,0xff,
0xff,0xff,0xc3,0xff,0xff,0xff,0xff,0xff,0x1f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xf8,0x1f,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf3,0xff,0xff,0xff,0xff,0xcf,
0xff,0xff,0xff,0xff,0xff,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf9,0xff,0xff,
0xff,
]
a_len = 26
for i in range(0,len(a), a_len):
r = ""
for j in range(a_len):
r += bin(a[i+j]).replace("0b","").zfill(8)
print r
print "-"*20
b_len = 29
for i in range(0,len(a), b_len):
r = ""
for j in range(b_len):
r += bin(a[i+j]).replace("0b","").zfill(8)
print r
得到两个倒过来的图像
后续的根据BAR来绘制矩形,得到最终flag
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
"""
Author : Virink <virink@outlook.com>
Date : 2019/05/18, 09:53
"""
from PIL import Image, ImageDraw
image = Image.new('RGB', (1000, 1000), (255, 255, 255))
draw = ImageDraw.Draw(image)
data = ""
with open("bar.txt", "r") as f:
data = f.readlines()
for d in data:
if 'BAR' not in d:
continue
d = d.replace('\n', '')[4:]
t = d.split(", ")
x = int(t[0])
y = int(t[1])
w = int(t[2])
h = int(t[3])
draw.line([(x, y), (x+w, y+h)], fill=(0, 0, 0), width=5)
image.show()
解题思路 PClog 6.5 去掉 setcolor pick [ red orange yellow green blue violet ]
cs pu lt 90 fd 500 rt 90 pd fd 100 rt 90 repeat 18[fd 5 rt 10] lt 135 fd 50 lt 135 pu bk 100 pd repeat 18[fd 5 rt 10] rt 90 fd 60 rt 90 bk 30 rt 90 fd 60 pu lt 90 fd 100 pd rt 90 fd 50 bk 50 lt 90 fd 50 rt 90 fd 50 pu fd 50 pd fd 25 bk 50 fd 25 rt 90 fd 50 pu fd 100 rt 90 fd 30 rt 45 pd fd 50 bk 50 rt 90 fd 50 bk 100 fd 50 rt 45 pu fd 50 lt 90 pd fd 50 bk 50 rt 90 fd 50 pu lt 90 fd 100 pd fd 50 rt 90 fd 25 bk 25 lt 90 bk 25 rt 90 fd 25 pu fd 25 lt 90 bk 30 pd rt 90 fd 25 pu fd 25 lt 90 pd fd 50 bk 25 rt 90 fd 25 lt 90 fd 25 bk 50 pu bk 100 lt 90 fd 100 pd rt 90 arc 360 20 pu rt 90 fd 50 pd arc 360 15 pu fd 15 lt 90 pd bk 50 lt 90 fd 25 pu home bk 100 lt 90 fd 100 pd arc 360 20 pu home
flag: RCTF_HeyLogo
解题思路 16字节输入unhex后xxtea解密,得到8字节明文,根据最后一字节表示填充长度对明文进行00截断,同时要求填充长度不大于4。然后对截断的明文进行线性移位加密并校验,如果正确则对截断的明文与常量异或并打印。
注意到程序开始时提示:Input right flag you can got 'Bingo!' 。 那最后输出的应该就是Bingo!,这样就不用管最后的校验,直接反解。还有个小问题,如果最后截断的明文是6字节,那8字节明文最后一字节就确定了,但是第7字节不明,有多解。后来看到了提示MD5(rctf{your answer}) == 5f8243a662cf71bf31d2b2602638dc1d,这样就直接爆一个字节。 解密密钥为:C7E0C7E0D7D3F1C6D3C6D3C6CED2D0C4 即中文: 青青子衿悠悠我心 Bingo! 与 0x17异或得到 hex值 557e79707836 ,具体反解如下:
from hashlib import md5
import xxtea
def cmd5():
hh = '5f8243a662cf71bf31d2b2602638dc1d'
s = '557e79707836%02d02'
for i in range(256):
t = s%i
enc = xxtea.encrypt_hex(t.decode('hex'),'C7E0C7E0D7D3F1C6D3C6D3C6CED2D0C4'.decode('hex'),padding = False)
flag = 'rctf{'+enc+'}'
if md5(flag).hexdigest() == hh:
print flag,t
break
def main():
cmd5()
print 'end.'
if __name__ == '__main__':
main()
最终flag为:rctf{05e8a376e4e0446e}
解题思路 此题主要也是xxtea加解密。要求输入user,password和data。输入限制方面,user和password长度为8-16之间,password的ascii码在10-99之间,data为1024字节以内的hex值(unhex后使用)。 先以user为密钥加密常量,再以password为基准取data的unhex为第二次xxtea解密的密钥(需进行padding和异或),对先第一次加密的结果进行解密,解密结果的最后一字节ascii码不大于5则成功。此题是远程验证的,通过后就会返回flag。
原始的明文为(hex):F8D4D5DCC9DACFCED7DACFD2D4D5C89AB1
先本地跑了下有效数据。
import random
import xxtea
table = ''.join(map(chr,[i for i in range(1,256)]))
def randstr(n):
return ''.join(random.sample(table, n))
def de():
m = 'F8D4D5DCC9DACFCED7DACFD2D4D5C89AB1'.decode('hex')
while True:
acc = randstr(8)
passwd = randstr(8)
lt = []
for i in range(16):
if i >= 8:
acc += chr(i+1-8)
passwd += chr(i+1-8)
lt.append(passwd[i])
else:
lt.append(chr(ord(passwd[i]) ^ 0xcc))
passwd_t = ''.join(lt)
mt = xxtea.encrypt_hex(m,acc,padding = True)
mt = xxtea.decrypt_hex(mt,passwd_t,padding = False)
if ord(mt[-1]) <= 4:
print acc.encode('hex'),passwd.encode('hex'),passwd_t.encode('hex')
break
本解取的一组有效输入user:e1c1624056a98fd6 data:34fdf7fb64339ad6。 远程构造下data结构和对应的password就OK了。
#!/usr/bin/env python
from pwn import *
s = lambda a: io.send(a)
sa = lambda a, b: io.sendafter(a, b)
st = lambda a, b: io.sendthen(a, b)
sl = lambda a: io.sendline(a)
sla = lambda a, b: io.sendlineafter(a, b)
slt = lambda a, b: io.sendlinethen(a, b)
r = lambda a=0x100: io.recv(a)
rl = lambda: io.recvline()
ru = lambda a: io.recvuntil(a)
it = lambda: io.interactive()
def pwn():
sa('account:','e1c1624056a98fd6'.decode('hex'))
passwd = ''.join(map(chr,[(i+1)*10 for i in range(8)]))
sa('password:',passwd)
tmp = list('34fdf7fb64339ad6'.decode('hex'))
data = ('\x00'*8).join(tmp)
data = ('\x00'*9+data).encode('hex')
sa('data:',data)
it()
if __name__ == '__main__':
context(arch='amd64', kernel='amd64', os='linux')
HOST, PORT = '139.180.215.222', 20000
if len(sys.argv) > 1 and sys.argv[1] == 'l':
io = process('./babyre2')
context.log_level = 'debug'
else:
io = remote(HOST, PORT)
context.log_level = 'debug'
pwn()
最终 flag为:rctf{f8b1644ac14529df029ac52b7b762493}
解题思路 本题是RISC-V架构的elf程序。找了下对应的ida loader,发现64位的不好找,而且有点小问题。直接编译的RISC-V的工具链https://github.com/riscv/riscv-gnu-toolchain。 反编后找到关键代码如下:
1017c: 000007b7 lui a5,0x0
10180: 00078793 mv a5,a5
10184: cf99 beqz a5,0x101a2
10186: 0001f537 lui a0,0x1f
1018a: 1141 addi sp,sp,-16
1018c: 8c018593 addi a1,gp,-1856
10190: b8850513 addi a0,a0,-1144 # 0x1eb88
10194: e406 sd ra,8(sp)
10196: 00000097 auipc ra,0x0
1019a: 000000e7 jalr zero # 0x0
1019e: 60a2 ld ra,8(sp)
101a0: 0141 addi sp,sp,16
101a2: f6fff06f j 0x10110
101a6: df010113 addi sp,sp,-528
101aa: 20113423 sd ra,520(sp)
101ae: 20813023 sd s0,512(sp)
101b2: 0c00 addi s0,sp,528
101b4: 67f5 lui a5,0x1d
101b6: f0078513 addi a0,a5,-256 # 0x1cf00
101ba: 31c000ef jal ra,0x104d6 # puts
101be: f8040793 addi a5,s0,-128
101c2: 85be mv a1,a5
101c4: 67f5 lui a5,0x1d
101c6: f1078513 addi a0,a5,-240 # 0x1cf10
101ca: 316000ef jal ra,0x104e #scanf
101ce: f8040793 addi a5,s0,-128
101d2: 853e mv a0,a5
101d4: 358000ef jal ra,0x1052c len
101d8: 87aa mv a5,a0
101da: fef42423 sw a5,-24(s0) length
101de: fe042623 sw zero,-20(s0) idx
101e2: a041 j 0x10262
101e4: fec42783 lw a5,-20(s0)
101e8: ff040713 addi a4,s0,-16
101ec: 97ba add a5,a5,a4
...
1029c: 00f70463 beq a4,a5,0x102a4 check
102a0: 4781 li a5,0
102a2: a025 j 0x102ca
102a4: fec42783 lw a5,-20(s0)
102a8: 2785 addiw a5,a5,1
102aa: fef42623 sw a5,-20(s0)
102ae: fec42703 lw a4,-20(s0)
102b2: fe842783 lw a5,-24(s0)
102b6: 2701 sext.w a4,a4
102b8: 2781 sext.w a5,a5
102ba: faf74fe3 blt a4,a5,0x10278
102be: 67f5 lui a5,0x1d
102c0: f1878513 addi a0,a5,-232 # 0x1cf18 OK
102c4: 212000ef jal ra,0x104d6
102c8: 4781 li a5,0
102ca: 853e mv a0,a5
102cc: 20813083 ld ra,520(sp)
102d0: 20013403 ld s0,512(sp)
102d4: 21010113 addi sp,sp,528
102d8: 8082 ret
猜测输入格式为'rctf…..'或'RCTF'(最终确认为RCTF),这样就能确定第一个字符,进行反解。
s = [0x11, 0x76, 0xD0, 0x1E, 0x99, 0xB6, 0x2C, 0x91, 0x12, 0x45, 0xFB, 0x2A, 0x97, 0xC6, 0x63, 0xB8, 0x14, 0x7C, 0xE1, 0x1E, 0x83, 0xE6, 0x45, 0xA0, 0x19, 0x63, 0xDD, 0x32, 0xA4, 0xDF, 0x71]
for i in range(30,-1,-1):
a = ((((i<<1)+i)<<5)+i)&0xff
if i == 30:
s[i] = s[i]^ord('R')^a
else:
s[i] = s[i]^s[(i+1)%31]^a
print ''.join(map(chr,s))
最终flag为:RCTF{f5_is_not_real_reversing_}
解题思路 本题应该算是迷宫题。初始位置为(5,10),目标位置是(9,4)。'1'表示墙。'wsad'分别表示上下左右。
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1
1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1
1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1
1 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1
1 0 1 1 1 1 0 1 1 1 1 1 0 1 1 1
1 0 1 1 1 1 0 1 1 1 1 1 0 1 1 1
1 0 1 1 1 1 0 0 0 0 1 1 0 1 1 1
1 0 1 1 1 1 1 1 1 0 1 1 0 1 1 1
1 0 1 1 1 1 1 1 1 0 1 1 0 1 1 1
1 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1
1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1
1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
则走出的最少步数走法为:ddddwwwaaawwwddd。 程序输入经过Blowfish解密得到的迷宫的走法,直接将正确的走法加密即得正确输入。
明文:ddddwwwaaawwwddd 密钥(hex):000F1A01353A3B20 加密结果(hex):db824ef8605c5235b4bbacfa2ff8e087
最终flag为:RCTF{db824ef8605c5235b4bbacfa2ff8e087}
解题思路 此题有一个512*512的双字二维矩阵,根据前512字节的‘01’输入,坐标(x,y)分两种累加方式从二维矩阵取两组值,一组值 与常量做减法计算,并且还有个符号计数,另一组值 取低三字节组装成vm的handler代码。 我开始想爆,想了下好像时间太长,放弃了(后来和出题人交流,动态规划解)。于是从另一组数据,生成vm代码的数据着手,人肉推算输入。
通过asm代码正常与否推算输入,找到一组貌似正常的477字节输入,其组合成的代码伪代码如下:
memset(&v4, 0xCCu, 0x350u);
v32 = (unsigned int)&savedregs ^ 0xCCCCCCCC;
v31 = &a1->input_c[a1->size];
v30 = a1->bin_res + 3;
v29 = *a1->bin_res;
v28 = a1->bin_res[1];
v27 = a1->bin_res[2];
v26 = v30;
pos = 0;
count = 0;
v23 = 0;
r1 = 0;
r2 = 0;
r4 = 0;
r3 = 0;
v11 = 0;
v12 = 0;
v13 = 0;
v14 = 0;
v15 = v31;
v16 = 0;
v17 = 0;
v18 = v29;
v19 = v28;
v20 = v27;
v21 = v30;
v22 = a2;
while ( 1 )
{
result = (int)&table[pos];
if ( !table[pos] )
return result;
v23 += (table[pos] - 48) << pos % 6;
result = pos / 6;
if ( pos % 6 != 5 )
goto LABEL_76;
switch ( v23 )
{
case 0:
v23 = 0;
for ( i = 0; i < 24; ++i )
v23 += (table[++pos] - 48) << i;
r1 = v23;
goto LABEL_75;
case 1:
v23 = 0;
for ( j = 0; j < 24; ++j )
v23 += (table[++pos] - 48) << j;
r2 = v23;
goto LABEL_75;
case 2:
r1 = (unsigned __int16)v31[count++];
LABEL_75:
v23 = 0;
LABEL_76:
++pos;
break;
case 3:
r2 = r1;
goto LABEL_75;
case 4:
r3 = r4;
goto LABEL_75;
case 5:
if ( r1 < 128 )
*(&r1 + r1) = r2;
goto LABEL_75;
case 6:
if ( r2 < 128 )
r1 = *(&r1 + r2);
goto LABEL_75;
case 7:
if ( r4 < 128 )
*(&r1 + r4) = r3;
goto LABEL_75;
case 8:
if ( r3 < 128 )
r4 = *(&r1 + r3);
goto LABEL_75;
case 9:
r1 = *(_DWORD *)(r1 + 4 * r2);
goto LABEL_75;
case 10:
*(_DWORD *)(r1 + 4 * r2) = v11;
goto LABEL_75;
case 11:
r1 += r2;
goto LABEL_75;
case 12:
r1 -= r2;
goto LABEL_75;
case 13:
r1 *= r2;
goto LABEL_75;
case 14:
r1 /= r2;
goto LABEL_75;
case 15:
r1 &= r2;
goto LABEL_75;
case 16:
r1 |= r2;
goto LABEL_75;
case 17:
r1 ^= r2;
goto LABEL_75;
case 18:
r1 <<= r2;
goto LABEL_75;
case 19:
r1 >>= r2;
goto LABEL_75;
case 20:
r1 = r1 > r2;
goto LABEL_75;
case 21:
r1 = r1 < r2;
goto LABEL_75;
case 22:
r1 = r1 == r2;
goto LABEL_75;
case 23:
r1 = r1 != r2;
goto LABEL_75;
case 24: // get pos
r1 = pos;
goto LABEL_75;
case 25: // jmp
pos = r1;
v23 = 0;
break;
case 26: // jmp if false
if ( r1 )
goto LABEL_75;
pos = r2;
v23 = 0;
break;
default:
return result;
}
}
代码是出来了,但是后面还有三个check:一是第一组数据减法计算结果为0,二是符号记数为256,三是vm运行后改变特定参数。为了过前两个check,跑出了后面一小部分的输入。但是第三个check过不了,目前得到的输入如下 :(比赛时就做到这)
00000000010101000000000111100111111110100111100101001000101010010011101100111101011111111111111111001110111011011000000101110111001111100100011000000000000110001111110100000000001101110111010101011111000101110000011000111001110000000000000000000000011001000010000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000011100011111110000100111000000000000000000000000000000010000000000000001000001100000000000000101000000000100000010000000000000000010000000000000000000000
后来和出题人交流,vm的opcode解析了就能过了。想着偷懒,于是乎对着ida,下好断点,动态调试了下vm,vm主要校验输入512字节之后 的数据,大致过程如下:
num = 0
for idx,v in enumerate(input):
num += (ord(v)-0x30)<<idx
assert( num * 7 == 0xf423f)
得到最后输入的18字节:100100000111010001