整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

钓鱼骗局:通过伪造App Store支付链接误导用户

络犯罪目前又将目标指向苹果用户,他们通过更加成熟的钓鱼手法,引导用户点击一个支付退款链接,由此获取用户个人敏感数据。

钓鱼的前期-引导用户进入“陷阱”

这种新的钓鱼攻击被伪装为Apple store 的退款邮件。一切,是从一封退款邮件开始。首先,用户将会收到一封邮件,通知用户,该用户ID正在进行支付交易,询问是否确认购买邮件中出现的产品,若是不购买的话,便需要用户点击邮件中提供的链接。接下来,才是此次钓鱼攻击的目的。

据 Malwarebytes分析,这封邮件的真正目的在于获取用户的AppleID和密码,同时收集有用的个人及银行信息。

其实,大部分用户可以较为容易地识破这种钓鱼攻击,因为用户根本就没买什么产品。然而有些用户可能缺乏一定的安全意识,他们往往认为既然我都没购买产品,那理所应当地需要退款,所以逐步陷入钓鱼攻击设计者的陷阱里。这正是钓鱼设计者所想要达到的效果,让用户在匆忙之间,并没有冷静思考其中细节,而匆匆点击了链接。

如果,我们点击了链接会发生什么呢?

首先,你会被引导到一个受感染的 T-shirt 网站(或其他产品的网站),同时出现一个伪造的登录页面。

据分析,目前该钓鱼网址大多数是以下网址:

aut0carhire,com/index/user12-appleid/index.HTML

接着,用户将会被要求输入你的Apple ID及密码,然后下一步将会要求你填写你的姓名,地址,生日及银行账户等信息。

最后,在页面上会出现一个“取消交易”按钮,点击之后的结果是,页面会在用户不知情的情况下,将输入的信息存储并发送到服务端。

安全建议

如果不小心完成了上述操作,请及时和相应银行联系,暂时挂失该银行卡,同时关注银行账户的交易情况。

平时接受邮件时,应当注意:

1、不要打开任何可疑的或者未知的邮件;

2、不要下载未知发送者的附件;

3、不要点击未知邮件中的任意链接。

信还在用4s的朋友应该还有很多吧,最近在问答里面回答了一个“8G的4s目前还有什么用”,我的回答是降级到6.1.3当备用机,怀旧经典。有朋友问怎么降级,还有朋友说很多软件无法适配…今天就来说一下如何下载旧版的app。

以下内容为转载,较久之前小编测试过,有用!现在贴出来分享给大家,希望能帮到大家(ps:教程为mac版本,win版软件类似,大家可以自行尝试。)

准备工作

你所需要的东西非常简单:

* iTunes (什么?你没有?)* Charles Proxy (点击下载)

你下载的 Charles Proxy 为30天试用版本,安装后你将看到如下界面,这是一个10秒的等待系统告诉你你正在使用使试用版本。

另外,边看视频教程边操作可能会更简单更节约时间。

Youtube: https://www.youtube.com/watch?v=XVejjUG9xUo

优酷: http://v.youku.com/v_show/id_XMTgxNTMxMTY0NA==.html

接下来你会收到这样的提示:

请点击 Grant Privilege 并输入管理员密码,这将自动为系统配置代理设置以启用 Charles 服务。

你便可以看到左边开始滚动显示你的网络流量了,先不管它。Charles Proxy 使用Men in the Middle (MitM) 来监视你的HTTPS协议,因此它需要证书。如果你配置过Surge MitM 那你已经很熟悉了,接下来我们需要先处理证书的问题:

注意 这步非常重要 如果你使用 iTunes 12 或以上版本 此步失败将导致 iTunes 不验证 SSL 服务器身份阻止你下载

Windows 通过证书方法请参照英语官网方法https://www.charlesproxy.com/documentation/using-charles/ssl-certificates/

在你的顶部 Bar 中找到 Help,SSL Proxying,点击「Install Charles Root CA」(图中「I这里」的位置),这将自动打开 macOS 钥匙串访问,你需要再次输入管理员密码。

双击打开(你的电脑上可能会有红色 X 图标)

