如何用eclipse做網(wǎng)站全媒體運營師報考條件
目錄
[WUSTCTF 2020]樸實無華
[FSCTF 2023]源碼!啟動!?
[LitCTF 2023]Flag點擊就送!?
相關(guān)知識點
1.intval 繞過
繞過的方式:
2.session偽造攻擊
[WUSTCTF 2020]樸實無華
1.進入頁面幾乎沒什么可用的信息,所以想到使用disearch掃描,發(fā)現(xiàn)robots.txt文件,這里也可以通過源代碼中聯(lián)想到robots文件
?2.訪問robots文件,發(fā)現(xiàn)一個php文件,訪問該php文件得到一個假的flag
3.再根據(jù)掃描的文件,發(fā)現(xiàn)有一個fl4g.php文件,訪問該文件,得到一長串php代碼
4.接下來就是進行代碼審計,首先是第一關(guān)卡
if (isset($_GET['num'])){$num = $_GET['num'];if(intval($num) < 2020 && intval($num + 1) > 2021){echo "我不經(jīng)意間看了看我的勞力士, 不是想看時間, 只是想不經(jīng)意間, 讓你知道我過得比你好.</br>";}else{die("金錢解決不了窮人的本質(zhì)問題");}
}else{die("去非洲吧");
}
這串代碼主要的作用是使用了
intval()
函數(shù),該函數(shù)用于獲取變量的整數(shù)值。它嘗試從給定的變量中獲取整數(shù)。接下來的if條件是一個邏輯與(&&)操作,它檢查兩個條件是否都為真?
注意:intval()這個函數(shù)是強制轉(zhuǎn)換為int類型。?
舉個例子:
<?php
echo '3e5' ;
?>
//結(jié)果為3e5
<?php
echo '3e5' + 1;
?>
//結(jié)果為300001
這是因為在第一個 echo
語句中,'3e5'
被視為字符串,因此會直接輸出其內(nèi)容 '3e5'
。而在第二個語句中,雖然 '3e5'
被當作字符串,但由于與數(shù)字相加,PHP 嘗試將其轉(zhuǎn)換為數(shù)字。在這種情況下,它將 '3e3'
解釋為科學記數(shù)法表示 3 乘以 10 的 5次方,即 300000,然后再加上 1,所以結(jié)果為 300001。
5.使用如上方法,繞過第一關(guān)?
6.接下來就是第二關(guān)
//level 2
if (isset($_GET['md5'])){$md5=$_GET['md5'];if ($md5==md5($md5))echo "想到這個CTFer拿到flag后, 感激涕零, 跑去東瀾岸, 找一家餐廳, 把廚師轟出去, 自己炒兩個拿手小菜, 倒一杯散裝白酒, 致富有道, 別學小暴.</br>";elsedie("我趕緊喊來我的酒肉朋友, 他打了個電話, 把他一家安排到了非洲");
}else{die("去非洲吧");
}
//這串代碼主要涉及到了弱比較
?補充:==弱類型比較中,字符'0e123'和字符'0e456'雖然是字符類型,但是因為==比較不比較數(shù)據(jù)類型,只比較值,而值就是科學計數(shù)法的表示格式,結(jié)果都是0,所以相等,返回true ===強類型比較中,字符'0e123'和字符'0e456'在比較數(shù)據(jù)類型的時候就被當作字符類型,而字符'0e123'和字符'0e456'當然不相等,所以返回false
7.接下來就是第三關(guān),這串代碼的關(guān)鍵就是過濾空格和cat,用其他的替換即可
代替cat: more、less、head、tail、sort、ca\t
代替空格:$IFS、${IFS}、$IFS$1、$IFS$9
//get flag
if (isset($_GET['get_flag'])){$get_flag = $_GET['get_flag'];if(!strstr($get_flag," ")) //strstr() 函數(shù)搜索字符串在另一字符串中是否存在,如果是,返回該字符串及剩余部分,否則返回 FALSE。
{$get_flag = str_ireplace("cat", "wctf2020", $get_flag);//str_replace() 函數(shù)替換字符串中的一些字符(區(qū)分大小寫)。這里的意思是將get_flag字符串中的"cat"替換成"wctf2020"echo "想到這里, 我充實而欣慰, 有錢人的快樂往往就是這么的樸實無華, 且枯燥.</br>";system($get_flag);}else{die("快到非洲了");}
}else{die("去非洲吧");
}
?資料參考:PHP strstr() 函數(shù) | 菜鳥教程
PHP str_replace() 函數(shù) | 菜鳥教程
8.按要求傳參,先傳個la看看,發(fā)現(xiàn)有回顯
9.繞過最后一個關(guān)卡,得到flag?
[FSCTF 2023]源碼!啟動!?
1.進入頁面,想到查看源代碼,發(fā)現(xiàn)禁用了右鍵,于是在更多工具中看源代碼,得到flag
[LitCTF 2023]Flag點擊就送!?
資料:【python】Flask之session使用_python flask session-CSDN博客
1.根據(jù)提示很容易想到要抓包,進入頁面,是如下的頁面
2.隨便輸入一個名字,出現(xiàn)以下頁面
3.點擊拿flag,出現(xiàn)以下回顯,只有管理員可以
4.接下來使用抓包工具,發(fā)現(xiàn)cookie中有session的值,并根據(jù)題目可知這個題可能是session偽裝漏洞
5. 打開kali,輸入以下命令進行加解密session的值
這里要使用到python腳本,如果載虛擬機中操作,還涉及到將腳本保存在虛擬機的文件中
#!/usr/bin/env python3
""" Flask Session Cookie Decoder/Encoder """
__author__ = 'Wilson Sumanang, Alexandre ZANNI'# standard imports
import sys
import zlib
from itsdangerous import base64_decode
import ast# Abstract Base Classes (PEP 3119)
if sys.version_info[0] < 3: # < 3.0raise Exception('Must be using at least Python 3')
elif sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4from abc import ABCMeta, abstractmethod
else: # > 3.4from abc import ABC, abstractmethod# Lib for argument parsing
import argparse# external Imports
from flask.sessions import SecureCookieSessionInterfaceclass MockApp(object):def __init__(self, secret_key):self.secret_key = secret_keyif sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4class FSCM(metaclass=ABCMeta):def encode(secret_key, session_cookie_structure):""" Encode a Flask session cookie """try:app = MockApp(secret_key)session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))si = SecureCookieSessionInterface()s = si.get_signing_serializer(app)return s.dumps(session_cookie_structure)except Exception as e:return "[Encoding error] {}".format(e)raise edef decode(session_cookie_value, secret_key=None):""" Decode a Flask cookie """try:if(secret_key==None):compressed = Falsepayload = session_cookie_valueif payload.startswith('.'):compressed = Truepayload = payload[1:]data = payload.split(".")[0]data = base64_decode(data)if compressed:data = zlib.decompress(data)return dataelse:app = MockApp(secret_key)si = SecureCookieSessionInterface()s = si.get_signing_serializer(app)return s.loads(session_cookie_value)except Exception as e:return "[Decoding error] {}".format(e)raise e
else: # > 3.4class FSCM(ABC):def encode(secret_key, session_cookie_structure):""" Encode a Flask session cookie """try:app = MockApp(secret_key)session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))si = SecureCookieSessionInterface()s = si.get_signing_serializer(app)return s.dumps(session_cookie_structure)except Exception as e:return "[Encoding error] {}".format(e)raise edef decode(session_cookie_value, secret_key=None):""" Decode a Flask cookie """try:if(secret_key==None):compressed = Falsepayload = session_cookie_valueif payload.startswith('.'):compressed = Truepayload = payload[1:]data = payload.split(".")[0]data = base64_decode(data)if compressed:data = zlib.decompress(data)return dataelse:app = MockApp(secret_key)si = SecureCookieSessionInterface()s = si.get_signing_serializer(app)return s.loads(session_cookie_value)except Exception as e:return "[Decoding error] {}".format(e)raise eif __name__ == "__main__":# Args are only relevant for __main__ usage## Description for helpparser = argparse.ArgumentParser(description='Flask Session Cookie Decoder/Encoder',epilog="Author : Wilson Sumanang, Alexandre ZANNI")## prepare sub commandssubparsers = parser.add_subparsers(help='sub-command help', dest='subcommand')## create the parser for the encode commandparser_encode = subparsers.add_parser('encode', help='encode')parser_encode.add_argument('-s', '--secret-key', metavar='<string>',help='Secret key', required=True)parser_encode.add_argument('-t', '--cookie-structure', metavar='<string>',help='Session cookie structure', required=True)## create the parser for the decode commandparser_decode = subparsers.add_parser('decode', help='decode')parser_decode.add_argument('-s', '--secret-key', metavar='<string>',help='Secret key', required=False)parser_decode.add_argument('-c', '--cookie-value', metavar='<string>',help='Session cookie value', required=True)## get argsargs = parser.parse_args()## find the option chosenif(args.subcommand == 'encode'):if(args.secret_key is not None and args.cookie_structure is not None):print(FSCM.encode(args.secret_key, args.cookie_structure))elif(args.subcommand == 'decode'):if(args.secret_key is not None and args.cookie_value is not None):print(FSCM.decode(args.cookie_value,args.secret_key))elif(args.cookie_value is not None):print(FSCM.decode(args.cookie_value))
解密:python session.py decode -s “secret_key” -c “需要解密的session值”
加密:python session.py encode -s “secret_key” -t “需要加密的session值”
?首先進行解密,發(fā)現(xiàn)是flask的session格式:
flask的session格式一般是由base64加密的Session數(shù)據(jù)(經(jīng)過了json、zlib壓縮處理的字符串) 、時間戳 、簽名組成的。
其次進行加密,又因為提示是必須是管理員,所以是name:admin
將得到的session加密值傳給頁面的session,得到flag
?
相關(guān)知識點
1.intval 繞過
intval()?函數(shù)可以獲取變量的「整數(shù)值」。常用于強制類型轉(zhuǎn)換
進行加 1 時會先將$a的科學計數(shù)法解析然后再加 1 。也就是說我們傳入 12e3 第一次intval會為12 ,+1后會取得12001,那么我們成功繞過了。
繞過的方式:
1.進制類型轉(zhuǎn)換
?繞過思路:當某個數(shù)字被過濾時,可以使用它的 8進制/16進制來繞過。
2.轉(zhuǎn)換數(shù)組
intval()?轉(zhuǎn)換數(shù)組類型時,不關(guān)心數(shù)組中的內(nèi)容,只判斷數(shù)組中有沒有元素。
?【空數(shù)組】返回 0
【非空數(shù)組】返回 1
如果傳入的?$var是數(shù)組中的某個值時,則當做變量來轉(zhuǎn)換,而不是當做數(shù)組類型。
$arr1 = array(8,6);var_dump(intval($arr1[0]));//輸出int(8)
繞過思路:對于弱比較(a==b),可以給a、b兩個參數(shù)傳入空數(shù)組,使弱比較為true。?
3.轉(zhuǎn)換小數(shù)
intval()?轉(zhuǎn)換小數(shù)類型時,只返回個位數(shù),不遵循四舍五入的原則。
繞過思路:當某個數(shù)字被過濾時,可以給它增加小數(shù)位來繞過。
4.轉(zhuǎn)換字符串
intval()?轉(zhuǎn)換字符串類型時,會判斷字符串是否以數(shù)字開頭
- 如果以數(shù)字開頭,就返回1個或多個連續(xù)的數(shù)字
- 如果以字母開頭,就返回0
單雙引號對轉(zhuǎn)換結(jié)果沒有影響,并且 0 或 0x 開頭也只會當做普通字符串
?5.取反
intval()?函數(shù)支持一些特殊符號的,比如~取反。
繞過思路:當某個數(shù)字被過濾時,可以兩次取反來繞過。
6.算數(shù)運算符
intval()?函數(shù)支持算數(shù)運算符,如果傳入的?$var參數(shù)包含算數(shù)運算符,會先運算,再對運算結(jié)果進行轉(zhuǎn)換。
繞過思路:當某個數(shù)字被過濾時,可以使用算數(shù)運算符繞過。?
7.浮點數(shù)精度缺失問題
由于PHP中的浮點數(shù)是【弱類型】,存在【精度丟失】的問題,在轉(zhuǎn)換時可能會出現(xiàn)意料之外的情況。
資料參考:WEB攻防基礎(chǔ)|PHP|過濾函數(shù)intval()繞過原理及方法-CSDN博客
PHP intval()函數(shù)詳解,intval()函數(shù)漏洞原理及繞過思路_intval函數(shù)-CSDN博客
2.session偽造攻擊
(1)session的作用:
由于http協(xié)議是一個無狀態(tài)的協(xié)議,也就是說同一個用戶第一次請求和第二次請求是完全沒有關(guān)系的,但是現(xiàn)在的網(wǎng)站基本上有登錄使用的功能,這就要求必須實現(xiàn)有狀態(tài),而session機制實現(xiàn)的就是這個功能。
用戶第一次請求后,將產(chǎn)生的狀態(tài)信息保存在session中,這時可以把session當做一個容器,它保存了正在使用的所有用戶的狀態(tài)信息;這段狀態(tài)信息分配了一個唯一的標識符用來標識用戶的身份,將其保存在響應(yīng)對象的cookie中;當?shù)诙握埱髸r,解析cookie中的標識符,拿到標識符后去session找到對應(yīng)的用戶的信息。
?(2)session偽造攻擊是一種非常流行的針對session的攻擊方式.它之所以流行的主要原因是:它是一個攻擊者獲得一個有效的SESSION ID(標識符)最簡單的方法,使用這種方法,可以模仿當前用戶的SESSION ID,偽裝成這個用戶,然后進一步進行SESSION劫持攻擊
(3)flask session的儲存方式:
第一種方式:直接存在客戶端的cookies中
第二種方式:存儲在服務(wù)端,如:redis,memcached,mysql,file,mongodb等等,存在flask-session第三方庫,flask的session可以保存在客戶端的cookie中,那么就會產(chǎn)生一定的安全問題。
flask框架的session若存儲在客戶端,就需要解決session被惡意纂改的問題,而flask通過一個secret_key,也就是密鑰對數(shù)據(jù)進行簽名來防止session被纂改。
(4)flask的session格式:
flask的session格式一般是由base64加密的Session數(shù)據(jù)(經(jīng)過了json、zlib壓縮處理的字符串) 、時間戳 、簽名組成的。
(5)json的數(shù)據(jù)可以用花括號{}或中括號[]包裹,對應(yīng)js中的object和array
對象:使用花括號
數(shù)組:使用方括號
字符串類型:必須使用雙引號
整形、浮點型、布爾類型還有null類型
多個數(shù)據(jù)之間使用逗號分開
json本質(zhì)上就是一個字符串
來看一段json數(shù)據(jù):
{"name":"admin","age":18}
資料:https://zhuanlan.zhihu.com/p/476520054?
Session攻擊-CSDN博客