ctf之WEB練習一


一、查找備份文件

1.通過https://github.com/maurosoria/dirsearch進行目錄掃描
python3 dirsearch.py   -u http://10.10.10.175:32770   -e   *
2.最終獲得index.php.bk備份文件,然后下載下來查看源碼,即可獲得flag
flag為:Cyberpeace{855A1C4B3401294CB6604CCC98BDE334}

二、隱藏在cookie中的flag

1.通過抓包工具對IP訪問進行抓取http頭部信息,發現cookie中包含信息:
Cookie: look-here=cookie.php
2.然后訪問網址:http://220.249.52.133:41440/cookie.php,顯示文字提示See the http response,說明flag有可能在響應包中
3.對網址 http://220.249.52.133:41440/cookie.php, 進行請求,查看響應包,可看到flag信息
4.最終flag為:cyberpeace{71de0ba3c98781d7f78c4af6e5b684be}

三、隱藏在按鈕下的flag
1.打開網址,http://220.249.52.133:52359/,發現按鈕灰色,提示不能使用,這時候通過f12進行元素審核
2.刪除 disabled="" ,然后點擊按鈕即可獲得flag
3.最終flag為: cyberpeace{e61ed8f7f37f036a89f6d3c5622bb8e9}
四、弱密碼獲得flag
1.打開網址:

2.輸入用戶名admin,123456,即可登錄到系統,並獲得flag
3.最終flag為: cyberpeace{a136364c15e239b4f32b99d2d23e42ce}

三、簡單的文件包含審計獲得flag
<?php
show_source
(__FILE__);
include(
"config.php");
$a=@$_GET['a'];
$b=@$_GET['b'];
if(
$a==and $a){
    echo 
$flag1;
}
if(
is_numeric($b)){
    exit();
}
if(
$b>1234){
    echo 
$flag2;
}
?>

這段php代碼的意思是,通過get方法得到a和b的值,然后如果$a==0 並且$a為真,得到flag1,如果b是整數或者數字字符串,就退出,然后如果$b>1234就得到flag2.

基礎知識:( 掌握php弱類型比較)
php中其中兩種比較符號:
==:先將字符串類型轉化成相同,再比較
===:先判斷兩種字符串的類型是否相等,再比較
字符串和數字比較使用==時,字符串會先轉換為數字類型再比較
var_dump('a' == 0);//true,此時a字符串類型轉化成數字,因為a字符串開頭中沒有找到數字,所以轉換為0
var_dump('123a' == 123);//true,這里'123a'會被轉換為123
var_dump('a123' == 123);//false,因為php中有這樣一個規定:字符串的開始部分決定了它的值,如果該字符串以合法的數字開始,則使用該數字至和它連續的最后一個數字結束,否則其比較時整體值為0。
var_dump('root' == 0);
var_dump('22r22oot' == 22); //true,先將字符串22r22oot轉化成和0同等類型即數字型,因為字符串開始有合法數值,則取其連續的合法數值22,r后面的22因為與開始的合法數值不連續,所以不取它的值,22==22,所以成立。
var_dump('root22' == 0); //true,先將字符串root22轉化成和0同等類型即數字型,因為字符串開始沒有合法數值,則字符串root22轉換為0,最后0==0,所以成立。
var_dump('0e170' == '0e180');//true,因為字符串中含有e開頭的值,那么php代碼會將其整體看成科學記數法,最后0的170次方==0的180次方,即0==0,所以成立
var_dump(0 === 'root');//fals,=== 在進行比較的時候,會先判斷兩邊類型是否相等,這里數值和字符串類型明顯不等,因此不成立
var_dump ("0e830400451993494058024219903391" == "0e830400451993494058024219904444");//true,先將字符串0e830400451993494058024219903391與0e830400451993494058024219904444分別轉化成數字型,因為兩個字符串開始都有合法數值,則字符串0e830400451993494058024219903391轉換為0,字符串0e830400451993494058024219904444轉換為0,最后0==0,所以成立。
var_dump("123.a1bc"==123);//true
var_dump("123.2abc"==123);//false
var_dump("123e2abc"==123);//false
var_dump("123ea1bc"==123);//true
開始部分存在數字,若連續的數字中包含.或e或E會干擾字符串和數字的比較,因為.就表示了浮點數,e和E表示了科學計數法,只要字符串中包含這些,上面所說的比較就不能理想地實現
字符串的開始部分決定了它的值,如果該字符串以合法的數值開始,則使用該數值,否則其值為0