将第一项「使用此证书时」改成始终信任,后面的会自动修改,然后关闭小窗口,并再次输入管理员密码保存。

接下来请退出 Charles,我们稍后再打开它来处理。

开始下载

打开 iTunes,在 App Store 中找到你所想要降级的 App,这里以 LoveLive! 学园偶像祭举例。

找到这个界面了吗?很好,现在我们重新打开 Charles,等待10s进入界面之后,点击 iTunes上的下载。

当你看到左边有「p数字-buy.itunes.apple.com」的时候,请前往 iTunes 取消下载,因为你实际上并不需要下载它。

右键点击「p数字-buy.itunes.apple.com」,找到「Enable SSL Proxying」并点击。然后回到 iTunes 刷新界面(可以重新搜索,也可以直接 Cmd+R)再次点击下载,然后再次取消。(听起来很奇怪不是吗,不过没有问题)

你惊奇地发现刚才的地址可以展开了,而且可以找到一个叫做 buyProduct 的东西,我们点开它。

在右边两个 XML 中,下边的那个里面找到比较底部的含有一大堆数字的项目「softwareVersionExternalIdentifiers」,这就是每个版本所对应的版本 ID。从小到大为从最旧的版本到最新的版本,也就是说这个App最新版本的ID是「818014617」,1.0版本是「401463784」。

如果你要下载它最早的版本,那么直接使用第一个 Integer 就可以了。但是如果要下载中间的一个版本怎么办呢?你可能需要对照App更新列表来找到你要的版本,并且不断尝试……此问题也困扰了我很久。

好的,现在我们找到了版本 ID,以 1.0 即 401463784 举例。现在我们再次右键「p数字-buy.itunes.apple.com」,在刚刚Enable SSL Proxying 的下方找到 Breakpoint:断点并勾选它。再次返回iTunes刷新并再次点击下载。

Duang!Charles 突然弹了出来!因为你刚刚设置了断点,iTunes 再次请求的时候 Charles 给了你一个暂停时间的功能,这个时候下面的 Cancel 就是忽略,Abort 就是阻止,Execute 就是执行。如果我点击 Abort,你会发现 iTunes 弹出窗口显示下载未完成,未知错误。那是因为你拒绝了它的 buyProduct 下载。

闲话不多说,我们选择顶上「Overview」旁边的「Edit Request」,并在 Cancel Abort 和 Execute 的上方选择 XML Text。

顶部有一个叫做 appExtVrsID 的项目,将它的值直接修改成我们需要的版本 401463784。然后点击底下的 Execute。接下来还会有几次弹窗,不需要做任何操作,直接 Execute 即可。

恭喜!这次下载的版本就是你所需要的老版本。下载完毕后可能还会有几次 Breakpoint,直接 Execute 即可,然后便可以关闭 Charles(如果你之前就关闭了 Charles,不影响)连接上你的 iPhone, iPad 或 iPod touch 将其同步进入设备即可。

脚注:其实并不一定需要用 Charles,任何支持修改 POST 请求 HTTPS 的代理工具,方法肯定也是大同小异的。像 Surge 貌似是只能捕获请求并不能编辑,就不太能完成这个操作。无论如何 Charles 只是其中一种选择。

Enjoy!

(不要尝试了 QQ 1.0 在我们现有的设备上都打不开)

*2016.11.14 更新:感谢各位支持,最近思考了一下能不能直接在 iOS 上完成这个操作,而不需要通过 iTunes 同步,因为本身 Charles 支持接管 iOS 流量,和 Surge 也是很类似的。但是很遗憾,由于 iTunes Store 类软件在 iOS 上用了特殊网络加密,不会由于系统信任证书来信任 Charles 的伪造中间人,而 Surge 采用了 TUN 原理所以强制成功。对于 Charles 的 SSL Proxy 其他 iOS 上的 App 都可以,说明 Apple 别有用意保证用户 App Store 安全。故大家还是需要麻烦一点通过 iTunes 来做这个操作。

