薄纱全网 史上最全SQL注入漏洞总结

注入漏洞在十大Web安全漏洞之中,其主要原因是对用户的输入过滤不严,导致程序以危险的方式运行,注入漏洞应用最广泛,杀伤力也很大如最常见的sql注入,命令注入,还有代码注入、xss等。

SQL注入:最常见的Web漏洞之一,作用对象在数据库中,程序没有对用户输入数据的合法性进行验证和过滤,导致sql查询语句被恶意拼接,sql注入漏洞存在的条件:参数用户可控、参数可以动态拼接sql语句并带入数据库查询、参数过滤不严。

注入攻击:SQl注入根据注入效果可以分为:UNION联合注入、报错注入、布尔盲注、时间盲注、堆叠注入、二次注入等,按照提交方式可以分为:GET注入、POST注入、HTTP头注入,以及其他分类。

UNION联合注入:联合注入的前提条件是用户可控参数所在Sql语句为查询语句,且以页面存在回显,如:select * from users where id=”$id”;。此时可以通过更改参数id来实现对数据库的操作。考虑到前提是查询双方具有相同的列,可以使用order by 语句大致判断列数,也可以使用select 1,2,3,4等依次查看。UNION联合注入往往是最实用的,因为判断了回显位后就可以拼接语句union select version()等获取数据库信息,当然如果权限允许也可以在information_schema中查看全部数据库信息。在查询过程中可能会遇到查询结果有多个数据,但页面只显示一段,可以使用concat()、group_concat()等函数。

布尔盲注:与UNION联合注入不同,布尔盲注用于页面无回显信息,但不同的语句会有不同的效果,如:id=1,页面显示登入成功,但当输入id=0(前提是数据库中没有id=0)时,页面显示登入失败或什么都不显示,此时就可以用布尔盲注来判断语句的真假。如id=0’ or length(database())>4 --+ 可以判断数据库的名称的长度,有了长度后就可以逐字符判断,如:id=0’ or substring(database(),1,1)=’s’--+表示判断从数据库名第一个字符开始截取一个字符判断是否是字符s。也可以构造一些特殊语句如:id=0’ord(substring(database(),1,1))=65 --+ ord函数可以将字符转换成ascii码,就可以将65设为变量,使用字典爆破的方法逐一判断,也可以直接爆破数据库名和其他表名、字段名等等。

时间盲注:时间盲注用于当输入不同的语句后页面效果一样的情况,时间盲注多与if(),sleep()函数使用,if(1=1,sleep(1),1)表明如果1=1,Sql查询休眠1秒,否则返回1,可以通过页面响应时间判断语句的正确。其他语句的拼接与布尔盲注一样。

