OSINT + Python = 自定義黑客

類別: IT
標籤: python

去年5月10號和11號,計算機取證專家(Computer Forensic Expert)課程在Reus(西班牙)由專業司法軟體鑑定協會(ANTPJI)主持舉行,我是其中一個成員,也是一個講師,在那次課程中我有幸做了我的兩個愛好的演講,分別是Python 以及 OSINT開源情報)。

Python是一個很棒的語言,可以通過許多的庫,迅速的開發出各種各樣強大的應用程式,去扮演漏洞探測,逆向工程,web分析工具等等角色。毫無疑問對於任何安全專家它都是一個有用的知識。

Internet是巨大的,它收容了所有不可思議的資訊,這也是為什麼OSINT技術對蒐集,分析和呈現這些資訊是至關重要的。

在這個課程中,我覺得與會者對學習怎樣開發出簡單的工具(指令碼)是很感興趣的,這使得他們可以通過使用Python,通過每個有特定目標的一系列實踐鍛鍊,去執行OSINT工作。

程式碼與描述可以在VULNEX網站 獲得。

注意:我刪除了指令碼中的Google Hacking 查詢 ,讀者可以插入自己的查詢。

工具 #1

目標: 在LinkedIn上使用Google Custom Search API搜尋 ANTPJI成員。

這些指令碼非常簡單,以不同的方式做了同樣的事情。第一個使用了 Google API 客戶端,第二個使用了神奇的 Requests 庫。

在這些指令碼中,我們使用了一些Google Hacking,以便在LinkedIn上找到協會的成員。

# File: ex1_a.py
# Date: 05/14/13
# Author: Simon Roses Femerling
# Desc: Basic Google Hacking 
#
# VULNEX (C) 2013
# www.vulnex.com

import const
from apiclient.discovery import build
import pprint

# your google hacking query
query=''
query_params=''

doquery=query+query_params

service = build("customsearch","v1",developerKey=const.cse_token)

res = service.cse().list(
	q=doquery,
	cx=const.cse_id,
	num=10).execute()

pprint.pprint(res)

# VULNEX EOF
# File: ex1_b.py        
# Date: 05/14/13
# Author: Simon Roses Femerling
# Desc: Simple Google Hacking                
#
# VULNEX (C) 2013
# www.vulnex.com

import requests
import json
import urllib
import const

site="https://www.googleapis.com/customsearch/v1?key="

# Your Google Hacking query
query='' 
query_params='' 

url=site+const.cse_token+"&cx="+const.cse_id+"&q=" + urllib.quote(query+query_params)
response = requests.get(url)
print json.dumps(response.json,indent=4)

# VULNEX EOF

執行任意一個指令碼,就可以得到如下結果:

py_osint_img1

現在還不是很有趣 :)

工具 #2

目標: 使用Google Custom Search API 獲得 ANTPJI 成員 LinkedIn檔案中的照片。

下面的指令碼獲取協會成員在LinkedIn的照片,並提取出圖片後設資料資訊 ;) 這個指令碼生成了一個包含所有照片的HTML頁面。

使用的庫: Google API 客戶端, PIL, RequestsMarkup

# File: ex2.py         
# Date: 05/14/13
# Author: Simon Roses Femerling
# Desc: Download picture and extract metadata               
#
# VULNEX (C) 2013
# www.vulnex.com

import const
from apiclient.discovery import build
import pprint
import os
from PIL import Image
from StringIO import StringIO
from PIL.ExifTags import TAGS
import requests
import markup

def do_query(istart=0):
	if istart == 0:
		res = service.cse().list(
		q=doquery,
		cx=const.cse_id,
		num=10).execute()
	else:
		res = service.cse().list(
		q=doquery,
		cx=const.cse_id,
		num=10,
		start=istart).execute()
	return res

pic_id=1
do_stop=10
cnt=1

page=markup.page()

# Set page title
page.init(title="ANTPJI OSINT") 
page.h1("ANTPJI OSINT")

# Set output directory
out_dir = "pics_gepl"

# Your Google Hacking query 
query=''
query_params=''

doquery=query+query_params

service = build("customsearch","v1",developerKey=const.cse_token)

if not os.path.exists(out_dir):
	os.makedirs(out_dir)