1.打開頁面,進行代碼審計,發現同時滿足 $a==0 和 $a 時,顯示flag1。

2.php中的弱類型比較會使’abc’ == 0為真,所以輸入a=c時,可得到flag1,如圖所示。(abc可換成任意字符)。

http://220.249.52.133:53517/index.php?a=abc

3.is_numeric() 函數會判斷如果是數字和數字字符串則返回 TRUE,否則返回 FALSE,且php中弱類型比較時,會使(‘1234a’ == 1234)為真,所以當輸入a=abc&b=1235a,可得到flag2,如圖所示。

入a=abc&b=1235a,可得到flag2,如圖所示。

http://220.249.52.133:53517/index.php?a=abc&b=12345f


四、post與get方式的flag
1.構造get方式訪問
http://220.249.52.133:48752/index.php?a=1
2.然后按照頁面提示,通過firefox中插件hackbar提交post數據,b=2,即可獲得flag
五、http頭部偽繞過限制訪問獲得flag
基礎知識:
xff是告訴服務器當前請求者的最終ip的http請求頭字段
通常可以直接通過修改http頭中的X-Forwarded-For字段來仿造請求的最終ip
referer就是告訴服務器當前訪問者是從哪個url地址跳轉到自己的,跟xff一樣,referer也可直接修改
1.打開網址http://220.249.52.133:54968/,提示必須是源ip為123.123.123.123才能訪問

2.通過抓包,在http頭部添加xff偽造請求頭,X-Forwarded-For: 123.123.123.123,然后訪問,發現響應頁面中包含,需要請求頭為必須來自https://www.google.com訪問,這里需要添加上,referer:  https://www.google.com,然后訪問可獲得flag
最終獲得flag:
cyberpeace{f116fe3f881eef96edaaf3159a3131f8}

六、遠程命令執行獲取flag
基礎知識:
 windows或linux下:
    command1 && command2 先執行command1,如果為真,再執行command2。
 command1 | command2 只執行command2。
 command1 & command2 先執行command2后執行command1。
 command1 || command2 先執行command1,如果為假,再執行command2
1.輸入IP地址,這里最好127.0.0.1,如果出現回顯,則存在命令執行
2.通過在后門加上命令:127.0.0.1|  find   /  -name    flag.txt  的文件目錄,其目錄為:/home/flag.txt
3.使用命令127.0.0.1| cat /home/flag.txt,查看flag.txt的flag
最終獲得flag:
cyberpeace{400f6c86f9dd25994afb930d13cc28b8}


JS代碼獲得flag

進入環境后我們遇到了輸入密碼,於是我們隨便輸入一個密碼,點擊確定
進行代碼審計,發現不論輸入什么都會跳到假密碼,真密碼位於 fromCharCode

執行流程:

一、首先定義了一個dechiffre函數,咱先不管,因為還沒有調用

注:先將\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30十六進制數轉換成字符串,python下print即可,或網址:https://www.bejson.com/convert/ox2str/


輸出結果55,56,54,79,115,69,114,116,107,49,50