报错注入:报错注入可用于Sql语句执行错误后页面会显示错误信息的情况,报错注入的前提条件是后端脚本中有mysql_error等报错函数。常见的报错方法有extractvalue()函数、updatexml()函数、floor型报错、整数溢出报错、几何函数报错等。在Mysql5.1.5版本以上,可以使用XPATH报错(extractvalue函数、updatexml函数),这两个函数用与查询修改xml文档,extractvalue()函数的使用extractvalue(xml文档,文档路径),文档路径的格式是/xx/xx/xx,若格式错误,会显示错误路径。如:id=0’or (select extractvalue(1,concat(‘!’,database()))) --+会显示(!数据库名)路径错误。floor型注入一般要与rand函数、group by一起使用。group by用于给查询数据分组,分组依据为by后面的语句,先创建虚拟表,然后在查询数据时,从数据库中取出数据,看在虚拟表中是否有同样的记录, 如果有,就在相应字段加一,如果没有就直接插入新记录。rand函数用于生成随机数,rand(0)表明生成一个0-1的随机数,但rand()确实是随机数,rand(0)生成的是有规律的随机数,floor函数用于向下取整,所以floor(rand(0)*2)只返回0或1,且为011011011…。查询中如果使用rand()的话,该值会被计算多次,也就是在使用group by 的时候,floor(rand(0)*2)会被执行一次,如果虚拟表中不存在记录,把数据插入虚拟表中时会再被执行一次。分析语句:select count(*) group by floor(rand(0)*2),查询前会建立虚拟表,取第一条记录,执行floor(rand(0*)2),发现结果是0(第一次计算),查询虚拟表,发现0的键值不存在,就会往虚拟表插入新的数据,则floor(rand(0)2)会被再计算一遍,结果为1(第二次计算),插入虚拟表,这时第一条记录查询完毕,查询第二条记录,再次计算floor(rand(0)*2),发现结果为1(第三次计算),查询虚拟表,发现1的键值存在(上图),所以floor(rand(0)*2)不会被计算第二次,直接count(*)+1,第二条记录查询完毕,查询第三条记录,再次计算floor(rand(0)2),发现结果为0(第四次计算),查询虚拟表,发现0的键值不存在,则虚拟表尝试插入一条新的数据,在插入数据时floor(rand(0)2)被再次计算,结果为1(第五次计算),然而1这个主键已经存在于虚拟表中,而新计算的值也为1(应为主键键值必须唯一),所以插入时直接报错了,于是在注入时就可以构造语句0' or (select count(*)  from users group by concat(database(),floor(rand(0)*2)))--+爆出数据库信息。在版本号为5.5.47和5.7.17之间,Mysql有一些几何函数如geometrycollection(),multipoint(),polygon(),multipolygon(),linestring(),multilinestring(),这些函数对参数要求是形如(1 2,3 3,2 2 1)这样几何数据,如果不满足要求,则会报错,就可以构造语句:id = 1 and GeometryCollection((select from (select from(select database())a)b))获取数据库信息。根据官方文档说明,只有版本号大于5.5时整数溢出才会报错,在注入过程中不可能输入这么大的数,一般采用按位取反如:~0就表示最大整数值,~0+1就会产生报错信息。Sql语句执行成功的返回值为0,进行逻辑非运算后为1,这个值是可以参与运算的,我们就可以构造语句:id=0’or  (select(~0+!(select * from (select database())a))) --+,此方式只适用于Mysql版本号小于5.5.53。整数溢出报错的另一种方式是利用exp函数,exp函数返回e的指定次幂,利用语句:(select exp(~(select * from (select database())a))) --+同样可以完成整数溢出报错。

堆叠注入:在SQL语句中,;代表一个语句的结束,如果在注入过程中注入;+语句,就可以执行构造的语句,堆叠注入的危害巨大,用户可以构造任何合法语句,包括但不限与删除数据,但一般服务器都会限制一次只能执行一条SQl语句。

二次注入:二次注入一般用于可以注册信息的场景,其原理是后端代码对用户上传的参数做了过滤,但是未对从数据库传出的数据进行过滤。分析语句:$username=addslashes($_GET[‘username’]);insert into             users(‘username’,’password’) values $username,代码对username参数进行了过滤,也就是对‘进行了转义,如输入test’,实际SQL语句为test\‘,但如果从数据库中取出数据时未再次转义,就可以产生注入点。输入参数test’union select 1,2,version() --+,再从数据库中查询,语句变为:select * from user where username=’test’union select 1,2,version() --+’就可以获取数据库信息。

GET注入:提交数据的方式是 GET , 注入点的位置在 GET 参数部分,可以在url中看到参数名称,但url有长度限制,所以一般参数不能过长。

POST注入:使用 POST 方式提交数据,注入点位置在 POST 数据部分,多见于表单。

HTTP头注入:常见的HTTP头注入有COOKIE、HTTP_CLIENT_IP、HTTP_X_FORWARDED_FOR、HTTP_X_FORWARDED、HTTP_X_CLUSTER_CLIENT_IP、HTTP_FORWARDED_FOR、HTTP_FORWARDED、REMOTE_ADDR、User-agent、Referer。后端脚本从客户端发起的请求中获取cookie信息,并用于SQL语句中,如$_COOKIE函数。用burp suite抓包,修改cookie的值为1’union select 1,version(),3 --+,用于SQL语句中变为select * from user where id=’1’union select 1,version(),3 --+’,所以,从本质上来讲,Cookie注入与传统的SQL注入并无不同,两者都是针对数据库的注入,只是表现形式上略有不同罢了。HTTP_X_FORWARDED_FOR的注入也叫XFF注入,服务器端从HTTP_X_FORWARDED_FOR中获取参数(IP),并带入SQL语句中,可以通过burp suite抓包修改HTTP_X_FORWARDED_FOR头,构造目标SQL语句,其他的头注入也类似,关键在于后端脚本有无获取头信息并利用头信息的参数。

