forked from client9/libinjection
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhtml5_cli.c
168 lines (151 loc) · 4.1 KB
/
html5_cli.c
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
/**
* Copyright 2012, 2013, 2014 Nick Galbreath
* BSD License -- see COPYING.txt for details
*
* This is for testing against files in ../data/ *.txt
* Reads from stdin or a list of files, and emits if a line
* is a SQLi attack or not, and does basic statistics
*
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "libinjection_html5.h"
#include "libinjection_xss.h"
#include "libinjection.h"
int urlcharmap(char ch);
size_t modp_url_decode(char* dest, const char* s, size_t len);
const char* h5_type_to_string(enum html5_type x);
void print_html5_token(h5_state_t* hs);
int urlcharmap(char ch) {
switch (ch) {
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
case 'a': case 'A': return 10;
case 'b': case 'B': return 11;
case 'c': case 'C': return 12;
case 'd': case 'D': return 13;
case 'e': case 'E': return 14;
case 'f': case 'F': return 15;
default:
return 256;
}
}
size_t modp_url_decode(char* dest, const char* s, size_t len)
{
const char* deststart = dest;
size_t i = 0;
int d = 0;
while (i < len) {
switch (s[i]) {
case '+':
*dest++ = ' ';
i += 1;
break;
case '%':
if (i+2 < len) {
d = (urlcharmap(s[i+1]) << 4) | urlcharmap(s[i+2]);
if ( d < 256) {
*dest = (char) d;
dest++;
i += 3; /* loop will increment one time */
} else {
*dest++ = '%';
i += 1;
}
} else {
*dest++ = '%';
i += 1;
}
break;
default:
*dest++ = s[i];
i += 1;
}
}
*dest = '\0';
return (size_t)(dest - deststart); /* compute "strlen" of dest */
}
const char* h5_type_to_string(enum html5_type x)
{
switch (x) {
case DATA_TEXT: return "DATA_TEXT";
case TAG_NAME_OPEN: return "TAG_NAME_OPEN";
case TAG_NAME_CLOSE: return "TAG_NAME_CLOSE";
case TAG_NAME_SELFCLOSE: return "TAG_NAME_SELFCLOSE";
case TAG_DATA: return "TAG_DATA";
case TAG_CLOSE: return "TAG_CLOSE";
case ATTR_NAME: return "ATTR_NAME";
case ATTR_VALUE: return "ATTR_VALUE";
case TAG_COMMENT: return "TAG_COMMENT";
case DOCTYPE: return "DOCTYPE";
default:
assert(0);
}
}
void print_html5_token(h5_state_t* hs)
{
char* tmp = (char*) malloc(hs->token_len + 1);
memcpy(tmp, hs->token_start, hs->token_len);
/* TODO.. encode to be printable */
tmp[hs->token_len] = '\0';
printf("%s,%d,%s\n",
h5_type_to_string(hs->token_type),
(int) hs->token_len,
tmp);
free(tmp);
}
int main(int argc, const char* argv[])
{
size_t slen;
h5_state_t hs;
char* copy;
int offset = 1;
int flag = 0;
int urldecode = 0;
if (argc < 2) {
fprintf(stderr, "need more args\n");
return 1;
}
while (offset < argc) {
if (strcmp(argv[offset], "-u") == 0) {
offset += 1;
urldecode = 1;
} else if (strcmp(argv[offset], "-f") == 0) {
offset += 1;
flag = atoi(argv[offset]);
offset += 1;
} else {
break;
}
}
/* ATTENTION: argv is a C-string, null terminated. We copy this
* to it's own location, WITHOUT null byte. This way, valgrind
* can see if we run past the buffer.
*/
slen = strlen(argv[offset]);
copy = (char* ) malloc(slen);
memcpy(copy, argv[offset], slen);
if (urldecode) {
slen = modp_url_decode(copy, copy, slen);
}
libinjection_h5_init(&hs, copy, slen, (enum html5_flags) flag);
while (libinjection_h5_next(&hs)) {
print_html5_token(&hs);
}
if (libinjection_is_xss(copy, slen, flag)) {
printf("is injection!\n");
}
free(copy);
return 0;
}