【威锋网-注册安全分析报告-无验证方式导致安全隐患】

news2024/12/26 23:42:37

前言

由于网站注册入口容易被黑客攻击,存在如下安全问题:

1. 暴力破解密码,造成用户信息泄露

2. 短信盗刷的安全问题,影响业务及导致用户投诉

3. 带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞

在这里插入图片描述

所以大部分网站及App 都采取图形验证码或滑动验证码等交互解决方案, 但在机器学习能力提高的当下,连百度这样的大厂都遭受攻击导致点名批评, 图形验证及交互验证方式的安全性到底如何? 请看具体分析

一、 威锋网PC 注册入口

简介: 威锋网自建立之日起一直是人气中文iPhone社区,给广大iPhone爱好者提供了一个自由交流,探讨,学习的平台,为iPhone在中国的应用及普及发挥了领军作用。

在这里插入图片描述

二、 安全性分析报告:

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

在这里插入图片描述

三、 测试方法:

1 模拟器交互部分

private final String INDEX_URL = "https://www.feng.com/";

	@Override
	public 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 测试结果输出,测试中发现,如果手机号已注册,会直接提示该手机号已注册

在这里插入图片描述

  由于碰到严重设计缺陷,本次测评非常简单

附早期的代码,采用的行为验证:


@Override
	public 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:.*&quot;\\)(.*?)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 * 10for (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("&quot;") + 6;
			int endIndex = divStr.lastIndexOf("&quot;");
			url = divStr.substring(beginIndex, endIndex);
		}
		return url;
	}

二丶结语

威锋网作为IPHONE 在国内知名的媒体公司, 具有很高的人气和影响力,之前测试时记得好像是采用网易易盾的验证方式,在最近测试不知道为何去掉了, 是因为没钱了还是对安全的不重视,总之,测试结果就是随便你怎么攻击都可以,这也有点太开发了, 短信验证码难道不要钱吗 ? 这对黑客来说肯定是好消息, 弄个简单的脚本就可以搞定

很多人在短信服务刚开始建设的阶段,可能不会在安全方面考虑太多,理由有很多。
比如:“ 需求这么赶,当然是先实现功能啊 ”,“ 业务量很小啦,系统就这么点人用,不怕的 ” , “ 我们怎么会被盯上呢,不可能的 ”等等。

有一些理由虽然有道理,但是该来的总是会来的。前期欠下来的债,总是要还的。越早还,问题就越小,损失就越低。

所以大家在安全方面还是要重视。(血淋淋的栗子!)#安全短信#

戳这里→康康你手机号在过多少网站注册过!!!

谷歌图形验证码在AI 面前已经形同虚设,所以谷歌宣布退出验证码服务, 那么当所有的图形验证码都被破解时,大家又该如何做好防御呢?

>>相关阅读
《腾讯防水墙滑动拼图验证码》
《百度旋转图片验证码》
《网易易盾滑动拼图验证码》
《顶象区域面积点选验证码》
《顶象滑动拼图验证码》
《极验滑动拼图验证码》
《使用深度学习来破解 captcha 验证码》
《验证码终结者-基于CNN+BLSTM+CTC的训练部署套件》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2054802.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaEE过滤器的创建与使用过滤器的使用场景

过滤器 Filter也称之为过滤器&#xff0c;过滤器是javaEE规范肿定义的一种技术,可以让请求到达目标servlet之前,先进入到过滤器中,在过滤器中统一进行一些拦截处理,当处理完成后,可以继续向后执行,到达目标servlet,如果配置了多个过滤器,也可以进入下一个过滤器 创建过滤器 创…

一键更换Linux优质的软件源和docker源 —— 筑梦之路

一个非常牛逼的开源项目&#xff1a;https://github.com/SuperManito/LinuxMirrors.git LinuxMirrors 使换源更简单 - LinuxMirrors 支持的操作系统 系统名称适配版本Debian8.0 ~ 13Ubuntu14.04 ~ 24Kali Linux2.0 ~ 2024Linux Mint19.0 ~ 21 / LMDE 6DeepinallArmbianallP…