web开发中,如果你想让用户下载或者导出一个文件,应该怎么做呢?
传统的做法是在后端存储或者即时生成一个文件来提供下载功能,这样的优势是可以做权限控制、数据二次处理,但缺点是需要额外发起请求、增大服务端压力、下载速度慢。

但随着HTML5的标准发布,我们已经能够做到只前端来下载各种文件了。

我自己是一名从事了多年开发的web前端老程序员,目前辞职在做自己的web前端私人定制课程,今年年初我花了一个月整理了一份最适合2019年学习的web前端学习干货,各种框架都有整理,送给每一位前端小伙伴,想要获取的可以关注我的头条号并在后台私信我:前端,即可免费获取。

后端响应式下载

在常规的HTTP应答中,Content-Disposition 消息头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。

在HTTP场景中,第一个参数或者是inline(默认值,表示回复中的消息体会以页面的一部分或者整个页面的形式展示),或者是attachment(意味着消息体应该被下载到本地;大多数浏览器会呈现一个“保存为”的对话框,将filename的值预填为下载后的文件名)。

我们在后端响应头中只要设置该头部信息,即可下载为文件,而不是请求并展示:

Content-Type: text/html; charset=utf-8

Content-Disposition: attachment; filename="cool.html"

但需要注意的是,如果想要用这种方式下载文件,不能使用AJAX的方式,而是应该新建一个<a>标签,模拟点击下载。原因为处于安全性考虑,JavaScript无法与磁盘进行交互,因此AJAX得到的内容将被保留在内存中,而不是磁盘上。

Nginx添加header头下载

location ~ \.(jpg|jpeg|png|bmp|ico|gif|swf)$ {

add_header Content-Disposition 'attachment; filename="cool.html"';

}

和后端一样的原理,只不过头部信息通过Nginx统一添加。

前端下载:<a>标签的download属性

此属性指示浏览器下载URL而不是导航到它,因此将提示用户将其保存为本地文件。如果属性有一个值,那么它将作为下载的文件名使用。此属性对允许的值没有限制,但是/和\会被转换为下划线。

  1. 此属性仅适用于同源 URLs。
  2. 尽管HTTP URL需要位于同一源中,但是可以使用 blob: URLs 和 data: URLs ,以方便用户下载 JavaScript 方式生成的内容(例如使用在线绘图的Web应用创建的照片)。

常规的<a>标签,用于链接的跳转,如新的页面,那么如果我们给<a>标签加上download属性,就能很简单的让用户保存新的html页面。

<a download="PHP实现并发请求.html" href="https://segmentfault.com/a/1190000016343861">PHP实现并发请求</a>

生成并下载字符串文件

首先我们需要了解一个特殊的数据格式:Blob。

Blob数据

Blob(Binary Large Object,二进制类型的大对象),表示一个不可变的原始数据的类文件对象,我们上传文件时常用的File对象就继承于Blob,并进行了扩展用于支持用户系统上的文件。

我们只能通过Blob()构造函数来创建一个新的Blob对象:

Blob(blobParts[, options])

// 创建一个json类型的Blob对象,支持传入同类型数据的一个数组

var debug = {hello: "world"};

var blob = new Blob([JSON.stringify(debug, null, 2)],

{type : 'application/json'});

// 此时blob的值

// Blob(22) {size: 22, type: 'application/json'}

Blob对象存在两个只读属性:

size: Blob 对象中所包含数据的大小(字节)。
type: 一个字符串,表明该Blob对象所包含数据的MIME类型。如果类型未知,则该值为空字符串。

URL对象和下载字符串文件

URL 接口是一个用来创建 URLs 的对象,包含两个静态方法:

objectURL = URL.createObjectURL(blob)

创建一个 URL(DOMString),包含一个唯一的blob链接(该链接协议为以blob:,后跟唯一标识浏览器中的对象的掩码)。这个 URL 的生命周期和创建它的窗口中的 document 绑定。

URL.revokeObjectURL(objectURL)

销毁之前使用URL.createObjectURL()方法创建的URL实例。浏览器会在文档退出的时候自动释放它们,但是为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。

var url = URL.createObjectURL(blob);

// 此时url的值,跟document绑定,所以每个页面创建的字符串均不同