读写文件:SQL注入还可以通过读写文件来进行,但通常条件苛刻,要对目标主机的路径有所了解,否则就算写入了文件叶无法利用,同时也要有相应的权限来读写文件,否则就算能使用outfile、load_file(),也不能产生实质性效果。如果成功写入文件并且可以访问到,就可以写入webshell,并通过中国菜刀、webacoo等工具进行连接。

一些绕过方法:

大小写绕过:sql语句是不区分大小写的,一些老式的容器、waf等对大小写敏感,如union可以写成Union来绕过,现在基本没怎么老的版本,基本这种方法不可行。

双写绕过:有些waf是过滤危险字符,如把字符转换成空字符,这时就可以通过双写绕过,如uniunionon经过过滤之后变成union,但是好像除了靶场,基本没有会过滤危险字符的,一般都是直接拒绝访问。

编码绕过:可以通过对参数进行编码进行绕过,前提是后端代码有相应解码的功能。

注释绕过:一些waf没有对注释符进行判断,就可以通过注释来绕过,如:id=1 /*!union*/ /*!select*/,或者如union /*kuyed*/ select /*iuysv*/ 1。

宽字节绕过:当客户端与服务端的编码不一致时,有可能可以使用宽字节注入,比如php使用utf8,而mysql使用gbk编码,utf8使用一个字节表示英文,而gbk用两个字节,比如在‘/前面加上df就可以使df与/结合而绕过,通过url编码就变为%df。

Cookie绕过:一些程序员会通过$_REQUEST来获得参数,它会一次检测GET POST COOKIE是否有值,但有时程序只检测get或post的值,这时就可以通过cookie传参数来绕过。

使用其它函数:使用一些偏僻的waf不会检测的函数。

攻击防范:学习一种漏洞,除了学习如何利用,还要清楚的知道如何防范。

防范漏洞的第一个原则就是永远不能相信用户可控的数据,包括数据库中的数据,一些开发人员过于相信从数据库调出来的数据,始终要对数据进行严格的过滤,不要尝试“修复”数据,而应该拒绝有安全隐患的请求,因为人们总能想到绕过“修复”的方法。

参数化查询可以基本防范住sql注入漏洞,也叫预处理语句,传统的sql查询是使用字符串与用户参数动态拼接,PDO 语句可用的bind_param() 方法让你可以给预处理语句中出现的占位符绑定参数,并且接受基本的数据类型参数,基本杜绝了动态拼接恶意语句的可能,下面是一个代码示例。

严谨的代码也是防范注入的一大方向,一些程序员在前期调试的时候会在代码中加入报错函数,但在上线后却忘记删除,或者一些程序员根本没有意识到要删除,这将会给不怀好意的用户提供很多信息,如代码路径、字段名称、数据库版本等。还有一些是只验证数据当下用途(例如,展示或计算),却不考虑数据最终存储位置的数据库表字段的验证需求,可能字符串长度超过了数据库中的限制。

除了尽可能的防范漏洞利用的可能,我们也要尽最大可能降低漏洞被利用后的危害。最小化当前执行业务的用户的权限,可以设置一个拥有写数据权限的用户,和另一个只有读数据权限的用户,这种角色区分可以确保在 SQL 注入攻击目标为只读用户时,攻击者无法写数据或操纵表数据,这种生物隔离区划可以延伸到进一步限制访问权限,这样就可以将 SQL 注入攻击的影响最小化。

XSS注入:XSS有自己的漏洞划分,但它其实也是注入漏洞的一种。

注入攻击:攻击者向web页面(input表单、URL、留言版等位置)插入恶意JavaScript代码,导致管理员/用户访问时触发,从而达到攻击者的目的,XSS攻击可以分为常见的四类,反射型、储存型、DOM型、基于页面型。XSS常见的绕过有大小写、双写、编码、事件绕过等

XSS常用的触发事件:

onclick:点击元素时触发

onerror:图片音频等加载错误时触发