Redis7基础篇(一)

redis十大数据类型 目录 redis十大数据类型 redis键key 数据类型命令 redis字符串string 分布式锁 ​编辑 ​编辑​编辑应用场景 ​编辑​编辑 reids列表list 应用场景 redis哈希hash 应用场景 redis集合set 应用场景 redis有序集合zset&#xff08;sorted set集…

【设计模式】观察者模式和订阅发布模式

观察者模式 观察者模式包含观察目标和观察者两类对象。一个目标可以有任意数目的与之相依赖的观察者。一旦观察目标的状态发生改变&#xff0c;所有的观察者都将得到通知。 当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都得到通知并被自动更新&#xff0c;解决…

《机器学习》逻辑回归 梯度下降、混淆矩阵、随机种子、正则化惩罚 No.6

一、混淆矩阵 1、什么是混淆矩阵&#xff1f; 混淆矩阵是用于评估分类模型在不同类别上的预测准确性的工具。它提供了模型预测结果与真实结果之间的对应关系&#xff0c;帮助我们分析和理解模型的分类性能。 假设&#xff0c;要对15个人预测是否患病&#xff0c;使用1表示患病…

生产环境中MapReduce的最佳实践

目录 MapReduce跑的慢的原因 MapReduce常用调优参数 1. MapTask相关参数 2. ReduceTask相关参数 3. 总体调优参数 4. 其他重要参数 调优策略 MapReduce数据倾斜问题 1. 数据预处理 2. 自定义Partitioner 3. 调整Reduce任务数 4. 小文件问题处理 5. 二次排序 6. 使用…

【python与java的区别-03(集合、字典)】

一、Set python: 集合&#xff08;set&#xff09;是一个无序的不重复元素序列。 集合中的元素不会重复&#xff0c;并且可以进行交集、并集、差集等常见的集合操作。 可以使用大括号 { } 创建集合&#xff0c;元素之间用逗号 , 分隔&#xff0c; 或者也可以使用 set() 函数…

【解释器模式】设计模式系列:构建动态语言解释器与复杂表达式处理(深入理解并实现)

文章目录 深入理解并实现解释器模式1. 引言1.1 解释器模式的定义1.2 模式的主要优点和缺点1.3 适用场景1.4 实际应用案例简介 2. 解释器模式的基本概念2.1 模式的核心思想2.2 模式的角色2.3 模式的动态行为分析 3. 解释器模式的工作原理3.1 如何构建表达式树3.2 如何通过递归遍…

可达鸭举牌网页版本在线生成源码html5

源码介绍 可达鸭举牌网页版本&#xff0c;在线生成源码&#xff0c;点击分享即可制作DIY自己的举牌文字网页&#xff0c;需要GIF动图的自行用GIF图片录制工具录制下来。 PS:上传到服务器运行或者本地nginx运行&#xff0c;不要双击index.html&#xff0c;如果本地双击HTML&…

【3】AT32F437 OpenHarmony轻量系统第一个程序:点灯

在搭建好AT32F437 OpenHarmony 轻量系统之后&#xff0c;当然要尝试点一下灯了。 编写点灯程序 笔者在适配OpenHarmony轻量系统的时候&#xff0c;只对源码的device和vendor目录进行了修改&#xff0c;AT32的app目录笔者放置在了vendor/tree/master/artery/AT-START-F437/app…

什么是网络安全?网络安全防范技术包括哪些?

一、引言 在当今数字化的时代&#xff0c;网络已经成为人们生活和工作中不可或缺的一部分。然而&#xff0c;随着网络的普及和应用的广泛&#xff0c;网络安全问题也日益凸显。从个人隐私泄露到企业关键信息被盗&#xff0c;从网络欺诈到大规模的网络攻击&#xff0c;网络安全…

在国产芯片上实现YOLOv5/v8图像AI识别-【2.5】yolov8使用C++部署在RK3588更多内容见视频