// blob:https://developer.mozilla.org/defe53c2-2882-43c6-b275-db2a57959789

此时,我们在页面中创建一个新<a>标签,点击即可下载我们想要的文件:

<a href="blob:https://developer.mozilla.org/58702010-433d-4097-990f-e483d84cd02a" download="file.json">下载文件链接</a>

FileReader读取Blob数据

想要读取Blob数据的唯一方法是FileReader。

FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。

其中File对象可以是来自用户在一个<input>元素上选择文件后返回的FileList对象,也可以来自拖放操作生成的 DataTransfer对象,还可以是来自在一个HTMLCanvasElement上执行mozGetAsFile()方法后返回结果。

该对象包含3个属性:

FileReader.error

一个DOMException,表示在读取文件时发生的错误 。

FileReader.readyState

表示FileReader状态的数字。取值如下:

常量名 值 描述

EMPTY 0 还没有加载任何数据.

LOADING 1 数据正在被加载.

DONE 2 已完成全部的读取请求.

FileReader.result

文件的内容。该属性仅在读取操作完成后才有效,数据的格式取决于使用哪个方法来启动读取操作。

包含6个事件处理:onabort,onerror,onload,onloadstart,onloadend,onprogress,这些不再详细说明,因为 FileReader 继承自EventTarget,所以所有这些事件也可以通过addEventListener方法使用。

包含5个方法:

FileReader.abort()

中止读取操作。在返回时,readyState属性为DONE。

FileReader.readAsArrayBuffer()

开始读取指定的 Blob中的内容, 一旦完成, result 属性中保存的将是被读取文件的 ArrayBuffer 数据对象.

FileReader.readAsBinaryString()

开始读取指定的Blob中的内容。一旦完成,result属性中将包含所读取文件的原始二进制数据。

FileReader.readAsDataURL()

开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容。

FileReader.readAsText()

开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个字符串以表示所读取的文件内容。

因此我们可以直接读取Blob对象的数据:

var reader = new FileReader();

reader.addEventListener("loadend", function() {

console.log(reader.result);

});

reader.readAsDataURL(blob);

// 此时result的值

// data:application/json;base64,ewogICJoZWxsbyI6ICJ3b3JsZCIKfQ==

reader.readAsText(blob);

// 此时result的值

// {

// "hello": "world"

// }

下载图片

除了下载手动生成的字符串或对象,我们还能提供下载图片的功能,一方面能用于支持Canvas绘图的保存功能,一方面能提供批量下载图片等高级功能。

除了浏览器自带的右键保存,我们还可以这么做来下载图片:

// 通过src获取图片的blob对象

function getImageBlob(url, cb) {

var xhr = new XMLHttpRequest();

xhr.open("get", url, true);

xhr.responseType = "blob";

xhr.onload = function() {

if (this.status == 200) {

cb(this.response);

}

};

xhr.send();

}

let reader = new FileReader();

reader.addEventListener("loadend", function() {

console.log(reader.result);

});

getImageBlob('https://cdn.segmentfault.com/v-5c4ec07f/global/img/user-64.png', function(blob){

// 读取来看下下载的内容

reader.readAsDataURL(blob);

// 最终生成的字符串

// data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAA...

// 生成下载用的URL对象

let url = URL.createObjectURL(blob);

// 生成一个a标签,并模拟点击,即可下载,批量下载同理

let aDom = aDom = document.createElement('a');

aDom.href = url;

aDom.download = 'download.json';

aDom.text = '下载文件';

document.getElementsByTagName('body')[0].appendChild(aDom);

aDom.click();

});

下载excel文件等