res=[]
while True:
	if cnt==1:
		res = do_query()
	else:
		if not res['queries'].has_key("nextPage"): break
		res = do_query(res['queries']['nextPage'][0]['startIndex'])
	cnt+=1
	if cnt > do_stop: break
	if res.has_key("items"):
		for item in res['items']:
			name=""
			if not item.has_key('pagemap'): continue
			if not item['pagemap'].has_key('hcard'): continue
			hcard = item['pagemap']['hcard']
			for card in hcard:
				pic_url=""
				if 'title' in card:
					if 'fn' in card: name = card['fn']
					if 'photo' in card: pic_url = card['photo']
				if pic_url != "":	
					image = requests.get(pic_url)
					pic_n = os.path.join(out_dir,"%s.jpg") % pic_id
					file = open(pic_n,"w")
					pic_id+=1
					try:
						i = Image.open(StringIO(image.content))
						if hasattr(i,"_getexif"):
							ret = {}
							info = i._getexif()
							if info:
								for k,v in info.items():
									decode = TAGS.get(k,v)
									ret[decode] = v
								print ret
						i.save(file,"JPEG")
						page.p(name.encode('ascii','ignore')) 
						page.img(src=pic_n)
						page.br()
						page.br()
					except IOError, e:
						print "error: %s" % e
					file.close()			

# Set your output filename
with open('index_gepl.html','w') as fp:
	fp.write(str(page))

# VULNEX EOF

結果是:

py_osint_img2

通過很少的數行程式碼,我們獲得了一個有趣的工具。

工具 #3

目標: LinkedIn上 ANTPJI 成員的關係是怎樣的 ?

通過這個指令碼,我們搜尋LinkedIn上協會成員之間的關係,並建立了一個與此相關的圖。

使用的庫: Google API 客戶端, NetworkXMatplotlib

# File: ex3.py         
# Date: 05/14/13
# Author: Simon Roses Femerling
# Desc: Build graph from profiles                
#
# VULNEX (C) 2013
# www.vulnex.com

import const
from apiclient.discovery import build
import networkx as nx
import matplotlib.pyplot as plt

def do_query(istart=0):
	if istart == 0:
		res = service.cse().list(
		q=doquery,
		cx=const.cse_id,
		num=10).execute()
	else:
		res = service.cse().list(
		q=doquery,
		cx=const.cse_id,
		num=10,
		start=istart).execute()
	return res

do_stop=10
cnt=1

# Your Google Hacking query here
query=''
query_params=''

doquery=query+query_params

service = build("customsearch","v1",developerKey=const.cse_token)

G=nx.DiGraph()
res=[]
while True:
	if cnt==1:
		res = do_query()
	else:
		if not res['queries'].has_key("nextPage"): break
		res = do_query(res['queries']['nextPage'][0]['startIndex'])
	cnt+=1
	if cnt > do_stop: break
	if res.has_key("items"):
		for item in res['items']:
			name=""
			if not item.has_key('pagemap'): continue
			if not item['pagemap'].has_key('hcard'): continue
			hcard = item['pagemap']['hcard']
			for card in hcard:
				if 'title' in card:
					if 'fn' in card: name = card['fn']
				G.add_edge(name,card["fn"])		
			
plt.figure(figsize=(30,30))
nx.draw(G)
# Set your output filename
plt.savefig('antpji_rela_map.png')

# VULNEX EOF

這就是生成的圖片:

py_osint_img3


工具 #4

目標: 協會的Twitter帳號有什麼熱點 ?

這個指令碼下載了協會帳號的最新tweets,並生成了一個tag雲。對快速的檢視他們在討論什麼很有用。

使用的庫: Requests, pytagcloud

# File: ex4.py         
# Date: 05/14/13
# Author: Simon Roses Femerling
# Desc: Create word cloud               
#
# VULNEX (C) 2013
# www.vulnex.com

import requests
import json
import urllib
import const

from pytagcloud import create_tag_image, make_tags
from pytagcloud.lang.counter import get_tag_counts

site="http://search.twitter.com/search.json?q="

# Your query here
query=""

url=site+urllib.quote(query)

response = requests.get(url)

tag = []
for res in response.json["results"]:
	tag.append(res["text"].encode('ascii','ignore'))

text = "%s" % "".join(tag)	
tags = make_tags(get_tag_counts(text),maxsize=100)
# Set your output filename
create_tag_image(tags,"antpji_word_cloud.png", size=(600,500), fontname="Lobster")

# VULNEX EOF

這就是 tag 雲:

py_osint_img4


工具 #5

目標: Twitter上的 ANTPJI使用者名稱在社交網路網站上存在嗎 ?

下面的指令碼提取出協會的Twitter上釋出或提到的使用者名稱,並在160個社交網路網站上進行查詢。