本专栏主要是提供一种国产化图像识别的解决方案&#xff0c;专栏中实现了YOLOv5/v8在国产化芯片上的使用部署&#xff0c;并可以实现网页端实时查看。根据自己的具体需求可以直接产品化部署使用。 B站配套视频&#xff1a;https://www.bilibili.com/video/BV1or421T74f 背景…

ubuntu 安装两个nginx实例时的坑,非默认nginx实例配置修改总也不生效的问题

一、问题 由于工作需求xx云服务器上安装了两个nginx实例&#xff0c;突然有一天需要在非默认nginx上增加一个子站点&#xff0c;根据网上教程和原来的记录修改vi nginx.conf 后保存载总也不生效&#xff1f; 怎么破&#xff1f; 二、过程记录 假如&#xff1a;非默认nginx安装在…

HanLP分词的使用与注意事项

1 概述 HanLP是一个自然语言处理工具包&#xff0c;它提供的主要功能如下&#xff1a; 分词转化为拼音繁转简、简转繁提取关键词提取短语提取词语自动摘要依存文法分析 下面将介绍其分词功能的使用。 2 依赖 下面是依赖的jar包。 <dependency><groupId>com.ha…

使用SSH协议远程连接Ubuntu

1.切换到root用户 sudo -i 2.安装openssh-server apt update apt install openssh-server 3.启动ssh服务 service ssh start 4.查看ssh状态 &#xff08;q键: 退出&#xff09; service ssh status 5.检查ssh服务是否启动成功 ps -e | grep ssh 6.开机自启动 systemctl enable …

基于STM32F103的FreeRTOS系列(九)·任务创建函数的使用·静态方法和动态方法

目录 1. 前期准备 1.1 中断文件修改 1.2 SysTick文件修改 1.3 任务创建函数API 2. 任务创建&#xff08;静态方法&#xff09; 2.1 创建两个任务函数 2.2 静态创建开始任务函数 2.3 创建开始任务的任务函数 2.4 补充 2.5 代码 3. 任务创建&#xff08;动…

【python基础】—利用pandas读取或写入mysql表数据

文章目录 一、read_sql()二、to_sql()三、连接数据库方式—MySQL1、用sqlalchemy包构建数据库链接2、用DBAPI构建数据库链接 四、容易遇到的问题 一、read_sql() 功能 将 SQL 查询/数据库表读入 DataFrame。 语法 读取数据库&#xff08;通过SQL语句或表名&#xff09; pand…

【书生大模型实战营(暑假场)闯关材料】基础岛:第4关 InternLM + LlamaIndex RAG 实践

基础任务 (完成此任务即完成闯关) 任务要求&#xff1a; 基于 LlamaIndex 构建自己的 RAG 知识库&#xff0c;寻找一个问题 A 在使用 LlamaIndex之前InternLM2-Chat-1.8B模型不会回答&#xff0c;借助 LlamaIndex 后 InternLM2-Chat-1.8B模型具备回答 A 的能力&#xff0c;截图…

SQL-约束篇

在数据库设计中&#xff0c;约束是确保数据完整性和准确性的关键元素。约束可以限制表中数据的类型、范围和关系&#xff0c;从而维护数据的一致性和可靠性。 1. 主键约束 (Primary Key) 主键约束用于唯一标识表中的每一行数据。一个表只能有一个主键&#xff0c;主键字段的值…

计算机毕业设计SpringBoot-VUE-python-nodeJS铁路列车安全管理-评估报告-铁路局-客运-货运-行车-站段-天气情况

1 引言 1.1 项目开发的背景 我国的普铁历史悠久&#xff0c;从19世纪至今已有百来年的历史。新中国以来&#xff0c;铁路的发展速度令人惊叹。但随着发展速度的增快&#xff0c;与之不对应的则是运营安全管理系统的落后。但这些来&#xff0c;我国铁路对于安全的重视程度已经…