1 package main 2 3 import ( 4 "encoding/base64" 5 "encoding/hex" 6 "fmt" 7 "math/rand" 8 "net/http" 9 "net/url" 10 "strings" 11 "time" 12 13 "vimagination.zapto.org/memio" 14 ) 15 16 type Hex2Dec struct { 17 Grabber 18 } 19 20 func (h Hex2Dec) Grab(r http.Request) string { 21 hx := h.Grabber.Grab(r) 22 dec := make([]byte, hex.DecodedLen(len(hx))) 23 _, err := hex.Decode(dec, []byte(hx)) 24 e(err) 25 return string(dec) 26 } 27 28 type Reverse struct { 29 Grabber 30 } 31 32 func (rv Reverse) Grab(r http.Request) string { 33 str := rv.Grabber.Grab(r) 34 rts := make([]byte, len(str)) 35 for n, b := range []byte(str) { 36 rts[len(rts)-n-1] = b 37 } 38 return string(rts) 39 } 40 41 type Base64Decode struct { 42 Grabber 43 } 44 45 func (b Base64Decode) Grab(r http.Request) string { 46 str := b.Grabber.Grab(r) 47 res, err := base64.StdEncoding.DecodeString(strings.Replace(str, "%3D", "=", -1)) 48 e(err) 49 return string(res) 50 } 51 52 type Base64Encode struct { 53 Grabber 54 } 55 56 func (b Base64Encode) Grab(r http.Request) string { 57 str := b.Grabber.Grab(r) 58 return base64.StdEncoding.EncodeToString([]byte(str)) 59 } 60 61 type XOR struct { 62 Input, Key Grabber 63 } 64 65 func (x XOR) Grab(r http.Request) string { 66 i := x.Input.Grab(r) 67 k := x.Key.Grab(r) 68 o := make([]byte, len(i)) 69 for n, c := range []byte(i) { 70 o[n] = c ^ k[n%len(k)] 71 } 72 return string(o) 73 } 74 75 type Combine struct { 76 Prefix, Suffix Grabber 77 } 78 79 func (c Combine) Grab(r http.Request) string { 80 prefix := c.Prefix.Grab(r) 81 suffix := c.Suffix.Grab(r) 82 return prefix + suffix 83 } 84 85 type Cut struct { 86 Grabber 87 Seperator string 88 Slice int 89 } 90 91 func (c Cut) Grab(r http.Request) string { 92 parts := strings.Split(c.Grabber.Grab(r), c.Seperator) 93 if c.Slice >= len(parts) { 94 panic("invalid slice number") 95 } 96 return parts[c.Slice] 97 } 98 99 type Trim struct { 100 Grabber 101 } 102 103 func (t Trim) Grab(r http.Request) string { 104 return strings.TrimSpace(t.Grabber.Grab(r)) 105 } 106 107 type URLDecode struct { 108 Grabber 109 } 110 111 func (u URLDecode) Grab(r http.Request) string { 112 str, err := url.QueryUnescape(u.Grabber.Grab(r)) 113 e(err) 114 return str 115 } 116 117 type URLEncode struct { 118 Grabber 119 } 120 121 func (u URLEncode) Grab(r http.Request) string { 122 return url.QueryEscape(u.Grabber.Grab(r)) 123 } 124 125 type FindRepeating struct { 126 Grabber 127 } 128 129 func (f FindRepeating) Grab(r http.Request) string { 130 str := f.Grabber.Grab(r) 131 for length := 1; length < len(str); length++ { 132 if r := strings.Repeat(str[:length], 1+(len(str)/length)); r[:len(str)] == str { 133 return str[:length] 134 } 135 } 136 return str 137 } 138 139 type PHPSerialize struct { 140 ObjectName string 141 Fields map[string]interface{} 142 } 143 144 func (p PHPSerialize) Grab(r http.Request) string { 145 var m memio.Buffer 146 fmt.Fprintf(&m, "O:%d:\"%s\":%d:{", len(p.ObjectName), p.ObjectName, len(p.Fields)) 147 for name, field := range p.Fields { 148 oName := "\x00" + p.ObjectName + "\x00" + name 149 fmt.Fprintf(&m, "s:%d:\"%s\";", len(oName), oName) 150 switch f := field.(type) { 151 case Grabber: 152 g := f.Grab(r) 153 fmt.Fprintf(&m, "s:%d:\"%s\";", len(g), g) 154 case string: 155 fmt.Fprintf(&m, "s:%d:\"%s\";", len(f), f) 156 default: 157 panic("type unsupported for PHP serialization") 158 } 159 } 160 fmt.Fprintf(&m, "}") 161 return string(m) 162 } 163 164 var vars = map[string]string{} 165 166 type SetVar struct { 167 Grabber 168 Name string 169 } 170 171 func (s SetVar) Grab(r http.Request) string { 172 str := s.Grabber.Grab(r) 173 vars[s.Name] = str 174 return str 175 } 176 177 type GetVar struct { 178 Name string 179 } 180 181 func (g GetVar) Grab(http.Request) string { 182 return vars[g.Name] 183 } 184 185 const RandomAlphaNum = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 186 187 var ( 188 RandomHex = RandomAlphaNum[:16] 189 RandomLetters = RandomAlphaNum[10:] 190 RandomLowerLetters = RandomLetters[:26] 191 RandomUpperLetters = RandomLetters[26:] 192 RandomNumLowerLetters = RandomAlphaNum[:36] 193 ) 194 195 func init() { 196 rand.Seed(time.Now().UnixNano()) 197 } 198 199 type Random struct { 200 Chars string 201 Length int 202 } 203 204 func (r Random) Grab(http.Request) string { 205 var b memio.Buffer 206 for i := 0; i < r.Length; i++ { 207 b.WriteByte(r.Chars[rand.Intn(len(r.Chars))]) 208 } 209 return string(b) 210 }