网页安全学习笔记

182 阅读5分钟

注入攻击:XSS其实就是一种典型的注入攻击

  • 数据和代码混在一起就存在“潜在注入风险”,用户需要将自己的数据提供给网站
  • 用户的输入嵌入代码里就可能有注入漏洞
  • 永远不能相信用户的输入,需要做相应的判断

SQL

  • 不同数据库类型,对比不同的注入语法以及有些数据库特殊的绕过技巧
  • select * from table where x=x, like, ... (查找数据库用户的隐私信息)
  • update table set x=x where x=x...# 破坏性攻击
  • delete...# 破坏性攻击
  • XSS针对网站的其他用户,SQL注入的攻击是针对网站提供者(也就是服务器端)的

SQL注入

永远不要相信用户的输入
Please go to row 2, shelf 3 and fetch __.
Please go to row 2, shelf 3 and fetch an apple. (没有限制输入内容)
Please go to row 2, shelf 3 and fetch an apple. Then XXX.(没有限制输入长度,则可以做别的动作)

  • 最简单的例子
    • 根据用户提供的id去查找用户名
      SELECT secret FROM users WHERE id='"+msg+"';"

image.png

  • 如果在一个网页中可以通过输入id = '来形成一个SELECT secret FROM users WHERE id = ''';的SQL查询语句,则说明这个网页是存在SQL注入漏洞的,因为输入的东西并没有被转义
    • 因为原来的id(判断条件)是由两个'包含起来的:WHERE id='" + msg + "';",则可以手动地添加额外的'来使得原来的条件闭合,从而达到添加多个条件的效果
      • 例如: 令msg="' or 1=1"则可以实现 "SELECT secret FROM users WHERE id='' or 1=1';"的SQL查询语句,从而很可能直接获得整张表的数据
      • 语句末尾的 1=1'; 这个'没有闭合,其实也是一个语法错误,但是可以处理掉
      • 可以将其改变为注释形式: "WHERE id='' or 1=1;#';",或"WHERE id = '' or 1=1 --';" 该形式更常用 (不同的数据库注释格式不一样)
      • 有的数据库不允许注释,也就是该语句需要依赖后面的条件语句,不能在语句中插入注释,此时需要使用别的方法
      插入`"' or 1=1 or 1='"`使得原来的语句
      
      "SELECT secret FROM users WHERE id='' or 1=1 or 1='';"
      //后面跟别的条件
      //这里只要保证了其中的1=1成立,则整个判断都会为true,因为是用or连接的
      

跳过口令验证

    where username = '{}' and passwd = '{}'
    
    //方法一:
    //"--"会把后面的语句全部注释掉,则该判断语句变成了永真,所以可以绕过口令验证
    //注释掉密码验证
    where username = '' or 1=1 --' and passwd = '{}'
    
    //方法二:
    //使密码验证永远通过
    where username = 'root' and passwd = '' or 1=1 --'//这里使得密码验证永远正确
    

堆叠查询

  • 使用分号;可以结束掉一个SQL语句同时开始一个新的SQL语句
  • 可以进行破坏性攻击,可以根据已知信息配合其他注入手法,比如时间盲注
    In: ff("';--")//先使用分号";"看一下能不能把原先的语句正常闭合掉
    Out: "SELECT secret FROM users WHERE id='';--';" // --会把后面的语句注释掉
    
    //这里可以写一个全新的SQL语句插在分号后面
    In: ff("';SELECT flag FROM users2;--")
    Out: "SELECT secret FROM users WHERE id=''; SELECT flag FROM users2;==';"
    
    //攻击不全是偷取信息,也可能是破坏,想要让网站崩溃
    In: ff("';DROP;--")
    In: ff("';DELETE;--")
    

UNION

  • 最常用的,可以把多个查询拼在一起,最终获取到想要获得的数据
  • UNION规则:
    • 按照要求查找id: select id from users;
    • 如果WHERE后可以自定义,则可以select id from user where 1=1 union select 'example',这样结果就会出现example
    • select id from user where 1=1 union select weight from user_ext就可以获取到其他表(user_ext)的信息,一般情况下要找的信息都存储在别的表里
    • 注意: UNION连接需要列数相同,所以可能要做一个暴力破解:
      • ' UNION SELECT 1--': 先用此语句做尝试,查看是不是1列,如果列数不一样,就会报错
      • ' UNION SELECT 1,2--': 查看是不是两列
      • ' UNION SELECT 1,2,3--': 查看是不是三列
    • 页面回显的数字对应泄漏信息的位置

攻击流程

首先要判断是否存在SQL输入:先输入一个'查看是否报错,如果报错了,则很有可能有漏洞;如果没报错,则可以继续尝试 ' or 1=1
接下来的流程:

  1. 判断列数, select 1,2,3...可以查到有多少列
  2. 检查哪些列是可显示字符串的,有的列可能被隐藏,不会显示到页面上去
  3. 找到数据库名,information_schema.schemata schema_name, 当前数据库database()
  4. 找到表名: information_schema.tables where TABLE_SCHEMA = {database}
  5. 找到列名: information_schema.columns where table_name = {table} and TABLE_SCHEMA = {database}
  6. 查找所需内容: select {columns} from {database.table}
    在盲注情况下,2-5都需要暴力破解

通配符攻击

  • 提供模糊查询的服务,用了like,过滤了注入,但是可以通过填通配符进去

盲注

文件包含(LFI)

  • 文件包含用于重用文件,如果包含的文件可控,可以在当前文件中加载指定文件(并解释执行),容易造成信息泄漏,配合其他操作也可以执行恶意代码
  • 当PHP包含一个文件时,会将该文件当作PHP代码执行,而不会在意文件是什么类型
    • 直接包含文件
    • PHP伪协议Only file:// and php:// will be used in examinable tasks(may be in the exam/ assignments)
      • file:// 访问文件,用绝对路径去读
      • php://filter 编码访问,比如base64 php://filter/read=convert.base64-encode/resource=file://...可以得到源码、避免执行
  • 截断:
    • %00 截断
    • 路径长度截断
  • 文件包含分类:
    • LFI:包含服务器上的文件
      • 敏感文件泄漏
      • 配合文件上传拿shell
    • RFI:远程文件,需要服务器配置允许
      • 包含webshell
  • 防护措施:
    • 检查输入、WAF、基本所有漏洞相关的防护都要做
    • 只包含信任来源文件(白名单)