huijio commited on
Commit
f569489
Β·
verified Β·
1 Parent(s): fc481ed

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +320 -0
app.py ADDED
@@ -0,0 +1,320 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import base64
3
+ import json
4
+ import re
5
+ import html
6
+ from typing import Dict, List, Any
7
+ import pandas as pd
8
+
9
+ # Set page configuration
10
+ st.set_page_config(
11
+ page_title="Proxy Server Decoder",
12
+ page_icon="πŸ”",
13
+ layout="wide",
14
+ initial_sidebar_state="expanded"
15
+ )
16
+
17
+ class ProxyServerDecoder:
18
+ def __init__(self):
19
+ self.results = []
20
+
21
+ def decode_proxy_entry(self, encoded_str: str) -> Dict[str, Any]:
22
+ """Decode a single proxy entry from base64 -> hex -> JSON"""
23
+ try:
24
+ # Add padding if needed
25
+ padding = len(encoded_str) % 4
26
+ if padding:
27
+ encoded_str += '=' * (4 - padding)
28
+
29
+ # Step 1: Base64 decode
30
+ decoded_bytes = base64.b64decode(encoded_str)
31
+
32
+ # Step 2: Convert hex to ASCII
33
+ hex_string = decoded_bytes.decode('ascii')
34
+ json_string = bytes.fromhex(hex_string).decode('ascii')
35
+
36
+ # Step 3: Parse JSON
37
+ return {
38
+ "status": "success",
39
+ "decoded_data": json.loads(json_string),
40
+ "original_length": len(encoded_str)
41
+ }
42
+ except Exception as e:
43
+ return {
44
+ "status": "error",
45
+ "error": f"Decoding failed: {str(e)}",
46
+ "original_length": len(encoded_str)
47
+ }
48
+
49
+ def extract_entries_from_html(self, html_content: str) -> List[str]:
50
+ """Extract base64 entries from HTML data-ss attribute"""
51
+ try:
52
+ unescaped_html = html.unescape(html_content)
53
+
54
+ # Multiple patterns to catch different HTML formats
55
+ patterns = [
56
+ r'data-ss="\[(.*?)\]"',
57
+ r"data-ss='\[(.*?)\]'",
58
+ r'data-ss=\s*\[\s*(.*?)\s*\]'
59
+ ]
60
+
61
+ data_ss_content = None
62
+ for pattern in patterns:
63
+ match = re.search(pattern, unescaped_html, re.DOTALL)
64
+ if match:
65
+ data_ss_content = match.group(1)
66
+ break
67
+
68
+ if not data_ss_content:
69
+ return []
70
+
71
+ # Extract base64 strings
72
+ base64_pattern = r'["\']([A-Za-z0-9+/=]+)["\']'
73
+ entries = re.findall(base64_pattern, data_ss_content)
74
+
75
+ return entries
76
+ except Exception as e:
77
+ st.error(f"Error extracting from HTML: {e}")
78
+ return []
79
+
80
+ def process_html(self, html_content: str) -> Dict[str, Any]:
81
+ """Process HTML content and decode all entries"""
82
+ entries = self.extract_entries_from_html(html_content)
83
+
84
+ if not entries:
85
+ return {
86
+ "status": "error",
87
+ "message": "No entries found in HTML"
88
+ }
89
+
90
+ results = []
91
+ success_count = 0
92
+
93
+ for i, entry in enumerate(entries):
94
+ result = self.decode_proxy_entry(entry)
95
+ result_data = {
96
+ "entry_number": i + 1,
97
+ "encoded_string": entry,
98
+ "encoded_preview": f"{entry[:20]}...{entry[-10:]}" if len(entry) > 40 else entry,
99
+ **result
100
+ }
101
+ results.append(result_data)
102
+
103
+ if result["status"] == "success":
104
+ success_count += 1
105
+
106
+ return {
107
+ "status": "success",
108
+ "statistics": {
109
+ "total_entries": len(entries),
110
+ "successful_decodes": success_count,
111
+ "failed_decodes": len(entries) - success_count,
112
+ "success_rate": f"{(success_count/len(entries))*100:.1f}%"
113
+ },
114
+ "results": results
115
+ }
116
+
117
+ def process_single_entry(self, encoded_string: str) -> Dict[str, Any]:
118
+ """Process a single encoded string"""
119
+ return self.decode_proxy_entry(encoded_string)
120
+
121
+ def main():
122
+ # Initialize decoder
123
+ decoder = ProxyServerDecoder()
124
+
125
+ # Sidebar
126
+ st.sidebar.title("πŸ” Proxy Server Decoder")
127
+ st.sidebar.markdown("""
128
+ Decode base64-encoded proxy server information from HTML script tags.
129
+
130
+ ### How to use:
131
+ 1. **Single Entry**: Paste a base64 string
132
+ 2. **HTML Parser**: Paste HTML with data-ss attribute
133
+ 3. View decoded results in tables and JSON
134
+
135
+ ### Input Format:
136
+ ```html
137
+ <script data-ss="[&quot;BASE64_STRING&quot;,...]"></script>
138
+ ```
139
+ """)
140
+
141
+ # Sample data
142
+ sample_html = '''<script
143
+ id="serverSelectorScript"
144
+ data-u="&quot;https://adnade.net/ptp/?user=platformsincome&amp;subid=131370&quot;"
145
+ data-d="0"
146
+ data-ss="[&quot;N2IyMjY5NjQyMjNhMzIzMDMxMmMyMjc1NzI2YzIyM2EyMjY4NzQ3NDcwNzMzYTVjMmY1YzJmMzEzMDM4MmUzMTM4MzEyZTMxMzEyZTMxMzczMTVjMmY1ZjVmNjM3MDMyMmU3MDY4NzAyMjJjMjI2ZTYxNmQ2NTIyM2EyMjcwNzM3OTYzNjg3YTRjNmY3MzQxNmU2NzY1NmM2NTczMzI0ZDIyN2Q=&quot;,&quot;N2IyMjY5NjQyMjNhMzEzODM1MmMyMjc1NzI2YzIyM2EyMjY4NzQ3NDcwNzMzYTVjMmY1YzJmMzkzNTJlMzIzMTM0MmUzNTMzMmUzNDM4NWMyZjVmNWY2MzcwMzIyZTcwNjg3MDIyMmMyMjZlNjE2ZDY1MjIzYTIyNmQ2NTc2NTM3MDYxNjM2NTU3NjE3MjczNjE3NzUwMjI3ZA==&quot;]"
147
+ ></script>'''
148
+
149
+ # Main content
150
+ st.title("πŸ” Proxy Server Decoder")
151
+
152
+ # Tabs for different functionality
153
+ tab1, tab2, tab3 = st.tabs(["πŸ“„ HTML Parser", "πŸ”€ Single Entry", "πŸ“Š Results"])
154
+
155
+ with tab1:
156
+ st.header("HTML Content Parser")
157
+
158
+ col1, col2 = st.columns([2, 1])
159
+
160
+ with col1:
161
+ html_input = st.text_area(
162
+ "Paste your HTML content here:",
163
+ value=sample_html,
164
+ height=300,
165
+ placeholder="Paste HTML with data-ss attribute here..."
166
+ )
167
+
168
+ with col2:
169
+ st.markdown("### Quick Actions")
170
+ if st.button("πŸš€ Use Sample Data", use_container_width=True):
171
+ st.session_state.sample_used = True
172
+
173
+ if st.button("πŸ—‘οΈ Clear Input", use_container_width=True):
174
+ html_input = ""
175
+ st.rerun()
176
+
177
+ st.markdown("---")
178
+ st.markdown("""
179
+ **Expected Format:**
180
+ ```html
181
+ <script data-ss="[&quot;base64_str1&quot;,&quot;base64_str2&quot;]">
182
+ ```
183
+ """)
184
+
185
+ if st.button("πŸ” Parse HTML", type="primary", use_container_width=True):
186
+ with st.spinner("Processing HTML content..."):
187
+ result = decoder.process_html(html_input)
188
+ st.session_state.html_result = result
189
+
190
+ if result["status"] == "success":
191
+ st.success(f"βœ… Successfully processed {result['statistics']['total_entries']} entries!")
192
+ else:
193
+ st.error(f"❌ {result.get('message', 'Processing failed')}")
194
+
195
+ with tab2:
196
+ st.header("Single Entry Decoder")
197
+
198
+ col1, col2 = st.columns([3, 1])
199
+
200
+ with col1:
201
+ single_input = st.text_area(
202
+ "Enter base64 encoded string:",
203
+ height=150,
204
+ placeholder="Paste your base64 string here..."
205
+ )
206
+
207
+ with col2:
208
+ st.markdown("### Example")
209
+ st.code("N2IyMjY5NjQyMjNhMz...", language="text")
210
+
211
+ if st.button("πŸ” Decode Single Entry", type="primary", use_container_width=True):
212
+ if single_input.strip():
213
+ with st.spinner("Decoding entry..."):
214
+ result = decoder.process_single_entry(single_input.strip())
215
+ st.session_state.single_result = result
216
+
217
+ if result["status"] == "success":
218
+ st.success("βœ… Entry decoded successfully!")
219
+ else:
220
+ st.error(f"❌ {result.get('error', 'Decoding failed')}")
221
+ else:
222
+ st.warning("⚠️ Please enter a base64 string")
223
+
224
+ with tab3:
225
+ st.header("Decoding Results")
226
+
227
+ # HTML Results
228
+ if 'html_result' in st.session_state:
229
+ result = st.session_state.html_result
230
+
231
+ if result["status"] == "success":
232
+ # Statistics
233
+ stats = result["statistics"]
234
+ col1, col2, col3, col4 = st.columns(4)
235
+
236
+ with col1:
237
+ st.metric("Total Entries", stats["total_entries"])
238
+ with col2:
239
+ st.metric("Successful", stats["successful_decodes"])
240
+ with col3:
241
+ st.metric("Failed", stats["failed_decodes"])
242
+ with col4:
243
+ st.metric("Success Rate", stats["success_rate"])
244
+
245
+ # Results table
246
+ st.subheader("Decoded Entries")
247
+
248
+ # Prepare data for table
249
+ table_data = []
250
+ for entry in result["results"]:
251
+ row = {
252
+ "Entry #": entry["entry_number"],
253
+ "Status": "βœ… Success" if entry["status"] == "success" else "❌ Failed",
254
+ "Preview": entry["encoded_preview"],
255
+ "Length": entry["original_length"]
256
+ }
257
+
258
+ if entry["status"] == "success":
259
+ decoded = entry["decoded_data"]
260
+ # Add decoded fields to row
261
+ for key, value in decoded.items():
262
+ row[key] = str(value)[:50] + "..." if len(str(value)) > 50 else str(value)
263
+
264
+ table_data.append(row)
265
+
266
+ # Display as dataframe
267
+ if table_data:
268
+ df = pd.DataFrame(table_data)
269
+ st.dataframe(df, use_container_width=True)
270
+
271
+ # Detailed view
272
+ st.subheader("Detailed Results")
273
+ for entry in result["results"]:
274
+ with st.expander(f"Entry #{entry['entry_number']} - {entry['encoded_preview']}"):
275
+ if entry["status"] == "success":
276
+ st.json(entry["decoded_data"])
277
+ else:
278
+ st.error(entry["error"])
279
+
280
+ # Download results
281
+ st.subheader("Export Results")
282
+ json_str = json.dumps(result, indent=2)
283
+ st.download_button(
284
+ label="πŸ“₯ Download JSON Results",
285
+ data=json_str,
286
+ file_name="decoded_results.json",
287
+ mime="application/json",
288
+ use_container_width=True
289
+ )
290
+
291
+ # Single Entry Results
292
+ elif 'single_result' in st.session_state:
293
+ result = st.session_state.single_result
294
+
295
+ if result["status"] == "success":
296
+ st.success("βœ… Decoding Successful!")
297
+ st.json(result["decoded_data"])
298
+
299
+ # Download single result
300
+ json_str = json.dumps(result["decoded_data"], indent=2)
301
+ st.download_button(
302
+ label="πŸ“₯ Download Decoded Data",
303
+ data=json_str,
304
+ file_name="single_decoded.json",
305
+ mime="application/json"
306
+ )
307
+ else:
308
+ st.error(f"❌ Decoding Failed: {result['error']}")
309
+
310
+ else:
311
+ st.info("πŸ‘† Process some data in the other tabs to see results here!")
312
+
313
+ # Footer
314
+ st.markdown("---")
315
+ st.markdown(
316
+ "**Proxy Server Decoder** β€’ Decodes base64 β†’ hex β†’ JSON proxy information"
317
+ )
318
+
319
+ if __name__ == "__main__":
320
+ main()