从文件中提取元数据。文件不是清晰可见 的对象,元数据可以存在于文档,电子表格,图像,音频和视频等文件类型中。 创作应用程序可能会存储一些细节如文件的作者,创建和修改时间,潜在的修订和注释。例如,拍照手机可以标记本地的GPS在照片中或者微软的 Word 应用程序可以存储文档的作者。检查每一个文件是个艰难的任务,我们可以使用Python自动处理。
PyPDF 是一个优秀的第三方管理 PDF 文件很实用的库,它提供了文档的信息提取,分割,合并,加密 和解密的能力。
为了提取元数据,我们使用函数 getDocumentInfo()。这个方法返回一个元组数组,每一个元组包含一个元数据元素和它的值。遍历这个数组并打印 PDF 文件的全部元数据。
# coding = utf-8
import pyPdf
from pyPdf import PdfFileReader
import optparse
def printMeta(fileName):
pdfFile = PdfFileReader(file(fileName, 'rb'))
docInfo = pdfFile.getDocumentInfo()
print('[*]PDF MetaData FOr:' + str(fileName))
for metaItem in docInfo:
print('[+]' + metaItem + ':' + docInfo[metaItem])
def main():
parser = optparse.OptionParser('usage %prog -F ' )
parser.add_option('-F', dest='fileName', type='string', help='specify PDF file name')
(options, args) = parser.parse_args()
fileName = options.fileName
if fileName == None:
print(parser.usage)
exit(0)
else:
printMeta(fileName)
if __name__ == '__main__':
main()
Exif 是一种图象文件格式,它的数据存储与 JPEG 格式是完全相同的。实际上 Exif 格式就是在 JPEG 格式头部插入了数码照片的信息,包括拍摄时的光圈、快 门、白平衡、ISO、焦距、日期时间等各种和拍摄条件以及相机品牌、型号、 色彩编码、拍摄时录制的声音以及全球定位系统(GPS)、缩略图等。简单地Exif=JPEG+拍摄参数。
Phil Harvey 编写了一个实用的工具名 叫 exiftool(从 http://www.sno.phy.queensu.ca/~phil/exiftool/可获得)能解析这 些参数。
investigator$ exiftool photo.JPG
ExifTool Version Number : 8.76
File Name : photo.JPG
Directory : /home/investigator/photo.JPG
File Size : 1626 kB
File Modification Date/Time : 2012:02:01 08:25:37-07:00
File Permissions : rw-r--r--
File Type : JPEG
MIME Type : image/jpeg
Exif Byte Order : Big-endian (Motorola, MM)
Make
: Apple
Camera Model Name : iPhone 4S
Orientation : Rotate 90 CW
<..SNIPPED..>
GPS Altitude : 10 m Above Sea Level
GPS Latitude : 89 deg 59' 59.97" N
GPS Longitude : 36 deg 26' 58.57" W
<..SNIPPED..>
建立一个脚本来连接web网站,下载图像,并检测他们的Exif元数据。
BeautifulSoup
允许我们快速的解析HTML和 XML文档,使用BeautifulSoup来抓取HTML文档的内容来获取文档中所有的图像。使用urllib2打开文档来读取它,可以创造Beautiful对象或者包含一个不同HTML文档对象的解析树。用这样的对象, 我么可以提取所有的图像标签,通过使用 findall(‘img’)函数,这个函数返回一 个包含所有图像标签的数组。
import urllib2
from bs4 import BeautifulSoup
def findImages(url):
print('[+] Finding images on' + url)
urlContent = urllib2.urlopen(url).read()
soup = BeautifulSoup(urlContent)
imgTags = soup.findAll('img')
return imgTags
从网站中下载每一个图像,然后在单独的函数中进行检查。 为了下载图像,我们将用到 urllib2,urlparse 和 os 模块。首先,我们从图像标 签中提取源地址,接着我们读取图像的二进制内容到一个变量,最后我们以写- 二进制模式打开文件将图像内容写入文件。
import urllib2
from urlparse import urlsplit
from os.path import basename
def downloadImage(imgTag):
try:
print('[+]Downloading image...')
imgSrc = imgTag['src']
imgContent = urllib2.urlopen(imgSrc).read()
imgFileName = basename(urlsplit(imgSrc)[2])
imgFle = open(imgFileName, 'wb')
imgFle.write(imgContent)
imgFle.close()
return imgFileName
except:
return ''
为了测试图像的内容特到 Exif 元数据,我们将使用 Python 图像库 PIL 来处理文 件,可以从 http://www.pythonware.com/products/pil/获得,以增加 Python 的 图像处理能力,并允许我们快速的提取与地理位置相关的元数据信息。为了测 试文件元数据,我们将打开的对象作为 PIL 图像对象并使用函数 getexif()。接 下来我们解析 Exif 数据到一个数组,通过元数据类型索引。数组完成后,我们 可以搜索数组看看它是否包含有 GPSInfo 的 Exif 参数。如果它包含 GPSInfo 参 数,我们就知道对象包含 GPS 元数据并打印信息到屏幕上。
from PIL import Image
from PIL.ExifTags import TAGS
def testForExif(imgFileName):
try:
exifData = {}
imgFile = Image.open(imgFileName)
info = imgFile._getexif()
if info:
for (tag, value) in info.items():
decoded = TAGS.get(tag, tag)
exifData[decoded] = value
exifGPS = exifData['GPSInfo']
if exifGPS:
print('[*]' + imgFileName + 'contains GPS MetaData')
except:
pass
将所有的包装在一起,可以连接到一个URL地址,解析并下载所有的图像文件,然后测试每个文件的Exif元数据。
main()函数中,首先获得站点上的所有图像的列表,然后对数据中的每一个图像,我们将下载并测试它的GPS元数据
# coding =UTF-8
import urllib2
import optparse
from bs4 import BeautifulSoup
from urlparse import urlsplit
from os.path import basename
from PIL import Image
from PIL.ExifTags import TAGS
def findImages(url):
print('[+] Finding images on ' + url)
urlContent = urllib2.urlopen(url).read()
soup = BeautifulSoup(urlContent)
imgTags = soup.findAll('img')
return imgTags
def downloadImage(imgTag):
try:
print('[+]Downloading image...')
imgSrc = imgTag['src']
imgContent = urllib2.urlopen(imgSrc).read()
imgFileName = basename(urlsplit(imgSrc)[2])
imgFle = open(imgFileName, 'wb')
imgFle.write(imgContent)
imgFle.close()
return imgFileName
except:
return ''
def testForExif(imgFileName):
try:
exifData = {}
imgFile = Image.open(imgFileName)
info = imgFile._getexif()
if info:
for (tag, value) in info.items():
decoded = TAGS.get(tag, tag)
exifData[decoded] = value
exifGPS = exifData['GPSInfo']
if exifGPS:
print('[*]' + imgFileName + 'contains GPS MetaData')
except:
pass
def main():
parser = optparse.OptionParser('usage%prog -u ' )
parser.add_option('-u', dest='url', type='string', help='specify url address')
(options, args) = parser.parse_args()
url = options.url
if url == None:
print(parser.usage)
exit(0)
else:
imgTags = findImages(url)
for imgTag in imgTags:
imgFileName = downloadImage(imgTag)
testForExif(imgFileName)
if __name__ == '__main__':
main()
forensics: # python exifFetch.py -u
http://www.flickr.com/photos/dvids/4999001925/sizes/o
[+] Finding images on
http://www.flickr.com/photos/dvids/4999001925/sizes/o
[+] Dowloading image...
[+] Dowloading image...
[+] Dowloading image...
[*] 4999001925_ab6da92710_o.jpg contains GPS MetaData
[+] Dowloading image...
[+] Dowloading image...
[+] Dowloading image...