​ 看提示信息是和bash相关:

​ ssh链接查看:

​ 很熟悉的几个文件,把shellshock.c下载查看源码分析:

1
2
3
4
5
6
7
#include <stdio.h>
int main(){
setresuid(getegid(), getegid(), getegid());
setresgid(getegid(), getegid(), getegid());
system("/home/shellshock/bash -c 'echo shock_me'");
return 0;
}

分析:

​ 很短的几行代码,这里需要了解一下Linux下进程权限问题,才好理解3、4行代码。

​ linux下进程权限有这么几个相关的属性:

  • ruid/rgid(实际用户id:real userid,real group id):由启动进程的用户来决定,通常是当前登录用户(即运行可执行文件的用户)
  • euid/egid(有效用户:effective userid,effective group id):一般在进程启动时,直接由ruid/rgid复制而来,或者是当进程对应的可执行文件的set-user-id/set-group-id即那个rwx之外的s标志位)标志位为true时,其为该文件的所属用户/组。euid/egid决定了进程访问文件的权限。
  • suid/sgid(保存用户id:saved setuserid、):从euid/egid复制。

​ ssh后运行shellshock是以other权限来执行的,执行后setresuid()/setresgid()可以设置上述的几个权限,函数原型如下:

1
2
3
4
5
#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <unistd.h>
//setresuid, setresgid - set real, effective and saved user or group ID
int setresuid(uid_t ruid, uid_t euid, uid_t suid);
int setresgid(gid_t rgid, gid_t egid, gid_t sgid);

​ 程序将所有的这几个权限设置为egid,egid对应的用户组s标志位刚好为true,所以3、4行代码的意思就是把程序shellshock权限提升为shellshock_pwn组权限,用来后面读flag。

​ 程序system并没有对flag进行读取操作,这里就需要费点脑筋了,其实如果对漏洞熟悉的话,看到shellshock这个名字就能想起来那个shellshock破壳漏洞(CVE-2014-6271),该漏洞的分析可以见我的分析报告。通过该漏洞源码,发现setresuid()/setresgid()其实还有另一种作用,那就是保证ruid和euid相同使得漏洞可以触发。

做题:

  1. 先验证一下服务器bash版本和漏洞是否存在,测试poc用env x='() { :;}; echo vulnerable' /home/shellshock/bash -c "echo this is a test",system()中用到的bash是存在该漏洞的:

  1. 改造poc,将echo vulnerable改为bash -c cat flag,然后测试,可以成功cat flag,本题完成。