如果你明白了下载的原理,那么所有的内容都能够理解,只不过是转换成对应的格式而已,当然,复杂格式的文档不需要你自己去配置,可以引入第三方库,在excel文档方面我选择用 tableExport库(https://tableexport.v5.travismclarke.com/#javascript):

// 引入CDN文件

'https://cdn.bootcss.com/xlsx/0.14.1/xlsx.core.min.js',

'https://cdn.bootcss.com/FileSaver.js/2014-11-29/FileSaver.min.js',

'https://cdn.bootcss.com/TableExport/5.2.0/js/tableexport.min.js'

// 绑定下载事件,这个是我自己的场景下代码,可能不适合大家,具体的参考官方文档

const tableDom = $('#table');

$('.table-exportBtn', tableDom).on('click', function () {

const tableExport = tableDom.tableExport({

formats: ['xlsx', 'txt'],

filename: '表格下载',

exportButtons: false

});

const type = $(this).data().type;

const exportData = tableExport.getExportData()[tableDom[0].id][type];

const {data, mimeType, filename, fileExtension, merges, RTL, sheetname} = exportData;

// 源码里才能看到完整参数,官方文档没有写全,导致下载的文件格式错误

tableExport.export2file(data, mimeType, filename, fileExtension, merges, RTL, sheetname);

});

默认的方法会自动生成下载按钮,但如果你想自定义下载功能,参考 exportButtons: false 设置(https://tableexport.v3.travismclarke.com/examples/exportButtons.html) 一节,但这个文档有问题,export2file参数不完整,导致下载的xlsx文件一直格式错误,通过查看源码,需要写全参数才可以,上面的示例里已经写出。

tableExport库源码

我们可以看下tableExport导出文件的核心代码,其导出为excel格式比较复杂,由xlsx.core.min.js来完成:

/**

* Exports and downloads the file

* @memberof TableExport.prototype

* @param data {String}

* @param mime {String} mime type

* @param name {String} filename

* @param extension {String} file extension

* @param merges {Object[]}

* @param RTL {Boolean}

*/

export2file: function(data, mime, name, extension, merges, RTL, sheetname) {

var format = extension.slice(1);

data = this.getRawData(data, extension, name, merges, RTL, sheetname);

if (_isMobile && (format === _FORMAT.CSV || format === _FORMAT.TXT)) {

// 拼凑指定格式的data:类型 URI

var dataURI = "data:" + mime + ";" + this.charset + "," + data;

this.downloadDataURI(dataURI, name, extension);

} else {

// TODO: error and fallback when `saveAs` not available

saveAs(new Blob([data], { type: mime + ";" + this.charset }), name + extension, true);

}

},

// 先创建<a>标签,然后提供href和download属性,并模拟点击

downloadDataURI: function(dataURI, name, extension) {

var encodedUri = encodeURI(dataURI);

var link = document.createElement("a");

link.setAttribute("href", encodedUri);

link.setAttribute("download", name + extension);

document.body.appendChild(link);

link.click();

},

xlsx文件导出导出

还没有仔细研究,感兴趣的可以查看其js-xlsx Github项目(https://github.com/SheetJS/js-xlsx/blob/master/README.md)

第三方库

上面我们主要讲了下载背后的原理,你可以自己封装,也可以使用现成的第三方库,如 download.js(https://github.com/rndme/download) ,这个能提供大部分常用数据的下载;但如果你是要下载表格数据为excel格式,还是推荐 tableExport.js(https://tableexport.v5.travismclarke.com/#javascript) 及其依赖组件。

参考资料

  1. MDN-a: (https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/a)
  2. MDN-blob: (https://developer.mozilla.org/zh-CN/docs/Web/API/Blob)
  3. 掘金-细说Web API中的Blob:(https://juejin.im/post/59e35d0e6fb9a045030f1f35)
  4. MDN-URL: (https://developer.mozilla.org/zh-CN/docs/Web/API/URL)
  5. MDN-FileReader: (https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader)
  6. 博客园-js 获取图片url的Blob值并预览:(https://www.cnblogs.com/tujia/p/6483255.html)
  7. tableExport文档:(https://tableexport.v5.travismclarke.com/#javascript)
  8. 感谢 @Oliveryoung 提供的其他解决方案
  9. MDN-Content-Disposition: (https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Disposition)
  10. Ajax请求无法下载文件的原因: (https://blog.csdn.net/w405722907/article/details/77366843)
  11. Github-download.js:(https://github.com/rndme/download)

作者:赵帅强

https://segmentfault.com/a/1190000018143902