设为首页 加入收藏

TOP

从nginx日志原始二进制数据还原文件(一)
2017-12-18 12:37:25 】 浏览:333
Tags:nginx 日志 原始 二进制数据 还原 文件

nginx的access日志自定义格式记录了post请求数据,因为一些原因需要从原始数据恢复出jpg格式图片。

首先处理日志,筛选出含有图片数据的日志条目,取出其中一条进行分析,大致格式如下,为了便于查看,做一下换行处理:

- | 09/Dec/2017:08:00:19 +0000 | POST /some/api HTTP/1.1 | 200 | 461 |
--SgX5AyE7dwyg0smH-Tqpt-ggGQwTU9
\x0D\x0AContent-Disposition: form-data; name=\x22name\x22\x0D\x0AContent-Type: text/plain; charset=UTF-8\x0D\x0A\x0D\x0value\x0D\x0A
--SgX5AyE7dwyg0smH-Tqpt-ggGQwTU9
\x0D\x0AContent-Disposition: form-data; name=\x22file\x22; filename=\abc.jpg\x22
\x0D\x0AContent-Type: application/octet-stream
\x0D\x0AContent-Transfer-Encoding: binary\x0D\x0A\x0D\x0A\xFF\xD8\xFF\xE0\x00\x10JFIF\x00 ... \xD2_\xA0\x1A\x7F\xFF\xD9\x0D\x0A
--SgX5AyE7dwyg0smH-Tqpt-ggGQwTU9--
\x0D\x0A | 42097 | - | - | - | 1.1.1.1 | d1fkkbcd02eb | 127.0.0.1:8888 | 0.034 | 0.123

其中,--SgX5AyE7dwyg0smH-Tqpt-ggGQwTU9是表单的分隔字段,\x0D\x0A是回车和换行的转义字符,分别等同于\r和\n,\xFF\xD8\xFF\xE0\x00\x10JFIF\x00 ... \xD2_\xA0\x1A\x7F\xFF\xD9部分就是图片原始数据。

使用上述单行日志文件tmp.log进行调试:

>>> f = open('tmp.log', 'rb')
>>> data = f.read()
>>> data
"- | 09/Dec/2017:08:00:19 +0000 | POST /some/api HTTP/1.1 | 200 | 461 | --SgX5AyE7dwyg0smH-Tqpt-ggGQwTU9\x0D\x0AContent-Disposition: form-data; name=\x22name\x22\x0D\x0AContent-Type: text/plain; charset=UTF-8\x0D\x0A\x0D\x0value\x0D\x0A--SgX5AyE7dwyg0smH-Tqpt-ggGQwTU9\x0D\x0AContent-Disposition: form-data; name=\x22file\x22; filename=\x221512806410245.jpg\x22\x0D\x0AContent-Type: application/octet-stream\x0D\x0AContent-Transfer-Encoding: binary\x0D\x0A\x0D\x0A\xFF\xD8\xFF\xE0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00 ... \xBC'\xF1\x8C\xCC\x83,\xFAo\xD2_\xA0\x1A\x7F\xFF\xD9
\x0D\x0A--SgX5AyE7dwyg0smH-Tqpt-ggGQwTU9--\x0D\x0A | 42097 | - | - | - | 1.1.1.1 | d1fkkbcd02eb | 127.0.0.1:8888 | 0.034 | 0.123"
>>> print data
- | 09/Dec/2017:08:00:19 +0000 | POST /some/api HTTP/1.1 | 200 | 461 | --SgX5AyE7dwyg0smH-Tqpt-ggGQwTU9\x0D\x0AContent-Disposition: form-data; name=\x22name\x22\x0D\x0AContent-Type: text/plain; charset=UTF-8\x0D\x0A\x0D\x0value\x0D\x0A--SgX5AyE7dwyg0smH-Tqpt-ggGQwTU9\x0D\x0AContent-Disposition: form-data; name=\x22file\x22; filename=\x221512806410245.jpg\x22\x0D\x0AContent-Type: application/octet-stream\x0D\x0AContent-Transfer-Encoding: binary\x0D\x0A\x0D\x0A\xFF\xD8\xFF\xE0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00 ... \xBC'\xF1\x8C\xCC\x83,\xFAo\xD2_\xA0\x1A\x7F\xFF\xD9\x0D\x0A--SgX5AyE7dwyg0smH-Tqpt-ggGQwTU9--\x0D\x0A | 42097 | - | - | - | 1.1.1.1 | d1fkkbcd02eb | 127.0.0.1:8888 | 0.034 | 0.123
>>> f.close()

可以看出,打印到屏幕上的转义字符,如"\x0D\x0A"在文件中的原始字符串实际上是"\\x0D\\x0A"。因为""是用于转义的,所以想要显示反斜杠本身就必须转义自身。也就是说,print的时候,"\"被转义成"",所以我们看到的是"\x0D",实际文件中储存的是"\\0D",而我们真正需要写入文件的,是"\x0D"这个转义字符,而不是"\x0D"这个字符串。

由于文件是以二进制方式打开的,读取到的都是原始的流,所以在匹配的时候需要使用"\\\\"来表示"\\"。

使用re库处理日志:

原始数据前面是Content-Transfer-Encoding: binary加上两个\r\n,后面是一个\r\n跟上表单分割字符串--SgX5AyE7dwyg0smH-Tqpt-ggGQwTU9--

>>> import re
>>> pf = re.compile('^.*Content-Transfer-Encoding: binary\\\\x0D\\\\x0A\\\\x0D\\\\x0A')
>>> pb = re.compile('\\\\x0D\\\\x0A--.*$')
>>> data = re.sub(pf,'
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇数据开源 - Boss直聘岗位和招聘信.. 下一篇快速实现增删改查组件(起步阶段!..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目