onmouseover:鼠标移动到元素时触发

onmouseout:移出元素时触发

XSS常用的触发标签:

<scirpt>alert("xss");</script>

<img src=1 οnmοuseοver="alert(1)">

<img src="x" οnerrοr=alert(1)>

<a href=javascript:alert('xss')>test</a>

<a href="" οnclick=alert('xss')>a</a>

<input οnfοcus="alert('xss');" autofocus>:自动触发

<iframe οnlοad=alert("xss");></iframe>

<iframe src=javascript:alert('xss')></iframe>

<svg οnlοad=alert(1)>

<details open οntοggle="alert('xss');">:自动触发

<select οnfοcus=alert(1) autofocus>:自动触发

<video><source οnerrοr="alert(1)">

<audio src=x οnerrοr=alert("xss");>

<textarea οnfοcus=alert("xss"); autofocus>:自动触发

一些绕过:

data:后接自定义流,data:text/html;base64, YWxlcnQoMSk=

大小写绕过:<SCript>alert();</SCript>

双写绕过:<scripScriptt> <imimgg src=>

空格绕过:有些时候会过滤空格,可以用换行符、制表符(TAB)、/来绕过

拼接绕过:要利用到eval,用于拼接字符串,<img src=1 οnerrοr=”a=aler,b=t(),eval(a+b)”>

注释、优先级绕过: <scri<!--test-->pt>alert("hello world!")</scri<!--test-->pt>,<title><img src=</title>><img src=x οnerrοr="alert(``xss``);">

编码绕过:unicode编码、base64编码、url编码、hex编码、八进制等

<img src=1 οnerrοr=&#108,&#101,&#114,&#116,&#40,&#34,&#120,&#115,&#115,&#34,&#41,&#59>

<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">

攻击防范:和sql注入一样,要对用户的参数进行严格过滤

一些比较简单的过滤有限制内容长度,还有比如php内置的函数htmlspecialchars()会把html预定义字符编码成html实体,如果把全部的字符都编码,该函数可以防止很大一部分的攻击。

在纯前端渲染中,浏览器先加载一个静态HTML,此HTML中不包含任何跟业务相关的数据。然后浏览器执行HTML中的JavaScript,JavaScript 通过 Ajax 加载业务数据,调用 DOM API 更新到页面上。在纯前端渲染中,我们会明确的告诉浏览器:下面要设置的内容是文本(.innerText),还是属性(.setAttribute),还是样式(.style)等等,浏览器就不会被轻易的被欺骗,执行预期外的代码了。

设置httponly也是防范XSS漏洞带来的危害的一种有效措施,禁止 JavaScript 读取某些敏感 Cookie,就算攻击者完成 XSS 注入后也无法窃取cookie。

命令注入漏洞(PHP):命令注入也是常见漏洞,Web有执行操作系统命令的业务,该漏洞的条件和sql注入相似,执行命令的函数的参数用户可控、后端对数据过滤不严格。

注入攻击:system、exec、shell_exec、passthru、popen、proc_popen等函数,如果函数中的参数用户可控,且过滤不严格,就有可能导致执行恶意命令,造成命令执行漏洞。

常见绕过:

Windows命令拼接符,$,$$,|,||

Linux拼接符

‘&’的作用是使命令在后台运行

()用于组合命令

;表示一个命令的结束,可以执行多条无关联的命令

命令执行的通配符?、*、[]