二、執行String["fromCharCode"](dechiffre("55,56,54,79,115,69,114,116,107,49,50

"));


三、調用了dechiffre,執行dechiffre函數

String["fromCharCode"](dechiffre("55,56,54,79,115,69,114,116,107,49,50

"));

(1)先將"55,56,54,79,115,69,114,116,107,49,50

"帶入dechiffre函數執行,即dechiffre(pass_enc)=dechiffre("55,56,54,79,115,69,114,116,107,49,50

")

(2)接着我們看到了pass變量,暫時先放着

(3)因為pass_enc="55,56,54,79,115,69,114,116,107,49,50"

將pass_enc字符串分割成字符串數組,賦值給tab參數,所以:

tab=[55,56,54,79,115,69,114,116,107,49,50]   注:tab此時是字符串數組!!!

(3)隨后也對pass分割

tab2=[70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65]

(4)變量賦值代碼分析:var i,j,k,l=0,m,n,o,p = "";i = 0;j = tab.length;

一開始i,j,k,m,n,o,沒有賦值,為undefined,其它參數l=0,p="",后來i被賦值=0,j被賦值為11

(5)第九行此時n被賦值為0,所以k=11+0+0,最后等於11    注:這里的(l)其中是英文字母l,不是數字1

(6)第十行中,n=18

(7)第一個for循環,精簡一下代碼:

for(i = 0; i < (18); i++ )

{o = tab[i-l];p += String.fromCharCode((o = tab2[i]));

    if(i == 5)break;}

解釋:前面的o=tab[i-1]是無用的,因為后面會被o=tab2[i]的值重新覆蓋

第一次循環:o=tab[0];p=p+String.fromCharCode((o = tab2[0])

=>o=70;p=""+String.fromCharCode(70)=>p=英文字母F

第二次...

第三次...

第四次...

第五次...

所以,這個for循環,最后的p為(盡管沒有輸出出來,這里我們知道就好)FAUX P

(8)第二個for循環,精簡一下代碼:

for(i = 0; i < 18; i++ ){

o = tab[i-l];

    if(i > 5 && i < 17)

        p += String.fromCharCode((o = tab2[i]));

}

解釋:這里的for循環和上面的差不多,注意這里的p值由於第一次for循環執行后現在已經是FAUX P了

加上第一次for循環的p值,最后的p為FAUX PASSWORD HAH

(9)p += String.fromCharCode(tab2[17]);

因為tab2=[70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65]

所以:p=FAUX PASSWORD HAH + A

因此,最后的p為FAUX PASSWORD HAHA


(10)pass = p;return pass;

 即 pass = FAUX PASSWORD HAHA;return FAUX PASSWORD HAHA;

 最后函數輸出為FAUX PASSWORD HAHA

三、dechiffre函數執行完成后,繼續執行其它的代碼

h = window.prompt('Enter password');

    alert( dechiffre(h) );

h=你輸入彈框內的內容

之后alert彈出dechiffre(h)的值,由前面所有的代碼可知,代碼里p的值與tab無關,因為最終都會被tab2的值替代,所以我們無論輸入什么,也就是pass_enc=h,無論輸入的這個h等於什么,不管tab能否被分割成字符串數組,是否存在,都只會利用到tab2。通俗點講,有關tab的參數與值都可以視為沒有,因此,pass_enc參數是什么也就沒有意義了

四、最后,結論就是,無論我們在彈框中輸入什么值,都只會返回FAUX PASSWORD HAHA

我就猜想,會不會String["fromCharCode"](dechiffre("\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30"));這個語法錯誤,並且沒有沒計算出來的是不是最后正確的值,也就是flag~

於是,我不用它這么無論pass_enc參數輸入什么都顯示FAUX PASSWORD HAHA的函數,咱也拋棄它一回,自己重新寫代碼執行它

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

</head>

<body>

<script>

    var n=String.fromCharCode(55,56,54,79,115,69,114,116,107,49,50);

    document.write(n);

</script>

</body>

</html>

最后結果為:786OsErtk12

通過python腳本將十六進制轉成asic編碼

a = [55,56,54,79,115,69,114,116,107,49,50]
c = ""
for i in a:
b = chr(i)
c = c + b
print(c)

最終獲得flag:Cyberpeace{786OsErtk12}


一、文件包含(修改全局變量)

題目:

<?php
include "flag.php";
$a = @$_REQUEST['hello'];
if(!
preg_match('/^\w*$/',$a )){
  die(
'ERROR');
}
eval(
"var_dump($$a);");
show_source(__FILE__);
?>

writeup:

代碼分析:

include "flag.php";
$a = @$_REQUEST['hello'];
if(!preg_match('/^\w*$/',$a )){//正則表達式^匹配一行的開頭,$表示結束。\w表示匹配包括下划線的任何單詞字符,等價於'[A-Za-z0-9_]'。*號:匹配前面的子表達式零次或多次。
  die('ERROR');
}
eval("var_dump($$a);");//var_dump — 打印變量的相關信息
show_source(__FILE__);//__FILE__當前運行文件的完整路徑和文件名。
?>

這個代碼的作用是如果匹配正則表達式 /^\w*$/,就打印變量 $$a
$a是hello, $$a是六位變量 $hello
由於 $a在函數中,所以函數之外無法訪問。如果要訪問,將hello修改為超全局變量GLOBALS。
在URL后加 ?hello=GLOBALS,將參數hello修改為Globals
實際執行語句:
eval("var_dump($$a);")--->eval("var_dump($hello);")--->eval("var_dump($GLOBALS);")
$GLOBALS的作用:引用全局作用域中可用的全部變量。
這樣就會打印出當前定義的所有變量,也包括 include 的文件中的變量,flag 也存在在這些變量中。

2.我們通過URL進行傳參

http://a7a380bd2f5c4ae3add25a7a518afc17fba46d89981f45fd.changame.ichunqiu.com/index.php?hello=GLOBALS

最終得到flag:

flag{146918ba-01c6-47a3-bc16-0761da476df8}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM