【威锋网-注册安全分析报告-无验证方式导致安全隐患】
前言
由于网站注册入口容易被黑客攻击,存在如下安全问题:
1. 暴力破解密码,造成用户信息泄露
2. 短信盗刷的安全问题,影响业务及导致用户投诉
3. 带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞

所以大部分网站及App 都采取图形验证码或滑动验证码等交互解决方案, 但在机器学习能力提高的当下,连百度这样的大厂都遭受攻击导致点名批评, 图形验证及交互验证方式的安全性到底如何? 请看具体分析
一、 威锋网PC 注册入口
简介: 威锋网自建立之日起一直是人气中文iPhone社区,给广大iPhone爱好者提供了一个自由交流,探讨,学习的平台,为iPhone在中国的应用及普及发挥了领军作用。

二、 安全性分析报告:
前端界面分析,威锋网未采取任何验证措施,存在验证的安全隐患,同行一般会在注册下发短信验证码时采用图形验证、行为验证方式。

三、 测试方法:
1 模拟器交互部分
private final String INDEX_URL = "https://www.feng.com/";@Overridepublic RetEntity send(WebDriver driver, String areaCode, String phone) {try {RetEntity retEntity = new RetEntity();driver.get(INDEX_URL);Thread.sleep(1000);driver.findElement(By.xpath("//a[text()='注册']")).click();WebElement nameElemet = driver.findElement(By.xpath("//input[@placeholder='请输入用户名']"));nameElemet.sendKeys("top_" + phone);// 输入手机号WebElement phoneElemet = driver.findElement(By.xpath("//input[@placeholder='请输入手机号']"));phoneElemet.sendKeys(phone);// 点击发送验证码按钮WebElement sendElemet = driver.findElement(By.xpath("//div/span[text()='获取验证码']"));if (sendElemet != null)sendElemet.click();Thread.sleep(1);WebElement exitsElement = ChromeDriverManager.waitElement(driver, By.className("ivu-message-notice-content-text"), 15);String exitsInfo = (exitsElement != null) ? exitsElement.getText() : null;if (exitsInfo != null) {System.out.println("phone=" + phone + ",exitsInfo=" + exitsInfo);retEntity.setMsg(exitsInfo);retEntity.setRet(0);return retEntity;}Thread.sleep(1000);WebElement gtElemet = ChromeDriverManager.waitElement(driver, By.xpath("//div/span[@class='count']"), 5);String gtInfo = (gtElemet != null) ? gtElemet.getText() : null;retEntity.setMsg(gtInfo);if (gtInfo != null && gtInfo.contains("重新获取")) {retEntity.setRet(0);} else {System.out.println("gtInfo=" + gtInfo);}return retEntity;} catch (Exception e) {System.out.println("phone=" + phone + ",e=" + e.toString());for (StackTraceElement ele : e.getStackTrace()) {System.out.println(ele.toString());}return null;} finally {driver.manage().deleteAllCookies();}}
2 测试结果输出,测试中发现,如果手机号已注册,会直接提示该手机号已注册

由于碰到严重设计缺陷,本次测评非常简单
附早期的代码,采用的行为验证:
@Overridepublic RetEntity reg(CloseableHttpClient httpclient, CookieStore cookieStore, Hashtable<String, String> input, String phone) {RetEntity retEntity = new RetEntity();System.setProperty("webdriver.chrome.driver", OCRUtil.chromePath + File.separator + "chromedriver.exe");WebDriver driver = new ChromeDriver();try {driver.get(INDEX_URL);// 输入手机 号 密码 确认密码WebElement inputPhoneElemet = driver.findElement(By.xpath("//input[@name='phone_number']"));inputPhoneElemet.sendKeys(phone);// 获取验证码点击按钮[a id=validation_code]By getCodeBtn = By.cssSelector("#validation_code");WebElement getCodeElemet = driver.findElement(getCodeBtn);getCodeElemet.click();sleep(2000);// 点球点By moveBtn = By.cssSelector(".feng_captcha_block_piece.feng_captcha_slider_piece");WebElement moveElemet = driver.findElement(moveBtn);// 移动距离点(左门柱)int[][] distance = getMoveDistance(driver, WeiFeng.class.getSimpleName(), phone);// 移动move(driver, moveElemet, distance);retEntity.setRet(0);return retEntity;} catch (Exception e) {logger.error(e.toString());retEntity.setRet(-1);return retEntity;} finally {driver.quit();delImg(WeiFeng.class.getSimpleName(), phone);// 删除图片}}
/*** 移动 三次* * @param driver* @param element* @param distance* @throws InterruptedException*/private static void move(WebDriver driver, WebElement element, int[][] distance) throws InterruptedException {Actions actions = new Actions(driver);for (int i = 2; i >= 0; i--) {actions.clickAndHold(element).perform();// 按住鼠标左键不释放int moveX = (distance[0][0] + 68 * i - 270) / 2;int moveY = distance[1][0] + 34 * 2 - 500;Thread.sleep(500 + new Random().nextInt(700));actions.moveByOffset(moveX, moveY).perform();// 移动Thread.sleep(300 + new Random().nextInt(300));actions.release(element).perform();// 释放鼠标左键}}/*** 计算需要平移的距离* * @param driver* @return* @throws IOException*/public static int[][] getMoveDistance(WebDriver driver, String spCode, String phone) throws IOException {String imgPrefix = spCode + phone;String pageSource = driver.getPageSource();String fullImageUrl = getFullImageUrl(pageSource);FileUtils.copyURLToFile(new URL(fullImageUrl), new File(basePath + "result/" + imgPrefix + FULL_IMAGE_NAME + ".jpg"));initMoveArray(driver);// 把两张图片剪切后拼接还原restoreImage(imgPrefix + FULL_IMAGE_NAME);BufferedImage fullBI = ImageIO.read(new File(basePath + "result/" + imgPrefix + FULL_IMAGE_NAME + "result3.jpg"));for (int j = fullBI.getHeight() / 2; j > fullBI.getHeight() / 3; j--) {for (int i = 0; i < fullBI.getWidth(); i++) {int[] fullRgb = new int[3];fullRgb[0] = (fullBI.getRGB(i, j) & 0xff0000) >> 16;fullRgb[1] = (fullBI.getRGB(i, j) & 0xff00) >> 8;fullRgb[2] = (fullBI.getRGB(i, j) & 0xff);if ((fullRgb[0] >= 38 && fullRgb[0] <= 77) && (fullRgb[1] >= 38 && fullRgb[1] <= 77) && (fullRgb[2] >= 38 && fullRgb[2] <= 77)) {int[][] pos = new int[2][1];pos[0][0] = i;pos[1][0] = j;return pos;}}}throw new RuntimeException("未找到需要平移的位置");}/*** 获取move数组* * @param driver*/private static void initMoveArray(WebDriver driver) {Document document = Jsoup.parse(driver.getPageSource());Elements elements = document.select("[class=feng_captcha_image_wrap]").first().children();int i = 0;for (Element element : elements) {Pattern pattern = Pattern.compile(".*background:.*"\\)(.*?)px (.*?)px.*");Matcher matcher = pattern.matcher(element.toString());if (matcher.find()) {String width = matcher.group(1);String height = matcher.group(2);moveArray[i][0] = Integer.parseInt(width.trim());moveArray[i++][1] = Integer.parseInt(height.trim());} else {throw new RuntimeException("解析异常");}}}/*** 还原图片* * @param type*/private static void restoreImage(String type) throws IOException {// 把图片裁剪为2 * 10份for (int i = 0; i < 20; i++) {ImageIOHelper.cutPic(basePath + "result/" + type + ".jpg", basePath + "result/" + type + i + ".jpg", -moveArray[i][0], -moveArray[i][1], 54, 250);}// 拼接图片String[] b = new String[10];for (int i = 0; i < 10; i++) {b[i] = String.format(basePath + "result/" + type + "%d.jpg", i);}ImageIOHelper.mergeImage(b, 1, basePath + "result/" + type + "result1.jpg");// 拼接图片String[] c = new String[10];for (int i = 0; i < 10; i++) {c[i] = String.format(basePath + "result/" + type + "%d.jpg", i + 10);}ImageIOHelper.mergeImage(c, 1, basePath + "result/" + type + "result2.jpg");ImageIOHelper.mergeImage(new String[] { basePath + "result/" + type + "result1.jpg", basePath + "result/" + type + "result2.jpg" }, 2, basePath + "result/" + type + "result3.jpg");// 删除产生的中间图片for (int i = 0; i < 20; i++) {new File(basePath + "result/" + type + i + ".jpg").delete();}new File(basePath + "result/" + type + "result1.jpg").delete();new File(basePath + "result/" + type + "result2.jpg").delete();}public void delImg(String spCode, String phone) {File dirFile = new File(basePath + "result/");if (!dirFile.exists()) {logger.debug("文件目录不存在:" + basePath + "result/");return;}File[] files = dirFile.listFiles();String prefix = spCode + phone;for (File file : files) {if (file.getName().startsWith(prefix)) {file.delete();}}}/*** 从后台源码中获取原始图,然后转换成URL返回* * @param pageSource* @return*/private static String getFullImageUrl(String pageSource) {String url = null;String divStr = null;Document document = Jsoup.parse(pageSource);Elements select = document.select("[class=feng_captcha_image_wrap]");String style = select.html();if (style != null) {divStr = style.substring(0, style.indexOf("</div>"));}if (divStr != null) {int beginIndex = divStr.indexOf(""") + 6;int endIndex = divStr.lastIndexOf(""");url = divStr.substring(beginIndex, endIndex);}return url;}
二丶结语
威锋网作为IPHONE 在国内知名的媒体公司, 具有很高的人气和影响力,之前测试时记得好像是采用网易易盾的验证方式,在最近测试不知道为何去掉了, 是因为没钱了还是对安全的不重视,总之,测试结果就是随便你怎么攻击都可以,这也有点太开发了, 短信验证码难道不要钱吗 ? 这对黑客来说肯定是好消息, 弄个简单的脚本就可以搞定
很多人在短信服务刚开始建设的阶段,可能不会在安全方面考虑太多,理由有很多。
比如:“ 需求这么赶,当然是先实现功能啊 ”,“ 业务量很小啦,系统就这么点人用,不怕的 ” , “ 我们怎么会被盯上呢,不可能的 ”等等。有一些理由虽然有道理,但是该来的总是会来的。前期欠下来的债,总是要还的。越早还,问题就越小,损失就越低。
所以大家在安全方面还是要重视。(血淋淋的栗子!)#安全短信#
戳这里→康康你手机号在过多少网站注册过!!!
谷歌图形验证码在AI 面前已经形同虚设,所以谷歌宣布退出验证码服务, 那么当所有的图形验证码都被破解时,大家又该如何做好防御呢?
>>相关阅读
《腾讯防水墙滑动拼图验证码》
《百度旋转图片验证码》
《网易易盾滑动拼图验证码》
《顶象区域面积点选验证码》
《顶象滑动拼图验证码》
《极验滑动拼图验证码》
《使用深度学习来破解 captcha 验证码》
《验证码终结者-基于CNN+BLSTM+CTC的训练部署套件》
相关文章:
【威锋网-注册安全分析报告-无验证方式导致安全隐患】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…...
01_React简介、基础入门
React 简介、基础入门 一、React 简介1、是什么?2、谁开发的?3、为什么要学?4、React 的特点5、学习 React 之前你要掌握的 Javascript 基础知识 二、React 入门1、相关 js 库2、Hello React 入门小例子---React16.8.0 版本3、为什么不用 js …...
【Java 内存区域】
Java内存区域 JDK1.7 VS JDK1.8堆 (Heap)方法区 (Method Area)String 常量池 (String Pool)运行时常量池 (Runtime Constant Pool)虚拟机栈 (JVM Stack)局部变量表操作数栈动态链接方法返回信息 本地方法栈 (Native Method Stack)程序计数器 (Program Counter Register)元空间 …...
你是如何克服编程学习中的挫折感的?
一:学习之路 在编程学习的过程中,挫折和挑战是不可避免的。面对这些困难,我个人的一些经验和方法如下,或许能为你提供一些启示: 1. 学会分解问题 当遇到复杂的算法或者Bug时,我会将问题分解成更小的部分。…...
【AI应用实战】灵办AI插件集成详细指南
一、写在前面 随着AI技术的日新月异,大型模型应用如雨后春笋般涌现,从ChatGPT到文心一言,再到讯飞星火,无一不彰显着智能科技的无限潜力。而在这股浪潮中,我们欣喜地发现,一些创新的浏览器插件正悄然兴起&a…...
MySQL数据库连接超时问题排查报告
1、问题描述 边端设备访问云端过程中有概率出现MySQL数据库连接超时报错,具体报错代码如下: [2024-08-13 13:47:44,036] ERROR in app: Exception on /est-tasks/start [POST] Traceback (most recent call last): File "/usr/local/lib/python3.1…...
代码随想录第三天 | 链表
文章目录 链表理论知识定义链表删除链表 Leetcode203 移除链表元素代码实现 Leetcode707 设计链表代码实现复杂度分析错误点 Leetcode206 反转链表新建链表双指针法 链表理论知识 链接: https://programmercarl.com/%E9%93%BE%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.h…...
Python编码系列—Python数据可视化:Matplotlib与Seaborn的实战应用
🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…...
putty中修改默认窗口大小和字体、字号
在WinSCP中调用putty,发现默认窗口太小,字号也很小,非常不友好。现在显示器都是1080p起步,所以很有必要修改之。 以中文版v0.70为例,方法: 1. 点击左上角图标 ,选择下拉菜单中的“修改设置”&…...
Windows下网络编与ESP8266-WiFi通信(win32-API)
一、前言 络编程是指编写程序使不同计算机之间能够通过网络进行通信和数据交换。网络编程涉及使用网络协议和编程接口来建立、管理和终止网络上的数据通信。在这一领域中,TCP/IP协议族是核心组成部分,尤其TCP(传输控制协议)是面向…...
【Golang】golang安装一些依赖包时总是失败
Golang安装一些依赖包失败: 比如安装gin包:go get -u github.com/gin-gonic/gin 可能会报错:连接网络失败、超时等 这时可能需要修改go的环境配置,修改代理即可: go env -w GO111MO…...
ubuntu如何监控Xvfb虚拟显示器
在Ubuntu中监控Xvfb显示器主要涉及到使用VNC服务器来远程访问这个环境。以下是一些基本步骤: 安装Xvfb和相关工具: 使用apt安装Xvfb和x11vnc,x11vnc是一个VNC服务器,可以远程访问Xvfb创建的虚拟桌面环境。 sudo apt-get install xvfb sudo ap…...
小型需求管理软件盘点:8款功能强大的工具
本文介绍了以下8款工具:PingCode、Worktile、易得云、Ping、燃草、Gitee、Monday.com、Slack。 在现代企业管理中,需求管理一直是个让人头疼的问题,特别是对于小型企业来说,选择一款合适的需求管理软件往往比想象中更复杂。如果选…...
Labelme的安装与使用教程
文章目录 一、Labelme是什么?二、安装步骤1.新建虚拟环境2.安装Labelme3.Labelme的使用 三、json2yolo 一、Labelme是什么? Labelme是一个用于图像标注的开源工具,可以实现图像标注、语义分割、实例分割等。 本文记录一下labelme的安装与使…...
C#基础:数据库中使用Linq作分组处理(反射/直接分组)
目录 一、使用反射分组 二、不使用反射分组 三、调用示例 四、代码demo 一、使用反射分组 private static List<GroupList<T>> GetGroupList<T>(List<T> entities, string groupByProperty) {// 获取分组字段的类型var propertyInfo typeof(T).…...
Revite二次开发_使用WPF和WebView2制作一个访问网站的窗口
如果想在revit里打开网页,可以使用WebView2来实现,下面是一个代码示例。 也尝试过使用CefSharp,但由于Revit本身也使用了CefSharp,所以需要根据不同的Revit版本选择适合的CefSharp版本,比较麻烦,所以最好还…...
Java Spring Boot 连接数据库
要在Java Spring Boot应用程序中连接数据库,您需要遵循以下步骤: 1. 添加数据库依赖项:在您的Spring Boot项目中的pom.xml文件中添加数据库依赖项,例如MySQL或PostgreSQL等。例如,如果您要连接MySQL数据库,…...
Java面试八股之消息队列中推模式和拉模式分别有哪些使用场景
消息队列中推模式和拉模式分别有哪些使用场景 消息队列的推模式(Push)和拉模式(Pull)各有不同的使用场景和优缺点。下面我会详细介绍这两种模式及其适用场景: 推模式(Push) 特点:…...
springboot jar是如何启动的
我们先来看一个项目的打完包后的MANIFEST.MF文件: Manifest‐Version: 1.0 Implementation‐Title: spring‐learn Implementation‐Version: 0.0.1‐SNAPSHOT Start‐Class: com.tulingxueyuan.Application Spring‐Boot‐Classes: BOOT‐INF/classes/ Spring‐Bo…...
Android 12系统源码_屏幕设备(二)DisplayAdapter和DisplayDevice的创建
前言 在Android 12系统源码_屏幕设备(一)DisplayManagerService的启动这篇文章中我们具体分析了DisplayManagerService 的启动流程,本篇文章我们将在这个的基础上具体来分析下设备屏幕适配器的创建过程。 一、注册屏幕适配器 系统是在Disp…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...
MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
Java中HashMap底层原理深度解析:从数据结构到红黑树优化
一、HashMap概述与核心特性 HashMap作为Java集合框架中最常用的数据结构之一,是基于哈希表的Map接口非同步实现。它允许使用null键和null值(但只能有一个null键),并且不保证映射顺序的恒久不变。与Hashtable相比,Hash…...
C++中vector类型的介绍和使用
文章目录 一、vector 类型的简介1.1 基本介绍1.2 常见用法示例1.3 常见成员函数简表 二、vector 数据的插入2.1 push_back() —— 在尾部插入一个元素2.2 emplace_back() —— 在尾部“就地”构造对象2.3 insert() —— 在任意位置插入一个或多个元素2.4 emplace() —— 在任意…...
