/src/detect-engine-hmd.c

https://github.com/decanio/suricata-tilera · C · 1728 lines · 1298 code · 298 blank · 132 comment · 274 complexity · b9caeee6f55de83ba9a4e023e9577604 MD5 · raw file

  1. /* Copyright (C) 2007-2010 Open Information Security Foundation
  2. *
  3. * You can copy, redistribute or modify this Program under the terms of
  4. * the GNU General Public License version 2 as published by the Free
  5. * Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * version 2 along with this program; if not, write to the Free Software
  14. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  15. * 02110-1301, USA.
  16. */
  17. /**
  18. * \ingroup httplayer
  19. *
  20. * @{
  21. */
  22. /** \file
  23. *
  24. * \author Anoop Saldanha <anoopsaldanha@gmail.com>
  25. *
  26. * \brief Handle HTTP method match
  27. *
  28. */
  29. #include "suricata-common.h"
  30. #include "suricata.h"
  31. #include "decode.h"
  32. #include "detect.h"
  33. #include "detect-engine.h"
  34. #include "detect-engine-hmd.h"
  35. #include "detect-engine-mpm.h"
  36. #include "detect-parse.h"
  37. #include "detect-engine-state.h"
  38. #include "detect-engine-content-inspection.h"
  39. #include "flow-util.h"
  40. #include "util-debug.h"
  41. #include "util-print.h"
  42. #include "flow.h"
  43. #include "app-layer-parser.h"
  44. #include "util-unittest.h"
  45. #include "util-unittest-helper.h"
  46. #include "app-layer.h"
  47. #include "app-layer-htp.h"
  48. #include "app-layer-protos.h"
  49. int DetectEngineRunHttpMethodMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
  50. HtpState *htp_state, uint8_t flags)
  51. {
  52. htp_tx_t *tx = NULL;
  53. uint32_t cnt = 0;
  54. int idx;
  55. /* we need to lock because the buffers are not actually true buffers
  56. * but are ones that point to a buffer given by libhtp */
  57. FLOWLOCK_RDLOCK(f);
  58. if (htp_state == NULL) {
  59. SCLogDebug("no HTTP state");
  60. goto end;
  61. }
  62. if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
  63. SCLogDebug("HTP state has no conn(p)");
  64. goto end;
  65. }
  66. idx = AppLayerTransactionGetInspectId(f);
  67. if (idx == -1) {
  68. goto end;
  69. }
  70. int size = (int)list_size(htp_state->connp->conn->transactions);
  71. for (; idx < size; idx++) {
  72. tx = list_get(htp_state->connp->conn->transactions, idx);
  73. if (tx == NULL || tx->request_method == NULL)
  74. continue;
  75. cnt += HttpMethodPatternSearch(det_ctx,
  76. (uint8_t *)bstr_ptr(tx->request_method),
  77. bstr_len(tx->request_method),
  78. flags);
  79. }
  80. end:
  81. FLOWLOCK_UNLOCK(f);
  82. return cnt;
  83. }
  84. /**
  85. * \brief Do the http_method content inspection for a signature.
  86. *
  87. * \param de_ctx Detection engine context.
  88. * \param det_ctx Detection engine thread context.
  89. * \param s Signature to inspect.
  90. * \param f Flow.
  91. * \param flags App layer flags.
  92. * \param state App layer state.
  93. *
  94. * \retval 0 No match.
  95. * \retval 1 Match.
  96. */
  97. int DetectEngineInspectHttpMethod(ThreadVars *tv,
  98. DetectEngineCtx *de_ctx,
  99. DetectEngineThreadCtx *det_ctx,
  100. Signature *s, Flow *f, uint8_t flags,
  101. void *alstate, int tx_id)
  102. {
  103. HtpState *htp_state = (HtpState *)alstate;
  104. htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
  105. if (tx == NULL || tx->request_method == NULL)
  106. return 0;
  107. det_ctx->buffer_offset = 0;
  108. det_ctx->discontinue_matching = 0;
  109. det_ctx->inspection_recursion_counter = 0;
  110. int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HMDMATCH],
  111. f,
  112. (uint8_t *)bstr_ptr(tx->request_method),
  113. bstr_len(tx->request_method),
  114. DETECT_ENGINE_CONTENT_INSPECTION_MODE_HMD, NULL);
  115. if (r == 1)
  116. return 1;
  117. return 0;
  118. }
  119. /***********************************Unittests**********************************/
  120. #ifdef UNITTESTS
  121. /**
  122. * \test Test that the http_method content matches against a http request
  123. * which holds the content.
  124. */
  125. static int DetectEngineHttpMethodTest01(void)
  126. {
  127. TcpSession ssn;
  128. Packet *p = NULL;
  129. ThreadVars th_v;
  130. DetectEngineCtx *de_ctx = NULL;
  131. DetectEngineThreadCtx *det_ctx = NULL;
  132. HtpState *http_state = NULL;
  133. Flow f;
  134. uint8_t http_buf[] =
  135. "GET /index.html HTTP/1.0\r\n"
  136. "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
  137. uint32_t http_len = sizeof(http_buf) - 1;
  138. int result = 0;
  139. memset(&th_v, 0, sizeof(th_v));
  140. memset(&f, 0, sizeof(f));
  141. memset(&ssn, 0, sizeof(ssn));
  142. p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
  143. FLOW_INITIALIZE(&f);
  144. f.protoctx = (void *)&ssn;
  145. f.flags |= FLOW_IPV4;
  146. p->flow = &f;
  147. p->flowflags |= FLOW_PKT_TOSERVER;
  148. p->flowflags |= FLOW_PKT_ESTABLISHED;
  149. p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
  150. f.alproto = ALPROTO_HTTP;
  151. StreamTcpInitConfig(TRUE);
  152. de_ctx = DetectEngineCtxInit();
  153. if (de_ctx == NULL)
  154. goto end;
  155. de_ctx->flags |= DE_QUIET;
  156. de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
  157. "(msg:\"http header test\"; "
  158. "content:\"GET\"; http_method; "
  159. "sid:1;)");
  160. if (de_ctx->sig_list == NULL)
  161. goto end;
  162. SigGroupBuild(de_ctx);
  163. DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
  164. int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
  165. if (r != 0) {
  166. printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
  167. result = 0;
  168. goto end;
  169. }
  170. http_state = f.alstate;
  171. if (http_state == NULL) {
  172. printf("no http state: ");
  173. result = 0;
  174. goto end;
  175. }
  176. /* do detect */
  177. SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
  178. if (!(PacketAlertCheck(p, 1))) {
  179. printf("sid 1 didn't match but should have: ");
  180. goto end;
  181. }
  182. result = 1;
  183. end:
  184. if (de_ctx != NULL)
  185. SigGroupCleanup(de_ctx);
  186. if (de_ctx != NULL)
  187. SigCleanSignatures(de_ctx);
  188. if (de_ctx != NULL)
  189. DetectEngineCtxFree(de_ctx);
  190. StreamTcpFreeConfig(TRUE);
  191. FLOW_DESTROY(&f);
  192. UTHFreePackets(&p, 1);
  193. return result;
  194. }
  195. /**
  196. * \test Test that the http_method content matches against a http request
  197. * which holds the content.
  198. */
  199. static int DetectEngineHttpMethodTest02(void)
  200. {
  201. TcpSession ssn;
  202. Packet *p = NULL;
  203. ThreadVars th_v;
  204. DetectEngineCtx *de_ctx = NULL;
  205. DetectEngineThreadCtx *det_ctx = NULL;
  206. HtpState *http_state = NULL;
  207. Flow f;
  208. uint8_t http_buf[] =
  209. "CONNECT /index.html HTTP/1.0\r\n"
  210. "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
  211. uint32_t http_len = sizeof(http_buf) - 1;
  212. int result = 0;
  213. memset(&th_v, 0, sizeof(th_v));
  214. memset(&f, 0, sizeof(f));
  215. memset(&ssn, 0, sizeof(ssn));
  216. p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
  217. FLOW_INITIALIZE(&f);
  218. f.protoctx = (void *)&ssn;
  219. f.flags |= FLOW_IPV4;
  220. p->flow = &f;
  221. p->flowflags |= FLOW_PKT_TOSERVER;
  222. p->flowflags |= FLOW_PKT_ESTABLISHED;
  223. p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
  224. f.alproto = ALPROTO_HTTP;
  225. StreamTcpInitConfig(TRUE);
  226. de_ctx = DetectEngineCtxInit();
  227. if (de_ctx == NULL)
  228. goto end;
  229. de_ctx->flags |= DE_QUIET;
  230. de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
  231. "(msg:\"http header test\"; "
  232. "content:\"CO\"; depth:4; http_method; "
  233. "sid:1;)");
  234. if (de_ctx->sig_list == NULL)
  235. goto end;
  236. SigGroupBuild(de_ctx);
  237. DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
  238. int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
  239. if (r != 0) {
  240. printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
  241. result = 0;
  242. goto end;
  243. }
  244. http_state = f.alstate;
  245. if (http_state == NULL) {
  246. printf("no http state: ");
  247. result = 0;
  248. goto end;
  249. }
  250. /* do detect */
  251. SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
  252. if (!(PacketAlertCheck(p, 1))) {
  253. printf("sid 1 didn't match but should have: ");
  254. goto end;
  255. }
  256. result = 1;
  257. end:
  258. if (de_ctx != NULL)
  259. SigGroupCleanup(de_ctx);
  260. if (de_ctx != NULL)
  261. SigCleanSignatures(de_ctx);
  262. if (de_ctx != NULL)
  263. DetectEngineCtxFree(de_ctx);
  264. StreamTcpFreeConfig(TRUE);
  265. FLOW_DESTROY(&f);
  266. UTHFreePackets(&p, 1);
  267. return result;
  268. }
  269. /**
  270. * \test Test that the http_method content matches against a http request
  271. * which holds the content.
  272. */
  273. static int DetectEngineHttpMethodTest03(void)
  274. {
  275. TcpSession ssn;
  276. Packet *p = NULL;
  277. ThreadVars th_v;
  278. DetectEngineCtx *de_ctx = NULL;
  279. DetectEngineThreadCtx *det_ctx = NULL;
  280. HtpState *http_state = NULL;
  281. Flow f;
  282. uint8_t http_buf[] =
  283. "CONNECT /index.html HTTP/1.0\r\n"
  284. "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
  285. uint32_t http_len = sizeof(http_buf) - 1;
  286. int result = 0;
  287. memset(&th_v, 0, sizeof(th_v));
  288. memset(&f, 0, sizeof(f));
  289. memset(&ssn, 0, sizeof(ssn));
  290. p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
  291. FLOW_INITIALIZE(&f);
  292. f.protoctx = (void *)&ssn;
  293. f.flags |= FLOW_IPV4;
  294. p->flow = &f;
  295. p->flowflags |= FLOW_PKT_TOSERVER;
  296. p->flowflags |= FLOW_PKT_ESTABLISHED;
  297. p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
  298. f.alproto = ALPROTO_HTTP;
  299. StreamTcpInitConfig(TRUE);
  300. de_ctx = DetectEngineCtxInit();
  301. if (de_ctx == NULL)
  302. goto end;
  303. de_ctx->flags |= DE_QUIET;
  304. de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
  305. "(msg:\"http header test\"; "
  306. "content:!\"ECT\"; depth:4; http_method; "
  307. "sid:1;)");
  308. if (de_ctx->sig_list == NULL)
  309. goto end;
  310. SigGroupBuild(de_ctx);
  311. DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
  312. int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
  313. if (r != 0) {
  314. printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
  315. result = 0;
  316. goto end;
  317. }
  318. http_state = f.alstate;
  319. if (http_state == NULL) {
  320. printf("no http state: ");
  321. result = 0;
  322. goto end;
  323. }
  324. /* do detect */
  325. SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
  326. if (!(PacketAlertCheck(p, 1))) {
  327. printf("sid 1 didn't match but should have: ");
  328. goto end;
  329. }
  330. result = 1;
  331. end:
  332. if (de_ctx != NULL)
  333. SigGroupCleanup(de_ctx);
  334. if (de_ctx != NULL)
  335. SigCleanSignatures(de_ctx);
  336. if (de_ctx != NULL)
  337. DetectEngineCtxFree(de_ctx);
  338. StreamTcpFreeConfig(TRUE);
  339. FLOW_DESTROY(&f);
  340. UTHFreePackets(&p, 1);
  341. return result;
  342. }
  343. /**
  344. * \test Test that the http_method content matches against a http request
  345. * which holds the content.
  346. */
  347. static int DetectEngineHttpMethodTest04(void)
  348. {
  349. TcpSession ssn;
  350. Packet *p = NULL;
  351. ThreadVars th_v;
  352. DetectEngineCtx *de_ctx = NULL;
  353. DetectEngineThreadCtx *det_ctx = NULL;
  354. HtpState *http_state = NULL;
  355. Flow f;
  356. uint8_t http_buf[] =
  357. "CONNECT /index.html HTTP/1.0\r\n"
  358. "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
  359. uint32_t http_len = sizeof(http_buf) - 1;
  360. int result = 0;
  361. memset(&th_v, 0, sizeof(th_v));
  362. memset(&f, 0, sizeof(f));
  363. memset(&ssn, 0, sizeof(ssn));
  364. p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
  365. FLOW_INITIALIZE(&f);
  366. f.protoctx = (void *)&ssn;
  367. f.flags |= FLOW_IPV4;
  368. p->flow = &f;
  369. p->flowflags |= FLOW_PKT_TOSERVER;
  370. p->flowflags |= FLOW_PKT_ESTABLISHED;
  371. p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
  372. f.alproto = ALPROTO_HTTP;
  373. StreamTcpInitConfig(TRUE);
  374. de_ctx = DetectEngineCtxInit();
  375. if (de_ctx == NULL)
  376. goto end;
  377. de_ctx->flags |= DE_QUIET;
  378. de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
  379. "(msg:\"http header test\"; "
  380. "content:\"ECT\"; depth:4; http_method; "
  381. "sid:1;)");
  382. if (de_ctx->sig_list == NULL)
  383. goto end;
  384. SigGroupBuild(de_ctx);
  385. DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
  386. int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
  387. if (r != 0) {
  388. printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
  389. result = 0;
  390. goto end;
  391. }
  392. http_state = f.alstate;
  393. if (http_state == NULL) {
  394. printf("no http state: ");
  395. result = 0;
  396. goto end;
  397. }
  398. /* do detect */
  399. SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
  400. if (PacketAlertCheck(p, 1)) {
  401. printf("sid 1 matched but shouldn't have: ");
  402. goto end;
  403. }
  404. result = 1;
  405. end:
  406. if (de_ctx != NULL)
  407. SigGroupCleanup(de_ctx);
  408. if (de_ctx != NULL)
  409. SigCleanSignatures(de_ctx);
  410. if (de_ctx != NULL)
  411. DetectEngineCtxFree(de_ctx);
  412. StreamTcpFreeConfig(TRUE);
  413. FLOW_DESTROY(&f);
  414. UTHFreePackets(&p, 1);
  415. return result;
  416. }
  417. /**
  418. * \test Test that the http_method content matches against a http request
  419. * which holds the content.
  420. */
  421. static int DetectEngineHttpMethodTest05(void)
  422. {
  423. TcpSession ssn;
  424. Packet *p = NULL;
  425. ThreadVars th_v;
  426. DetectEngineCtx *de_ctx = NULL;
  427. DetectEngineThreadCtx *det_ctx = NULL;
  428. HtpState *http_state = NULL;
  429. Flow f;
  430. uint8_t http_buf[] =
  431. "CONNECT /index.html HTTP/1.0\r\n"
  432. "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
  433. uint32_t http_len = sizeof(http_buf) - 1;
  434. int result = 0;
  435. memset(&th_v, 0, sizeof(th_v));
  436. memset(&f, 0, sizeof(f));
  437. memset(&ssn, 0, sizeof(ssn));
  438. p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
  439. FLOW_INITIALIZE(&f);
  440. f.protoctx = (void *)&ssn;
  441. f.flags |= FLOW_IPV4;
  442. p->flow = &f;
  443. p->flowflags |= FLOW_PKT_TOSERVER;
  444. p->flowflags |= FLOW_PKT_ESTABLISHED;
  445. p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
  446. f.alproto = ALPROTO_HTTP;
  447. StreamTcpInitConfig(TRUE);
  448. de_ctx = DetectEngineCtxInit();
  449. if (de_ctx == NULL)
  450. goto end;
  451. de_ctx->flags |= DE_QUIET;
  452. de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
  453. "(msg:\"http header test\"; "
  454. "content:!\"CON\"; depth:4; http_method; "
  455. "sid:1;)");
  456. if (de_ctx->sig_list == NULL)
  457. goto end;
  458. SigGroupBuild(de_ctx);
  459. DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
  460. int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
  461. if (r != 0) {
  462. printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
  463. result = 0;
  464. goto end;
  465. }
  466. http_state = f.alstate;
  467. if (http_state == NULL) {
  468. printf("no http state: ");
  469. result = 0;
  470. goto end;
  471. }
  472. /* do detect */
  473. SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
  474. if (PacketAlertCheck(p, 1)) {
  475. printf("sid 1 matched but shouldn't have: ");
  476. goto end;
  477. }
  478. result = 1;
  479. end:
  480. if (de_ctx != NULL)
  481. SigGroupCleanup(de_ctx);
  482. if (de_ctx != NULL)
  483. SigCleanSignatures(de_ctx);
  484. if (de_ctx != NULL)
  485. DetectEngineCtxFree(de_ctx);
  486. StreamTcpFreeConfig(TRUE);
  487. FLOW_DESTROY(&f);
  488. UTHFreePackets(&p, 1);
  489. return result;
  490. }
  491. /**
  492. * \test Test that the http_method content matches against a http request
  493. * which holds the content.
  494. */
  495. static int DetectEngineHttpMethodTest06(void)
  496. {
  497. TcpSession ssn;
  498. Packet *p = NULL;
  499. ThreadVars th_v;
  500. DetectEngineCtx *de_ctx = NULL;
  501. DetectEngineThreadCtx *det_ctx = NULL;
  502. HtpState *http_state = NULL;
  503. Flow f;
  504. uint8_t http_buf[] =
  505. "CONNECT /index.html HTTP/1.0\r\n"
  506. "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
  507. uint32_t http_len = sizeof(http_buf) - 1;
  508. int result = 0;
  509. memset(&th_v, 0, sizeof(th_v));
  510. memset(&f, 0, sizeof(f));
  511. memset(&ssn, 0, sizeof(ssn));
  512. p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
  513. FLOW_INITIALIZE(&f);
  514. f.protoctx = (void *)&ssn;
  515. f.flags |= FLOW_IPV4;
  516. p->flow = &f;
  517. p->flowflags |= FLOW_PKT_TOSERVER;
  518. p->flowflags |= FLOW_PKT_ESTABLISHED;
  519. p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
  520. f.alproto = ALPROTO_HTTP;
  521. StreamTcpInitConfig(TRUE);
  522. de_ctx = DetectEngineCtxInit();
  523. if (de_ctx == NULL)
  524. goto end;
  525. de_ctx->flags |= DE_QUIET;
  526. de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
  527. "(msg:\"http header test\"; "
  528. "content:\"ECT\"; offset:3; http_method; "
  529. "sid:1;)");
  530. if (de_ctx->sig_list == NULL)
  531. goto end;
  532. SigGroupBuild(de_ctx);
  533. DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
  534. int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
  535. if (r != 0) {
  536. printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
  537. result = 0;
  538. goto end;
  539. }
  540. http_state = f.alstate;
  541. if (http_state == NULL) {
  542. printf("no http state: ");
  543. result = 0;
  544. goto end;
  545. }
  546. /* do detect */
  547. SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
  548. if (!(PacketAlertCheck(p, 1))) {
  549. printf("sid 1 didn't match but should have: ");
  550. goto end;
  551. }
  552. result = 1;
  553. end:
  554. if (de_ctx != NULL)
  555. SigGroupCleanup(de_ctx);
  556. if (de_ctx != NULL)
  557. SigCleanSignatures(de_ctx);
  558. if (de_ctx != NULL)
  559. DetectEngineCtxFree(de_ctx);
  560. StreamTcpFreeConfig(TRUE);
  561. FLOW_DESTROY(&f);
  562. UTHFreePackets(&p, 1);
  563. return result;
  564. }
  565. /**
  566. * \test Test that the http_method content matches against a http request
  567. * which holds the content.
  568. */
  569. static int DetectEngineHttpMethodTest07(void)
  570. {
  571. TcpSession ssn;
  572. Packet *p = NULL;
  573. ThreadVars th_v;
  574. DetectEngineCtx *de_ctx = NULL;
  575. DetectEngineThreadCtx *det_ctx = NULL;
  576. HtpState *http_state = NULL;
  577. Flow f;
  578. uint8_t http_buf[] =
  579. "CONNECT /index.html HTTP/1.0\r\n"
  580. "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
  581. uint32_t http_len = sizeof(http_buf) - 1;
  582. int result = 0;
  583. memset(&th_v, 0, sizeof(th_v));
  584. memset(&f, 0, sizeof(f));
  585. memset(&ssn, 0, sizeof(ssn));
  586. p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
  587. FLOW_INITIALIZE(&f);
  588. f.protoctx = (void *)&ssn;
  589. f.flags |= FLOW_IPV4;
  590. p->flow = &f;
  591. p->flowflags |= FLOW_PKT_TOSERVER;
  592. p->flowflags |= FLOW_PKT_ESTABLISHED;
  593. p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
  594. f.alproto = ALPROTO_HTTP;
  595. StreamTcpInitConfig(TRUE);
  596. de_ctx = DetectEngineCtxInit();
  597. if (de_ctx == NULL)
  598. goto end;
  599. de_ctx->flags |= DE_QUIET;
  600. de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
  601. "(msg:\"http header test\"; "
  602. "content:!\"CO\"; offset:3; http_method; "
  603. "sid:1;)");
  604. if (de_ctx->sig_list == NULL)
  605. goto end;
  606. SigGroupBuild(de_ctx);
  607. DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
  608. int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
  609. if (r != 0) {
  610. printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
  611. result = 0;
  612. goto end;
  613. }
  614. http_state = f.alstate;
  615. if (http_state == NULL) {
  616. printf("no http state: ");
  617. result = 0;
  618. goto end;
  619. }
  620. /* do detect */
  621. SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
  622. if (!(PacketAlertCheck(p, 1))) {
  623. printf("sid 1 didn't match but should have: ");
  624. goto end;
  625. }
  626. result = 1;
  627. end:
  628. if (de_ctx != NULL)
  629. SigGroupCleanup(de_ctx);
  630. if (de_ctx != NULL)
  631. SigCleanSignatures(de_ctx);
  632. if (de_ctx != NULL)
  633. DetectEngineCtxFree(de_ctx);
  634. StreamTcpFreeConfig(TRUE);
  635. FLOW_DESTROY(&f);
  636. UTHFreePackets(&p, 1);
  637. return result;
  638. }
  639. /**
  640. * \test Test that the http_method content matches against a http request
  641. * which holds the content.
  642. */
  643. static int DetectEngineHttpMethodTest08(void)
  644. {
  645. TcpSession ssn;
  646. Packet *p = NULL;
  647. ThreadVars th_v;
  648. DetectEngineCtx *de_ctx = NULL;
  649. DetectEngineThreadCtx *det_ctx = NULL;
  650. HtpState *http_state = NULL;
  651. Flow f;
  652. uint8_t http_buf[] =
  653. "CONNECT /index.html HTTP/1.0\r\n"
  654. "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
  655. uint32_t http_len = sizeof(http_buf) - 1;
  656. int result = 0;
  657. memset(&th_v, 0, sizeof(th_v));
  658. memset(&f, 0, sizeof(f));
  659. memset(&ssn, 0, sizeof(ssn));
  660. p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
  661. FLOW_INITIALIZE(&f);
  662. f.protoctx = (void *)&ssn;
  663. f.flags |= FLOW_IPV4;
  664. p->flow = &f;
  665. p->flowflags |= FLOW_PKT_TOSERVER;
  666. p->flowflags |= FLOW_PKT_ESTABLISHED;
  667. p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
  668. f.alproto = ALPROTO_HTTP;
  669. StreamTcpInitConfig(TRUE);
  670. de_ctx = DetectEngineCtxInit();
  671. if (de_ctx == NULL)
  672. goto end;
  673. de_ctx->flags |= DE_QUIET;
  674. de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
  675. "(msg:\"http header test\"; "
  676. "content:!\"ECT\"; offset:3; http_method; "
  677. "sid:1;)");
  678. if (de_ctx->sig_list == NULL)
  679. goto end;
  680. SigGroupBuild(de_ctx);
  681. DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
  682. int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
  683. if (r != 0) {
  684. printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
  685. result = 0;
  686. goto end;
  687. }
  688. http_state = f.alstate;
  689. if (http_state == NULL) {
  690. printf("no http state: ");
  691. result = 0;
  692. goto end;
  693. }
  694. /* do detect */
  695. SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
  696. if (PacketAlertCheck(p, 1)) {
  697. printf("sid 1 matched but shouldn't have: ");
  698. goto end;
  699. }
  700. result = 1;
  701. end:
  702. if (de_ctx != NULL)
  703. SigGroupCleanup(de_ctx);
  704. if (de_ctx != NULL)
  705. SigCleanSignatures(de_ctx);
  706. if (de_ctx != NULL)
  707. DetectEngineCtxFree(de_ctx);
  708. StreamTcpFreeConfig(TRUE);
  709. FLOW_DESTROY(&f);
  710. UTHFreePackets(&p, 1);
  711. return result;
  712. }
  713. /**
  714. * \test Test that the http_method content matches against a http request
  715. * which holds the content.
  716. */
  717. static int DetectEngineHttpMethodTest09(void)
  718. {
  719. TcpSession ssn;
  720. Packet *p = NULL;
  721. ThreadVars th_v;
  722. DetectEngineCtx *de_ctx = NULL;
  723. DetectEngineThreadCtx *det_ctx = NULL;
  724. HtpState *http_state = NULL;
  725. Flow f;
  726. uint8_t http_buf[] =
  727. "CONNECT /index.html HTTP/1.0\r\n"
  728. "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
  729. uint32_t http_len = sizeof(http_buf) - 1;
  730. int result = 0;
  731. memset(&th_v, 0, sizeof(th_v));
  732. memset(&f, 0, sizeof(f));
  733. memset(&ssn, 0, sizeof(ssn));
  734. p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
  735. FLOW_INITIALIZE(&f);
  736. f.protoctx = (void *)&ssn;
  737. f.flags |= FLOW_IPV4;
  738. p->flow = &f;
  739. p->flowflags |= FLOW_PKT_TOSERVER;
  740. p->flowflags |= FLOW_PKT_ESTABLISHED;
  741. p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
  742. f.alproto = ALPROTO_HTTP;
  743. StreamTcpInitConfig(TRUE);
  744. de_ctx = DetectEngineCtxInit();
  745. if (de_ctx == NULL)
  746. goto end;
  747. de_ctx->flags |= DE_QUIET;
  748. de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
  749. "(msg:\"http header test\"; "
  750. "content:\"CON\"; offset:3; http_method; "
  751. "sid:1;)");
  752. if (de_ctx->sig_list == NULL)
  753. goto end;
  754. SigGroupBuild(de_ctx);
  755. DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
  756. int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
  757. if (r != 0) {
  758. printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
  759. result = 0;
  760. goto end;
  761. }
  762. http_state = f.alstate;
  763. if (http_state == NULL) {
  764. printf("no http state: ");
  765. result = 0;
  766. goto end;
  767. }
  768. /* do detect */
  769. SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
  770. if (PacketAlertCheck(p, 1)) {
  771. printf("sid 1 matched but shouldn't have: ");
  772. goto end;
  773. }
  774. result = 1;
  775. end:
  776. if (de_ctx != NULL)
  777. SigGroupCleanup(de_ctx);
  778. if (de_ctx != NULL)
  779. SigCleanSignatures(de_ctx);
  780. if (de_ctx != NULL)
  781. DetectEngineCtxFree(de_ctx);
  782. StreamTcpFreeConfig(TRUE);
  783. FLOW_DESTROY(&f);
  784. UTHFreePackets(&p, 1);
  785. return result;
  786. }
  787. /**
  788. * \test Test that the http_method content matches against a http request
  789. * which holds the content.
  790. */
  791. static int DetectEngineHttpMethodTest10(void)
  792. {
  793. TcpSession ssn;
  794. Packet *p = NULL;
  795. ThreadVars th_v;
  796. DetectEngineCtx *de_ctx = NULL;
  797. DetectEngineThreadCtx *det_ctx = NULL;
  798. HtpState *http_state = NULL;
  799. Flow f;
  800. uint8_t http_buf[] =
  801. "CONNECT /index.html HTTP/1.0\r\n"
  802. "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
  803. uint32_t http_len = sizeof(http_buf) - 1;
  804. int result = 0;
  805. memset(&th_v, 0, sizeof(th_v));
  806. memset(&f, 0, sizeof(f));
  807. memset(&ssn, 0, sizeof(ssn));
  808. p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
  809. FLOW_INITIALIZE(&f);
  810. f.protoctx = (void *)&ssn;
  811. f.flags |= FLOW_IPV4;
  812. p->flow = &f;
  813. p->flowflags |= FLOW_PKT_TOSERVER;
  814. p->flowflags |= FLOW_PKT_ESTABLISHED;
  815. p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
  816. f.alproto = ALPROTO_HTTP;
  817. StreamTcpInitConfig(TRUE);
  818. de_ctx = DetectEngineCtxInit();
  819. if (de_ctx == NULL)
  820. goto end;
  821. de_ctx->flags |= DE_QUIET;
  822. de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
  823. "(msg:\"http header test\"; "
  824. "content:\"CO\"; http_method; "
  825. "content:\"EC\"; within:4; http_method; "
  826. "sid:1;)");
  827. if (de_ctx->sig_list == NULL)
  828. goto end;
  829. SigGroupBuild(de_ctx);
  830. DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
  831. int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
  832. if (r != 0) {
  833. printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
  834. result = 0;
  835. goto end;
  836. }
  837. http_state = f.alstate;
  838. if (http_state == NULL) {
  839. printf("no http state: ");
  840. result = 0;
  841. goto end;
  842. }
  843. /* do detect */
  844. SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
  845. if (!PacketAlertCheck(p, 1)) {
  846. printf("sid 1 didn't match but should have: ");
  847. goto end;
  848. }
  849. result = 1;
  850. end:
  851. if (de_ctx != NULL)
  852. SigGroupCleanup(de_ctx);
  853. if (de_ctx != NULL)
  854. SigCleanSignatures(de_ctx);
  855. if (de_ctx != NULL)
  856. DetectEngineCtxFree(de_ctx);
  857. StreamTcpFreeConfig(TRUE);
  858. FLOW_DESTROY(&f);
  859. UTHFreePackets(&p, 1);
  860. return result;
  861. }
  862. /**
  863. * \test Test that the http_method content matches against a http request
  864. * which holds the content.
  865. */
  866. static int DetectEngineHttpMethodTest11(void)
  867. {
  868. TcpSession ssn;
  869. Packet *p = NULL;
  870. ThreadVars th_v;
  871. DetectEngineCtx *de_ctx = NULL;
  872. DetectEngineThreadCtx *det_ctx = NULL;
  873. HtpState *http_state = NULL;
  874. Flow f;
  875. uint8_t http_buf[] =
  876. "CONNECT /index.html HTTP/1.0\r\n"
  877. "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
  878. uint32_t http_len = sizeof(http_buf) - 1;
  879. int result = 0;
  880. memset(&th_v, 0, sizeof(th_v));
  881. memset(&f, 0, sizeof(f));
  882. memset(&ssn, 0, sizeof(ssn));
  883. p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
  884. FLOW_INITIALIZE(&f);
  885. f.protoctx = (void *)&ssn;
  886. f.flags |= FLOW_IPV4;
  887. p->flow = &f;
  888. p->flowflags |= FLOW_PKT_TOSERVER;
  889. p->flowflags |= FLOW_PKT_ESTABLISHED;
  890. p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
  891. f.alproto = ALPROTO_HTTP;
  892. StreamTcpInitConfig(TRUE);
  893. de_ctx = DetectEngineCtxInit();
  894. if (de_ctx == NULL)
  895. goto end;
  896. de_ctx->flags |= DE_QUIET;
  897. de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
  898. "(msg:\"http header test\"; "
  899. "content:\"CO\"; http_method; "
  900. "content:!\"EC\"; within:3; http_method; "
  901. "sid:1;)");
  902. if (de_ctx->sig_list == NULL)
  903. goto end;
  904. SigGroupBuild(de_ctx);
  905. DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
  906. int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
  907. if (r != 0) {
  908. printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
  909. result = 0;
  910. goto end;
  911. }
  912. http_state = f.alstate;
  913. if (http_state == NULL) {
  914. printf("no http state: ");
  915. result = 0;
  916. goto end;
  917. }
  918. /* do detect */
  919. SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
  920. if (!PacketAlertCheck(p, 1)) {
  921. printf("sid 1 didn't match but should have: ");
  922. goto end;
  923. }
  924. result = 1;
  925. end:
  926. if (de_ctx != NULL)
  927. SigGroupCleanup(de_ctx);
  928. if (de_ctx != NULL)
  929. SigCleanSignatures(de_ctx);
  930. if (de_ctx != NULL)
  931. DetectEngineCtxFree(de_ctx);
  932. StreamTcpFreeConfig(TRUE);
  933. FLOW_DESTROY(&f);
  934. UTHFreePackets(&p, 1);
  935. return result;
  936. }
  937. /**
  938. * \test Test that the http_method content matches against a http request
  939. * which holds the content.
  940. */
  941. static int DetectEngineHttpMethodTest12(void)
  942. {
  943. TcpSession ssn;
  944. Packet *p = NULL;
  945. ThreadVars th_v;
  946. DetectEngineCtx *de_ctx = NULL;
  947. DetectEngineThreadCtx *det_ctx = NULL;
  948. HtpState *http_state = NULL;
  949. Flow f;
  950. uint8_t http_buf[] =
  951. "CONNECT /index.html HTTP/1.0\r\n"
  952. "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
  953. uint32_t http_len = sizeof(http_buf) - 1;
  954. int result = 0;
  955. memset(&th_v, 0, sizeof(th_v));
  956. memset(&f, 0, sizeof(f));
  957. memset(&ssn, 0, sizeof(ssn));
  958. p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
  959. FLOW_INITIALIZE(&f);
  960. f.protoctx = (void *)&ssn;
  961. f.flags |= FLOW_IPV4;
  962. p->flow = &f;
  963. p->flowflags |= FLOW_PKT_TOSERVER;
  964. p->flowflags |= FLOW_PKT_ESTABLISHED;
  965. p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
  966. f.alproto = ALPROTO_HTTP;
  967. StreamTcpInitConfig(TRUE);
  968. de_ctx = DetectEngineCtxInit();
  969. if (de_ctx == NULL)
  970. goto end;
  971. de_ctx->flags |= DE_QUIET;
  972. de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
  973. "(msg:\"http header test\"; "
  974. "content:\"CO\"; http_method; "
  975. "content:\"EC\"; within:3; http_method; "
  976. "sid:1;)");
  977. if (de_ctx->sig_list == NULL)
  978. goto end;
  979. SigGroupBuild(de_ctx);
  980. DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
  981. int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
  982. if (r != 0) {
  983. printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
  984. result = 0;
  985. goto end;
  986. }
  987. http_state = f.alstate;
  988. if (http_state == NULL) {
  989. printf("no http state: ");
  990. result = 0;
  991. goto end;
  992. }
  993. /* do detect */
  994. SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
  995. if (PacketAlertCheck(p, 1)) {
  996. printf("sid 1 matched but shouldn't have: ");
  997. goto end;
  998. }
  999. result = 1;
  1000. end:
  1001. if (de_ctx != NULL)
  1002. SigGroupCleanup(de_ctx);
  1003. if (de_ctx != NULL)
  1004. SigCleanSignatures(de_ctx);
  1005. if (de_ctx != NULL)
  1006. DetectEngineCtxFree(de_ctx);
  1007. StreamTcpFreeConfig(TRUE);
  1008. FLOW_DESTROY(&f);
  1009. UTHFreePackets(&p, 1);
  1010. return result;
  1011. }
  1012. /**
  1013. * \test Test that the http_method content matches against a http request
  1014. * which holds the content.
  1015. */
  1016. static int DetectEngineHttpMethodTest13(void)
  1017. {
  1018. TcpSession ssn;
  1019. Packet *p = NULL;
  1020. ThreadVars th_v;
  1021. DetectEngineCtx *de_ctx = NULL;
  1022. DetectEngineThreadCtx *det_ctx = NULL;
  1023. HtpState *http_state = NULL;
  1024. Flow f;
  1025. uint8_t http_buf[] =
  1026. "CONNECT /index.html HTTP/1.0\r\n"
  1027. "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
  1028. uint32_t http_len = sizeof(http_buf) - 1;
  1029. int result = 0;
  1030. memset(&th_v, 0, sizeof(th_v));
  1031. memset(&f, 0, sizeof(f));
  1032. memset(&ssn, 0, sizeof(ssn));
  1033. p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
  1034. FLOW_INITIALIZE(&f);
  1035. f.protoctx = (void *)&ssn;
  1036. f.flags |= FLOW_IPV4;
  1037. p->flow = &f;
  1038. p->flowflags |= FLOW_PKT_TOSERVER;
  1039. p->flowflags |= FLOW_PKT_ESTABLISHED;
  1040. p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
  1041. f.alproto = ALPROTO_HTTP;
  1042. StreamTcpInitConfig(TRUE);
  1043. de_ctx = DetectEngineCtxInit();
  1044. if (de_ctx == NULL)
  1045. goto end;
  1046. de_ctx->flags |= DE_QUIET;
  1047. de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
  1048. "(msg:\"http header test\"; "
  1049. "content:\"CO\"; http_method; "
  1050. "content:!\"EC\"; within:4; http_method; "
  1051. "sid:1;)");
  1052. if (de_ctx->sig_list == NULL)
  1053. goto end;
  1054. SigGroupBuild(de_ctx);
  1055. DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
  1056. int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
  1057. if (r != 0) {
  1058. printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
  1059. result = 0;
  1060. goto end;
  1061. }
  1062. http_state = f.alstate;
  1063. if (http_state == NULL) {
  1064. printf("no http state: ");
  1065. result = 0;
  1066. goto end;
  1067. }
  1068. /* do detect */
  1069. SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
  1070. if (PacketAlertCheck(p, 1)) {
  1071. printf("sid 1 matched but shouldn't have: ");
  1072. goto end;
  1073. }
  1074. result = 1;
  1075. end:
  1076. if (de_ctx != NULL)
  1077. SigGroupCleanup(de_ctx);
  1078. if (de_ctx != NULL)
  1079. SigCleanSignatures(de_ctx);
  1080. if (de_ctx != NULL)
  1081. DetectEngineCtxFree(de_ctx);
  1082. StreamTcpFreeConfig(TRUE);
  1083. FLOW_DESTROY(&f);
  1084. UTHFreePackets(&p, 1);
  1085. return result;
  1086. }
  1087. /**
  1088. * \test Test that the http_method content matches against a http request
  1089. * which holds the content.
  1090. */
  1091. static int DetectEngineHttpMethodTest14(void)
  1092. {
  1093. TcpSession ssn;
  1094. Packet *p = NULL;
  1095. ThreadVars th_v;
  1096. DetectEngineCtx *de_ctx = NULL;
  1097. DetectEngineThreadCtx *det_ctx = NULL;
  1098. HtpState *http_state = NULL;
  1099. Flow f;
  1100. uint8_t http_buf[] =
  1101. "CONNECT /index.html HTTP/1.0\r\n"
  1102. "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
  1103. uint32_t http_len = sizeof(http_buf) - 1;
  1104. int result = 0;
  1105. memset(&th_v, 0, sizeof(th_v));
  1106. memset(&f, 0, sizeof(f));
  1107. memset(&ssn, 0, sizeof(ssn));
  1108. p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
  1109. FLOW_INITIALIZE(&f);
  1110. f.protoctx = (void *)&ssn;
  1111. f.flags |= FLOW_IPV4;
  1112. p->flow = &f;
  1113. p->flowflags |= FLOW_PKT_TOSERVER;
  1114. p->flowflags |= FLOW_PKT_ESTABLISHED;
  1115. p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
  1116. f.alproto = ALPROTO_HTTP;
  1117. StreamTcpInitConfig(TRUE);
  1118. de_ctx = DetectEngineCtxInit();
  1119. if (de_ctx == NULL)
  1120. goto end;
  1121. de_ctx->flags |= DE_QUIET;
  1122. de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
  1123. "(msg:\"http header test\"; "
  1124. "content:\"CO\"; http_method; "
  1125. "content:\"EC\"; distance:2; http_method; "
  1126. "sid:1;)");
  1127. if (de_ctx->sig_list == NULL)
  1128. goto end;
  1129. SigGroupBuild(de_ctx);
  1130. DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
  1131. int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
  1132. if (r != 0) {
  1133. printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
  1134. result = 0;
  1135. goto end;
  1136. }
  1137. http_state = f.alstate;
  1138. if (http_state == NULL) {
  1139. printf("no http state: ");
  1140. result = 0;
  1141. goto end;
  1142. }
  1143. /* do detect */
  1144. SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
  1145. if (!PacketAlertCheck(p, 1)) {
  1146. printf("sid 1 didn't match but should have: ");
  1147. goto end;
  1148. }
  1149. result = 1;
  1150. end:
  1151. if (de_ctx != NULL)
  1152. SigGroupCleanup(de_ctx);
  1153. if (de_ctx != NULL)
  1154. SigCleanSignatures(de_ctx);
  1155. if (de_ctx != NULL)
  1156. DetectEngineCtxFree(de_ctx);
  1157. StreamTcpFreeConfig(TRUE);
  1158. FLOW_DESTROY(&f);
  1159. UTHFreePackets(&p, 1);
  1160. return result;
  1161. }
  1162. /**
  1163. * \test Test that the http_method content matches against a http request
  1164. * which holds the content.
  1165. */
  1166. static int DetectEngineHttpMethodTest15(void)
  1167. {
  1168. TcpSession ssn;
  1169. Packet *p = NULL;
  1170. ThreadVars th_v;
  1171. DetectEngineCtx *de_ctx = NULL;
  1172. DetectEngineThreadCtx *det_ctx = NULL;
  1173. HtpState *http_state = NULL;
  1174. Flow f;
  1175. uint8_t http_buf[] =
  1176. "CONNECT /index.html HTTP/1.0\r\n"
  1177. "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
  1178. uint32_t http_len = sizeof(http_buf) - 1;
  1179. int result = 0;
  1180. memset(&th_v, 0, sizeof(th_v));
  1181. memset(&f, 0, sizeof(f));
  1182. memset(&ssn, 0, sizeof(ssn));
  1183. p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
  1184. FLOW_INITIALIZE(&f);
  1185. f.protoctx = (void *)&ssn;
  1186. f.flags |= FLOW_IPV4;
  1187. p->flow = &f;
  1188. p->flowflags |= FLOW_PKT_TOSERVER;
  1189. p->flowflags |= FLOW_PKT_ESTABLISHED;
  1190. p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
  1191. f.alproto = ALPROTO_HTTP;
  1192. StreamTcpInitConfig(TRUE);
  1193. de_ctx = DetectEngineCtxInit();
  1194. if (de_ctx == NULL)
  1195. goto end;
  1196. de_ctx->flags |= DE_QUIET;
  1197. de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
  1198. "(msg:\"http header test\"; "
  1199. "content:\"CO\"; http_method; "
  1200. "content:!\"EC\"; distance:3; http_method; "
  1201. "sid:1;)");
  1202. if (de_ctx->sig_list == NULL)
  1203. goto end;
  1204. SigGroupBuild(de_ctx);
  1205. DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
  1206. int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
  1207. if (r != 0) {
  1208. printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
  1209. result = 0;
  1210. goto end;
  1211. }
  1212. http_state = f.alstate;
  1213. if (http_state == NULL) {
  1214. printf("no http state: ");
  1215. result = 0;
  1216. goto end;
  1217. }
  1218. /* do detect */
  1219. SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
  1220. if (!PacketAlertCheck(p, 1)) {
  1221. printf("sid 1 didn't match but should have: ");
  1222. goto end;
  1223. }
  1224. result = 1;
  1225. end:
  1226. if (de_ctx != NULL)
  1227. SigGroupCleanup(de_ctx);
  1228. if (de_ctx != NULL)
  1229. SigCleanSignatures(de_ctx);
  1230. if (de_ctx != NULL)
  1231. DetectEngineCtxFree(de_ctx);
  1232. StreamTcpFreeConfig(TRUE);
  1233. FLOW_DESTROY(&f);
  1234. UTHFreePackets(&p, 1);
  1235. return result;
  1236. }
  1237. /**
  1238. * \test Test that the http_method content matches against a http request
  1239. * which holds the content.
  1240. */
  1241. static int DetectEngineHttpMethodTest16(void)
  1242. {
  1243. TcpSession ssn;
  1244. Packet *p = NULL;
  1245. ThreadVars th_v;
  1246. DetectEngineCtx *de_ctx = NULL;
  1247. DetectEngineThreadCtx *det_ctx = NULL;
  1248. HtpState *http_state = NULL;
  1249. Flow f;
  1250. uint8_t http_buf[] =
  1251. "CONNECT /index.html HTTP/1.0\r\n"
  1252. "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
  1253. uint32_t http_len = sizeof(http_buf) - 1;
  1254. int result = 0;
  1255. memset(&th_v, 0, sizeof(th_v));
  1256. memset(&f, 0, sizeof(f));
  1257. memset(&ssn, 0, sizeof(ssn));
  1258. p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
  1259. FLOW_INITIALIZE(&f);
  1260. f.protoctx = (void *)&ssn;
  1261. f.flags |= FLOW_IPV4;
  1262. p->flow = &f;
  1263. p->flowflags |= FLOW_PKT_TOSERVER;
  1264. p->flowflags |= FLOW_PKT_ESTABLISHED;
  1265. p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
  1266. f.alproto = ALPROTO_HTTP;
  1267. StreamTcpInitConfig(TRUE);
  1268. de_ctx = DetectEngineCtxInit();
  1269. if (de_ctx == NULL)
  1270. goto end;
  1271. de_ctx->flags |= DE_QUIET;
  1272. de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
  1273. "(msg:\"http header test\"; "
  1274. "content:\"CO\"; http_method; "
  1275. "content:\"EC\"; distance:3; http_method; "
  1276. "sid:1;)");
  1277. if (de_ctx->sig_list == NULL)
  1278. goto end;
  1279. SigGroupBuild(de_ctx);
  1280. DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
  1281. int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
  1282. if (r != 0) {
  1283. printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
  1284. result = 0;
  1285. goto end;
  1286. }
  1287. http_state = f.alstate;
  1288. if (http_state == NULL) {
  1289. printf("no http state: ");
  1290. result = 0;
  1291. goto end;
  1292. }
  1293. /* do detect */
  1294. SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
  1295. if (PacketAlertCheck(p, 1)) {
  1296. printf("sid 1 matched but shouldn't have: ");
  1297. goto end;
  1298. }
  1299. result = 1;
  1300. end:
  1301. if (de_ctx != NULL)
  1302. SigGroupCleanup(de_ctx);
  1303. if (de_ctx != NULL)
  1304. SigCleanSignatures(de_ctx);
  1305. if (de_ctx != NULL)
  1306. DetectEngineCtxFree(de_ctx);
  1307. StreamTcpFreeConfig(TRUE);
  1308. FLOW_DESTROY(&f);
  1309. UTHFreePackets(&p, 1);
  1310. return result;
  1311. }
  1312. /**
  1313. * \test Test that the http_method content matches against a http request
  1314. * which holds the content.
  1315. */
  1316. static int DetectEngineHttpMethodTest17(void)
  1317. {
  1318. TcpSession ssn;
  1319. Packet *p = NULL;
  1320. ThreadVars th_v;
  1321. DetectEngineCtx *de_ctx = NULL;
  1322. DetectEngineThreadCtx *det_ctx = NULL;
  1323. HtpState *http_state = NULL;
  1324. Flow f;
  1325. uint8_t http_buf[] =
  1326. "CONNECT /index.html HTTP/1.0\r\n"
  1327. "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
  1328. uint32_t http_len = sizeof(http_buf) - 1;
  1329. int result = 0;
  1330. memset(&th_v, 0, sizeof(th_v));
  1331. memset(&f, 0, sizeof(f));
  1332. memset(&ssn, 0, sizeof(ssn));
  1333. p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
  1334. FLOW_INITIALIZE(&f);
  1335. f.protoctx = (void *)&ssn;
  1336. f.flags |= FLOW_IPV4;
  1337. p->flow = &f;
  1338. p->flowflags |= FLOW_PKT_TOSERVER;
  1339. p->flowflags |= FLOW_PKT_ESTABLISHED;
  1340. p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
  1341. f.alproto = ALPROTO_HTTP;
  1342. StreamTcpInitConfig(TRUE);
  1343. de_ctx = DetectEngineCtxInit();
  1344. if (de_ctx == NULL)
  1345. goto end;
  1346. de_ctx->flags |= DE_QUIET;
  1347. de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
  1348. "(msg:\"http header test\"; "
  1349. "content:\"CO\"; http_method; "
  1350. "content:!\"EC\"; distance:2; http_method; "
  1351. "sid:1;)");
  1352. if (de_ctx->sig_list == NULL)
  1353. goto end;
  1354. SigGroupBuild(de_ctx);
  1355. DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
  1356. int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
  1357. if (r != 0) {
  1358. printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
  1359. result = 0;
  1360. goto end;
  1361. }
  1362. http_state = f.alstate;
  1363. if (http_state == NULL) {
  1364. printf("no http state: ");
  1365. result = 0;
  1366. goto end;
  1367. }
  1368. /* do detect */
  1369. SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
  1370. if (PacketAlertCheck(p, 1)) {
  1371. printf("sid 1 matched but shouldn't have: ");
  1372. goto end;
  1373. }
  1374. result = 1;
  1375. end:
  1376. if (de_ctx != NULL)
  1377. SigGroupCleanup(de_ctx);
  1378. if (de_ctx != NULL)
  1379. SigCleanSignatures(de_ctx);
  1380. if (de_ctx != NULL)
  1381. DetectEngineCtxFree(de_ctx);
  1382. StreamTcpFreeConfig(TRUE);
  1383. FLOW_DESTROY(&f);
  1384. UTHFreePackets(&p, 1);
  1385. return result;
  1386. }
  1387. #endif /* UNITTESTS */
  1388. void DetectEngineHttpMethodRegisterTests(void)
  1389. {
  1390. #ifdef UNITTESTS
  1391. UtRegisterTest("DetectEngineHttpMethodTest01",
  1392. DetectEngineHttpMethodTest01, 1);
  1393. UtRegisterTest("DetectEngineHttpMethodTest02",
  1394. DetectEngineHttpMethodTest02, 1);
  1395. UtRegisterTest("DetectEngineHttpMethodTest03",
  1396. DetectEngineHttpMethodTest03, 1);
  1397. UtRegisterTest("DetectEngineHttpMethodTest04",
  1398. DetectEngineHttpMethodTest04, 1);
  1399. UtRegisterTest("DetectEngineHttpMethodTest05",
  1400. DetectEngineHttpMethodTest05, 1);
  1401. UtRegisterTest("DetectEngineHttpMethodTest06",
  1402. DetectEngineHttpMethodTest06, 1);
  1403. UtRegisterTest("DetectEngineHttpMethodTest07",
  1404. DetectEngineHttpMethodTest07, 1);
  1405. UtRegisterTest("DetectEngineHttpMethodTest08",
  1406. DetectEngineHttpMethodTest08, 1);
  1407. UtRegisterTest("DetectEngineHttpMethodTest09",
  1408. DetectEngineHttpMethodTest09, 1);
  1409. UtRegisterTest("DetectEngineHttpMethodTest10",
  1410. DetectEngineHttpMethodTest10, 1);
  1411. UtRegisterTest("DetectEngineHttpMethodTest11",
  1412. DetectEngineHttpMethodTest11, 1);
  1413. UtRegisterTest("DetectEngineHttpMethodTest12",
  1414. DetectEngineHttpMethodTest12, 1);
  1415. UtRegisterTest("DetectEngineHttpMethodTest13",
  1416. DetectEngineHttpMethodTest13, 1);
  1417. UtRegisterTest("DetectEngineHttpMethodTest14",
  1418. DetectEngineHttpMethodTest14, 1);
  1419. UtRegisterTest("DetectEngineHttpMethodTest15",
  1420. DetectEngineHttpMethodTest15, 1);
  1421. UtRegisterTest("DetectEngineHttpMethodTest16",
  1422. DetectEngineHttpMethodTest16, 1);
  1423. UtRegisterTest("DetectEngineHttpMethodTest17",
  1424. DetectEngineHttpMethodTest17, 1);
  1425. #endif /* UNITTESTS */
  1426. return;
  1427. }
  1428. /**
  1429. * @}
  1430. */