使用的庫: Requests

# File: ex5.py         
# Date: 05/14/13
# Author: Simon Roses Femerling
# Desc: Check usernames on 160 social network sites               
#
# VULNEX (C) 2013
# www.vulnex.com

import requests
import json
import urllib
import const
import pprint

site="http://search.twitter.com/search.json?q="

# Your query here
query=""

url=site+urllib.quote(query)

print "Recolectando alias en Twitter: %s\n" % query
response = requests.get(url)

users = []

for res in response.json["results"]:
	if res.has_key('to_user'):
		if not res['to_user'] in users: users.append(str(res["to_user"]))
	if res.has_key('from_user'):
		if not res['from_user'] in users: users.append(str(res["from_user"]))

print "ALIAS-> %s" % users

print "\nComprobrando alias en 160 websites\n"
for username in users:	
	for service in const.services:  
      		try:    
			res1 = requests.get('http://checkusernames.com/usercheckv2.php?target=' + service + '&username=' + username, headers={'X-Requested-With': 'XMLHttpRequest'}).text
			if 'notavailable' in res1: 
				print ""
				print username + " -> " + service 
				print "" 
      		except Exception as e:  
           		print e 

# VULNEX EOF

結果像下面這樣:

py_osint_img5

工具 #6

目標: 我們能從ANTPJI 照片中提取出後設資料嗎?

這個指令碼從Google下載有關ANTPJI的照片,並提取出後設資料。

使用的庫: Requests, PILMarkup

# File: ex6.py         
# Date: 05/14/13
# Author: Simon Roses Femerling
# Desc: Download pictures from Google and extract metadata               
#
# VULNEX (C) 2013
# www.vulnex.com

import const
from apiclient.discovery import build
import pprint
import os
from PIL import Image
from StringIO import StringIO
from PIL.ExifTags import TAGS
import requests
import markup

def do_query(istart=0):
	if istart == 0:
		res = service.cse().list(
		q=doquery,
		cx=const.cse_id,
		num=10).execute()
	else:
		res = service.cse().list(
		q=doquery,
		cx=const.cse_id,
		num=10,
		start=istart).execute()
	return res

pic_id=1
do_stop=10
cnt=1

page=markup.page()
# Set your page title
page.init(title="ANTPJI OSINT") 
page.h1("ANTPJI OSINT")

# Set output directory
out_dir = "pics_gepl"

# Define your Google hacking query here
query=''
query_params=''

doquery=query+query_params

service = build("customsearch","v1",developerKey=const.cse_token)

if not os.path.exists(out_dir):
	os.makedirs(out_dir)

res=[]
while True:
	if cnt==1:
		res = do_query()
	else:
		if not res['queries'].has_key("nextPage"): break
		res = do_query(res['queries']['nextPage'][0]['startIndex'])
	cnt+=1
	if cnt > do_stop: break
	if res.has_key("items"):
		for item in res['items']:
			name=""
			if not item.has_key('pagemap'): continue
			if not item['pagemap'].has_key('hcard'): continue
			hcard = item['pagemap']['hcard']
			for card in hcard:
				pic_url=""
				if 'title' in card:
					if 'fn' in card: name = card['fn']
					if 'photo' in card: pic_url = card['photo']
				if pic_url != "":	
					image = requests.get(pic_url)
					pic_n = os.path.join(out_dir,"%s.jpg") % pic_id
					file = open(pic_n,"w")
					pic_id+=1
					try:
						i = Image.open(StringIO(image.content))
						if hasattr(i,"_getexif"):
							ret = {}
							info = i._getexif()
							if info:
								for k,v in info.items():
									decode = TAGS.get(k,v)
									ret[decode] = v
								print ret
						i.save(file,"JPEG")
						page.p(name.encode('ascii','ignore')) 
						page.img(src=pic_n)
						page.br()
						page.br()
					except IOError, e:
						print "error: %s" % e
					file.close()			

# Set your output filename
with open('index_gepl.html','w') as fp:
	fp.write(str(page))

# VULNEX EOF

一圖勝千言!

py_osint_img6

正如從這篇文章看到的,通過使用一點Python語句,就能收集到關於個人或者集體的大量的資訊,因此我們可以很容易的寫出複雜的OSINT工具。

如果你想讓我深入任何Python 和 OSINT的話題,請告訴我 :)

你使用什麼樣的 OSINT工具?

– Simon Roses Femerling

參考

OSINT + Python = 自定義黑客原文請看這裡

推薦文章