如cat /etc/passwd可以替换成cat /*tc/pa??wd,通配符也可以配合使用

Linux中未定义的变量为null,可以通过未定义的变量来绕过

如:cat$a /etc$a/passwd$a、cat /et$ac/pass$bwd等,但是经过测试,好像$a,$b这种有英文的在命令字母中间并不起作用,但是$1等可以绕过

‘命令’(反引号)、$(命令)也是命令执行的一种方式,它将结果保存到一个变量中,如echo $(pwd)

插入单双引号反斜杠绕过

变量组合

关键字被过滤的话,可以试着替换关键字,如cat可以替换成more、vi、vim、head等等

还可以考虑将代码分段写入文件中,再通过调用文件来执行命令,这种方法可以用于限制长度的情况

还可以利用编码绕过,如base64编码,16进制编码,8进制编码等

攻击防范:

对数据的合法性进行校验():比如IP地址,直接校验IP地址的格式看,如果是url域名,则从url域名中获取IP地址后,在进行IP格式校验,若获取失败或者校验失败,则认为数据非法。

使用白名单,限制参数的内容也是很有效的方法

给web服务器系统及使用的中间件及时打上安全补丁,同时将应用程序的权限降到最低

代码注入(PHP):php代码注入包含很多内容,文件包含、内置函数、动态函数、正则表达式等,代码注入的危害是巨大的,用户通过拼接参数影响php代码的执行,使服务器等处于危险之中。

注入攻击:

代码注入最显眼的就是文件包含了,其影响函数有include(),include_once(),require()等,include和require区别主要是,include在包含的过程中如果出现错误,会抛出一个警告,程序继续运行;而require函数出现错误的时候,会直接报错并退出程序的执行,如果不可信输入被允许来决定传输给这些函数的路径参数,它就可能影响被包含的文件,应该注意的是,被包含的文件不一定是一个真正的 PHP 文件,任何能够携带文字数据的被包含文件都有可能,文件包含也可以包含远程文件,高版本php默认关闭该功能。

Windows下一些默认隐私文件

Linux下的一些文件

本地文件中的session文件包含用户可以控制服务器中session文件的内容,除了可以查看内容还可以执行恶意代码,如

用户可以控制ctfs变量的值,如传入<?php phpinfo(); ?>,再通过文件包含漏洞访问到该文件,前提是要了解session文件的路径,就可以执行上述代码

文件包含的一些绕过:

本地文件包含中有这种后缀限制的可以通过00截断绕过,但是有php版本限制,同时也可以利用路径长度限制截断,也就是大量的././././之后的内容会被丢弃,点号也有长度限制,如果是远程文件包含,可以在url结尾加?#空格等字符过滤掉不需要的后缀

http(s)协议:也就是远程文件包含,需要allow_url_fopen和allow_url_include都开启

file协议:用于访问本地文件,php 涉及到文件以及协议的地方默认使用 file 协议,如果没有写出协议名或者协议不存在,都会被当成 file 协议来解析

ftp协议:跟http协议一样,只是换了个协议名,同样需要allow_url_fopen和allow_url_include都开启

zip协议:压缩流,可以访问压缩文件中的子文件,格式为zip://[压缩包绝对路径]#[压缩包内的子文件名],压缩包内的子文件名后缀可以更改,如换成图片的后缀名

data协议:使用方法data://text/plain;base64,xxxx(base64编码后的数据),需要allow_url_fopen和allow_url_include都开启

php协议:常见的有php://input,php://filter,filter可以对打开的数据流进行筛选和过滤,常用于查看源码,格式为php://filter/过滤器|过滤器/resource=待过滤的数据流,如base64编码过滤器为read=convert.base64-encode,php://input 可以访问请求的原始数据,配合文件包含漏洞可以将post请求体中的内容当做文件内容执行,从而实现任意代码执行,需要注意的是,当enctype=multipart/form-data时,php:/input将会无效,需要allow_url_include开启

php的一些函数把参数当做php代码执行的,eval(),assert(),preg_replace()等。eval函数可以将字符串当作代码来执行,assert与eval用法一样,正则函数preg_replace()中的e修饰符可以将截取的字符串作为代码来执行

call_user_func()函数把第一个参数作为回调函数

意思是$fun是一个函数,$para作为函数的参数,如果用户参数可控,则可以实现远程代码执行

php支持动态变量、函数,如$$a,$a($b),可以动态拼接变量

攻击防范:

对于代码注入,最主要的还是少使用危险函数,如果要使用,一定要严格过滤用户参数,还有preg_replace放弃使用/e修饰符

对于文件包含,除了要严格限制外来参数外,如/,.,..等字符,还有的防范措施是限制文件包含的路径,从源头将文件包含限制在一个相对安全的路径。

严格管控权限范围,或对服务器中的重要信息文件、隐私文件加密,就算有文件包含漏洞,攻击者也获取不到有用的信息。

尽量避免使用一些常见的路径名称。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 早晨,一切都像是在沉睡中苏醒,宁静而又美好。晨光透过窗户洒在床上,温柔地唤醒每一个沉睡的灵魂。轻柔的微风轻拂着脸颊,仿佛在为这新的一天送来祝福。 在这美好的早晨里,空气格外清新,每一次呼吸都让人感到无比清爽。鸟儿的歌声在耳边回响,似乎在为这新的一天奏响序曲,让人感到生命的无限美好。远处,一缕缕白色的薄雾缭绕在树林中,犹如一层薄纱,将大地渲染得更加迷人。 在这美好的早晨里,人们也开始忙碌起来。从厨房飘来的香味让人垂涎欲滴,一杯温热的咖啡或者茶,更是为新的一天注入了不少能量和希望。 在这样美好的早晨,一切都变得轻盈而又欢快,仿佛所有的困难都可以轻松地迎刃而解。这一天将是充满机会和惊喜的,让我们满怀期待地迎接这美好的早晨,开始新的一天的旅程。 ### 回答2: 早晨,当黎明的第一缕阳光透过窗帘洒进房间,睡梦中的世界渐渐苏醒。微风轻拂着窗外的树梢,窗前的鸟儿欢快地鸣叫着,仿佛在为这新的一天献上美妙的序曲。 慵懒地伸了个懒腰,感受到清晨的柔和温暖。缓缓地下床,脚步轻盈如细雨纷纷,步入厨房,咖啡的丝丝香气弥漫开来。温润的杯子中,冒着慵慵的白烟,带来一天开始前的舒爽和惬意。 推开窗子,阳光洒在窗台上,四周一片宁静。清晨的街道上,行人匆匆而过,远方的车辆轻声呼啸,让人忍不住想起一切忙碌的工作。但此刻,我却拥有这片宁静,享受着大自然的恩赐。 透过窗户,望着迷人的天空,云朵像绵羊一样舒展着身躯,一切都那么悠然而祥和。这时候,阳光如丝绸般柔软,洒进房间,让人感受到一丝温情。闻着清晨花朵的香气,感受着大地的苏醒,心情平静而宁谧,仿佛跟大自然融为一体。 早晨,不仅是大自然的醒来,也是自己内心的觉醒。静静地坐在窗边,看着窗外的风景,给了我一种静心思考和抒发情感的机会。早晨美好的不只是阳光,还有对新的一天充满希望的期待,对生活的热爱与憧憬。在这宁静而美好的早晨里,我会拥抱每一个新的开始,为每一次希望的发芽而感恩。 ### 回答3: 早晨,晨光透过窗户强劲而柔和地洒在房间里。微风拂过,空气中弥漫着一股新鲜和清新的味道。天空的颜色由深蓝渐渐转为浅蓝,美丽的太阳羞涩地露出了它的笑脸,带来了无限的温暖和希望。 一觉醒来,眼睛逐渐适应了这迷人而温暖的光线,心情也变得轻松而愉悦。飞鸟在天空中跃跃欲试,它们的鸣叫声清脆而悦耳。远处的小溪,水波粼粼,似乎与大自然的和谐音乐相呼应,仿佛所有的生命都在这美丽的早晨醒来。 身体和心灵逐渐变得活跃,思绪也变得清晰。早晨的阳光,温暖地洒向大地,照亮了一切。行走在宁静的道路上,呼吸新鲜的空气,感受绿叶和花朵散发出的芳香,仿佛能够听到大自然的呢喃和歌唱。 早晨,是一个全新的开始。阳光洗涤了昨夜的疲惫,带来了新的希望和动力。这是一个独特的时刻,我们可以思考今天的目标和计划,为自己树立起一个美好的开始,为未来种下希望的种子。 早晨的美好并不仅仅是自然景色的绚烂,更是一种心灵的洗礼和生命的喜悦。在这美好的时刻,内心变得平静和安宁,准备面对新的一天的挑战。早晨是一个充满生机和活力的时刻,让人感受到生命的宝贵和无限可能性。 在早晨,我们不仅仅是起床和开始新的一天,更是迎接生活中的美妙瞬间和无穷的幸福体验。早晨,是一种宝贵而美妙的礼物,让我们怀着感激的心情拥抱它,享受生活的意义和价值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是黑客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值