-
Notifications
You must be signed in to change notification settings - Fork 0
/
Online Judge 是如何解决判题端安全性问题的? - 知乎.htm
142 lines (132 loc) · 255 KB
/
Online Judge 是如何解决判题端安全性问题的? - 知乎.htm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<!DOCTYPE html>
<html data-theme="light" data-react-helmet="data-theme" style="" lang="zh"><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"><meta charset="utf-8"><title>Online Judge 是如何解决判题端安全性问题的? - 知乎</title><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"><meta name="renderer" content="webkit"><meta name="force-rendering" content="webkit"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="google-site-verification" content="FTeR0c8arOPKh8c5DYh_9uu98_zJbaWw53J-Sch9MTg"><meta data-react-helmet="true" name="description" property="og:description" content="如何过滤恶意提交的危险代码??分析了一下hustoj的实现,貌似只是通过创建一个低磁盘读写权限的linux用…"><meta data-react-helmet="true" name="keywords" content="Linux,网络安全,信息安全,Online Judge"><link data-react-helmet="true" rel="apple-touch-icon" href="https://static.zhihu.com/heifetz/assets/apple-touch-icon-152.a53ae37b.png"><link data-react-helmet="true" rel="apple-touch-icon" href="https://static.zhihu.com/heifetz/assets/apple-touch-icon-152.a53ae37b.png" sizes="152x152"><link data-react-helmet="true" rel="apple-touch-icon" href="https://static.zhihu.com/heifetz/assets/apple-touch-icon-120.bbce8f18.png" sizes="120x120"><link data-react-helmet="true" rel="apple-touch-icon" href="https://static.zhihu.com/heifetz/assets/apple-touch-icon-76.cbade8f9.png" sizes="76x76"><link data-react-helmet="true" rel="apple-touch-icon" href="https://static.zhihu.com/heifetz/assets/apple-touch-icon-60.8f6c52aa.png" sizes="60x60"><link crossorigin="" rel="shortcut icon" type="image/x-icon" href="https://static.zhihu.com/heifetz/favicon.ico"><link crossorigin="" rel="search" type="application/opensearchdescription+xml" href="https://static.zhihu.com/heifetz/search.xml" title="知乎"><link rel="dns-prefetch" href="https://static.zhimg.com/"><link rel="dns-prefetch" href="https://pic1.zhimg.com/"><link rel="dns-prefetch" href="https://pic2.zhimg.com/"><link rel="dns-prefetch" href="https://pic3.zhimg.com/"><link rel="dns-prefetch" href="https://pic4.zhimg.com/"><style>
.u-safeAreaInset-top {
height: constant(safe-area-inset-top) !important;
height: env(safe-area-inset-top) !important;
}
.u-safeAreaInset-bottom {
height: constant(safe-area-inset-bottom) !important;
height: env(safe-area-inset-bottom) !important;
}
</style><link href="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/main_008.css" crossorigin="" rel="stylesheet"><link crossorigin="" href="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/main_002.css" rel="stylesheet"><script type="text/javascript" async="" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/auto_dup"></script><script nonce="">!function(){"use strict";!function(e,n){var r,t,a,c,o,i=[];function s(e){return function(){i.push([e,arguments])}}function u(e){var n=e;if(!(e instanceof Error||e instanceof ErrorEvent||e instanceof DOMError||e instanceof DOMException)){var r=e.message||e.reason;n=Error(r)}Raven.captureException(n)}n.Raven={captureException:s("captureException"),captureMessage:s("captureMessage"),captureBreadcrumb:s("captureBreadcrumb")},n.addEventListener("unhandledrejection",u),n.addEventListener("error",u,!0),r=e.src,t=e,a=function(){i.forEach(function(e){var n;(n=Raven)[e[0]].apply(n,e[1])}),n.removeEventListener("unhandledrejection",u),n.removeEventListener("error",u,!0)},c=document.head||document.getElementsByTagName("head")[0],(o=document.createElement("script")).crossOrigin=t.crossOrigin,o.dataset.sentryConfig=t["data-sentry-config"],o.onload=a,o.src=r,c.appendChild(o)}({"defer":true,"crossOrigin":"anonymous","src":"https://unpkg.zhimg.com/@cfe/sentry-script@1.3.0/dist/init.js","data-sentry-config":"{\"dsn\":\"https://2d8d764432cc4f6fb3bc78ab9528299d@crash2.zhihu.com/1224\",\"sampleRate\":0.1,\"release\":\"2589-084dfbd8\",\"ignoreErrorNames\":[\"NetworkError\",\"SecurityError\"],\"ignoreErrorsPreset\":\"ReactApp\"}"},window)}();
</script><script crossorigin="anonymous" data-sentry-config="{"dsn":"https://2d8d764432cc4f6fb3bc78ab9528299d@crash2.zhihu.com/1224","sampleRate":0.1,"release":"2589-084dfbd8","ignoreErrorNames":["NetworkError","SecurityError"],"ignoreErrorsPreset":"ReactApp"}" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/init.js"></script><style data-emotion-css="qqgmyv">.css-qqgmyv{width:auto;max-width:1156px;min-width:1000px;padding-left:16px;padding-right:30px;}.css-qqgmyv .AppHeader-userInfo{margin-left:30px;width:auto;}.css-qqgmyv .AppHeader-TabsLink.is-active,.css-qqgmyv .AppHeader-TabsLink:hover{color:#121212;}</style><style data-emotion-css="g0ay3v">.css-g0ay3v{margin-left:25px;margin-right:15px;}.css-g0ay3v .AppHeader-Tab{padding-left:15px;padding-right:15px;}.css-g0ay3v .Tabs-link.is-active::after{height:4px;}</style><style data-emotion-css="1acwmmj">.css-1acwmmj{box-sizing:border-box;margin:0;min-width:0;-webkit-flex:1;-ms-flex:1;flex:1;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}</style><style data-emotion-css="10fy1q8">.css-10fy1q8{max-width:482px;}.css-10fy1q8 .SearchBar-input{border-radius:999px;padding-left:16px;}.css-10fy1q8 .SearchBar-askButton{border-radius:999px;width:70px;margin-left:12px;}.css-10fy1q8 .SearchBar-searchButton{border-bottom-right-radius:999px;border-top-right-radius:999px;}</style><style data-emotion-css="eew49z">.css-eew49z{min-height:10px;}</style><style data-emotion-css="1cd9gw4">.css-1cd9gw4{margin-left:.3em;}</style><style data-emotion-css="n99yhz">.css-n99yhz{box-sizing:border-box;margin:0;min-width:0;color:#175199;display:inline-block;margin-left:.3em;}</style><style data-emotion-css="g9eqf4-StrutAlign">.css-g9eqf4-StrutAlign{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}</style><style data-emotion-css="svsrxm-Octangle">.css-svsrxm-Octangle{overflow:visible!important;}</style><style data-emotion-css="h5al4j">.css-h5al4j{box-sizing:border-box;margin:0;min-width:0;color:#8590A6;font-size:14px;margin-top:10px;margin-bottom:-4px;}</style><style data-emotion-css="1cd9gw4">.css-1cd9gw4{margin-left:.3em;}</style><style data-emotion-css="h5al4j">.css-h5al4j{box-sizing:border-box;margin:0;min-width:0;color:#8590A6;font-size:14px;margin-top:10px;margin-bottom:-4px;}</style><script charset="utf-8" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/main_007.js" crossorigin="anonymous"></script><link rel="stylesheet" type="text/css" href="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/main.css" crossorigin="anonymous"><script charset="utf-8" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/main_009.js" crossorigin="anonymous"></script><link rel="stylesheet" type="text/css" href="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/main_006.css" crossorigin="anonymous"><script charset="utf-8" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/main.js" crossorigin="anonymous"></script><link rel="stylesheet" type="text/css" href="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/main_007.css" crossorigin="anonymous"><script charset="utf-8" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/main_003.js" crossorigin="anonymous"></script><link rel="stylesheet" type="text/css" href="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/main_003.css" crossorigin="anonymous"><script charset="utf-8" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/main_008.js" crossorigin="anonymous"></script><link rel="stylesheet" type="text/css" href="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/main_004.css" crossorigin="anonymous"><script charset="utf-8" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/main_004.js" crossorigin="anonymous"></script><style data-emotion="css"></style><link rel="stylesheet" type="text/css" href="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/main_005.css" crossorigin="anonymous"><script charset="utf-8" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/main_002.js" crossorigin="anonymous"></script></head><body style="overflow: auto;"><div id="root"><div><div class="LoadingBar"></div><div><header role="banner" class="Sticky AppHeader is-fixed" data-za-module="TopNavBar" style="width: 100%; top: 0px;"><div class="AppHeader-inner css-qqgmyv"><a href="https://www.zhihu.com/" aria-label="知乎"><svg viewBox="0 0 64 30" fill="#0066FF" width="64" height="30"><path d="M29.05 4.582H16.733V25.94h3.018l.403 2.572 4.081-2.572h4.815V4.582zm-5.207 18.69l-2.396 1.509-.235-1.508h-1.724V7.233h6.78v16.04h-2.425zM14.46 14.191H9.982c0-.471.033-.954.039-1.458v-5.5h5.106V5.935a1.352 1.352 0 0 0-.404-.957 1.378 1.378 0 0 0-.968-.396H5.783c.028-.088.056-.177.084-.255.274-.82 1.153-3.326 1.153-3.326a4.262 4.262 0 0 0-2.413.698c-.57.4-.912.682-1.371 1.946-.532 1.453-.997 2.856-1.31 3.693C1.444 8.674.28 11.025.28 11.025a5.85 5.85 0 0 0 2.52-.61c1.119-.593 1.679-1.502 2.054-2.883l.09-.3h2.334v5.5c0 .5-.045.982-.073 1.46h-4.12c-.71 0-1.39.278-1.893.775a2.638 2.638 0 0 0-.783 1.874h6.527a17.717 17.717 0 0 1-.778 3.649 16.796 16.796 0 0 1-3.012 5.273A33.104 33.104 0 0 1 0 28.74s3.13 1.175 5.425-.954c1.388-1.292 2.631-3.814 3.23-5.727a28.09 28.09 0 0 0 1.12-5.229h5.967v-1.37a1.254 1.254 0 0 0-.373-.899 1.279 1.279 0 0 0-.909-.37z"></path><path d="M11.27 19.675l-2.312 1.491 5.038 7.458a6.905 6.905 0 0 0 .672-2.218 3.15 3.15 0 0 0-.28-2.168l-3.118-4.563zM51.449 15.195V5.842c4.181-.205 7.988-.405 9.438-.483l.851-.05c.387-.399.885-2.395.689-3.021-.073-.25-.213-.666-.638-.555a33.279 33.279 0 0 1-4.277.727c-2.766.321-3.97.404-7.804.682-6.718.487-12.709.72-12.709.72a2.518 2.518 0 0 0 .788 1.834 2.567 2.567 0 0 0 1.883.706c2.278-.095 5.598-.25 8.996-.41v9.203h-12.78c0 .703.281 1.377.783 1.874a2.69 2.69 0 0 0 1.892.777h10.105v7.075c0 .887-.464 1.192-1.231 1.214h-3.92a4.15 4.15 0 0 0 .837 1.544 4.2 4.2 0 0 0 1.403 1.067 6.215 6.215 0 0 0 2.71.277c1.36-.066 2.967-.826 2.967-3.57v-7.607h11.28c.342 0 .67-.135.91-.374.242-.239.378-.563.378-.902v-1.375H51.449z"></path><path d="M42.614 8.873a2.304 2.304 0 0 0-1.508-.926 2.334 2.334 0 0 0-1.727.405l-.376.272 4.255 5.85 2.24-1.62-2.884-3.98zM57.35 8.68l-3.125 4.097 2.24 1.663 4.517-5.927-.375-.277a2.32 2.32 0 0 0-1.722-.452 2.327 2.327 0 0 0-1.536.896z"></path></svg></a><ul role="navigation" class="Tabs AppHeader-Tabs css-g0ay3v"><li role="tab" class="Tabs-item AppHeader-Tab Tabs-item--noMeta"><a tabindex="0" class="Tabs-link AppHeader-TabsLink" href="https://www.zhihu.com/" data-za-not-track-link="true">首页</a></li><li role="tab" class="Tabs-item AppHeader-Tab Tabs-item--noMeta"><a tabindex="0" class="Tabs-link AppHeader-TabsLink" href="https://www.zhihu.com/xen/vip-web" data-za-not-track-link="true">会员</a></li><li role="tab" class="Tabs-item AppHeader-Tab Tabs-item--noMeta"><a tabindex="0" class="Tabs-link AppHeader-TabsLink" href="https://www.zhihu.com/explore" data-za-not-track-link="true">发现</a></li><li role="tab" class="Tabs-item AppHeader-Tab Tabs-item--noMeta"><a tabindex="0" class="Tabs-link AppHeader-TabsLink" href="https://www.zhihu.com/question/waiting" data-za-not-track-link="true">等你来答</a></li></ul><div class="css-1acwmmj"><div class="SearchBar AppHeader-SearchBar css-10fy1q8" role="search" data-za-module="PresetWordItem"><form class="SearchBar-tool"><div><div class="Popover"><label class="SearchBar-input Input-wrapper Input-wrapper--grey"><input type="text" maxlength="100" autocomplete="off" role="combobox" aria-expanded="false" aria-autocomplete="list" aria-activedescendant="AutoComplete3--1" id="Popover2-toggle" aria-haspopup="true" aria-owns="Popover2-content" class="Input" placeholder="搜索你感兴趣的内容…"><button aria-label="搜索" type="button" class="Button SearchBar-searchButton Button--primary"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Search SearchBar-searchIcon" fill="currentColor" viewBox="0 0 24 24" width="18" height="18"><path d="M17.068 15.58a8.377 8.377 0 0 0 1.774-5.159 8.421 8.421 0 1 0-8.42 8.421 8.38 8.38 0 0 0 5.158-1.774l3.879 3.88c.957.573 2.131-.464 1.488-1.49l-3.879-3.878zm-6.647 1.157a6.323 6.323 0 0 1-6.316-6.316 6.323 6.323 0 0 1 6.316-6.316 6.323 6.323 0 0 1 6.316 6.316 6.323 6.323 0 0 1-6.316 6.316z" fill-rule="evenodd"></path></svg></span></button></label></div></div></form></div></div><div class="AppHeader-userInfo"><div class="AppHeader-profile"><div><button type="button" class="Button AppHeader-login Button--blue">登录</button><button type="button" class="Button Button--primary Button--blue">加入知乎</button></div></div></div></div><div><div class="PageHeader"><div class="QuestionHeader-content"><div class="QuestionHeader-main"><h1 class="QuestionHeader-title">Online Judge 是如何解决判题端安全性问题的?</h1></div><div class="QuestionHeader-side" data-za-detail-view-path-module="ToolBar" data-za-extra-module="{"card":{"content":{"type":"Question","token":"23067497"}}}"><div class="QuestionButtonGroup"><button type="button" class="Button FollowButton Button--primary Button--blue">关注问题</button><button type="button" class="Button Button--blue"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Edit QuestionButton-icon" fill="currentColor" viewBox="0 0 24 24" width="16" height="16"><path d="M4.076 16.966a4.19 4.19 0 0 1 1.05-1.76l8.568-8.569a.524.524 0 0 1 .741 0l2.928 2.927a.524.524 0 0 1 0 .74l-8.568 8.57c-.49.49-1.096.852-1.761 1.051l-3.528 1.058a.394.394 0 0 1-.49-.488l1.06-3.53zM20.558 4.83c.59.59.59 1.546 0 2.136l-1.693 1.692a.503.503 0 0 1-.712 0l-2.812-2.812a.504.504 0 0 1 0-.712l1.693-1.693a1.51 1.51 0 0 1 2.135 0l1.389 1.389z"></path></svg></span>写回答</button></div></div></div></div></div></header><div class="Sticky--holder" style="position: relative; inset: 0px; display: block; float: none; margin: 0px; height: 52px;"></div></div><main role="main" class="App-main"><div class="QuestionPage" itemscope="" itemtype="http://schema.org/Question" data-za-detail-view-path-module="QuestionItem" data-za-extra-module="{"card":{"content":{"type":"Question","token":"23067497"}}}"><meta itemprop="name" content="Online Judge 是如何解决判题端安全性问题的?"><meta itemprop="url" content="https://www.zhihu.com/question/23067497"><meta itemprop="keywords" content="Linux,网络安全,信息安全,Online Judge"><meta itemprop="answerCount" content="21"><meta itemprop="commentCount" content="4"><meta itemprop="dateCreated" content="2014-03-17T03:06:35.000Z"><meta itemprop="dateModified" content="2014-03-20T08:31:37.000Z"><meta itemprop="zhihu:visitsCount"><meta itemprop="zhihu:followerCount" content="1040"><div data-zop-question="{"title":"Online Judge 是如何解决判题端安全性问题的?","topics":[{"name":"Linux","id":"19554300"},{"name":"网络安全","id":"19554927"},{"name":"信息安全","id":"19561983"},{"name":"Online Judge","id":"19600988"}],"id":23067497,"isEditable":false}"><div class="QuestionStatus"></div><div data-za-detail-view-path-module="QuestionDescription" data-za-extra-module="{"card":{"content":{"type":"Question","token":"23067497"}}}"><div class="QuestionHeader"><div class="QuestionHeader-content"><div class="QuestionHeader-main"><div class="QuestionHeader-tags"><div class="QuestionHeader-topics"><div class="Tag QuestionTopic" data-za-detail-view-path-module="TopicItem" data-za-extra-module="{"card":{"content":{"type":"Topic","token":"19554300"}}}"><span class="Tag-content"><a class="TopicLink" href="https://www.zhihu.com/topic/19554300" target="_blank"><div class="Popover"><div id="Popover4-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover4-content">Linux</div></div></a></span></div><div class="Tag QuestionTopic" data-za-detail-view-path-module="TopicItem" data-za-extra-module="{"card":{"content":{"type":"Topic","token":"19554927"}}}"><span class="Tag-content"><a class="TopicLink" href="https://www.zhihu.com/topic/19554927" target="_blank"><div class="Popover"><div id="Popover5-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover5-content">网络安全</div></div></a></span></div><div class="Tag QuestionTopic" data-za-detail-view-path-module="TopicItem" data-za-extra-module="{"card":{"content":{"type":"Topic","token":"19561983"}}}"><span class="Tag-content"><a class="TopicLink" href="https://www.zhihu.com/topic/19561983" target="_blank"><div class="Popover"><div id="Popover6-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover6-content">信息安全</div></div></a></span></div><div class="Tag QuestionTopic" data-za-detail-view-path-module="TopicItem" data-za-extra-module="{"card":{"content":{"type":"Topic","token":"19600988"}}}"><span class="Tag-content"><a class="TopicLink" href="https://www.zhihu.com/topic/19600988" target="_blank"><div class="Popover"><div id="Popover7-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover7-content">Online Judge</div></div></a></span></div></div></div><h1 class="QuestionHeader-title">Online Judge 是如何解决判题端安全性问题的?</h1><div class="LabelContainer-wrapper"></div><div><div class="css-eew49z"><div class="QuestionRichText QuestionRichText--expandable QuestionRichText--collapsed"><div><span>如何过滤恶意提交的危险代码??分析了一下hustoj的实现,貌似只是通过创建一个低磁盘读写权限的linux用户限制磁盘操作,然后用ptrace去过滤系…</span><button type="button" class="Button QuestionRichText-more Button--plain">显示全部 <span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--ArrowDown" fill="currentColor" viewBox="0 0 24 24" width="24" height="24"><path d="M12 13L8.285 9.218a.758.758 0 0 0-1.064 0 .738.738 0 0 0 0 1.052l4.249 4.512a.758.758 0 0 0 1.064 0l4.246-4.512a.738.738 0 0 0 0-1.052.757.757 0 0 0-1.063 0L12.002 13z" fill-rule="evenodd"></path></svg></span></button></div></div></div></div></div><div class="QuestionHeader-side"><div class="QuestionHeader-follow-status"><div class="QuestionFollowStatus"><div class="NumberBoard QuestionFollowStatus-counts NumberBoard--divider"><div class="NumberBoard-item"><div class="NumberBoard-itemInner"><div class="NumberBoard-itemName">关注者</div><strong class="NumberBoard-itemValue" title="1040">1,040</strong></div></div><div class="NumberBoard-item"><div class="NumberBoard-itemInner"><div class="NumberBoard-itemName">被浏览</div><strong class="NumberBoard-itemValue" title="61921">61,921</strong></div></div></div></div></div></div></div><div class="QuestionHeader-footer"><div class="QuestionHeader-footer-inner"><div class="QuestionHeader-main QuestionHeader-footer-main"><div class="QuestionButtonGroup"><button type="button" class="Button FollowButton Button--primary Button--blue">关注问题</button><button type="button" class="Button Button--blue"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Edit QuestionButton-icon" fill="currentColor" viewBox="0 0 24 24" width="16" height="16"><path d="M4.076 16.966a4.19 4.19 0 0 1 1.05-1.76l8.568-8.569a.524.524 0 0 1 .741 0l2.928 2.927a.524.524 0 0 1 0 .74l-8.568 8.57c-.49.49-1.096.852-1.761 1.051l-3.528 1.058a.394.394 0 0 1-.49-.488l1.06-3.53zM20.558 4.83c.59.59.59 1.546 0 2.136l-1.693 1.692a.503.503 0 0 1-.712 0l-2.812-2.812a.504.504 0 0 1 0-.712l1.693-1.693a1.51 1.51 0 0 1 2.135 0l1.389 1.389z"></path></svg></span>写回答</button></div><div class="QuestionHeaderActions"><button style="margin-right: 16px;" type="button" class="Button Button--grey Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Invite Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M4 10V8a1 1 0 1 1 2 0v2h2a1 1 0 0 1 0 2H6v2a1 1 0 0 1-2 0v-2H2a1 1 0 0 1 0-2h2zm10.455 2c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm-7 6c0-2.66 4.845-4 7.272-4C17.155 14 22 15.34 22 18v1.375c0 .345-.28.625-.625.625H8.08a.625.625 0 0 1-.625-.625V18z" fill-rule="evenodd"></path></svg></span>邀请回答</button><div class="GoodQuestionAction"><button type="button" class="Button GoodQuestionAction-commonBtn Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Like Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M14.445 9h5.387s2.997.154 1.95 3.669c-.168.51-2.346 6.911-2.346 6.911s-.763 1.416-2.86 1.416H8.989c-1.498 0-2.005-.896-1.989-2v-7.998c0-.987.336-2.032 1.114-2.639 4.45-3.773 3.436-4.597 4.45-5.83.985-1.13 3.2-.5 3.037 2.362C15.201 7.397 14.445 9 14.445 9zM3 9h2a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V10a1 1 0 0 1 1-1z" fill-rule="evenodd"></path></svg></span>好问题 5</button></div><div class="QuestionHeader-Comment"><button type="button" class="Button Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Comment Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M10.241 19.313a.97.97 0 0 0-.77.2 7.908 7.908 0 0 1-3.772 1.482.409.409 0 0 1-.38-.637 5.825 5.825 0 0 0 1.11-2.237.605.605 0 0 0-.227-.59A7.935 7.935 0 0 1 3 11.25C3 6.7 7.03 3 12 3s9 3.7 9 8.25-4.373 9.108-10.759 8.063z" fill-rule="evenodd"></path></svg></span>4 条评论</button></div><div class="Popover ShareMenu"><div class="ShareMenu-toggler" id="Popover8-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover8-content"><button type="button" class="Button Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Share Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M2.931 7.89c-1.067.24-1.275 1.669-.318 2.207l5.277 2.908 8.168-4.776c.25-.127.477.198.273.39L9.05 14.66l.927 5.953c.18 1.084 1.593 1.376 2.182.456l9.644-15.242c.584-.892-.212-2.029-1.234-1.796L2.93 7.89z" fill-rule="evenodd"></path></svg></span>分享</button></div></div><div class="Popover"><button aria-label="更多" id="Popover9-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover9-content" type="button" class="Button Button--plain Button--withIcon Button--iconOnly"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Dots Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M5 14a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm7 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm7 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4z" fill-rule="evenodd"></path></svg></span></button></div></div><div class="QuestionHeader-actions"></div></div></div></div></div></div><div><div class="Sticky"></div></div></div><div class="Question-main"><div class="Question-mainColumn"><div><div id="QuestionAnswers-answers" class="QuestionAnswers-answers" data-zop-feedlistmap="0,0,1,0" data-za-detail-view-path-module="ContentList" data-za-extra-module="{}"><div class="Card AnswersNavWrapper"><div class="ListShortcut"><div class="List"><div class="List-header"><h4 class="List-headerText"><span>21 个回答</span></h4><div class="List-headerOptions"><div class="Popover"><button role="combobox" aria-expanded="false" id="Popover10-toggle" aria-haspopup="true" aria-owns="Popover10-content" type="button" class="Button InputLike InputButton Select-button Select-plainButton Button--plain">默认排序<svg class="Zi Zi--Select Select-arrow" fill="currentColor" viewBox="0 0 24 24" width="24" height="24"><path d="M12 16.183l2.716-2.966a.757.757 0 0 1 1.064.001.738.738 0 0 1 0 1.052l-3.247 3.512a.758.758 0 0 1-1.064 0L8.22 14.27a.738.738 0 0 1 0-1.052.758.758 0 0 1 1.063 0L12 16.183zm0-9.365L9.284 9.782a.758.758 0 0 1-1.064 0 .738.738 0 0 1 0-1.052l3.248-3.512a.758.758 0 0 1 1.065 0L15.78 8.73a.738.738 0 0 1 0 1.052.757.757 0 0 1-1.063.001L12 6.818z" fill-rule="evenodd"></path></svg></button></div></div></div><div><div class=""><div class="List-item" tabindex="0"><div class="ContentItem AnswerItem" data-za-index="0" data-zop="{"authorName":"马宏菩","itemId":23538675,"title":"Online Judge 是如何解决判题端安全性问题的?","type":"answer"}" name="23538675" itemprop="acceptedAnswer" itemtype="http://schema.org/Answer" itemscope="" data-za-detail-view-path-module="AnswerItem" data-za-detail-view-path-index="0" data-za-extra-module="{"card":{"has_image":false,"has_video":false,"content":{"type":"Answer","token":"23538675","upvote_num":365,"comment_num":32,"publish_timestamp":null,"parent_token":"23067497","author_member_hash_id":"5627c888358180619f67a91d39ad8e54"}}}"><div class="ContentItem-meta"><div class="AuthorInfo AnswerItem-authorInfo AnswerItem-authorInfo--related" itemprop="author" itemscope="" itemtype="http://schema.org/Person"><div class="AuthorInfo"><meta itemprop="name" content="马宏菩"><meta itemprop="image" content="https://pic2.zhimg.com/a10724048_l.jpg?source=1940ef5c"><meta itemprop="url" content="https://www.zhihu.com/people/hexcles"><meta itemprop="zhihu:followerCount" content="7825"><span class="UserLink AuthorInfo-avatarWrapper"><div class="Popover"><div id="Popover17-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover17-content"><a target="_blank" class="UserLink-link" data-za-detail-view-element_name="User" href="https://www.zhihu.com/people/hexcles"><img class="Avatar AuthorInfo-avatar" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/a10724048_xs.jpg" srcset="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/a10724048_l.jpg 2x" alt="马宏菩" width="38" height="38"></a></div></div></span><div class="AuthorInfo-content"><div class="AuthorInfo-head"><span class="UserLink AuthorInfo-name"><div class="Popover"><div id="Popover18-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover18-content"><a target="_blank" class="UserLink-link" data-za-detail-view-element_name="User" href="https://www.zhihu.com/people/hexcles">马宏菩</a></div></div><a href="https://www.zhihu.com/topic/20054793" target="_blank" class="css-n99yhz" aria-label="Linux话题下的优秀答主" data-tooltip="Linux话题下的优秀答主"><span class="css-g9eqf4-StrutAlign"><svg viewBox="0 0 24 24" class="css-svsrxm-Octangle" width="18" height="18"><svg viewBox="0 0 24 24" x="-3" y="-3" fill="#FFFFFF" width="30" height="30"><path d="M3.56231227,13.8535307 C2.40051305,12.768677 2.41398885,11.0669203 3.59484487,9.99979213 L3.59222085,9.99654885 C4.26730143,9.45036719 4.79446755,8.21005186 4.7184197,7.34453784 L4.72305873,7.34412719 C4.66942824,5.75539997 5.8824188,4.56066914 7.47188965,4.64242381 L7.47229112,4.6386236 C8.33515314,4.72977993 9.58467253,4.22534048 10.1426329,3.55925173 L10.1462611,3.56228565 C11.2316055,2.40008701 12.9353108,2.41394456 14.0015072,3.59634088 L14.0047263,3.59374004 C14.5498229,4.26841874 15.7896857,4.79521622 16.6545744,4.71844347 L16.6549836,4.72304294 C18.245027,4.66894057 19.4396947,5.88213996 19.3575031,7.47241135 L19.3623099,7.47292747 C19.2704388,8.3358681 19.7742711,9.58421483 20.4407199,10.1424506 L20.437686,10.1460789 C21.5997217,11.2312209 21.5860695,12.9345218 20.4042441,14.0007396 L20.4072865,14.0045125 C19.7325967,14.5495925 19.2055209,15.7896954 19.2815865,16.6561959 L19.2770449,16.6565978 C19.3315454,18.2453037 18.1173775,19.4393568 16.5274188,19.3571512 L16.5269029,19.3619539 C15.6647098,19.270083 14.415408,19.7741709 13.8573671,20.4403558 L13.8537409,20.4373235 C12.76842,21.5995708 11.0650432,21.5864553 9.99899434,20.4039226 L9.99527367,20.406923 C9.45025436,19.7323399 8.21017638,19.2051872 7.34461983,19.2812352 L7.344304,19.2776405 C5.75448683,19.3312904 4.55977145,18.1170085 4.64254978,16.527117 L4.63769921,16.5265942 C4.72957031,15.6644394 4.22547659,14.4151814 3.55928015,13.8571569 L3.56231227,13.8535307 Z"></path></svg><path d="M2.63951518,13.3895441 C3.70763333,14.2842292 4.44777637,16.1226061 4.30075305,17.5023312 L4.32211542,17.3063047 C4.17509209,18.6910561 5.17786655,19.7063729 6.5613937,19.5844846 L6.364106,19.6008202 C7.75140298,19.4789319 9.57474349,20.2554985 10.4468305,21.3349009 L10.3224262,21.1803415 C11.1982831,22.2647703 12.6257916,22.2723098 13.5167278,21.2079863 L13.3898102,21.3600325 C14.2845162,20.2919393 16.1229361,19.5518136 17.5026934,19.6988334 L17.3054057,19.6774716 C18.6914461,19.8244915 19.7067866,18.8217404 19.5836389,17.4395022 L19.6012314,17.6367853 C19.4793403,16.2482641 20.255925,14.4249662 21.3353526,13.5528995 L21.1807897,13.677301 C22.2639871,12.8014646 22.2727834,11.3739894 21.2084351,10.483074 L21.3604848,10.6099886 C20.2923667,9.71530351 19.5522236,7.87818322 19.6992469,6.49720154 L19.6778846,6.69448464 C19.8249079,5.30847665 18.8221335,4.2944164 17.4386063,4.41630468 L17.635894,4.39871256 C16.248597,4.52185742 14.4252565,3.74529084 13.5531695,2.66588842 L13.6775738,2.81919121 C12.8017169,1.73601905 11.3742084,1.72722299 10.4832722,2.79154644 L10.6101898,2.63950024 C9.71548377,3.70759343 7.87706394,4.44771919 6.49730661,4.30195588 L6.69459432,4.32206116 C5.30855394,4.17504128 4.29447,5.17904888 4.41636114,6.56128713 L4.3987686,6.36400404 C4.52065973,7.75126861 3.74407501,9.57456653 2.66464737,10.4478898 L2.81921035,10.3222318 C1.73601288,11.1993248 1.72721662,12.6255433 2.79156494,13.5164587 L2.63951518,13.3895441 Z" fill="#FF9607"></path><svg class="Zi Zi--Star" fill="#fff" x="6" y="6" viewBox="0 0 24 24" width="12" height="12"><path d="M5.515 19.64l.918-5.355-3.89-3.792c-.926-.902-.639-1.784.64-1.97L8.56 7.74l2.404-4.871c.572-1.16 1.5-1.16 2.072 0L15.44 7.74l5.377.782c1.28.186 1.566 1.068.64 1.97l-3.89 3.793.918 5.354c.219 1.274-.532 1.82-1.676 1.218L12 18.33l-4.808 2.528c-1.145.602-1.896.056-1.677-1.218z" fill-rule="evenodd"></path></svg></svg></span></a></span></div><div class="AuthorInfo-detail"><div class="AuthorInfo-badge"><div class="ztext AuthorInfo-badgeText">Linux话题下的优秀答主</div></div></div></div></div></div><div class="LabelContainer-wrapper"></div><div class="css-h5al4j"><span><span class="Voters"><button type="button" class="Button Button--plain">365 人赞同了该回答</button></span></span></div></div><meta itemprop="image"><meta itemprop="upvoteCount" content="365"><meta itemprop="url" content="https://www.zhihu.com/question/23067497/answer/23538675"><meta itemprop="dateCreated" content="2014-03-18T03:24:34.000Z"><meta itemprop="dateModified" content="2014-03-18T03:24:34.000Z"><meta itemprop="commentCount" content="32"><div class="RichContent RichContent--unescapable"><div class="RichContent-inner"><span class="RichText ztext CopyrightRichText-richText" itemprop="text">其实这就是在做一个沙盒,而一个可靠的沙盒不是那么简单的。我简单说一些高中时写 OJ 获得的经验,抛砖引玉。<br><br>几个错误做法:<br><ol><li>所有的字符串过滤都是耍流氓,坑人坑自己:C语言强大的宏几乎没有绕不过的字符串过滤,而且误伤也是很常见的(我就见过小白 OIer 问为什么程序老是被判非法,结果一看里头有个变量叫做 fork )。</li><li>手
工审计头文件,去掉某些头文件或者注释掉一些部分是辛苦且无用的:做了这样的工作之后,你就几乎再也不会想去升级编译器及头文件了,更可怕的是——这个工
作需要你对语言、编译器、连接器有一定程度的了解,而我认为拥有足够了解的人都应该知道这是不靠谱的:就算没有头文件、没有了函数原型,调用系统调用的方
法还是有一大把而且都不是很麻烦。</li></ol><br><p>准备工作:</p><ol><li>熟悉你的目标系统(Windows or Linux):</li><ol><li>必须要了解这个平台下的原生系统调用 API 是怎么使用的(不然你要怎么屏蔽?),最好可以了解到汇编层面。</li><li>必须要了解这个平台下的用户系统、权限控制、资源限制。</li><li>最好要了解一下进程跟踪/调试/监控工具或者系统调用,例如 Linux 下的 ptrace 。</li><li>最好要了解目标系统提供的各种沙盒限制功能。<br></li></ol><li>了解你的编程语言及工具链:</li><ol><li>必须要了解你的目标语言的特性,及其在一般的 OI / ACM 比赛中的规定、限制。</li><li>必须要了解你的工具链的功能及各种参数。</li></ol><li>拥有足够的编程功底,对于这样小的程序,应当严格杜绝缓冲区溢出之类的 bug 。</li></ol><br><p>然后我再说说我的做法,在其中大家就可以看到上面列的这些“准备知识”是如何派上用场的。我的目标平台是 Linux ,目标语言是 Pascal 、 C 、 C++ 。</p><br><p>我采取了以下措施:</p><ol><li>操作系统层面:</li><ol><li>时间、资源的限制:</li><ol><li>内存:我使用了 rlimit 进行控制,同时也方便在运行结束后获得内存使用情况的数据,不过有一个“缺点”就是如果是声明了一个超大的空间但从未访问使用就不会被统计进来(经过观察发现很多 ACM 或者 OI 比赛也都是这么处理的,所以应该不算是一个问题)。</li><li>时
间:首先同样也是使用 rlimit 进行 CPU 时间控制。注意它只能控制 CPU 时间,不能控制实际运行时间,所以像是 sleep 或者 IO
阻塞之类的情况是没有办法的,所以还在额外添加了一个 alarm 来进行实际时间的限制。按照大部分比赛的管理,最终统计的时间是 CPU 时间。</li><li>文件句柄:同样可以通过 rlimit 来实现,以保证程序不要打开太多文件。不过其实文件这一块问题是比较多的,如果可行的话最好还是使用 stdio 然后管道重定向,完全禁止程序的文件 IO 操作。<br></li></ol><li>访问控制:</li><ol><li>通过 chroot 建立一个 jail ,将程序限制在指定目录中运行。由于是比赛程序,使用的动态链接库很有限,所以直接静态编译,从而使得运行目录中连 .so 都不需要。</li><li>进行必要的权限控制,例如将输入文件和程序文件本身设置为程序的运行用户只读不可写。<br></li></ol><li>权限控制:</li><ol><li>监控程序使用 root 权限运行, 完成必要准备后 fork 并切换为受限用户(比如 nobody )来运行程序。<br></li><li>rlimit 设置的都是 hard limit ,非 root 无法修改。</li><li>正确设置运行用户之后,之前由 root 创造的 jail 受限用户是无法逃出的。<br></li></ol><li>系统调用控制:<br>上
面这些(尤其是第一步)是有很大问题,就算不是 root ,也还能做到很多事情。且不说 fork 之类的,光是那个 alarm
,就可以很轻松的把计时器取消了或者干脆主动接收这个信号。所以最根本的还是需要使用 ptrace
之类的调试器附着上程序,监控所有的系统调用,进行白名单 + 计数器(比如 exec 和 open
)过滤。这一步其实是最麻烦的(不同平台的系统调用号不一样,我们使用的是 strace 项目里头整理的调用号)。</li><li>更进一步:<br>如果你对操作系统更熟悉,那么还有一些更有趣的事情可以做。比如 Linux 下的 seccomp 功能(<a href="https://link.zhihu.com/?target=http%3A//en.wikipedia.org/wiki/Seccomp" class=" wrap external" target="_blank" rel="nofollow noreferrer">seccomp - Wikipedia</a> , Chrome Linux 版就在沙盒中使用了这个技术 ),尤其是后期加入了 seccomp-bpf 之后变得更加易用。还比如 SELinux 也可以作为 defend-by-depth 的一环。另外, cgroup 其实也可以用得上。<br></li></ol><li>编译层面:</li><ol><li>很多编译工具都提供了强大的参数控制,允许你进行包括禁用内嵌 ASM 、限制连接路径之类的一些操作。通读一遍 manpage 肯定会有帮助的。</li><li>算法竞赛的程序推荐静态编译,之后控制起来少了动态链接库会方便许多。</li><li>小
心编译期间的一些“高级功能”,比如 C 的 include 其实是有很多巧妙的用法,试试看在 Linux 下 #include
"/dev/random" 或者 #include "/dev/tty" 之类的(这两个东西会把网络上不少二流 OJ 直接卡死……)。</li><li>不要使用 root 用户编译,越复杂的程序越容易有 bug ,万一哪天出个编译器的 0day ……</li><li>考虑给编译过程同样进行时间、资源限制以作为额外防护手段。</li></ol><li>架构层面:</li><ol><li>运行在虚拟机/容器中</li><li>快照</li><li>心跳检测<br></li></ol></ol><p>……</p><br><p>你
会发现,其实主要的限制都是在操作系统层面完成的。我认为,这样做才能带来更高的安全性,因为引发、启动危险操作的方法有很多,很难一一杜绝(包括源码分
析、编译时限制等),但最后要让这些危险操作起效几乎都需要落回系统调用上,所以直接从这里下手也许会是个更好的办法。</p><br><p>我对于 Windows 不了解,不知道 Windows 下该如何实现以上的类似功能,或者是否情况完全不同,欢迎大家补充。</p><br><p>最后是我之前写的沙盒项目,写得很丑,尤其是 ptrace 一块目前还比较坑(64位系统下好像还无法正常工作),总的来讲还只能算是一个 demo 而已:<a href="https://link.zhihu.com/?target=https%3A//github.com/Hexcles/Eevee" class=" wrap external" target="_blank" rel="nofollow noreferrer">Hexcles/Eevee · GitHub</a></p></span></div><div><div class="ContentItem-time"><a target="_blank" href="https://www.zhihu.com/question/23067497/answer/23538675"><span data-tooltip="发布于 2014-03-18 11:24">发布于 2014-03-18</span></a></div></div><div><div class="ContentItem-actions Sticky RichContent-actions is-fixed is-bottom" style="width: 694px; bottom: 0px; left: 133.5px;"><span><button aria-label="赞同 365 " type="button" class="Button VoteButton VoteButton--up"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--TriangleUp VoteButton-TriangleUp" fill="currentColor" viewBox="0 0 24 24" width="10" height="10"><path d="M2 18.242c0-.326.088-.532.237-.896l7.98-13.203C10.572 3.57 11.086 3 12 3c.915 0 1.429.571 1.784 1.143l7.98 13.203c.15.364.236.57.236.896 0 1.386-.875 1.9-1.955 1.9H3.955c-1.08 0-1.955-.517-1.955-1.9z" fill-rule="evenodd"></path></svg></span>赞同 365</button><button aria-label="反对" type="button" class="Button VoteButton VoteButton--down"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--TriangleDown" fill="currentColor" viewBox="0 0 24 24" width="10" height="10"><path d="M20.044 3H3.956C2.876 3 2 3.517 2 4.9c0 .326.087.533.236.896L10.216 19c.355.571.87 1.143 1.784 1.143s1.429-.572 1.784-1.143l7.98-13.204c.149-.363.236-.57.236-.896 0-1.386-.876-1.9-1.956-1.9z" fill-rule="evenodd"></path></svg></span></button></span><button type="button" class="Button ContentItem-action Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Comment Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M10.241 19.313a.97.97 0 0 0-.77.2 7.908 7.908 0 0 1-3.772 1.482.409.409 0 0 1-.38-.637 5.825 5.825 0 0 0 1.11-2.237.605.605 0 0 0-.227-.59A7.935 7.935 0 0 1 3 11.25C3 6.7 7.03 3 12 3s9 3.7 9 8.25-4.373 9.108-10.759 8.063z" fill-rule="evenodd"></path></svg></span>32 条评论</button><div class="Popover ShareMenu ContentItem-action"><div class="ShareMenu-toggler" id="Popover16-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover16-content"><button type="button" class="Button Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Share Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M2.931 7.89c-1.067.24-1.275 1.669-.318 2.207l5.277 2.908 8.168-4.776c.25-.127.477.198.273.39L9.05 14.66l.927 5.953c.18 1.084 1.593 1.376 2.182.456l9.644-15.242c.584-.892-.212-2.029-1.234-1.796L2.93 7.89z" fill-rule="evenodd"></path></svg></span>分享</button></div></div><button type="button" class="Button ContentItem-action Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Star Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M5.515 19.64l.918-5.355-3.89-3.792c-.926-.902-.639-1.784.64-1.97L8.56 7.74l2.404-4.871c.572-1.16 1.5-1.16 2.072 0L15.44 7.74l5.377.782c1.28.186 1.566 1.068.64 1.97l-3.89 3.793.918 5.354c.219 1.274-.532 1.82-1.676 1.218L12 18.33l-4.808 2.528c-1.145.602-1.896.056-1.677-1.218z" fill-rule="evenodd"></path></svg></span>收藏</button><button type="button" class="Button ContentItem-action Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Heart Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M2 8.437C2 5.505 4.294 3.094 7.207 3 9.243 3 11.092 4.19 12 6c.823-1.758 2.649-3 4.651-3C19.545 3 22 5.507 22 8.432 22 16.24 13.842 21 12 21 10.158 21 2 16.24 2 8.437z" fill-rule="evenodd"></path></svg></span>喜欢</button><button data-zop-retract-question="true" type="button" class="Button ContentItem-action ContentItem-rightButton Button--plain"><span class="RichContent-collapsedText">收起</span><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--ArrowDown ContentItem-arrowIcon is-active" fill="currentColor" viewBox="0 0 24 24" width="24" height="24"><path d="M12 13L8.285 9.218a.758.758 0 0 0-1.064 0 .738.738 0 0 0 0 1.052l4.249 4.512a.758.758 0 0 0 1.064 0l4.246-4.512a.738.738 0 0 0 0-1.052.757.757 0 0 0-1.063 0L12.002 13z" fill-rule="evenodd"></path></svg></span></button></div><div class="Sticky--holder" style="position: static; inset: auto; display: flex; float: none; margin: 0px -20px -10px; height: 54px; width: 694px;"></div></div></div><div class="ModalWrap"><div><div class=""></div><div class="ModalExp-content"><div class="ModalWrap-content"><div class="ModalWrap-title">继续浏览内容</div><div class="ModalWrap-item"><div class="ModalWrap-itemImg"><img src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-88158afcff1e7f4b8b00a1ba81171b61_720w.png"></div><div class="ModalWrap-itemContent"><div class="ModalWrap-itemTitle">知乎</div><div class="ModalWrap-itemDesc">发现更大的世界</div></div><div class="ModalWrap-itemBtn">打开</div></div><div class="ModalWrap-item"><div class="ModalWrap-itemImg"><img src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-da7d9e4b6a7ddba507299bcf5a4d0600_1440w.png"></div><div class="ModalWrap-itemContent"><div class="ModalWrap-itemTitle">浏览器</div></div><div class="ModalWrap-itemBtn">继续</div></div></div></div></div></div><div><div><div class=""></div><div class="ModalLoading-content"><svg width="30" height="30" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg" class="CircleLoadingBar" aria-hidden="true"><g><circle class="path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></g></svg></div></div></div></div></div><div class="List-item" tabindex="0"><div class="ContentItem AnswerItem" data-za-index="1" data-zop="{"authorName":"CeleryL","itemId":82308751,"title":"Online Judge 是如何解决判题端安全性问题的?","type":"answer"}" name="82308751" itemprop="suggestedAnswer" itemtype="http://schema.org/Answer" itemscope="" data-za-detail-view-path-module="AnswerItem" data-za-detail-view-path-index="1" data-za-extra-module="{"card":{"has_image":false,"has_video":false,"content":{"type":"Answer","token":"82308751","upvote_num":66,"comment_num":39,"publish_timestamp":null,"parent_token":"23067497","author_member_hash_id":"f6f52271761a065e28d7125c335c9775"}}}"><div class="ContentItem-meta"><div class="AuthorInfo AnswerItem-authorInfo AnswerItem-authorInfo--related" itemprop="author" itemscope="" itemtype="http://schema.org/Person"><div class="AuthorInfo"><meta itemprop="name" content="CeleryL"><meta itemprop="image" content="https://pic2.zhimg.com/v2-8c3b7860ec5a7ac8b7cfff779f69d6e7_l.jpg?source=1940ef5c"><meta itemprop="url" content="https://www.zhihu.com/people/virusdefender"><meta itemprop="zhihu:followerCount" content="1694"><span class="UserLink AuthorInfo-avatarWrapper"><div class="Popover"><div id="Popover19-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover19-content"><a target="_blank" class="UserLink-link" data-za-detail-view-element_name="User" href="https://www.zhihu.com/people/virusdefender"><img class="Avatar AuthorInfo-avatar" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-8c3b7860ec5a7ac8b7cfff779f69d6e7_xs.jpg" srcset="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-8c3b7860ec5a7ac8b7cfff779f69d6e7_l.jpg 2x" alt="CeleryL" width="38" height="38"></a></div></div></span><div class="AuthorInfo-content"><div class="AuthorInfo-head"><span class="UserLink AuthorInfo-name"><div class="Popover"><div id="Popover20-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover20-content"><a target="_blank" class="UserLink-link" data-za-detail-view-element_name="User" href="https://www.zhihu.com/people/virusdefender">CeleryL</a></div></div></span></div><div class="AuthorInfo-detail"><div class="AuthorInfo-badge"><div class="ztext AuthorInfo-badgeText">test</div></div></div></div></div></div><div class="LabelContainer-wrapper"></div><div class="css-h5al4j"><span><span class="Voters"><button type="button" class="Button Button--plain">66 人赞同了该回答</button></span></span></div></div><meta itemprop="image"><meta itemprop="upvoteCount" content="66"><meta itemprop="url" content="https://www.zhihu.com/question/23067497/answer/82308751"><meta itemprop="dateCreated" content="2016-01-19T06:45:12.000Z"><meta itemprop="dateModified" content="2018-11-24T06:16:30.000Z"><meta itemprop="commentCount" content="39"><div class="RichContent RichContent--unescapable"><div class="RichContent-inner"><span class="RichText ztext CopyrightRichText-richText" itemprop="text"><p></p><p>转载自我的 blog <a href="https://link.zhihu.com/?target=https%3A//strcpy.me/index.php/archives/652/" class=" wrap external" target="_blank" rel="nofollow noreferrer">OnlineJudge 沙箱实现思路 - virusdefender's blog (^-^)V</a></p><h2>限制系统调用</h2><p>目前常用的有 <code>ptrace</code> 和 <code>seccomp</code>。</p><h2>ptrace 很惨</h2><p>听说 <code>ptrace</code> 存在效率问题,可能会让你的代码运行时间增加很多,这个是可以<a href="https://link.zhihu.com/?target=https%3A//github.com/virusdefender/UndergraduateThesis" class=" wrap external" target="_blank" rel="nofollow noreferrer">简单测试</a>看出来的。</p><p>而加载 <code>seccomp</code> 需要主动的在自己的代码中加载策略,也就是说需要修改已有的代码,但是去修改用户提交的代码是不大可能的。然后就想到了下面几个方法:</p><h2>LD_PRELOAD hook</h2><p><code>LD_PRELOAD</code>加载动态链接库,然后在 so 中 hook <code>__libc_start_main</code>,然后就可以在用户的 <code>main</code> 函数前执行自己的代码了。但是如果在用户的代码中再定义<code>__lbc_start_main</code>函数就可以绕过,虽然网上有人说需要 <code>-nostdlib</code> 的编译参数,但是我实际测试并不需要。下面是沙箱的实现代码</p><div class="highlight"><pre><code class="language-c"><span class="cp">#define _BSD_SOURCE </span><span class="c1">// readlink
</span><span class="c1"></span><span class="cp">#include</span> <span class="cpf"><dlfcn.h></span><span class="cp">
</span><span class="cp">#include</span> <span class="cpf"><stdlib.h> // exit</span><span class="cp">
</span><span class="cp">#include</span> <span class="cpf"><string.h> // strstr, memset</span><span class="cp">
</span><span class="cp">#include</span> <span class="cpf"><link.h> // ElfW</span><span class="cp">
</span><span class="cp">#include</span> <span class="cpf"><errno.h> // EPERM</span><span class="cp">
</span><span class="cp">#include</span> <span class="cpf"><unistd.h> // readlink</span><span class="cp">
</span><span class="cp">#include</span> <span class="cpf"><seccomp.h></span><span class="cp">
</span><span class="cp">#include</span> <span class="cpf"><stdio.h></span><span class="cp">
</span><span class="cp"></span><span class="kt">int</span> <span class="n">syscalls_whitelist</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="n">SCMP_SYS</span><span class="p">(</span><span class="n">read</span><span class="p">),</span> <span class="n">SCMP_SYS</span><span class="p">(</span><span class="n">write</span><span class="p">),</span>
<span class="n">SCMP_SYS</span><span class="p">(</span><span class="n">fstat</span><span class="p">),</span> <span class="n">SCMP_SYS</span><span class="p">(</span><span class="n">mmap</span><span class="p">),</span>
<span class="n">SCMP_SYS</span><span class="p">(</span><span class="n">mprotect</span><span class="p">),</span> <span class="n">SCMP_SYS</span><span class="p">(</span><span class="n">munmap</span><span class="p">),</span>
<span class="n">SCMP_SYS</span><span class="p">(</span><span class="n">brk</span><span class="p">),</span> <span class="n">SCMP_SYS</span><span class="p">(</span><span class="n">access</span><span class="p">),</span>
<span class="n">SCMP_SYS</span><span class="p">(</span><span class="n">exit_group</span><span class="p">)};</span>
<span class="k">typedef</span> <span class="nf">int</span> <span class="p">(</span><span class="o">*</span><span class="n">main_t</span><span class="p">)(</span><span class="kt">int</span><span class="p">,</span> <span class="kt">char</span> <span class="o">**</span><span class="p">,</span> <span class="kt">char</span> <span class="o">**</span><span class="p">);</span>
<span class="cp">#ifndef __unbounded
</span><span class="cp"># define __unbounded
</span><span class="cp">#endif
</span><span class="cp"></span>
<span class="kt">int</span> <span class="nf">__libc_start_main</span><span class="p">(</span><span class="n">main_t</span> <span class="n">main</span><span class="p">,</span> <span class="kt">int</span> <span class="n">argc</span><span class="p">,</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">__unbounded</span> <span class="o">*</span><span class="n">__unbounded</span> <span class="n">ubp_av</span><span class="p">,</span>
<span class="n">ElfW</span><span class="p">(</span><span class="n">auxv_t</span><span class="p">)</span> <span class="o">*</span><span class="n">__unbounded</span> <span class="n">auxvec</span><span class="p">,</span>
<span class="n">__typeof</span> <span class="p">(</span><span class="n">main</span><span class="p">)</span> <span class="n">init</span><span class="p">,</span>
<span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">fini</span><span class="p">)</span> <span class="p">(</span><span class="kt">void</span><span class="p">),</span>
<span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">rtld_fini</span><span class="p">)</span> <span class="p">(</span><span class="kt">void</span><span class="p">),</span> <span class="kt">void</span> <span class="o">*</span><span class="n">__unbounded</span>
<span class="n">stack_end</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">i</span><span class="p">;</span>
<span class="n">ssize_t</span> <span class="n">len</span><span class="p">;</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">libc</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">whitelist_length</span> <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">syscalls_whitelist</span><span class="p">)</span> <span class="o">/</span> <span class="k">sizeof</span><span class="p">(</span><span class="kt">int</span><span class="p">);</span>
<span class="n">scmp_filter_ctx</span> <span class="n">ctx</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">libc_start_main</span><span class="p">)(</span><span class="n">main_t</span> <span class="n">main</span><span class="p">,</span>
<span class="kt">int</span><span class="p">,</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">__unbounded</span> <span class="o">*</span><span class="n">__unbounded</span><span class="p">,</span>
<span class="n">ElfW</span><span class="p">(</span><span class="n">auxv_t</span><span class="p">)</span> <span class="o">*</span><span class="p">,</span>
<span class="n">__typeof</span> <span class="p">(</span><span class="n">main</span><span class="p">),</span>
<span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">fini</span><span class="p">)</span> <span class="p">(</span><span class="kt">void</span><span class="p">),</span>
<span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">rtld_fini</span><span class="p">)</span> <span class="p">(</span><span class="kt">void</span><span class="p">),</span>
<span class="kt">void</span> <span class="o">*</span><span class="n">__unbounded</span> <span class="n">stack_end</span><span class="p">);</span>
<span class="c1">// Get __libc_start_main entry point
</span><span class="c1"></span> <span class="n">libc</span> <span class="o">=</span> <span class="n">dlopen</span><span class="p">(</span><span class="s">"libc.so.6"</span><span class="p">,</span> <span class="n">RTLD_LOCAL</span> <span class="o">|</span> <span class="n">RTLD_LAZY</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">libc</span><span class="p">)</span> <span class="p">{</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">libc_start_main</span> <span class="o">=</span> <span class="n">dlsym</span><span class="p">(</span><span class="n">libc</span><span class="p">,</span> <span class="s">"__libc_start_main"</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">libc_start_main</span><span class="p">)</span> <span class="p">{</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">seccomp_init</span><span class="p">(</span><span class="n">SCMP_ACT_KILL</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">ctx</span><span class="p">)</span> <span class="p">{</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">for</span><span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">whitelist_length</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">seccomp_rule_add</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="n">SCMP_ACT_ALLOW</span><span class="p">,</span>
<span class="n">syscalls_whitelist</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="mi">0</span><span class="p">))</span> <span class="p">{</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">4</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">seccomp_load</span><span class="p">(</span><span class="n">ctx</span><span class="p">))</span> <span class="p">{</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">seccomp_release</span><span class="p">(</span><span class="n">ctx</span><span class="p">);</span>
<span class="k">return</span> <span class="p">((</span><span class="o">*</span><span class="n">libc_start_main</span><span class="p">)(</span><span class="n">main</span><span class="p">,</span> <span class="n">argc</span><span class="p">,</span> <span class="n">ubp_av</span><span class="p">,</span> <span class="n">auxvec</span><span class="p">,</span>
<span class="n">init</span><span class="p">,</span> <span class="n">fini</span><span class="p">,</span> <span class="n">rtld_fini</span><span class="p">,</span> <span class="n">stack_end</span><span class="p">));</span>
<span class="p">}</span></code></pre></div><p>参考 <a href="https://link.zhihu.com/?target=http%3A//stackoverflow.com/a/27735456/2737403" class=" external" target="_blank" rel="nofollow noreferrer"><span class="invisible">http://</span><span class="visible">stackoverflow.com/a/277</span><span class="invisible">35456/2737403</span><span class="ellipsis"></span></a> 和 <a href="https://link.zhihu.com/?target=https%3A//github.com/daveho/EasySandbox" class=" external" target="_blank" rel="nofollow noreferrer"><span class="invisible">https://</span><span class="visible">github.com/daveho/EasyS</span><span class="invisible">andbox</span><span class="ellipsis"></span></a></p><h2>代码级别 hook</h2><p>编译的时候将两个文件编译在一起,<code>gcc sandbox.c user_code.c -ldl -lseccomp -o user_code</code>,虽然说直接定义<code>__libc_start_main</code>函数会提示重复定义,但是部分库函数还是可以通过定义同名函数覆盖绕过,比如 <code>seccomp</code> 里面的函数、<code>dlopen</code>函数。</p><h2>execve 前面加载策略</h2><p><code>exceve</code> 之前加载策略,就需要将 <code>exceve</code> 系统调用加白名单,有点不安全,但是可以在 <code>seccomp</code> 参数中指定 <code>exceve</code> 的执行参数,第一个参数就是文件路径,必须得匹配才行,否则就会 kill 掉。可以将指定的文件名加白名单。</p><div class="highlight"><pre><code class="language-c"><span class="cp">#include</span> <span class="cpf"><stdio.h></span><span class="cp">
</span><span class="cp">#include</span> <span class="cpf"><unistd.h></span><span class="cp">
</span><span class="cp">#include</span> <span class="cpf"><seccomp.h></span><span class="cp">
</span><span class="cp"></span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="kt">char</span> <span class="n">file_name</span><span class="p">[</span><span class="mi">30</span><span class="p">]</span> <span class="o">=</span> <span class="s">"/bin/ls"</span><span class="p">;</span>
<span class="kt">char</span> <span class="n">file_name1</span><span class="p">[</span><span class="mi">30</span><span class="p">]</span> <span class="o">=</span> <span class="s">"xxxxxx"</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="s">"/"</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">};</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">env</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="nb">NULL</span><span class="p">};</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"unrestricted</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="c1">// Init the filter
</span><span class="c1"></span> <span class="n">scmp_filter_ctx</span> <span class="n">ctx</span><span class="p">;</span>
<span class="n">ctx</span> <span class="o">=</span> <span class="n">seccomp_init</span><span class="p">(</span><span class="n">SCMP_ACT_ALLOW</span><span class="p">);</span>
<span class="n">seccomp_rule_add</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="n">SCMP_ACT_KILL</span><span class="p">,</span> <span class="n">SCMP_SYS</span><span class="p">(</span><span class="n">execve</span><span class="p">),</span> <span class="mi">1</span><span class="p">,</span>
<span class="n">SCMP_A0</span><span class="p">(</span><span class="n">SCMP_CMP_NE</span><span class="p">,</span> <span class="n">file_name</span><span class="p">));</span>
<span class="n">seccomp_load</span><span class="p">(</span><span class="n">ctx</span><span class="p">);</span>
<span class="n">execve</span><span class="p">(</span><span class="n">file_name</span><span class="p">,</span> <span class="n">argv</span><span class="p">,</span> <span class="n">env</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span></code></pre></div><p>如果改成<code>execve(file_name1, argv, env);</code>,就没法执行了。</p><p>当然要注意的是,<code>execve</code> 第一个参数匹配是内存地址匹配,毕竟是一个指针,而不是字符串匹配。Linux 系统开启 ASLR 之后,内存地址会随机化,用户代码几乎不可能简单的在相同的地址下面再放置一个路径。但是如果 <code>file_name</code> 不在栈上或者是指定地址加载的,那用户代码也可能通过 mmap 来加载到同一个地址上,可以参考 <a href="https://link.zhihu.com/?target=https%3A//dangokyo.me/2018/07/12/googlectf-2018-qual-pwn-execve-sandbox-write-up/" class=" wrap external" target="_blank" rel="nofollow noreferrer">Google CTF</a> 的一道题。</p><h2>seccomp 应该怎么用</h2><p>文档看 <a href="https://link.zhihu.com/?target=http%3A//man7.org/linux/man-pages/man3/seccomp_rule_add.3.html" class=" external" target="_blank" rel="nofollow noreferrer"><span class="invisible">http://</span><span class="visible">man7.org/linux/man-page</span><span class="invisible">s/man3/seccomp_rule_add.3.html</span><span class="ellipsis"></span></a> 就够了,可以看到 seccomp 是支持某个参数的原始数据大小比较和掩码后数据一致比较的。</p><p>对于 C/C++ 等,我们可以开放<a href="https://link.zhihu.com/?target=https%3A//github.com/QingdaoU/Judger/blob/newnew/src/rules/c_cpp.c%23L10" class=" wrap external" target="_blank" rel="nofollow noreferrer">白名单</a>,类似 execve 这种需要特殊处理。 </p><h2>控制写文件</h2><p>我们不期望这些程序可以写任何文件。这种想法的直觉是限制 <code>write</code> 的第一个参数 fd 不能大于 stderr,但是实际是可绕过的,那就是 <code>mmap</code>。 参考 <a href="https://link.zhihu.com/?target=http%3A//man7.org/linux/man-pages/man2/mmap.2.html" class=" external" target="_blank" rel="nofollow noreferrer"><span class="invisible">http://</span><span class="visible">man7.org/linux/man-page</span><span class="invisible">s/man2/mmap.2.html</span><span class="ellipsis"></span></a></p><p>页面最下面的例子修改下然后 strace 运行就会发现只需要 open 然后 mmap 也可以写文件的。</p><p>正确的方法是限制 <code>open</code>,不能带写权限。<a href="https://link.zhihu.com/?target=http%3A//man7.org/linux/man-pages/man2/open.2.html" class=" wrap external" target="_blank" rel="nofollow noreferrer">open 的 man page</a> 中说</p><blockquote> The argument flags must include one of the following access modes: O_RDONLY, O_WRONLY, or O_RDWR<br> </blockquote><p>所以这里就需要之前的掩码后比较了,其实掩码操作就是使用掩码和原数据进行与操作,<code>SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY | O_RDWR, 0)</code> 就是说这两位上都是0才可以通过。</p><p>和 <code>mmap</code> 类似的是 <code>creat</code> 系统调用,也可以创建一个文件。</p><p>这种问题的根本解决办法是修改文件系统的用户权限。</p><h2>__x32_compat 系统调用</h2><p><a href="https://link.zhihu.com/?target=https%3A//github.com/torvalds/linux/blob/master/arch/x86/entry/syscalls/syscall_64.tbl%23L353" class=" external" target="_blank" rel="nofollow noreferrer"><span class="invisible">https://</span><span class="visible">github.com/torvalds/lin</span><span class="invisible">ux/blob/master/arch/x86/entry/syscalls/syscall_64.tbl#L353</span><span class="ellipsis"></span></a> 有一些 <code>__x32_compat</code> 开头的系统调用,很容易忽略它们,没有加入黑名单,这些系统调用和不带 <code>_x32_compat</code> 的用法基本一致。</p><h2>资源占用的限制</h2><h2>CPU 时间限制,是 setrlimit 还是 setitimer</h2><p>主要是的区别是子进程能否继承限制,进程能否捕获超时错误。</p><p>当 <code>setitimer</code> 定时器计时结束时,系统就会给进程发送一个信号。</p><p>需要关心的两个计数器分别是 <code>ITIMER_REAL</code> 进程实际运行时间计数器,结束的时候发送 <code>SIGALRM</code> 信号;<code>ITIMER_VIRTUAL</code> 进程 CPU 时间计数器,结束的时候发送 <code>SIGVTALRM</code> 信号。我们设置好定时器之后,如果捕获到了对应的信号,说明当前进程运行超时。</p><p>具体实现代码如下</p><div class="highlight"><pre><code class="language-text">int set_timer(int sec, int ms, int is_cpu_time) {
struct itimerval time_val;
time_val.it_interval.tv_sec = time_val.it_interval.tv_usec = 0;
time_val.it_value.tv_sec = sec;
time_val.it_value.tv_usec = ms * 1000;
if (setitimer(is_cpu_time?ITIMER_VIRTUAL:ITIMER_REAL, &time_val, NULL)) {
LOG_FATAL("setitimer failed, errno %d", errno);
return SETITIMER_FAILED;
}
return SUCCESS;
}</code></pre></div><p>但是有一点是需要注意的,<a href="https://link.zhihu.com/?target=http%3A//man7.org/linux/man-pages/man2/setitimer.2.html" class=" wrap external" target="_blank" rel="nofollow noreferrer">setitimer 不能限制子进程的 CPU 和实际运行时间</a>。</p><p>在部分只限制资源占用而不启用沙箱的场景下,这可能导致资源限制失效,因为进程可以取消这个设定。</p><p>Linux 中 <code>setrlimit</code> 函数可以用来限制进程的资源占用, 其中支持 <code>RLIMIT_CPU</code>、<code>RLIMIT_AS</code> 等参数, 同时子进程会继承父进程的设置。RLIMIT_CPU 也可以控制进程 CPU 时间, 所以要设置为 CPU 时间向上取整的值,然后和最后获取的时间再比较。</p><h2>限制内存和最大输出大小</h2><p><code>RLIMIT_AS</code> 是限制进程最大内存地址空间,超过这个地址空间的将不能 分配成功,影响 <code>brk</code>、<code>mmap</code>、<code>mremap</code> 等系统调用。 <code>RLIMIT_FSIZE</code> 是限制进程最大输出或者写文件的大小,估计是限制了 <code>write</code> 等。</p><h2>实际运行时间</h2><p>这个也很重要,如果一个进程啥都不做只 <code>sleep</code> 的话,CPU 时间几乎不会超,这里我的方案是新开一个线程一直监视某个 PID,超时就 kill 掉。</p><h2>RLIMIT_NPROC 有点坑</h2><p>很多人都知道 <code>while(1) fork()</code> 可以卡死机器,怎么防?尤其是 go 这类这种天生就要开线程的语言。</p><blockquote>
The maximum number of processes (or, more precisely on Linux, threads)
that can be created for the real user ID of the calling process. Upon
encountering this limit, fork(2) fails with the error EAGAIN<br> </blockquote><p>如果简单的使用 <code>nproc</code> 限制是不可以的,原因是 <code>real user ID</code> 这个其实不仅仅是进程的,和用户也有关。一个用户已经有10个进程了,那你给进程设置 <code>nproc=10</code> 是没用的,因为已经满了,而设置更低的数字可能导致进程无法启动。</p><p>也许给每个进程都设置一个单独的用户可破?没有试</p><h2>还有哪里容易出现问题</h2><h2>编译器安全</h2><p>这是一个容易被忽视的方面,目前已知的主要有以下几种。</p><ul><li>引用某些可以无限输出的文件,比如 <code>#include</dev/random></code>,编译器会一直读取, 导致卡死</li><li>让编译器产生大量的错误信息,比如下面一段代码,可以让 g++ 编译器产生数 G 的错误日志</li></ul><div class="highlight"><pre><code class="language-text">int main() {
struct x struct z<x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(y,x(y><y*,x(y*w>v<y*,w,x{}
return 0;
}</code></pre></div><p>处理方法就是编译器运行的时候也要控制 CPU 时间和实际运行时间还有最大输出,同时使用编译器参数 <code>-fmax-errors=N</code> 来控制最大错误数量</p><ul><li>C++ 的模板元编程,部分代码是编译期执行的,可以构造出让编译器产生大量计算的代码。类似的有 Python 的编译器常量优化等等。</li><li>引用一些敏感文件可能导致信息泄露,比如 <code>#include</etc/shadow/></code> 或者测试用例等,会在编译错误的信息中泄露文件开头的内容。需要给编译器和运行代码设置单独的用户。</li></ul><h2>上面说的基础环境其实都在 Docker 里面</h2><p>Docker 默认会<a href="https://link.zhihu.com/?target=https%3A//docs.docker.com/engine/security/security/" class=" wrap external" target="_blank" rel="nofollow noreferrer">屏蔽一些系统调用和 capability</a>,所以上面的很多方案都是基于这个前提的,否则需要自己处理 Docker 默认屏蔽的系统调用调用黑名单和降权。</p><p>开源 <a href="https://link.zhihu.com/?target=https%3A//github.com/QingdaoU/Judger" class=" external" target="_blank" rel="nofollow noreferrer"><span class="invisible">https://</span><span class="visible">github.com/QingdaoU/Jud</span><span class="invisible">ger</span><span class="ellipsis"></span></a></p><p>参考 </p><ul><li><a href="https://link.zhihu.com/?target=http%3A//manpages.ubuntu.com/manpages/saucy/man3/seccomp_rule_add.3.html" class=" external" target="_blank" rel="nofollow noreferrer"><span class="invisible">http://</span><span class="visible">manpages.ubuntu.com/man</span><span class="invisible">pages/saucy/man3/seccomp_rule_add.3.html</span><span class="ellipsis"></span></a></li><li><a href="https://link.zhihu.com/?target=https%3A//filippo.io/linux-syscall-table/" class=" external" target="_blank" rel="nofollow noreferrer"><span class="invisible">https://</span><span class="visible">filippo.io/linux-syscal</span><span class="invisible">l-table/</span><span class="ellipsis"></span></a></li><li><a href="https://www.zhihu.com/question/23067497" class="internal"><span class="invisible">https://www.</span><span class="visible">zhihu.com/question/2306</span><span class="invisible">7497</span><span class="ellipsis"></span></a></li></ul><p>再加个广告,我们开发的 OnlineJudge 系统 <a href="https://link.zhihu.com/?target=https%3A//github.com/QingdaoU/OnlineJudge" class=" wrap external" target="_blank" rel="nofollow noreferrer">QingdaoU/OnlineJudge: Open source online judge based on Python, Django and Docker.</a> 也开源了,欢迎给个 star。</p></span></div><div><div class="ContentItem-time"><a target="_blank" href="https://www.zhihu.com/question/23067497/answer/82308751"><span data-tooltip="发布于 2016-01-19 14:45">编辑于 2018-11-24</span></a></div></div><div class="ContentItem-actions RichContent-actions"><span><button aria-label="赞同 66 " type="button" class="Button VoteButton VoteButton--up"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--TriangleUp VoteButton-TriangleUp" fill="currentColor" viewBox="0 0 24 24" width="10" height="10"><path d="M2 18.242c0-.326.088-.532.237-.896l7.98-13.203C10.572 3.57 11.086 3 12 3c.915 0 1.429.571 1.784 1.143l7.98 13.203c.15.364.236.57.236.896 0 1.386-.875 1.9-1.955 1.9H3.955c-1.08 0-1.955-.517-1.955-1.9z" fill-rule="evenodd"></path></svg></span>赞同 66</button><button aria-label="反对" type="button" class="Button VoteButton VoteButton--down"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--TriangleDown" fill="currentColor" viewBox="0 0 24 24" width="10" height="10"><path d="M20.044 3H3.956C2.876 3 2 3.517 2 4.9c0 .326.087.533.236.896L10.216 19c.355.571.87 1.143 1.784 1.143s1.429-.572 1.784-1.143l7.98-13.204c.149-.363.236-.57.236-.896 0-1.386-.876-1.9-1.956-1.9z" fill-rule="evenodd"></path></svg></span></button></span><button type="button" class="Button ContentItem-action Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Comment Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M10.241 19.313a.97.97 0 0 0-.77.2 7.908 7.908 0 0 1-3.772 1.482.409.409 0 0 1-.38-.637 5.825 5.825 0 0 0 1.11-2.237.605.605 0 0 0-.227-.59A7.935 7.935 0 0 1 3 11.25C3 6.7 7.03 3 12 3s9 3.7 9 8.25-4.373 9.108-10.759 8.063z" fill-rule="evenodd"></path></svg></span>39 条评论</button><div class="Popover ShareMenu ContentItem-action"><div class="ShareMenu-toggler" id="Popover12-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover12-content"><button type="button" class="Button Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Share Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M2.931 7.89c-1.067.24-1.275 1.669-.318 2.207l5.277 2.908 8.168-4.776c.25-.127.477.198.273.39L9.05 14.66l.927 5.953c.18 1.084 1.593 1.376 2.182.456l9.644-15.242c.584-.892-.212-2.029-1.234-1.796L2.93 7.89z" fill-rule="evenodd"></path></svg></span>分享</button></div></div><button type="button" class="Button ContentItem-action Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Star Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M5.515 19.64l.918-5.355-3.89-3.792c-.926-.902-.639-1.784.64-1.97L8.56 7.74l2.404-4.871c.572-1.16 1.5-1.16 2.072 0L15.44 7.74l5.377.782c1.28.186 1.566 1.068.64 1.97l-3.89 3.793.918 5.354c.219 1.274-.532 1.82-1.676 1.218L12 18.33l-4.808 2.528c-1.145.602-1.896.056-1.677-1.218z" fill-rule="evenodd"></path></svg></span>收藏</button><button type="button" class="Button ContentItem-action Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Heart Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M2 8.437C2 5.505 4.294 3.094 7.207 3 9.243 3 11.092 4.19 12 6c.823-1.758 2.649-3 4.651-3C19.545 3 22 5.507 22 8.432 22 16.24 13.842 21 12 21 10.158 21 2 16.24 2 8.437z" fill-rule="evenodd"></path></svg></span>喜欢</button><button data-zop-retract-question="true" type="button" class="Button ContentItem-action ContentItem-rightButton Button--plain"><span class="RichContent-collapsedText">收起</span><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--ArrowDown ContentItem-arrowIcon is-active" fill="currentColor" viewBox="0 0 24 24" width="24" height="24"><path d="M12 13L8.285 9.218a.758.758 0 0 0-1.064 0 .738.738 0 0 0 0 1.052l4.249 4.512a.758.758 0 0 0 1.064 0l4.246-4.512a.738.738 0 0 0 0-1.052.757.757 0 0 0-1.063 0L12.002 13z" fill-rule="evenodd"></path></svg></span></button></div></div><div class="ModalWrap"><div><div class=""></div><div class="ModalExp-content"><div class="ModalWrap-content"><div class="ModalWrap-title">继续浏览内容</div><div class="ModalWrap-item"><div class="ModalWrap-itemImg"><img src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-88158afcff1e7f4b8b00a1ba81171b61_720w.png"></div><div class="ModalWrap-itemContent"><div class="ModalWrap-itemTitle">知乎</div><div class="ModalWrap-itemDesc">发现更大的世界</div></div><div class="ModalWrap-itemBtn">打开</div></div><div class="ModalWrap-item"><div class="ModalWrap-itemImg"><img src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-da7d9e4b6a7ddba507299bcf5a4d0600_1440w.png"></div><div class="ModalWrap-itemContent"><div class="ModalWrap-itemTitle">浏览器</div></div><div class="ModalWrap-itemBtn">继续</div></div></div></div></div></div><div><div><div class=""></div><div class="ModalLoading-content"><svg width="30" height="30" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg" class="CircleLoadingBar" aria-hidden="true"><g><circle class="path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></g></svg></div></div></div></div></div><div class="List-item" tabindex="0"><div class="ContentItem AnswerItem" data-za-index="2" data-zop="{"authorName":"alex zhang","itemId":40878704,"title":"Online Judge 是如何解决判题端安全性问题的?","type":"answer"}" name="40878704" itemprop="suggestedAnswer" itemtype="http://schema.org/Answer" itemscope="" data-za-detail-view-path-module="AnswerItem" data-za-detail-view-path-index="2" data-za-extra-module="{"card":{"has_image":false,"has_video":false,"content":{"type":"Answer","token":"40878704","upvote_num":22,"comment_num":5,"publish_timestamp":null,"parent_token":"23067497","author_member_hash_id":"7bf7ca5658d8d6f979efc6de351a7e1f"}}}"><div class="ContentItem-meta"><div class="AuthorInfo AnswerItem-authorInfo AnswerItem-authorInfo--related" itemprop="author" itemscope="" itemtype="http://schema.org/Person"><div class="AuthorInfo"><meta itemprop="name" content="alex zhang"><meta itemprop="image" content="https://pic4.zhimg.com/2b4336ec5_l.jpg?source=1940ef5c"><meta itemprop="url" content="https://www.zhihu.com/people/alexzhang2015"><meta itemprop="zhihu:followerCount" content="1026"><span class="UserLink AuthorInfo-avatarWrapper"><div class="Popover"><div id="Popover21-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover21-content"><a target="_blank" class="UserLink-link" data-za-detail-view-element_name="User" href="https://www.zhihu.com/people/alexzhang2015"><img class="Avatar AuthorInfo-avatar" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/2b4336ec5_xs.jpg" srcset="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/2b4336ec5_l.jpg 2x" alt="alex zhang" width="38" height="38"></a></div></div></span><div class="AuthorInfo-content"><div class="AuthorInfo-head"><span class="UserLink AuthorInfo-name"><div class="Popover"><div id="Popover22-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover22-content"><a target="_blank" class="UserLink-link" data-za-detail-view-element_name="User" href="https://www.zhihu.com/people/alexzhang2015">alex zhang</a></div></div></span></div><div class="AuthorInfo-detail"><div class="AuthorInfo-badge"><div class="ztext AuthorInfo-badgeText">互联网研发</div></div></div></div></div></div><div class="LabelContainer-wrapper"></div><div class="css-h5al4j"><span><span class="Voters"><button type="button" class="Button Button--plain">22 人赞同了该回答</button></span></span></div></div><meta itemprop="image"><meta itemprop="upvoteCount" content="22"><meta itemprop="url" content="https://www.zhihu.com/question/23067497/answer/40878704"><meta itemprop="dateCreated" content="2015-03-01T14:32:49.000Z"><meta itemprop="dateModified" content="2015-03-07T11:57:16.000Z"><meta itemprop="commentCount" content="5"><div class="RichContent RichContent--unescapable"><div class="RichContent-inner"><span class="RichText ztext CopyrightRichText-richText" itemprop="text">之前写过一个这样的系统,09年的时候,那时候也是同样遇到这些问题,思路类似,构建一个sandbox,filter syscall。 <a href="https://link.zhihu.com/?target=http%3A//alex_zhang.intscan.org" class=" wrap external" target="_blank" rel="nofollow noreferrer">Online Compiler!</a><br><br><br><b><i><u>1. Then Google Native Client</u></i></b><br>后来遇见了chrome,在看其native client的实现,其实就是OJ后台的一套sandbox系统。<br>核心部分,构建的2套sandbox<br><p>• inner sandbox: binary validation<br>• outer sandbox: OS system-call interception </p><br><br>--> inner sandbox<br>Protection Rule For Inner Sandbox<br><figure><noscript><img src="https://pic4.zhimg.com/50/e3b1c24280d6babb4d1259ef5c1cf2ce_hd.jpg?source=1940ef5c" data-rawwidth="728" data-rawheight="452" class="origin_image zh-lightbox-thumb" width="728" data-original="https://pic4.zhimg.com/e3b1c24280d6babb4d1259ef5c1cf2ce_r.jpg?source=1940ef5c"/></noscript><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='728' height='452'></svg>" data-rawwidth="728" data-rawheight="452" class="origin_image zh-lightbox-thumb lazy" data-original="https://pic4.zhimg.com/e3b1c24280d6babb4d1259ef5c1cf2ce_r.jpg?source=1940ef5c" data-actualsrc="https://pic4.zhimg.com/50/e3b1c24280d6babb4d1259ef5c1cf2ce_hd.jpg?source=1940ef5c" width="728"></figure>--> outer sandbox<br>Based on systrace.<br><br>Reference:<br><a href="https://link.zhihu.com/?target=http%3A//static.googleusercontent.com/media/research.google.com/en//pubs/archive/34913.pdf" class=" external" target="_blank" rel="nofollow noreferrer"><span class="invisible">http://</span><span class="visible">static.googleusercontent.com</span><span class="invisible">/media/research.google.com/en//pubs/archive/34913.pdf</span><span class="ellipsis"></span></a><br><a href="https://link.zhihu.com/?target=http%3A//www.citi.umich.edu/u/provos/papers/systrace.pdf" class=" external" target="_blank" rel="nofollow noreferrer"><span class="invisible">http://www.</span><span class="visible">citi.umich.edu/u/provos</span><span class="invisible">/papers/systrace.pdf</span><span class="ellipsis"></span></a><br><br><br><u><i><b>2. ZeroVM</b></i></u><br><a href="https://link.zhihu.com/?target=https%3A//github.com/zerovm/zerovm" class=" wrap external" target="_blank" rel="nofollow noreferrer">zerovm/zerovm · GitHub</a><br><br>APP Sandbo领域新出生的创业公司,核心思路如下<br><blockquote>ZeroVM creates a sandbox around a single process,<br> using technology based on <a href="https://link.zhihu.com/?target=http%3A//en.wikipedia.org/wiki/Google_Native_Client" class=" wrap external" target="_blank" rel="nofollow noreferrer">Google Native Client</a>
(NaCl). The sandbox ensures that the application executed cannot access
data in the host operating system, so it is safe to execute untrusted
code. </blockquote><figure><noscript><img src="https://pic4.zhimg.com/50/62d7f039a8cce47202ffdd022e02417c_hd.jpg?source=1940ef5c" data-rawwidth="1024" data-rawheight="768" class="origin_image zh-lightbox-thumb" width="1024" data-original="https://pic3.zhimg.com/62d7f039a8cce47202ffdd022e02417c_r.jpg?source=1940ef5c"/></noscript><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='1024' height='768'></svg>" data-rawwidth="1024" data-rawheight="768" class="origin_image zh-lightbox-thumb lazy" data-original="https://pic3.zhimg.com/62d7f039a8cce47202ffdd022e02417c_r.jpg?source=1940ef5c" data-actualsrc="https://pic4.zhimg.com/50/62d7f039a8cce47202ffdd022e02417c_hd.jpg?source=1940ef5c" width="1024"></figure><br>所以,如果不想自己造轮子,可以用ZeroVM。过几天,把我那个系统试试移到ZeroVM上~~<br><br><u><i><b>3. Qubes OS</b></i></u><br>看下architecture 感受下,<br><figure><noscript><img src="https://pic1.zhimg.com/50/dfb41379166fb5703366c4a6163aa8dc_hd.jpg?source=1940ef5c" data-rawwidth="683" data-rawheight="496" class="origin_image zh-lightbox-thumb" width="683" data-original="https://pic4.zhimg.com/dfb41379166fb5703366c4a6163aa8dc_r.jpg?source=1940ef5c"/></noscript><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='683' height='496'></svg>" data-rawwidth="683" data-rawheight="496" class="origin_image zh-lightbox-thumb lazy" data-original="https://pic4.zhimg.com/dfb41379166fb5703366c4a6163aa8dc_r.jpg?source=1940ef5c" data-actualsrc="https://pic1.zhimg.com/50/dfb41379166fb5703366c4a6163aa8dc_hd.jpg?source=1940ef5c" width="683"></figure>著名的波兰美女黑客Joanna Rutkowska设计的,基于Xen、X和Linux的新开源操作。<br>它充分利用了虚拟化技术(基于安全虚拟机Xen),所有用户应用程序都运行在AppVM(基于Linux的轻量级虚 拟机)中,彼此隔离。<br>也能利用,但是用来跑OJ可能有点大材小用了。<br><br><br><br>欢迎讨论~</span></div><div><div class="ContentItem-time"><a target="_blank" href="https://www.zhihu.com/question/23067497/answer/40878704"><span data-tooltip="发布于 2015-03-01 22:32">编辑于 2015-03-07</span></a></div></div><div class="ContentItem-actions RichContent-actions"><span><button aria-label="赞同 22 " type="button" class="Button VoteButton VoteButton--up"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--TriangleUp VoteButton-TriangleUp" fill="currentColor" viewBox="0 0 24 24" width="10" height="10"><path d="M2 18.242c0-.326.088-.532.237-.896l7.98-13.203C10.572 3.57 11.086 3 12 3c.915 0 1.429.571 1.784 1.143l7.98 13.203c.15.364.236.57.236.896 0 1.386-.875 1.9-1.955 1.9H3.955c-1.08 0-1.955-.517-1.955-1.9z" fill-rule="evenodd"></path></svg></span>赞同 22</button><button aria-label="反对" type="button" class="Button VoteButton VoteButton--down"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--TriangleDown" fill="currentColor" viewBox="0 0 24 24" width="10" height="10"><path d="M20.044 3H3.956C2.876 3 2 3.517 2 4.9c0 .326.087.533.236.896L10.216 19c.355.571.87 1.143 1.784 1.143s1.429-.572 1.784-1.143l7.98-13.204c.149-.363.236-.57.236-.896 0-1.386-.876-1.9-1.956-1.9z" fill-rule="evenodd"></path></svg></span></button></span><button type="button" class="Button ContentItem-action Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Comment Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M10.241 19.313a.97.97 0 0 0-.77.2 7.908 7.908 0 0 1-3.772 1.482.409.409 0 0 1-.38-.637 5.825 5.825 0 0 0 1.11-2.237.605.605 0 0 0-.227-.59A7.935 7.935 0 0 1 3 11.25C3 6.7 7.03 3 12 3s9 3.7 9 8.25-4.373 9.108-10.759 8.063z" fill-rule="evenodd"></path></svg></span>5 条评论</button><div class="Popover ShareMenu ContentItem-action"><div class="ShareMenu-toggler" id="Popover13-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover13-content"><button type="button" class="Button Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Share Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M2.931 7.89c-1.067.24-1.275 1.669-.318 2.207l5.277 2.908 8.168-4.776c.25-.127.477.198.273.39L9.05 14.66l.927 5.953c.18 1.084 1.593 1.376 2.182.456l9.644-15.242c.584-.892-.212-2.029-1.234-1.796L2.93 7.89z" fill-rule="evenodd"></path></svg></span>分享</button></div></div><button type="button" class="Button ContentItem-action Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Star Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M5.515 19.64l.918-5.355-3.89-3.792c-.926-.902-.639-1.784.64-1.97L8.56 7.74l2.404-4.871c.572-1.16 1.5-1.16 2.072 0L15.44 7.74l5.377.782c1.28.186 1.566 1.068.64 1.97l-3.89 3.793.918 5.354c.219 1.274-.532 1.82-1.676 1.218L12 18.33l-4.808 2.528c-1.145.602-1.896.056-1.677-1.218z" fill-rule="evenodd"></path></svg></span>收藏</button><button type="button" class="Button ContentItem-action Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Heart Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M2 8.437C2 5.505 4.294 3.094 7.207 3 9.243 3 11.092 4.19 12 6c.823-1.758 2.649-3 4.651-3C19.545 3 22 5.507 22 8.432 22 16.24 13.842 21 12 21 10.158 21 2 16.24 2 8.437z" fill-rule="evenodd"></path></svg></span>喜欢</button><button data-zop-retract-question="true" type="button" class="Button ContentItem-action ContentItem-rightButton Button--plain"><span class="RichContent-collapsedText">收起</span><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--ArrowDown ContentItem-arrowIcon is-active" fill="currentColor" viewBox="0 0 24 24" width="24" height="24"><path d="M12 13L8.285 9.218a.758.758 0 0 0-1.064 0 .738.738 0 0 0 0 1.052l4.249 4.512a.758.758 0 0 0 1.064 0l4.246-4.512a.738.738 0 0 0 0-1.052.757.757 0 0 0-1.063 0L12.002 13z" fill-rule="evenodd"></path></svg></span></button></div></div><div class="ModalWrap"><div><div class=""></div><div class="ModalExp-content"><div class="ModalWrap-content"><div class="ModalWrap-title">继续浏览内容</div><div class="ModalWrap-item"><div class="ModalWrap-itemImg"><img src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-88158afcff1e7f4b8b00a1ba81171b61_720w.png"></div><div class="ModalWrap-itemContent"><div class="ModalWrap-itemTitle">知乎</div><div class="ModalWrap-itemDesc">发现更大的世界</div></div><div class="ModalWrap-itemBtn">打开</div></div><div class="ModalWrap-item"><div class="ModalWrap-itemImg"><img src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-da7d9e4b6a7ddba507299bcf5a4d0600_1440w.png"></div><div class="ModalWrap-itemContent"><div class="ModalWrap-itemTitle">浏览器</div></div><div class="ModalWrap-itemBtn">继续</div></div></div></div></div></div><div><div><div class=""></div><div class="ModalLoading-content"><svg width="30" height="30" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg" class="CircleLoadingBar" aria-hidden="true"><g><circle class="path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></g></svg></div></div></div></div></div><div class="Pc-word"><div class="Pc-word-card"><a target="_blank" href="https://www.beaconedu.com/lpv1/iit-0826?cb=https%3A%2F%2Fsugar.zhihu.com%2Fplutus_adreaper_callback%3Fsi%3D1ba5f8fe-c7f5-4928-8f95-f42c9e3c4cd4%26os%3D3%26zid%3D236%26zaid%3D1437272%26zcid%3D1486153%26cid%3D1486152%26event%3D__EVENTTYPE__%26value%3D__EVENTVALUE__%26ts%3D__TIMESTAMP__%26cts%3D__TS__%26mh%3D__MEMBERHASHID__"><div class="Pc-word-card-brand"><div class="Pc-word-card-brand-wrapper"><img src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-742b70686c0a04f6d77a011904d9d704_250x250.jpeg" alt="logo" width="20" height="20"><span>彼岸教育</span></div></div></a><div class="Pc-word-card-sign"><div class="Pc-word-card-sign-label">广告<svg class="Icon Icon--triangle Pc-word-card-sign-svg" viewBox="0 0 24 24"><path d="M9.218 16.78a.737.737 0 0 0 1.052 0l4.512-4.249a.758.758 0 0 0 0-1.063L10.27 7.22a.737.737 0 0 0-1.052 0 .759.759 0 0 0-.001 1.063L13 12l-3.782 3.716a.758.758 0 0 0 0 1.063z" fill-rule="evenodd"></path></svg></div><div class="Pc-word-card-sign-popup Pc-word-card-sign-popup--isHidden"><span class="Pc-word-card-sign-popup-arrow"></span><div class="Pc-word-card-sign-popup-menu"><button type="button">不感兴趣</button><a target="_blank" rel="noopener noreferrer" href="https://www.zhihu.com/promotion-intro">知乎广告介绍</a></div></div></div><a target="_blank" href="https://www.beaconedu.com/lpv1/iit-0826?cb=https%3A%2F%2Fsugar.zhihu.com%2Fplutus_adreaper_callback%3Fsi%3D1ba5f8fe-c7f5-4928-8f95-f42c9e3c4cd4%26os%3D3%26zid%3D236%26zaid%3D1437272%26zcid%3D1486153%26cid%3D1486152%26event%3D__EVENTTYPE__%26value%3D__EVENTVALUE__%26ts%3D__TIMESTAMP__%26cts%3D__TS__%26mh%3D__MEMBERHASHID__"><h2 class="Pc-word-card-title">海外名校来华招生!想读在职名校硕士的小伙伴不要错过!</h2><div class="Pc-word-card-content "><span>伊利诺伊理工大学来华招生,免联考,在职可读,课程教授与本校同步,毕业拿全日制硕士证书,点击测试是否符合报考条件</span><span class="Pc-word-card-content-cta ">查看详情</span></div></a></div></div><div class="List-item" tabindex="0"><div class="ContentItem AnswerItem" data-za-index="4" data-zop="{"authorName":"匿名用户","itemId":77491830,"title":"Online Judge 是如何解决判题端安全性问题的?","type":"answer"}" name="77491830" itemprop="suggestedAnswer" itemtype="http://schema.org/Answer" itemscope="" data-za-detail-view-path-module="AnswerItem" data-za-detail-view-path-index="4" data-za-extra-module="{"card":{"has_image":false,"has_video":false,"content":{"type":"Answer","token":"77491830","upvote_num":3,"comment_num":0,"publish_timestamp":null,"parent_token":"23067497","author_member_hash_id":"0"}}}"><div class="ContentItem-meta"><div class="AuthorInfo AnswerItem-authorInfo AnswerItem-authorInfo--related" itemprop="author" itemscope="" itemtype="http://schema.org/Person"><div class="AuthorInfo"><meta itemprop="name" content="匿名用户"><meta itemprop="image" content="https://pic1.zhimg.com/aadd7b895_l.jpg?source=1940ef5c"><meta itemprop="url" content="https://www.zhihu.com/people/"><meta itemprop="zhihu:followerCount" content="0"><span class="UserLink AuthorInfo-avatarWrapper"><img class="Avatar AuthorInfo-avatar" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/aadd7b895_xs.jpg" srcset="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/aadd7b895_l.jpg 2x" alt="匿名用户" width="38" height="38"></span><div class="AuthorInfo-content"><div class="AuthorInfo-head"><span class="UserLink AuthorInfo-name">匿名用户</span></div><div class="AuthorInfo-detail"><div class="AuthorInfo-badge"></div></div></div></div></div><div class="LabelContainer-wrapper"></div><div class="css-h5al4j"><span><span class="Voters"><button type="button" class="Button Button--plain">3 人赞同了该回答</button></span></span></div></div><meta itemprop="image"><meta itemprop="upvoteCount" content="3"><meta itemprop="url" content="https://www.zhihu.com/question/23067497/answer/77491830"><meta itemprop="dateCreated" content="2015-12-18T18:59:42.000Z"><meta itemprop="dateModified" content="2015-12-18T19:05:55.000Z"><meta itemprop="commentCount" content="0"><div class="RichContent RichContent--unescapable"><div class="RichContent-inner"><span class="RichText ztext CopyrightRichText-richText" itemprop="text"><p>给ZOJ写过Patch的来回答一下。</p><p>ZOJ的沙箱是ptrace。但是ptrace的规则是硬写进去的,规则写的也比较复杂。比如:我记得当时glibc升级之后,由于某些安全功能(貌似是pointer guard?),需要在程序启动的时候读取/dev/urandom。</p><p>沙箱的内存控制是简单的setrlimit。</p><p>ptrace倒是并不慢,因为OJ的题目大部分很少频繁的调用system call。如果很频繁,那恐怕那个程序本身就是攻击的恶意程序。</p><p>前
面说用语言环境运行时而非动态沙箱的解决方法,我觉得做起来难度比较大。我对JIT
Spraying攻击不了解,但是个人感觉语言运行时的JIT是一个很大的attack
surface。而且还有,OJ里用Java和C#的比较少,部分原因是IO库比较慢,而且有些OJ问题对性能要求实在是太高了,OJ提交者往往喜欢对一
切过程都有控制。</p>如果说其他的选择,我会觉得虚拟化是个很好的选择。唯一的attack surface就是虚拟机和硬件本身</span></div><div><div class="ContentItem-time"><a target="_blank" href="https://www.zhihu.com/question/23067497/answer/77491830"><span data-tooltip="发布于 2015-12-19 02:59">编辑于 2015-12-19</span></a></div></div><div class="ContentItem-actions RichContent-actions"><span><button aria-label="赞同 3 " type="button" class="Button VoteButton VoteButton--up"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--TriangleUp VoteButton-TriangleUp" fill="currentColor" viewBox="0 0 24 24" width="10" height="10"><path d="M2 18.242c0-.326.088-.532.237-.896l7.98-13.203C10.572 3.57 11.086 3 12 3c.915 0 1.429.571 1.784 1.143l7.98 13.203c.15.364.236.57.236.896 0 1.386-.875 1.9-1.955 1.9H3.955c-1.08 0-1.955-.517-1.955-1.9z" fill-rule="evenodd"></path></svg></span>赞同 3</button><button aria-label="反对" type="button" class="Button VoteButton VoteButton--down"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--TriangleDown" fill="currentColor" viewBox="0 0 24 24" width="10" height="10"><path d="M20.044 3H3.956C2.876 3 2 3.517 2 4.9c0 .326.087.533.236.896L10.216 19c.355.571.87 1.143 1.784 1.143s1.429-.572 1.784-1.143l7.98-13.204c.149-.363.236-.57.236-.896 0-1.386-.876-1.9-1.956-1.9z" fill-rule="evenodd"></path></svg></span></button></span><button type="button" class="Button ContentItem-action Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Comment Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M10.241 19.313a.97.97 0 0 0-.77.2 7.908 7.908 0 0 1-3.772 1.482.409.409 0 0 1-.38-.637 5.825 5.825 0 0 0 1.11-2.237.605.605 0 0 0-.227-.59A7.935 7.935 0 0 1 3 11.25C3 6.7 7.03 3 12 3s9 3.7 9 8.25-4.373 9.108-10.759 8.063z" fill-rule="evenodd"></path></svg></span>添加评论</button><div class="Popover ShareMenu ContentItem-action"><div class="ShareMenu-toggler" id="Popover14-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover14-content"><button type="button" class="Button Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Share Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M2.931 7.89c-1.067.24-1.275 1.669-.318 2.207l5.277 2.908 8.168-4.776c.25-.127.477.198.273.39L9.05 14.66l.927 5.953c.18 1.084 1.593 1.376 2.182.456l9.644-15.242c.584-.892-.212-2.029-1.234-1.796L2.93 7.89z" fill-rule="evenodd"></path></svg></span>分享</button></div></div><button type="button" class="Button ContentItem-action Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Star Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M5.515 19.64l.918-5.355-3.89-3.792c-.926-.902-.639-1.784.64-1.97L8.56 7.74l2.404-4.871c.572-1.16 1.5-1.16 2.072 0L15.44 7.74l5.377.782c1.28.186 1.566 1.068.64 1.97l-3.89 3.793.918 5.354c.219 1.274-.532 1.82-1.676 1.218L12 18.33l-4.808 2.528c-1.145.602-1.896.056-1.677-1.218z" fill-rule="evenodd"></path></svg></span>收藏</button><button type="button" class="Button ContentItem-action Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Heart Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M2 8.437C2 5.505 4.294 3.094 7.207 3 9.243 3 11.092 4.19 12 6c.823-1.758 2.649-3 4.651-3C19.545 3 22 5.507 22 8.432 22 16.24 13.842 21 12 21 10.158 21 2 16.24 2 8.437z" fill-rule="evenodd"></path></svg></span>喜欢</button><button data-zop-retract-question="true" type="button" class="Button ContentItem-action ContentItem-rightButton Button--plain"><span class="RichContent-collapsedText">收起</span><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--ArrowDown ContentItem-arrowIcon is-active" fill="currentColor" viewBox="0 0 24 24" width="24" height="24"><path d="M12 13L8.285 9.218a.758.758 0 0 0-1.064 0 .738.738 0 0 0 0 1.052l4.249 4.512a.758.758 0 0 0 1.064 0l4.246-4.512a.738.738 0 0 0 0-1.052.757.757 0 0 0-1.063 0L12.002 13z" fill-rule="evenodd"></path></svg></span></button></div></div><div class="ModalWrap"><div><div class=""></div><div class="ModalExp-content"><div class="ModalWrap-content"><div class="ModalWrap-title">继续浏览内容</div><div class="ModalWrap-item"><div class="ModalWrap-itemImg"><img src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-88158afcff1e7f4b8b00a1ba81171b61_720w.png"></div><div class="ModalWrap-itemContent"><div class="ModalWrap-itemTitle">知乎</div><div class="ModalWrap-itemDesc">发现更大的世界</div></div><div class="ModalWrap-itemBtn">打开</div></div><div class="ModalWrap-item"><div class="ModalWrap-itemImg"><img src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-da7d9e4b6a7ddba507299bcf5a4d0600_1440w.png"></div><div class="ModalWrap-itemContent"><div class="ModalWrap-itemTitle">浏览器</div></div><div class="ModalWrap-itemBtn">继续</div></div></div></div></div></div><div><div><div class=""></div><div class="ModalLoading-content"><svg width="30" height="30" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg" class="CircleLoadingBar" aria-hidden="true"><g><circle class="path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></g></svg></div></div></div></div></div><div class="List-item" tabindex="0"><div class="ContentItem AnswerItem" data-za-index="5" data-zop="{"authorName":"时国怀","itemId":23509924,"title":"Online Judge 是如何解决判题端安全性问题的?","type":"answer"}" name="23509924" itemprop="suggestedAnswer" itemtype="http://schema.org/Answer" itemscope="" data-za-detail-view-path-module="AnswerItem" data-za-detail-view-path-index="5" data-za-extra-module="{"card":{"has_image":false,"has_video":false,"content":{"type":"Answer","token":"23509924","upvote_num":19,"comment_num":6,"publish_timestamp":null,"parent_token":"23067497","author_member_hash_id":"e06466186ede5b598d3cef8bc5013283"}}}"><div class="ContentItem-meta"><div class="AuthorInfo AnswerItem-authorInfo AnswerItem-authorInfo--related" itemprop="author" itemscope="" itemtype="http://schema.org/Person"><div class="AuthorInfo"><meta itemprop="name" content="时国怀"><meta itemprop="image" content="https://pic1.zhimg.com/a277ac6ae_l.jpg?source=1940ef5c"><meta itemprop="url" content="https://www.zhihu.com/people/shi-guo-huai"><meta itemprop="zhihu:followerCount" content="10007"><span class="UserLink AuthorInfo-avatarWrapper"><div class="Popover"><div id="Popover23-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover23-content"><a target="_blank" class="UserLink-link" data-za-detail-view-element_name="User" href="https://www.zhihu.com/people/shi-guo-huai"><img class="Avatar AuthorInfo-avatar" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/a277ac6ae_xs.jpg" srcset="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/a277ac6ae_l.jpg 2x" alt="时国怀" width="38" height="38"></a></div></div></span><div class="AuthorInfo-content"><div class="AuthorInfo-head"><span class="UserLink AuthorInfo-name"><div class="Popover"><div id="Popover24-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover24-content"><a target="_blank" class="UserLink-link" data-za-detail-view-element_name="User" href="https://www.zhihu.com/people/shi-guo-huai">时国怀</a></div></div></span></div><div class="AuthorInfo-detail"><div class="AuthorInfo-badge"><div class="ztext AuthorInfo-badgeText">账号不再使用了,所有回答都可以随意转载,无需授权</div></div></div></div></div></div><div class="LabelContainer-wrapper"></div><div class="css-h5al4j"><span><span class="Voters"><button type="button" class="Button Button--plain">19 人赞同了该回答</button></span></span></div></div><meta itemprop="image"><meta itemprop="upvoteCount" content="19"><meta itemprop="url" content="https://www.zhihu.com/question/23067497/answer/23509924"><meta itemprop="dateCreated" content="2014-03-17T05:40:52.000Z"><meta itemprop="dateModified" content="2014-03-17T05:43:02.000Z"><meta itemprop="commentCount" content="6"><div class="RichContent RichContent--unescapable"><div class="RichContent-inner"><span class="RichText ztext CopyrightRichText-richText" itemprop="text"><p>曾经在我们学校里做过online judge,用的好像是POJ当时的一个demo,在Windows上弄的。</p><p>当时做法也没考虑太多,先是建立一个guest账户,用guest账户运行代码,所有权限全限制在某一个盘里,大不了就废了一个盘,也无所谓。</p><p>反对匿名用户说的不危险,实际上OJ这种东西太危险了,允许上传+执行权限,危险特别大。</p><p>把网页部分和代码分开,我忘记当时我们是用一个账户还是两个账户,反正网页的路径是一个很古怪的路径,这样入侵者也不太好在页面上挂马,我记得页面好像是PHP或者JSP之类的。</p><p>在编译器和连接器上做了点手脚,一共有几层防御:</p><p>第一层是把标准库里的头文件先都注释掉,包括文件操作、还有system、网络操作等等,对于一般的菜鸟就足够了,大多数菜鸟没了头文件都不知道该怎么办。</p><p>第二层是彻底干掉C++,我记得当时我们用的是MinGW,直接不安装G++组件,因为G++的库太复杂了,像cin/cout这些不好控制</p><p>第三层是修改链接库,当时在大学时候技术也很一般,我记得方法很糙,就是找到lib文件,用winhex之类的工具打开,找到fopen这些直接把所有敏感的字符串全换掉。实际上允许用的就string库和stdlib这些,这样连接器也找不到符号。</p><p>这样下来入侵者要是想通过标准库的话基本就很困难了。</p><p>在上传页面上也要做限制,比如,禁用汇编内联,直接通过过滤字符串asm实现,必要的时候做一个WindowsAPI的过滤表,在上传代码的时候就过滤掉所有WindowsAPI,但这个很困难,因为代码里可以不用字符串。</p><p>这样折腾下来,基本上把主要的入口都封死了。然后关键的一步:服务器网卡上关掉所有的端口,仅限于某几个端口开放(80/8080之类的)。</p><p>但是现在想想,并不是特别的安全,比如上传代码如果自己实现一套LoadLibrary然后直接调用WindowsAPI的话,还是可以入侵的。</p><p>至于说限制运行时间的,这个太困难了,1秒钟够执行很多指令了,没意义。</p><p>更稳妥的方法是限制注册,但这已经不是技术范畴了。</p>我能记得的就这些了。</span></div><div><div class="ContentItem-time"><a target="_blank" href="https://www.zhihu.com/question/23067497/answer/23509924"><span data-tooltip="发布于 2014-03-17 13:40">编辑于 2014-03-17</span></a></div></div><div class="ContentItem-actions RichContent-actions"><span><button aria-label="赞同 19 " type="button" class="Button VoteButton VoteButton--up"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--TriangleUp VoteButton-TriangleUp" fill="currentColor" viewBox="0 0 24 24" width="10" height="10"><path d="M2 18.242c0-.326.088-.532.237-.896l7.98-13.203C10.572 3.57 11.086 3 12 3c.915 0 1.429.571 1.784 1.143l7.98 13.203c.15.364.236.57.236.896 0 1.386-.875 1.9-1.955 1.9H3.955c-1.08 0-1.955-.517-1.955-1.9z" fill-rule="evenodd"></path></svg></span>赞同 19</button><button aria-label="反对" type="button" class="Button VoteButton VoteButton--down"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--TriangleDown" fill="currentColor" viewBox="0 0 24 24" width="10" height="10"><path d="M20.044 3H3.956C2.876 3 2 3.517 2 4.9c0 .326.087.533.236.896L10.216 19c.355.571.87 1.143 1.784 1.143s1.429-.572 1.784-1.143l7.98-13.204c.149-.363.236-.57.236-.896 0-1.386-.876-1.9-1.956-1.9z" fill-rule="evenodd"></path></svg></span></button></span><button type="button" class="Button ContentItem-action Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Comment Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M10.241 19.313a.97.97 0 0 0-.77.2 7.908 7.908 0 0 1-3.772 1.482.409.409 0 0 1-.38-.637 5.825 5.825 0 0 0 1.11-2.237.605.605 0 0 0-.227-.59A7.935 7.935 0 0 1 3 11.25C3 6.7 7.03 3 12 3s9 3.7 9 8.25-4.373 9.108-10.759 8.063z" fill-rule="evenodd"></path></svg></span>6 条评论</button><div class="Popover ShareMenu ContentItem-action"><div class="ShareMenu-toggler" id="Popover15-toggle" aria-haspopup="true" aria-expanded="false" aria-owns="Popover15-content"><button type="button" class="Button Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Share Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M2.931 7.89c-1.067.24-1.275 1.669-.318 2.207l5.277 2.908 8.168-4.776c.25-.127.477.198.273.39L9.05 14.66l.927 5.953c.18 1.084 1.593 1.376 2.182.456l9.644-15.242c.584-.892-.212-2.029-1.234-1.796L2.93 7.89z" fill-rule="evenodd"></path></svg></span>分享</button></div></div><button type="button" class="Button ContentItem-action Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Star Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M5.515 19.64l.918-5.355-3.89-3.792c-.926-.902-.639-1.784.64-1.97L8.56 7.74l2.404-4.871c.572-1.16 1.5-1.16 2.072 0L15.44 7.74l5.377.782c1.28.186 1.566 1.068.64 1.97l-3.89 3.793.918 5.354c.219 1.274-.532 1.82-1.676 1.218L12 18.33l-4.808 2.528c-1.145.602-1.896.056-1.677-1.218z" fill-rule="evenodd"></path></svg></span>收藏</button><button type="button" class="Button ContentItem-action Button--plain Button--withIcon Button--withLabel"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Heart Button-zi" fill="currentColor" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path d="M2 8.437C2 5.505 4.294 3.094 7.207 3 9.243 3 11.092 4.19 12 6c.823-1.758 2.649-3 4.651-3C19.545 3 22 5.507 22 8.432 22 16.24 13.842 21 12 21 10.158 21 2 16.24 2 8.437z" fill-rule="evenodd"></path></svg></span>喜欢</button><button data-zop-retract-question="true" type="button" class="Button ContentItem-action ContentItem-rightButton Button--plain"><span class="RichContent-collapsedText">收起</span><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--ArrowDown ContentItem-arrowIcon is-active" fill="currentColor" viewBox="0 0 24 24" width="24" height="24"><path d="M12 13L8.285 9.218a.758.758 0 0 0-1.064 0 .738.738 0 0 0 0 1.052l4.249 4.512a.758.758 0 0 0 1.064 0l4.246-4.512a.738.738 0 0 0 0-1.052.757.757 0 0 0-1.063 0L12.002 13z" fill-rule="evenodd"></path></svg></span></button></div></div><div class="ModalWrap"><div><div class=""></div><div class="ModalExp-content"><div class="ModalWrap-content"><div class="ModalWrap-title">继续浏览内容</div><div class="ModalWrap-item"><div class="ModalWrap-itemImg"><img src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-88158afcff1e7f4b8b00a1ba81171b61_720w.png"></div><div class="ModalWrap-itemContent"><div class="ModalWrap-itemTitle">知乎</div><div class="ModalWrap-itemDesc">发现更大的世界</div></div><div class="ModalWrap-itemBtn">打开</div></div><div class="ModalWrap-item"><div class="ModalWrap-itemImg"><img src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-da7d9e4b6a7ddba507299bcf5a4d0600_1440w.png"></div><div class="ModalWrap-itemContent"><div class="ModalWrap-itemTitle">浏览器</div></div><div class="ModalWrap-itemBtn">继续</div></div></div></div></div></div><div><div><div class=""></div><div class="ModalLoading-content"><svg width="30" height="30" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg" class="CircleLoadingBar" aria-hidden="true"><g><circle class="path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></g></svg></div></div></div></div></div><div></div></div></div></div></div></div></div></div></div><div class="Question-sideColumn Question-sideColumn--sticky" data-za-detail-view-path-module="RightSideBar" data-za-extra-module="{}"><div><div class="Sticky"><div class="Card AppBanner"><a class="AppBanner-link" href="http://zhi.hu/BDXoI"><div class="AppBanner-layout"><img class="AppBanner-qrcode" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/sidebar-download-qrcode.png" alt="QR Code of Downloading Zhihu App"><div class="AppBanner-content"><div class="AppBanner-title">下载知乎客户端</div><div class="AppBanner-description">与世界分享知识、经验和见解</div></div></div></a></div><div class="Card"><div class="Pc-card Card"><a class="Banner-link" href="https://aws.amazon.com/cn/campaigns/goglobal/?trk=ba_a134p000007BryxAAC&trkCampaign=go_global&sc_channel=ba&sc_campaign=zhihupc&sc_outcome=Acquisition&sc_geo=CHNA&sc_country=CN&sc_publisher=Others" target="_blank"><div class="Banner-adTag">广告</div><img class="Banner-image" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-b83cf570406a285a0db1d92ef65748d4_540x450.jpeg" alt="广告"></a><div class="Pc-card-button-close " data-tooltip="不再显示" data-tooltip-position="bottom"><svg viewBox="0 0 12 12" class="Icon Icon--close Pc-card-button-close-svg "><path fill-rule="evenodd" d="M3 2L2 3l3 3-3 3 1 1 3-3 3 3 1-1-3-3 3-3-1-1-3 3"></path></svg></div></div></div><div class="Card" data-za-detail-view-path-module="RelatedQuestions" data-za-extra-module="{}"><div class="Card-header SimilarQuestions-title"><div class="Card-headerText">相关问题</div></div><div class="Card-section SimilarQuestions-list"><div class="SimilarQuestions-item" itemprop="zhihu:similarQuestion" itemtype="http://schema.org/Question" itemscope="" data-za-detail-view-path-module="QuestionItem" data-za-extra-module="{"card":{"content":{"type":"Question","token":"328871175"}}}"><meta itemprop="name" content="如何理解这句话:服务器的安全性通常比普通PC高很多,一般无法通过感染、网页挂马等方式植入僵尸程序?"><meta itemprop="url" content="https://www.zhihu.com/question/328871175"><meta itemprop="answerCount" content="7"><meta itemprop="zhihu:followerCount" content="10"><a target="_blank" type="button" class="Button Button--plain" href="https://www.zhihu.com/question/328871175">如何理解这句话:服务器的安全性通常比普通PC高很多,一般无法通过感染、网页挂马等方式植入僵尸程序?</a> 7 个回答</div><div class="SimilarQuestions-item" itemprop="zhihu:similarQuestion" itemtype="http://schema.org/Question" itemscope="" data-za-detail-view-path-module="QuestionItem" data-za-extra-module="{"card":{"content":{"type":"Question","token":"436689557"}}}"><meta itemprop="name" content="三次握手可以保证安全性吗?"><meta itemprop="url" content="https://www.zhihu.com/question/436689557"><meta itemprop="answerCount" content="12"><meta itemprop="zhihu:followerCount" content="28"><a target="_blank" type="button" class="Button Button--plain" href="https://www.zhihu.com/question/436689557">三次握手可以保证安全性吗?</a> 12 个回答</div><div class="SimilarQuestions-item" itemprop="zhihu:similarQuestion" itemtype="http://schema.org/Question" itemscope="" data-za-detail-view-path-module="QuestionItem" data-za-extra-module="{"card":{"content":{"type":"Question","token":"22809840"}}}"><meta itemprop="name" content="Linux 有所谓「天生安全基因」吗,整体安全性设计是否更优秀?"><meta itemprop="url" content="https://www.zhihu.com/question/22809840"><meta itemprop="answerCount" content="21"><meta itemprop="zhihu:followerCount" content="403"><a target="_blank" type="button" class="Button Button--plain" href="https://www.zhihu.com/question/22809840">Linux 有所谓「天生安全基因」吗,整体安全性设计是否更优秀?</a> 21 个回答</div><div class="SimilarQuestions-item" itemprop="zhihu:similarQuestion" itemtype="http://schema.org/Question" itemscope="" data-za-detail-view-path-module="QuestionItem" data-za-extra-module="{"card":{"content":{"type":"Question","token":"23142949"}}}"><meta itemprop="name" content="如何确保放在公网上的管理系统的安全性?"><meta itemprop="url" content="https://www.zhihu.com/question/23142949"><meta itemprop="answerCount" content="5"><meta itemprop="zhihu:followerCount" content="25"><a target="_blank" type="button" class="Button Button--plain" href="https://www.zhihu.com/question/23142949">如何确保放在公网上的管理系统的安全性?</a> 5 个回答</div><div class="SimilarQuestions-item" itemprop="zhihu:similarQuestion" itemtype="http://schema.org/Question" itemscope="" data-za-detail-view-path-module="QuestionItem" data-za-extra-module="{"card":{"content":{"type":"Question","token":"38749469"}}}"><meta itemprop="name" content="我看的是机械设备公司,图纸以及资料的保密性非常重要,信息安全管理软件有没有什么好的推荐?"><meta itemprop="url" content="https://www.zhihu.com/question/38749469"><meta itemprop="answerCount" content="9"><meta itemprop="zhihu:followerCount" content="49"><a target="_blank" type="button" class="Button Button--plain" href="https://www.zhihu.com/question/38749469">我看的是机械设备公司,图纸以及资料的保密性非常重要,信息安全管理软件有没有什么好的推荐?</a> 9 个回答</div></div></div><div class="Card" data-za-detail-view-path-module="ContentList" data-za-detail-view-path-module_name="相关推荐" data-za-extra-module="{}"><div class="Card-header RelatedCommodities-title"><div class="Card-headerText">相关推荐</div></div><div class="Card-section RelatedCommodities-list"><a target="_blank" href="https://www.zhihu.com/pub/book/119631298" type="button" class="Button RelatedCommodities-item Button--plain" data-za-detail-view-path-module="EBookItem" data-za-extra-module="{"card":{"content":{"type":"EBook","token":"119631298"}}}"><img class="RelatedCommodities-image" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-90d3d7283f93d7fc94e6a123199a8c59_250x0.jpg" alt="live"><div class="RelatedCommodities-content"><div class="RelatedCommodities-subject RelatedCommodities-subject-two" data-tooltip="Kali Linux 2 网络渗透测试实践指南">Kali Linux 2 网络渗透测试实践指南</div><div class="RelatedCommodities-meta"><div class="RelatedCommodities-bookMeta">62 人读过<span class="RelatedCommodities-bookRead"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Ebook" width="13" height="14" fill="currentColor" viewBox="0 0 24 24"><path d="M16 17.649V2.931a.921.921 0 0 0-.045-.283.943.943 0 0 0-1.182-.604L4.655 5.235A.932.932 0 0 0 4 6.122v14.947c0 .514.421.931.941.931H19.06c.52 0 .941-.417.941-.93V7.292a.936.936 0 0 0-.941-.931h-.773v12.834a.934.934 0 0 1-.83.924L6.464 21.416c-.02.002 2.94-.958 8.883-2.881a.932.932 0 0 0 .653-.886z" fill-rule="evenodd"></path></svg></span>阅读</span></div></div></div></a><a target="_blank" href="https://www.zhihu.com/pub/book/119585230" type="button" class="Button RelatedCommodities-item Button--plain" data-za-detail-view-path-module="EBookItem" data-za-extra-module="{"card":{"content":{"type":"EBook","token":"119585230"}}}"><img class="RelatedCommodities-image" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-cc4ef8d4b59600369b510e1051f9bcd7_250x0.jpg" alt="live"><div class="RelatedCommodities-content"><div class="RelatedCommodities-subject RelatedCommodities-subject-two" data-tooltip="Kali Linux 无线渗透测试指南(第 3 版)">Kali Linux 无线渗透测试指南(第 3 版)</div><div class="RelatedCommodities-meta"><div class="RelatedCommodities-bookMeta">96 人读过<span class="RelatedCommodities-bookRead"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Ebook" width="13" height="14" fill="currentColor" viewBox="0 0 24 24"><path d="M16 17.649V2.931a.921.921 0 0 0-.045-.283.943.943 0 0 0-1.182-.604L4.655 5.235A.932.932 0 0 0 4 6.122v14.947c0 .514.421.931.941.931H19.06c.52 0 .941-.417.941-.93V7.292a.936.936 0 0 0-.941-.931h-.773v12.834a.934.934 0 0 1-.83.924L6.464 21.416c-.02.002 2.94-.958 8.883-2.881a.932.932 0 0 0 .653-.886z" fill-rule="evenodd"></path></svg></span>阅读</span></div></div></div></a><a target="_blank" href="https://www.zhihu.com/pub/book/119564839" type="button" class="Button RelatedCommodities-item Button--plain" data-za-detail-view-path-module="EBookItem" data-za-extra-module="{"card":{"content":{"type":"EBook","token":"119564839"}}}"><img class="RelatedCommodities-image" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-8ae242146950f8714a9429467e4ea464_250x0.jpg" alt="live"><div class="RelatedCommodities-content"><div class="RelatedCommodities-subject RelatedCommodities-subject-two" data-tooltip="Android 安全攻防权威指南">Android 安全攻防权威指南</div><div class="RelatedCommodities-meta"><div class="RelatedCommodities-bookMeta">75 人读过<span class="RelatedCommodities-bookRead"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--Ebook" width="13" height="14" fill="currentColor" viewBox="0 0 24 24"><path d="M16 17.649V2.931a.921.921 0 0 0-.045-.283.943.943 0 0 0-1.182-.604L4.655 5.235A.932.932 0 0 0 4 6.122v14.947c0 .514.421.931.941.931H19.06c.52 0 .941-.417.941-.93V7.292a.936.936 0 0 0-.941-.931h-.773v12.834a.934.934 0 0 1-.83.924L6.464 21.416c-.02.002 2.94-.958 8.883-2.881a.932.932 0 0 0 .653-.886z" fill-rule="evenodd"></path></svg></span>阅读</span></div></div></div></a></div></div><div class="Card"><div class="Pc-card Card"><a class="Banner-link" href="" target="_blank"><div id="_cc1506aifjr" class="_cc1506aifjr Banner-adsense"><iframe id="iframeu6559262_0" name="iframeu6559262_0" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/mckm.htm" scrolling="no" width="300" height="250" frameborder="0"></iframe></div></a><div class="Pc-card-button-close " data-tooltip="不再显示" data-tooltip-position="bottom"><svg viewBox="0 0 12 12" class="Icon Icon--close Pc-card-button-close-svg "><path fill-rule="evenodd" d="M3 2L2 3l3 3-3 3 1 1 3-3 3 3 1-1-3-3 3-3-1-1-3 3"></path></svg></div></div></div><footer class="Footer"><a class="Footer-item" target="_blank" rel="noopener noreferrer" href="https://liukanshan.zhihu.com/">刘看山</a><span class="Footer-dot"></span><a class="Footer-item" target="_blank" rel="noopener noreferrer" href="https://www.zhihu.com/question/19581624">知乎指南</a><span class="Footer-dot"></span><a class="Footer-item" target="_blank" rel="noopener noreferrer" href="https://www.zhihu.com/term/zhihu-terms">知乎协议</a><span class="Footer-dot"></span><a class="Footer-item" target="_blank" rel="noopener noreferrer" href="https://www.zhihu.com/term/privacy">知乎隐私保护指引</a><br><a class="Footer-item" target="_blank" href="https://www.zhihu.com/app">应用</a><span class="Footer-dot"></span><a class="Footer-item" target="_blank" rel="noopener noreferrer" href="https://app.mokahr.com/apply/zhihu">工作</a><span class="Footer-dot"></span><button type="button" class="Button OrgCreateButton">申请开通知乎机构号</button><br><a class="Footer-item" target="_blank" rel="noopener noreferrer" href="https://zhuanlan.zhihu.com/p/28852607">侵权举报</a><span class="Footer-dot"></span><a class="Footer-item" target="_blank" rel="noopener noreferrer" href="http://www.12377.cn/">网上有害信息举报专区</a><br><a class="Footer-item" target="_blank" rel="noopener noreferrer" href="https://tsm.miit.gov.cn/dxxzsp/">京 ICP 证 110745 号</a><br><a class="Footer-item" target="_blank" rel="noopener noreferrer" href="https://beian.miit.gov.cn/">京 ICP 备 13052560 号 - 1</a><br><a class="Footer-item" target="_blank" rel="noopener noreferrer" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11010802020088"><img src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/v2-d0289dc0a46fc5b15b3363ffa78cf6c7.png">京公网安备 11010802020088 号</a><br><span class="Footer-item">互联网药品信息服务资格证书<br>(京)- 非经营性 - 2017 - 0067</span><span class="Footer-item">违法和不良信息举报:010-82716601</span><br><a class="Footer-item" target="_blank" href="https://www.zhihu.com/term/child-jubao">儿童色情信息举报专区</a><br><a class="Footer-item" target="_blank" href="https://www.zhihu.com/certificates">证照中心</a><span class="Footer-dot"></span><a class="Footer-item" target="_blank" rel="noopener noreferrer" href="https://ir.zhihu.com/">Investor Relations</a><br><a class="Footer-item" target="_blank" href="https://www.zhihu.com/contact">联系我们</a><span> © 2021 知乎</span></footer></div></div></div></div></div></main><div data-zop-usertoken="{}"></div><div class="CornerButtons"><div class="CornerAnimayedFlex CornerAnimayedFlex--hidden"><button data-tooltip="回到顶部" data-tooltip-position="left" data-tooltip-will-hide-on-click="true" aria-label="回到顶部" type="button" class="Button CornerButton Button--plain"><svg class="Zi Zi--BackToTop" aria-label="回到顶部" fill="currentColor" viewBox="0 0 24 24" width="24" height="24"><path d="M16.036 19.59a1 1 0 0 1-.997.995H9.032a.996.996 0 0 1-.997-.996v-7.005H5.03c-1.1 0-1.36-.633-.578-1.416L11.33 4.29a1.003 1.003 0 0 1 1.412 0l6.878 6.88c.782.78.523 1.415-.58 1.415h-3.004v7.005z"></path></svg></button></div></div></div></div><script id="js-clientConfig" type="text/json">{"host":"zhihu.com","protocol":"https:","wwwHost":"www.zhihu.com","videoHost":"video.zhihu.com","fetchRoot":{"www":"https:\u002F\u002Fwww.zhihu.com","api":"https:\u002F\u002Fapi.zhihu.com","lens":"https:\u002F\u002Flens.zhihu.com","zhuanlan":"https:\u002F\u002Fzhuanlan.zhihu.com","walletpay":"https:\u002F\u002Fwalletpay.zhihu.com","captcha":"https:\u002F\u002Fcaptcha.zhihu.com","vzuu":"https:\u002F\u002Fv.vzuu.com"}}</script><script id="js-initialData" type="text/json">{"initialState":{"common":{"ask":{}},"loading":{"global":{"count":0},"local":{"question\u002Fget\u002F":false,"question\u002FgetAnswers\u002F23067497":false}},"club":{"tags":{},"admins":{"data":[]},"members":{"data":[]},"explore":{"candidateSyncClubs":{}},"profile":{},"checkin":{},"comments":{"paging":{},"loading":{},"meta":{},"ids":{}},"postList":{"paging":{},"loading":{},"ids":{}},"recommend":{"data":[]},"silences":{"data":[]},"application":{"profile":null}},"entities":{"users":{},"questions":{"23067497":{"type":"question","id":23067497,"title":"Online Judge 是如何解决判题端安全性问题的?","questionType":"normal","created":1395025595,"updatedTime":1395304297,"url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fquestions\u002F23067497","isMuted":false,"isVisible":true,"isNormal":true,"isEditable":false,"adminClosedComment":false,"hasPublishingDraft":false,"answerCount":21,"visitCount":61921,"commentCount":4,"followerCount":1040,"collapsedAnswerCount":3,"excerpt":"如何过滤恶意提交的危险代码??分析了一下hustoj的实现,貌似只是通过创建一个低磁盘读写权限的linux用户限制磁盘操作,然后用ptrace去过滤系统调用,但是代码写的非常混乱(目测是故意的),几乎没有啥借鉴的价值了— —。。。但是网络操作啥的貌似都没做限制…大家有没有啥好的建议?","commentPermission":"all","detail":"如何过滤恶意提交的危险代码??分析了一下hustoj的实现,貌似只是通过创建一个低磁盘读写权限的linux用户限制磁盘操作,然后用ptrace去过滤系统调用,但是代码写的非常混乱(目测是故意的),几乎没有啥借鉴的价值了— —。。。但是网络操作啥的貌似都没做限制……大家有没有啥好的建议?","editableDetail":"如何过滤恶意提交的危险代码??分析了一下hustoj的实现,貌似只是通过创建一个低磁盘读写权限的linux用户限制磁盘操作,然后用ptrace去过滤系统调用,但是代码写的非常混乱(目测是故意的),几乎没有啥借鉴的价值了— —。。。但是网络操作啥的貌似都没做限制……大家有没有啥好的建议?","status":{"isLocked":false,"isClose":false,"isEvaluate":false,"isSuggest":false},"relationship":{"isAuthor":false,"isFollowing":false,"isAnonymous":false,"canLock":false,"canStickAnswers":false,"canCollapseAnswers":false,"voting":0},"topics":[{"id":"19554300","type":"topic","url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Ftopics\u002F19554300","name":"Linux","avatarUrl":"https:\u002F\u002Fpic4.zhimg.com\u002F50\u002Fv2-4d682e48d948fcdf430d23d376934b8d_720w.jpg?source=54b3c3a5","topicType":"CHANNEL"},{"id":"19554927","type":"topic","url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Ftopics\u002F19554927","name":"网络安全","avatarUrl":"https:\u002F\u002Fpic1.zhimg.com\u002F50\u002Fv2-3a6fbe1eac1aa42fd3bf95573efe250e_720w.jpg?source=54b3c3a5","topicType":"CHANNEL"},{"id":"19561983","type":"topic","url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Ftopics\u002F19561983","name":"信息安全","avatarUrl":"https:\u002F\u002Fpic4.zhimg.com\u002F50\u002Fv2-84024cf1e40452c9134863852ccc68d5_720w.jpg?source=54b3c3a5","topicType":"NORMAL"},{"id":"19600988","type":"topic","url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Ftopics\u002F19600988","name":"Online Judge","avatarUrl":"https:\u002F\u002Fpic1.zhimg.com\u002Fe82bab09c_l.jpg?source=1940ef5c","topicType":"NORMAL"}],"author":{"id":"adb8e1c02bfe4549863b30f81cad0e75","urlToken":"friskit","name":"石博天","avatarUrl":"https:\u002F\u002Fpic1.zhimg.com\u002Fv2-7d3fe59a8bdb276a488b4805f08b965f_l.jpg?source=1940ef5c","avatarUrlTemplate":"https:\u002F\u002Fpic4.zhimg.com\u002Fv2-7d3fe59a8bdb276a488b4805f08b965f.jpg?source=1940ef5c","isOrg":false,"type":"people","url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fpeople\u002Fadb8e1c02bfe4549863b30f81cad0e75","userType":"people","headline":"","badge":[],"badgeV2":{"title":"","mergedBadges":[],"detailBadges":[],"icon":"","nightIcon":""},"gender":1,"isAdvertiser":false,"isPrivacy":false},"canComment":{"status":true,"reason":""},"thumbnailInfo":{"count":0,"type":"thumbnail_info","thumbnails":[]},"reviewInfo":{"type":"","tips":"","editTips":"","isReviewing":false,"editIsReviewing":false},"relatedCards":[],"muteInfo":{"type":""},"showAuthor":false,"isLabeled":false,"isBannered":false,"showEncourageAuthor":false,"voteupCount":5,"canVote":true,"visibleOnlyToAuthor":false}},"answers":{"23509924":{"id":23509924,"type":"answer","answerType":"normal","question":{"type":"question","id":23067497,"title":"Online Judge 是如何解决判题端安全性问题的?","questionType":"normal","created":1395025595,"updatedTime":1395304297,"url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fquestions\u002F23067497","relationship":{}},"author":{"id":"e06466186ede5b598d3cef8bc5013283","urlToken":"shi-guo-huai","name":"时国怀","avatarUrl":"https:\u002F\u002Fpic1.zhimg.com\u002Fa277ac6ae_l.jpg?source=1940ef5c","avatarUrlTemplate":"https:\u002F\u002Fpic3.zhimg.com\u002Fa277ac6ae.jpg?source=1940ef5c","isOrg":false,"type":"people","url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fpeople\u002Fe06466186ede5b598d3cef8bc5013283","userType":"people","headline":"账号不再使用了,所有回答都可以随意转载,无需授权","badge":[],"badgeV2":{"title":"","mergedBadges":[],"detailBadges":[],"icon":"","nightIcon":""},"gender":1,"isAdvertiser":false,"followerCount":10007,"isFollowed":false,"isPrivacy":false,"vipInfo":{"isVip":false}},"url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fanswers\u002F23509924","isCollapsed":false,"createdTime":1395034852,"updatedTime":1395034982,"extras":"","isCopyable":true,"isNormal":true,"voteupCount":19,"commentCount":6,"isSticky":false,"adminClosedComment":false,"commentPermission":"all","canComment":{"reason":"","status":true},"reshipmentSettings":"allowed","content":"曾经在我们学校里做过online judge,用的好像是POJ当时的一个demo,在Windows上弄的。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E当时做法也没考虑太多,先是建立一个guest账户,用guest账户运行代码,所有权限全限制在某一个盘里,大不了就废了一个盘,也无所谓。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E反对匿名用户说的不危险,实际上OJ这种东西太危险了,允许上传+执行权限,危险特别大。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E把网页部分和代码分开,我忘记当时我们是用一个账户还是两个账户,反正网页的路径是一个很古怪的路径,这样入侵者也不太好在页面上挂马,我记得页面好像是PHP或者JSP之类的。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E在编译器和连接器上做了点手脚,一共有几层防御:\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E第一层是把标准库里的头文件先都注释掉,包括文件操作、还有system、网络操作等等,对于一般的菜鸟就足够了,大多数菜鸟没了头文件都不知道该怎么办。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E第二层是彻底干掉C++,我记得当时我们用的是MinGW,直接不安装G++组件,因为G++的库太复杂了,像cin\u002Fcout这些不好控制\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E第三层是修改链接库,当时在大学时候技术也很一般,我记得方法很糙,就是找到lib文件,用winhex之类的工具打开,找到fopen这些直接把所有敏感的字符串全换掉。实际上允许用的就string库和stdlib这些,这样连接器也找不到符号。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E这样下来入侵者要是想通过标准库的话基本就很困难了。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E在上传页面上也要做限制,比如,禁用汇编内联,直接通过过滤字符串asm实现,必要的时候做一个WindowsAPI的过滤表,在上传代码的时候就过滤掉所有WindowsAPI,但这个很困难,因为代码里可以不用字符串。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E这样折腾下来,基本上把主要的入口都封死了。然后关键的一步:服务器网卡上关掉所有的端口,仅限于某几个端口开放(80\u002F8080之类的)。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E但是现在想想,并不是特别的安全,比如上传代码如果自己实现一套LoadLibrary然后直接调用WindowsAPI的话,还是可以入侵的。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E至于说限制运行时间的,这个太困难了,1秒钟够执行很多指令了,没意义。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E更稳妥的方法是限制注册,但这已经不是技术范畴了。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E我能记得的就这些了。","editableContent":"","excerpt":"曾经在我们学校里做过online judge,用的好像是POJ当时的一个demo,在Windows上弄的。 当时做法也没考虑太多,先是建立一个guest账户,用guest账户运行代码,所有权限全限制在某一个盘里,大不了就废了一个盘,也无所谓。 反对匿名用户说的不危险,实际上OJ这种东西太危险了,允许上传+执行权限,危险特别大。 把网页部分和代码分开,我忘记当时我们是用一个账户还是两个账户,反正网页的路径是一个很古怪的路径,这样入侵者也不…","collapsedBy":"nobody","collapseReason":"","annotationAction":null,"markInfos":[],"relevantInfo":{"isRelevant":false,"relevantType":"","relevantText":""},"suggestEdit":{"reason":"","status":false,"tip":"","title":"","unnormalDetails":{"status":"","description":"","reason":"","reasonId":0,"note":""},"url":""},"isLabeled":false,"contentMark":null,"rewardInfo":{"canOpenReward":false,"isRewardable":false,"rewardMemberCount":0,"rewardTotalMoney":0,"tagline":""},"relationship":{"isAuthor":false,"isAuthorized":false,"isNothelp":false,"isThanked":false,"isRecognized":false,"voting":0,"upvotedFollowees":[]},"adAnswer":null},"23538675":{"id":23538675,"type":"answer","answerType":"normal","question":{"type":"question","id":23067497,"title":"Online Judge 是如何解决判题端安全性问题的?","questionType":"normal","created":1395025595,"updatedTime":1395304297,"url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fquestions\u002F23067497","relationship":{}},"author":{"id":"5627c888358180619f67a91d39ad8e54","urlToken":"hexcles","name":"马宏菩","avatarUrl":"https:\u002F\u002Fpic2.zhimg.com\u002Fa10724048_l.jpg?source=1940ef5c","avatarUrlTemplate":"https:\u002F\u002Fpic4.zhimg.com\u002Fa10724048.jpg?source=1940ef5c","isOrg":false,"type":"people","url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fpeople\u002F5627c888358180619f67a91d39ad8e54","userType":"people","headline":"No longer active","badge":[{"type":"best_answerer","description":"优秀答主","topics":[{"id":"19554300","type":"topic","url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Ftopics\u002F19554300","name":"Linux","avatarUrl":"https:\u002F\u002Fpic4.zhimg.com\u002F50\u002Fv2-4d682e48d948fcdf430d23d376934b8d_720w.jpg?source=54b3c3a5","topicType":"CHANNEL"}]}],"badgeV2":{"title":"Linux话题下的优秀答主","mergedBadges":[{"type":"best","detailType":"best","title":"优秀答主","description":"Linux话题下的优秀答主","url":"https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F20054793","sources":[{"id":"19554300","token":"19554300","type":"topic","url":"https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F19554300","name":"Linux","avatarPath":"v2-4d682e48d948fcdf430d23d376934b8d","avatarUrl":"https:\u002F\u002Fpic2.zhimg.com\u002Fv2-4d682e48d948fcdf430d23d376934b8d_hd.jpg","description":"","priority":0}],"icon":"","nightIcon":""}],"detailBadges":[{"type":"best","detailType":"best_answerer","title":"优秀答主","description":"Linux话题下的优秀答主","url":"https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F20054793","sources":[{"id":"19554300","token":"19554300","type":"topic","url":"https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F19554300","name":"Linux","avatarPath":"v2-4d682e48d948fcdf430d23d376934b8d","avatarUrl":"https:\u002F\u002Fpic2.zhimg.com\u002Fv2-4d682e48d948fcdf430d23d376934b8d_hd.jpg","description":"","priority":0}],"icon":"https:\u002F\u002Fpic3.zhimg.com\u002Fv2-bf0eec3c31c8e866c468f60eb296696c_l.png","nightIcon":"https:\u002F\u002Fpic4.zhimg.com\u002Fv2-c724649168d8f9d36d7c3d13140a2594_l.png"}],"icon":"https:\u002F\u002Fpic2.zhimg.com\u002Fv2-bf0eec3c31c8e866c468f60eb296696c_l.png","nightIcon":"https:\u002F\u002Fpic2.zhimg.com\u002Fv2-c724649168d8f9d36d7c3d13140a2594_l.png"},"gender":1,"isAdvertiser":false,"followerCount":7825,"isFollowed":false,"isPrivacy":false,"vipInfo":{"isVip":false}},"url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fanswers\u002F23538675","isCollapsed":false,"createdTime":1395113074,"updatedTime":1395113074,"extras":"","isCopyable":true,"isNormal":true,"voteupCount":365,"commentCount":32,"isSticky":false,"adminClosedComment":false,"commentPermission":"all","canComment":{"reason":"","status":true},"reshipmentSettings":"allowed","content":"其实这就是在做一个沙盒,而一个可靠的沙盒不是那么简单的。我简单说一些高中时写 OJ 获得的经验,抛砖引玉。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E几个错误做法:\u003Cbr\u002F\u003E\u003Col\u003E\u003Cli\u003E所有的字符串过滤都是耍流氓,坑人坑自己:C语言强大的宏几乎没有绕不过的字符串过滤,而且误伤也是很常见的(我就见过小白 OIer 问为什么程序老是被判非法,结果一看里头有个变量叫做 fork )。\u003C\u002Fli\u003E\u003Cli\u003E手工审计头文件,去掉某些头文件或者注释掉一些部分是辛苦且无用的:做了这样的工作之后,你就几乎再也不会想去升级编译器及头文件了,更可怕的是——这个工作需要你对语言、编译器、连接器有一定程度的了解,而我认为拥有足够了解的人都应该知道这是不靠谱的:就算没有头文件、没有了函数原型,调用系统调用的方法还是有一大把而且都不是很麻烦。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cbr\u002F\u003E\u003Cp\u003E准备工作:\u003C\u002Fp\u003E\u003Col\u003E\u003Cli\u003E熟悉你的目标系统(Windows or Linux):\u003C\u002Fli\u003E\u003Col\u003E\u003Cli\u003E必须要了解这个平台下的原生系统调用 API 是怎么使用的(不然你要怎么屏蔽?),最好可以了解到汇编层面。\u003C\u002Fli\u003E\u003Cli\u003E必须要了解这个平台下的用户系统、权限控制、资源限制。\u003C\u002Fli\u003E\u003Cli\u003E最好要了解一下进程跟踪\u002F调试\u002F监控工具或者系统调用,例如 Linux 下的 ptrace 。\u003C\u002Fli\u003E\u003Cli\u003E最好要了解目标系统提供的各种沙盒限制功能。\u003Cbr\u002F\u003E\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cli\u003E了解你的编程语言及工具链:\u003C\u002Fli\u003E\u003Col\u003E\u003Cli\u003E必须要了解你的目标语言的特性,及其在一般的 OI \u002F ACM 比赛中的规定、限制。\u003C\u002Fli\u003E\u003Cli\u003E必须要了解你的工具链的功能及各种参数。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cli\u003E拥有足够的编程功底,对于这样小的程序,应当严格杜绝缓冲区溢出之类的 bug 。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cbr\u002F\u003E\u003Cp\u003E然后我再说说我的做法,在其中大家就可以看到上面列的这些“准备知识”是如何派上用场的。我的目标平台是 Linux ,目标语言是 Pascal 、 C 、 C++ 。\u003C\u002Fp\u003E\u003Cbr\u002F\u003E\u003Cp\u003E我采取了以下措施:\u003C\u002Fp\u003E\u003Col\u003E\u003Cli\u003E操作系统层面:\u003C\u002Fli\u003E\u003Col\u003E\u003Cli\u003E时间、资源的限制:\u003C\u002Fli\u003E\u003Col\u003E\u003Cli\u003E内存:我使用了 rlimit 进行控制,同时也方便在运行结束后获得内存使用情况的数据,不过有一个“缺点”就是如果是声明了一个超大的空间但从未访问使用就不会被统计进来(经过观察发现很多 ACM 或者 OI 比赛也都是这么处理的,所以应该不算是一个问题)。\u003C\u002Fli\u003E\u003Cli\u003E时间:首先同样也是使用 rlimit 进行 CPU 时间控制。注意它只能控制 CPU 时间,不能控制实际运行时间,所以像是 sleep 或者 IO 阻塞之类的情况是没有办法的,所以还在额外添加了一个 alarm 来进行实际时间的限制。按照大部分比赛的管理,最终统计的时间是 CPU 时间。\u003C\u002Fli\u003E\u003Cli\u003E文件句柄:同样可以通过 rlimit 来实现,以保证程序不要打开太多文件。不过其实文件这一块问题是比较多的,如果可行的话最好还是使用 stdio 然后管道重定向,完全禁止程序的文件 IO 操作。\u003Cbr\u002F\u003E\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cli\u003E访问控制:\u003C\u002Fli\u003E\u003Col\u003E\u003Cli\u003E通过 chroot 建立一个 jail ,将程序限制在指定目录中运行。由于是比赛程序,使用的动态链接库很有限,所以直接静态编译,从而使得运行目录中连 .so 都不需要。\u003C\u002Fli\u003E\u003Cli\u003E进行必要的权限控制,例如将输入文件和程序文件本身设置为程序的运行用户只读不可写。\u003Cbr\u002F\u003E\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cli\u003E权限控制:\u003C\u002Fli\u003E\u003Col\u003E\u003Cli\u003E监控程序使用 root 权限运行, 完成必要准备后 fork 并切换为受限用户(比如 nobody )来运行程序。\u003Cbr\u002F\u003E\u003C\u002Fli\u003E\u003Cli\u003Erlimit 设置的都是 hard limit ,非 root 无法修改。\u003C\u002Fli\u003E\u003Cli\u003E正确设置运行用户之后,之前由 root 创造的 jail 受限用户是无法逃出的。\u003Cbr\u002F\u003E\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cli\u003E系统调用控制:\u003Cbr\u002F\u003E上面这些(尤其是第一步)是有很大问题,就算不是 root ,也还能做到很多事情。且不说 fork 之类的,光是那个 alarm ,就可以很轻松的把计时器取消了或者干脆主动接收这个信号。所以最根本的还是需要使用 ptrace 之类的调试器附着上程序,监控所有的系统调用,进行白名单 + 计数器(比如 exec 和 open )过滤。这一步其实是最麻烦的(不同平台的系统调用号不一样,我们使用的是 strace 项目里头整理的调用号)。\u003C\u002Fli\u003E\u003Cli\u003E更进一步:\u003Cbr\u002F\u003E如果你对操作系统更熟悉,那么还有一些更有趣的事情可以做。比如 Linux 下的 seccomp 功能(\u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSeccomp\" class=\" wrap external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003Eseccomp - Wikipedia\u003C\u002Fa\u003E , Chrome Linux 版就在沙盒中使用了这个技术 ),尤其是后期加入了 seccomp-bpf 之后变得更加易用。还比如 SELinux 也可以作为 defend-by-depth 的一环。另外, cgroup 其实也可以用得上。\u003Cbr\u002F\u003E\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cli\u003E编译层面:\u003C\u002Fli\u003E\u003Col\u003E\u003Cli\u003E很多编译工具都提供了强大的参数控制,允许你进行包括禁用内嵌 ASM 、限制连接路径之类的一些操作。通读一遍 manpage 肯定会有帮助的。\u003C\u002Fli\u003E\u003Cli\u003E算法竞赛的程序推荐静态编译,之后控制起来少了动态链接库会方便许多。\u003C\u002Fli\u003E\u003Cli\u003E小心编译期间的一些“高级功能”,比如 C 的 include 其实是有很多巧妙的用法,试试看在 Linux 下 #include "\u002Fdev\u002Frandom" 或者 #include "\u002Fdev\u002Ftty" 之类的(这两个东西会把网络上不少二流 OJ 直接卡死……)。\u003C\u002Fli\u003E\u003Cli\u003E不要使用 root 用户编译,越复杂的程序越容易有 bug ,万一哪天出个编译器的 0day ……\u003C\u002Fli\u003E\u003Cli\u003E考虑给编译过程同样进行时间、资源限制以作为额外防护手段。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cli\u003E架构层面:\u003C\u002Fli\u003E\u003Col\u003E\u003Cli\u003E运行在虚拟机\u002F容器中\u003C\u002Fli\u003E\u003Cli\u003E快照\u003C\u002Fli\u003E\u003Cli\u003E心跳检测\u003Cbr\u002F\u003E\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003C\u002Fol\u003E\u003Cp\u003E……\u003C\u002Fp\u003E\u003Cbr\u002F\u003E\u003Cp\u003E你会发现,其实主要的限制都是在操作系统层面完成的。我认为,这样做才能带来更高的安全性,因为引发、启动危险操作的方法有很多,很难一一杜绝(包括源码分析、编译时限制等),但最后要让这些危险操作起效几乎都需要落回系统调用上,所以直接从这里下手也许会是个更好的办法。\u003C\u002Fp\u003E\u003Cbr\u002F\u003E\u003Cp\u003E我对于 Windows 不了解,不知道 Windows 下该如何实现以上的类似功能,或者是否情况完全不同,欢迎大家补充。\u003C\u002Fp\u003E\u003Cbr\u002F\u003E\u003Cp\u003E最后是我之前写的沙盒项目,写得很丑,尤其是 ptrace 一块目前还比较坑(64位系统下好像还无法正常工作),总的来讲还只能算是一个 demo 而已:\u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=https%3A\u002F\u002Fgithub.com\u002FHexcles\u002FEevee\" class=\" wrap external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003EHexcles\u002FEevee · GitHub\u003C\u002Fa\u003E\u003C\u002Fp\u003E","editableContent":"","excerpt":"其实这就是在做一个沙盒,而一个可靠的沙盒不是那么简单的。我简单说一些高中时写 OJ 获得的经验,抛砖引玉。 几个错误做法: 所有的字符串过滤都是耍流氓,坑人坑自己:C语言强大的宏几乎没有绕不过的字符串过滤,而且误伤也是很常见的(我就见过小白 OIer 问为什么程序老是被判非法,结果一看里头有个变量叫做 fork )。手工审计头文件,去掉某些头文件或者注释掉一些部分是辛苦且无用的:做了这样的工作之后,你就几乎再也不…","collapsedBy":"nobody","collapseReason":"","annotationAction":null,"markInfos":[],"relevantInfo":{"isRelevant":false,"relevantType":"","relevantText":""},"suggestEdit":{"reason":"","status":false,"tip":"","title":"","unnormalDetails":{"status":"","description":"","reason":"","reasonId":0,"note":""},"url":""},"isLabeled":false,"contentMark":null,"rewardInfo":{"canOpenReward":false,"isRewardable":false,"rewardMemberCount":0,"rewardTotalMoney":0,"tagline":""},"relationship":{"isAuthor":false,"isAuthorized":false,"isNothelp":false,"isThanked":false,"isRecognized":false,"voting":0,"upvotedFollowees":[]},"adAnswer":null},"40878704":{"id":40878704,"type":"answer","answerType":"normal","question":{"type":"question","id":23067497,"title":"Online Judge 是如何解决判题端安全性问题的?","questionType":"normal","created":1395025595,"updatedTime":1395304297,"url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fquestions\u002F23067497","relationship":{}},"author":{"id":"7bf7ca5658d8d6f979efc6de351a7e1f","urlToken":"alexzhang2015","name":"alex zhang","avatarUrl":"https:\u002F\u002Fpic4.zhimg.com\u002F2b4336ec5_l.jpg?source=1940ef5c","avatarUrlTemplate":"https:\u002F\u002Fpic1.zhimg.com\u002F2b4336ec5.jpg?source=1940ef5c","isOrg":false,"type":"people","url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fpeople\u002F7bf7ca5658d8d6f979efc6de351a7e1f","userType":"people","headline":"互联网研发","badge":[],"badgeV2":{"title":"","mergedBadges":[],"detailBadges":[],"icon":"","nightIcon":""},"gender":1,"isAdvertiser":false,"followerCount":1026,"isFollowed":false,"isPrivacy":false,"vipInfo":{"isVip":false}},"url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fanswers\u002F40878704","isCollapsed":false,"createdTime":1425220369,"updatedTime":1425729436,"extras":"","isCopyable":true,"isNormal":true,"voteupCount":22,"commentCount":5,"isSticky":false,"adminClosedComment":false,"commentPermission":"all","canComment":{"reason":"","status":true},"reshipmentSettings":"allowed","content":"之前写过一个这样的系统,09年的时候,那时候也是同样遇到这些问题,思路类似,构建一个sandbox,filter syscall。 \u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Falex_zhang.intscan.org\" class=\" wrap external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003EOnline Compiler!\u003C\u002Fa\u003E\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E\u003Cb\u003E\u003Ci\u003E\u003Cu\u003E1. Then Google Native Client\u003C\u002Fu\u003E\u003C\u002Fi\u003E\u003C\u002Fb\u003E\u003Cbr\u002F\u003E后来遇见了chrome,在看其native client的实现,其实就是OJ后台的一套sandbox系统。\u003Cbr\u002F\u003E核心部分,构建的2套sandbox\u003Cbr\u002F\u003E\u003Cp\u003E• inner sandbox: binary validation\u003Cbr\u002F\u003E• outer sandbox: OS system-call interception \u003C\u002Fp\u003E\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E--> inner sandbox\u003Cbr\u002F\u003EProtection Rule For Inner Sandbox\u003Cbr\u002F\u003E\u003Cfigure\u003E\u003Cnoscript\u003E\u003Cimg src=\"https:\u002F\u002Fpic4.zhimg.com\u002F50\u002Fe3b1c24280d6babb4d1259ef5c1cf2ce_hd.jpg?source=1940ef5c\" data-rawwidth=\"728\" data-rawheight=\"452\" class=\"origin_image zh-lightbox-thumb\" width=\"728\" data-original=\"https:\u002F\u002Fpic4.zhimg.com\u002Fe3b1c24280d6babb4d1259ef5c1cf2ce_r.jpg?source=1940ef5c\"\u002F\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\"data:image\u002Fsvg+xml;utf8,<svg xmlns='http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg' width='728' height='452'><\u002Fsvg>\" data-rawwidth=\"728\" data-rawheight=\"452\" class=\"origin_image zh-lightbox-thumb lazy\" width=\"728\" data-original=\"https:\u002F\u002Fpic4.zhimg.com\u002Fe3b1c24280d6babb4d1259ef5c1cf2ce_r.jpg?source=1940ef5c\" data-actualsrc=\"https:\u002F\u002Fpic4.zhimg.com\u002F50\u002Fe3b1c24280d6babb4d1259ef5c1cf2ce_hd.jpg?source=1940ef5c\"\u002F\u003E\u003C\u002Ffigure\u003E--> outer sandbox\u003Cbr\u002F\u003EBased on systrace.\u003Cbr\u002F\u003E\u003Cbr\u002F\u003EReference:\u003Cbr\u002F\u003E\u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fstatic.googleusercontent.com\u002Fmedia\u002Fresearch.google.com\u002Fen\u002F\u002Fpubs\u002Farchive\u002F34913.pdf\" class=\" external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003E\u003Cspan class=\"invisible\"\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\"visible\"\u003Estatic.googleusercontent.com\u003C\u002Fspan\u003E\u003Cspan class=\"invisible\"\u003E\u002Fmedia\u002Fresearch.google.com\u002Fen\u002F\u002Fpubs\u002Farchive\u002F34913.pdf\u003C\u002Fspan\u003E\u003Cspan class=\"ellipsis\"\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E\u003Cbr\u002F\u003E\u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fwww.citi.umich.edu\u002Fu\u002Fprovos\u002Fpapers\u002Fsystrace.pdf\" class=\" external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003E\u003Cspan class=\"invisible\"\u003Ehttp:\u002F\u002Fwww.\u003C\u002Fspan\u003E\u003Cspan class=\"visible\"\u003Eciti.umich.edu\u002Fu\u002Fprovos\u003C\u002Fspan\u003E\u003Cspan class=\"invisible\"\u003E\u002Fpapers\u002Fsystrace.pdf\u003C\u002Fspan\u003E\u003Cspan class=\"ellipsis\"\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E\u003Cu\u003E\u003Ci\u003E\u003Cb\u003E2. ZeroVM\u003C\u002Fb\u003E\u003C\u002Fi\u003E\u003C\u002Fu\u003E\u003Cbr\u002F\u003E\u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=https%3A\u002F\u002Fgithub.com\u002Fzerovm\u002Fzerovm\" class=\" wrap external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003Ezerovm\u002Fzerovm · GitHub\u003C\u002Fa\u003E\u003Cbr\u002F\u003E\u003Cbr\u002F\u003EAPP Sandbo领域新出生的创业公司,核心思路如下\u003Cbr\u002F\u003E\u003Cblockquote\u003EZeroVM creates a sandbox around a single process,\u003Cbr\u002F\u003E using technology based on \u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FGoogle_Native_Client\" class=\" wrap external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003EGoogle Native Client\u003C\u002Fa\u003E (NaCl). The sandbox ensures that the application executed cannot access data in the host operating system, so it is safe to execute untrusted code. \u003C\u002Fblockquote\u003E\u003Cfigure\u003E\u003Cnoscript\u003E\u003Cimg src=\"https:\u002F\u002Fpic4.zhimg.com\u002F50\u002F62d7f039a8cce47202ffdd022e02417c_hd.jpg?source=1940ef5c\" data-rawwidth=\"1024\" data-rawheight=\"768\" class=\"origin_image zh-lightbox-thumb\" width=\"1024\" data-original=\"https:\u002F\u002Fpic3.zhimg.com\u002F62d7f039a8cce47202ffdd022e02417c_r.jpg?source=1940ef5c\"\u002F\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\"data:image\u002Fsvg+xml;utf8,<svg xmlns='http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg' width='1024' height='768'><\u002Fsvg>\" data-rawwidth=\"1024\" data-rawheight=\"768\" class=\"origin_image zh-lightbox-thumb lazy\" width=\"1024\" data-original=\"https:\u002F\u002Fpic3.zhimg.com\u002F62d7f039a8cce47202ffdd022e02417c_r.jpg?source=1940ef5c\" data-actualsrc=\"https:\u002F\u002Fpic4.zhimg.com\u002F50\u002F62d7f039a8cce47202ffdd022e02417c_hd.jpg?source=1940ef5c\"\u002F\u003E\u003C\u002Ffigure\u003E\u003Cbr\u002F\u003E所以,如果不想自己造轮子,可以用ZeroVM。过几天,把我那个系统试试移到ZeroVM上~~\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E\u003Cu\u003E\u003Ci\u003E\u003Cb\u003E3. Qubes OS\u003C\u002Fb\u003E\u003C\u002Fi\u003E\u003C\u002Fu\u003E\u003Cbr\u002F\u003E看下architecture 感受下,\u003Cbr\u002F\u003E\u003Cfigure\u003E\u003Cnoscript\u003E\u003Cimg src=\"https:\u002F\u002Fpic1.zhimg.com\u002F50\u002Fdfb41379166fb5703366c4a6163aa8dc_hd.jpg?source=1940ef5c\" data-rawwidth=\"683\" data-rawheight=\"496\" class=\"origin_image zh-lightbox-thumb\" width=\"683\" data-original=\"https:\u002F\u002Fpic4.zhimg.com\u002Fdfb41379166fb5703366c4a6163aa8dc_r.jpg?source=1940ef5c\"\u002F\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\"data:image\u002Fsvg+xml;utf8,<svg xmlns='http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg' width='683' height='496'><\u002Fsvg>\" data-rawwidth=\"683\" data-rawheight=\"496\" class=\"origin_image zh-lightbox-thumb lazy\" width=\"683\" data-original=\"https:\u002F\u002Fpic4.zhimg.com\u002Fdfb41379166fb5703366c4a6163aa8dc_r.jpg?source=1940ef5c\" data-actualsrc=\"https:\u002F\u002Fpic1.zhimg.com\u002F50\u002Fdfb41379166fb5703366c4a6163aa8dc_hd.jpg?source=1940ef5c\"\u002F\u003E\u003C\u002Ffigure\u003E著名的波兰美女黑客Joanna Rutkowska设计的,基于Xen、X和Linux的新开源操作。\u003Cbr\u002F\u003E它充分利用了虚拟化技术(基于安全虚拟机Xen),所有用户应用程序都运行在AppVM(基于Linux的轻量级虚 拟机)中,彼此隔离。\u003Cbr\u002F\u003E也能利用,但是用来跑OJ可能有点大材小用了。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E欢迎讨论~","editableContent":"","excerpt":"之前写过一个这样的系统,09年的时候,那时候也是同样遇到这些问题,思路类似,构建一个sandbox,filter syscall。 Online Compiler! 1. Then Google Native Client 后来遇见了chrome,在看其native client的实现,其实就是OJ后台的一套sandbox系统。 核心部分,构建的2套sandbox • inner sandbox: binary validation • outer sandbox: OS system-call interception --> inner sandbox Protection Rule For Inner Sandbox [图片] …","collapsedBy":"nobody","collapseReason":"","annotationAction":null,"markInfos":[],"relevantInfo":{"isRelevant":false,"relevantType":"","relevantText":""},"suggestEdit":{"reason":"","status":false,"tip":"","title":"","unnormalDetails":{"status":"","description":"","reason":"","reasonId":0,"note":""},"url":""},"isLabeled":false,"contentMark":null,"rewardInfo":{"canOpenReward":false,"isRewardable":false,"rewardMemberCount":0,"rewardTotalMoney":0,"tagline":""},"relationship":{"isAuthor":false,"isAuthorized":false,"isNothelp":false,"isThanked":false,"isRecognized":false,"voting":0,"upvotedFollowees":[]},"adAnswer":null},"77491830":{"id":77491830,"type":"answer","answerType":"normal","question":{"type":"question","id":23067497,"title":"Online Judge 是如何解决判题端安全性问题的?","questionType":"normal","created":1395025595,"updatedTime":1395304297,"url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fquestions\u002F23067497","relationship":{}},"author":{"id":"0","urlToken":"","name":"匿名用户","avatarUrl":"https:\u002F\u002Fpic1.zhimg.com\u002Faadd7b895_l.jpg?source=1940ef5c","avatarUrlTemplate":"https:\u002F\u002Fpic2.zhimg.com\u002Faadd7b895.jpg?source=1940ef5c","isOrg":false,"type":"people","url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fpeople\u002F0","userType":"people","headline":"","badge":[],"badgeV2":{"title":"","mergedBadges":[],"detailBadges":[],"icon":"","nightIcon":""},"gender":1,"isAdvertiser":false,"followerCount":0,"isFollowing":false,"isFollowed":false,"isCelebrity":false,"isBlocking":false,"isBlocked":false,"isPrivacy":false},"url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fanswers\u002F77491830","isCollapsed":false,"createdTime":1450465182,"updatedTime":1450465555,"extras":"","isCopyable":false,"isNormal":true,"voteupCount":3,"commentCount":0,"isSticky":false,"adminClosedComment":false,"commentPermission":"all","canComment":{"reason":"","status":true},"reshipmentSettings":"disallowed","content":"给ZOJ写过Patch的来回答一下。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003EZOJ的沙箱是ptrace。但是ptrace的规则是硬写进去的,规则写的也比较复杂。比如:我记得当时glibc升级之后,由于某些安全功能(貌似是pointer guard?),需要在程序启动的时候读取\u002Fdev\u002Furandom。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E沙箱的内存控制是简单的setrlimit。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003Eptrace倒是并不慢,因为OJ的题目大部分很少频繁的调用system call。如果很频繁,那恐怕那个程序本身就是攻击的恶意程序。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E前面说用语言环境运行时而非动态沙箱的解决方法,我觉得做起来难度比较大。我对JIT Spraying攻击不了解,但是个人感觉语言运行时的JIT是一个很大的attack surface。而且还有,OJ里用Java和C#的比较少,部分原因是IO库比较慢,而且有些OJ问题对性能要求实在是太高了,OJ提交者往往喜欢对一切过程都有控制。\u003Cbr\u002F\u003E\u003Cbr\u002F\u003E如果说其他的选择,我会觉得虚拟化是个很好的选择。唯一的attack surface就是虚拟机和硬件本身","editableContent":"","excerpt":"给ZOJ写过Patch的来回答一下。 ZOJ的沙箱是ptrace。但是ptrace的规则是硬写进去的,规则写的也比较复杂。比如:我记得当时glibc升级之后,由于某些安全功能(貌似是pointer guard?),需要在程序启动的时候读取\u002Fdev\u002Furandom。 沙箱的内存控制是简单的setrlimit。 ptrace倒是并不慢,因为OJ的题目大部分很少频繁的调用system call。如果很频繁,那恐怕那个程序本身就是攻击的恶意程序。 前面说用语言环境运行时而非动态沙箱的解决…","collapsedBy":"nobody","collapseReason":"","annotationAction":null,"markInfos":[],"relevantInfo":{"isRelevant":false,"relevantType":"","relevantText":""},"suggestEdit":{"reason":"","status":false,"tip":"","title":"","unnormalDetails":{"status":"","description":"","reason":"","reasonId":0,"note":""},"url":""},"isLabeled":false,"contentMark":null,"rewardInfo":{"canOpenReward":false,"isRewardable":false,"rewardMemberCount":0,"rewardTotalMoney":0,"tagline":""},"relationship":{"isAuthor":false,"isAuthorized":false,"isNothelp":false,"isThanked":false,"isRecognized":false,"voting":0,"upvotedFollowees":[]},"adAnswer":null},"82308751":{"id":82308751,"type":"answer","answerType":"normal","question":{"type":"question","id":23067497,"title":"Online Judge 是如何解决判题端安全性问题的?","questionType":"normal","created":1395025595,"updatedTime":1395304297,"url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fquestions\u002F23067497","relationship":{}},"author":{"id":"f6f52271761a065e28d7125c335c9775","urlToken":"virusdefender","name":"CeleryL","avatarUrl":"https:\u002F\u002Fpic2.zhimg.com\u002Fv2-8c3b7860ec5a7ac8b7cfff779f69d6e7_l.jpg?source=1940ef5c","avatarUrlTemplate":"https:\u002F\u002Fpic1.zhimg.com\u002Fv2-8c3b7860ec5a7ac8b7cfff779f69d6e7.jpg?source=1940ef5c","isOrg":false,"type":"people","url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fpeople\u002Ff6f52271761a065e28d7125c335c9775","userType":"people","headline":"test","badge":[],"badgeV2":{"title":"","mergedBadges":[],"detailBadges":[],"icon":"","nightIcon":""},"gender":1,"isAdvertiser":false,"followerCount":1694,"isFollowed":false,"isPrivacy":false,"vipInfo":{"isVip":false}},"url":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fanswers\u002F82308751","isCollapsed":false,"createdTime":1453185912,"updatedTime":1543040190,"extras":"","isCopyable":false,"isNormal":true,"voteupCount":66,"commentCount":39,"isSticky":false,"adminClosedComment":false,"commentPermission":"all","canComment":{"reason":"","status":true},"reshipmentSettings":"disallowed","content":"\u003Cp\u003E\u003C\u002Fp\u003E\u003Cp\u003E转载自我的 blog \u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=https%3A\u002F\u002Fstrcpy.me\u002Findex.php\u002Farchives\u002F652\u002F\" class=\" wrap external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003EOnlineJudge 沙箱实现思路 - virusdefender's blog (^-^)V\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003Ch2\u003E限制系统调用\u003C\u002Fh2\u003E\u003Cp\u003E目前常用的有 \u003Ccode\u003Eptrace\u003C\u002Fcode\u003E 和 \u003Ccode\u003Eseccomp\u003C\u002Fcode\u003E。\u003C\u002Fp\u003E\u003Ch2\u003Eptrace 很惨\u003C\u002Fh2\u003E\u003Cp\u003E听说 \u003Ccode\u003Eptrace\u003C\u002Fcode\u003E 存在效率问题,可能会让你的代码运行时间增加很多,这个是可以\u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=https%3A\u002F\u002Fgithub.com\u002Fvirusdefender\u002FUndergraduateThesis\" class=\" wrap external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003E简单测试\u003C\u002Fa\u003E看出来的。\u003C\u002Fp\u003E\u003Cp\u003E而加载 \u003Ccode\u003Eseccomp\u003C\u002Fcode\u003E 需要主动的在自己的代码中加载策略,也就是说需要修改已有的代码,但是去修改用户提交的代码是不大可能的。然后就想到了下面几个方法:\u003C\u002Fp\u003E\u003Ch2\u003ELD_PRELOAD hook\u003C\u002Fh2\u003E\u003Cp\u003E\u003Ccode\u003ELD_PRELOAD\u003C\u002Fcode\u003E加载动态链接库,然后在 so 中 hook \u003Ccode\u003E__libc_start_main\u003C\u002Fcode\u003E,然后就可以在用户的 \u003Ccode\u003Emain\u003C\u002Fcode\u003E 函数前执行自己的代码了。但是如果在用户的代码中再定义\u003Ccode\u003E__lbc_start_main\u003C\u002Fcode\u003E函数就可以绕过,虽然网上有人说需要 \u003Ccode\u003E-nostdlib\u003C\u002Fcode\u003E 的编译参数,但是我实际测试并不需要。下面是沙箱的实现代码\u003C\u002Fp\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Ccode class=\"language-c\"\u003E\u003Cspan class=\"cp\"\u003E#define _BSD_SOURCE \u003C\u002Fspan\u003E\u003Cspan class=\"c1\"\u003E\u002F\u002F readlink\n\u003C\u002Fspan\u003E\u003Cspan class=\"c1\"\u003E\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E#include\u003C\u002Fspan\u003E \u003Cspan class=\"cpf\"\u003E<dlfcn.h>\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E\n\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E#include\u003C\u002Fspan\u003E \u003Cspan class=\"cpf\"\u003E<stdlib.h> \u002F\u002F exit\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E\n\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E#include\u003C\u002Fspan\u003E \u003Cspan class=\"cpf\"\u003E<string.h> \u002F\u002F strstr, memset\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E\n\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E#include\u003C\u002Fspan\u003E \u003Cspan class=\"cpf\"\u003E<link.h> \u002F\u002F ElfW\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E\n\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E#include\u003C\u002Fspan\u003E \u003Cspan class=\"cpf\"\u003E<errno.h> \u002F\u002F EPERM\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E\n\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E#include\u003C\u002Fspan\u003E \u003Cspan class=\"cpf\"\u003E<unistd.h> \u002F\u002F readlink\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E\n\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E#include\u003C\u002Fspan\u003E \u003Cspan class=\"cpf\"\u003E<seccomp.h>\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E\n\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E#include\u003C\u002Fspan\u003E \u003Cspan class=\"cpf\"\u003E<stdio.h>\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E\n\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E\u003C\u002Fspan\u003E\u003Cspan class=\"kt\"\u003Eint\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Esyscalls_whitelist\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E[]\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003ESCMP_SYS\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Eread\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E),\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003ESCMP_SYS\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Ewrite\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E),\u003C\u002Fspan\u003E \n \u003Cspan class=\"n\"\u003ESCMP_SYS\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Efstat\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E),\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003ESCMP_SYS\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Emmap\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E),\u003C\u002Fspan\u003E \n \u003Cspan class=\"n\"\u003ESCMP_SYS\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Emprotect\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E),\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003ESCMP_SYS\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Emunmap\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E),\u003C\u002Fspan\u003E \n \u003Cspan class=\"n\"\u003ESCMP_SYS\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Ebrk\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E),\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003ESCMP_SYS\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Eaccess\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E),\u003C\u002Fspan\u003E \n \u003Cspan class=\"n\"\u003ESCMP_SYS\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Eexit_group\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E)};\u003C\u002Fspan\u003E\n\u003Cspan class=\"k\"\u003Etypedef\u003C\u002Fspan\u003E \u003Cspan class=\"nf\"\u003Eint\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Emain_t\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E)(\u003C\u002Fspan\u003E\u003Cspan class=\"kt\"\u003Eint\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"kt\"\u003Echar\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E**\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"kt\"\u003Echar\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E**\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E);\u003C\u002Fspan\u003E\n\n\u003Cspan class=\"cp\"\u003E#ifndef __unbounded\n\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E# define __unbounded\n\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E#endif\n\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E\u003C\u002Fspan\u003E\n\u003Cspan class=\"kt\"\u003Eint\u003C\u002Fspan\u003E \u003Cspan class=\"nf\"\u003E__libc_start_main\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Emain_t\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Emain\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"kt\"\u003Eint\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Eargc\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \n \u003Cspan class=\"kt\"\u003Echar\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003E__unbounded\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003E__unbounded\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Eubp_av\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003EElfW\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Eauxv_t\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003E__unbounded\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Eauxvec\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003E__typeof\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Emain\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Einit\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E\n \u003Cspan class=\"kt\"\u003Evoid\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Efini\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"kt\"\u003Evoid\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E),\u003C\u002Fspan\u003E\n \u003Cspan class=\"kt\"\u003Evoid\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Ertld_fini\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"kt\"\u003Evoid\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E),\u003C\u002Fspan\u003E \u003Cspan class=\"kt\"\u003Evoid\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003E__unbounded\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003Estack_end\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E)\u003C\u002Fspan\u003E\n\u003Cspan class=\"p\"\u003E{\u003C\u002Fspan\u003E\n\n \u003Cspan class=\"kt\"\u003Eint\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Ei\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E;\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003Essize_t\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Elen\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E;\u003C\u002Fspan\u003E\n \u003Cspan class=\"kt\"\u003Evoid\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Elibc\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E;\u003C\u002Fspan\u003E\n \u003Cspan class=\"kt\"\u003Eint\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Ewhitelist_length\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\"k\"\u003Esizeof\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Esyscalls_whitelist\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E\u002F\u003C\u002Fspan\u003E \u003Cspan class=\"k\"\u003Esizeof\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"kt\"\u003Eint\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E);\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003Escmp_filter_ctx\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Ectx\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\"nb\"\u003ENULL\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E;\u003C\u002Fspan\u003E\n \u003Cspan class=\"kt\"\u003Eint\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Elibc_start_main\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E)(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Emain_t\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Emain\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E\n \u003Cspan class=\"kt\"\u003Eint\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E\n \u003Cspan class=\"kt\"\u003Echar\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003E__unbounded\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003E__unbounded\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003EElfW\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Eauxv_t\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003E__typeof\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Emain\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E),\u003C\u002Fspan\u003E\n \u003Cspan class=\"kt\"\u003Evoid\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Efini\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"kt\"\u003Evoid\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E),\u003C\u002Fspan\u003E\n \u003Cspan class=\"kt\"\u003Evoid\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Ertld_fini\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"kt\"\u003Evoid\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E),\u003C\u002Fspan\u003E\n \u003Cspan class=\"kt\"\u003Evoid\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003E__unbounded\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Estack_end\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E);\u003C\u002Fspan\u003E\n\n \u003Cspan class=\"c1\"\u003E\u002F\u002F Get __libc_start_main entry point\n\u003C\u002Fspan\u003E\u003Cspan class=\"c1\"\u003E\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Elibc\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Edlopen\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"s\"\u003E"libc.so.6"\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003ERTLD_LOCAL\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E|\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003ERTLD_LAZY\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E);\u003C\u002Fspan\u003E\n \u003Cspan class=\"k\"\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"o\"\u003E!\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Elibc\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E{\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003Eexit\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"mi\"\u003E1\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E);\u003C\u002Fspan\u003E\n \u003Cspan class=\"p\"\u003E}\u003C\u002Fspan\u003E\n\n \u003Cspan class=\"n\"\u003Elibc_start_main\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Edlsym\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Elibc\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"s\"\u003E"__libc_start_main"\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E);\u003C\u002Fspan\u003E\n \u003Cspan class=\"k\"\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"o\"\u003E!\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Elibc_start_main\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E{\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003Eexit\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"mi\"\u003E2\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E);\u003C\u002Fspan\u003E\n \u003Cspan class=\"p\"\u003E}\u003C\u002Fspan\u003E\n\n \u003Cspan class=\"n\"\u003Ectx\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Eseccomp_init\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003ESCMP_ACT_KILL\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E);\u003C\u002Fspan\u003E\n \u003Cspan class=\"k\"\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"o\"\u003E!\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Ectx\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E{\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003Eexit\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"mi\"\u003E3\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E);\u003C\u002Fspan\u003E\n \u003Cspan class=\"p\"\u003E}\u003C\u002Fspan\u003E\n \u003Cspan class=\"k\"\u003Efor\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Ei\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\"mi\"\u003E0\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E;\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Ei\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E<\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Ewhitelist_length\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E;\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Ei\u003C\u002Fspan\u003E\u003Cspan class=\"o\"\u003E++\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E{\u003C\u002Fspan\u003E\n \u003Cspan class=\"k\"\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Eseccomp_rule_add\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Ectx\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003ESCMP_ACT_ALLOW\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \n \u003Cspan class=\"n\"\u003Esyscalls_whitelist\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E[\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Ei\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E],\u003C\u002Fspan\u003E \u003Cspan class=\"mi\"\u003E0\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E))\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E{\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003Eexit\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"mi\"\u003E4\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E);\u003C\u002Fspan\u003E\n \u003Cspan class=\"p\"\u003E}\u003C\u002Fspan\u003E\n \u003Cspan class=\"p\"\u003E}\u003C\u002Fspan\u003E\n \u003Cspan class=\"k\"\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Eseccomp_load\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Ectx\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E))\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E{\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003Eexit\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"mi\"\u003E5\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E);\u003C\u002Fspan\u003E\n \u003Cspan class=\"p\"\u003E}\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003Eseccomp_release\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Ectx\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E);\u003C\u002Fspan\u003E\n \u003Cspan class=\"k\"\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E((\u003C\u002Fspan\u003E\u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Elibc_start_main\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E)(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Emain\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Eargc\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Eubp_av\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Eauxvec\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003Einit\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Efini\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Ertld_fini\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Estack_end\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E));\u003C\u002Fspan\u003E\n\u003Cspan class=\"p\"\u003E}\u003C\u002Fspan\u003E\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E参考 \u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fstackoverflow.com\u002Fa\u002F27735456\u002F2737403\" class=\" external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003E\u003Cspan class=\"invisible\"\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\"visible\"\u003Estackoverflow.com\u002Fa\u002F277\u003C\u002Fspan\u003E\u003Cspan class=\"invisible\"\u003E35456\u002F2737403\u003C\u002Fspan\u003E\u003Cspan class=\"ellipsis\"\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E 和 \u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=https%3A\u002F\u002Fgithub.com\u002Fdaveho\u002FEasySandbox\" class=\" external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003E\u003Cspan class=\"invisible\"\u003Ehttps:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\"visible\"\u003Egithub.com\u002Fdaveho\u002FEasyS\u003C\u002Fspan\u003E\u003Cspan class=\"invisible\"\u003Eandbox\u003C\u002Fspan\u003E\u003Cspan class=\"ellipsis\"\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003Ch2\u003E代码级别 hook\u003C\u002Fh2\u003E\u003Cp\u003E编译的时候将两个文件编译在一起,\u003Ccode\u003Egcc sandbox.c user_code.c -ldl -lseccomp -o user_code\u003C\u002Fcode\u003E,虽然说直接定义\u003Ccode\u003E__libc_start_main\u003C\u002Fcode\u003E函数会提示重复定义,但是部分库函数还是可以通过定义同名函数覆盖绕过,比如 \u003Ccode\u003Eseccomp\u003C\u002Fcode\u003E 里面的函数、\u003Ccode\u003Edlopen\u003C\u002Fcode\u003E函数。\u003C\u002Fp\u003E\u003Ch2\u003Eexecve 前面加载策略\u003C\u002Fh2\u003E\u003Cp\u003E\u003Ccode\u003Eexceve\u003C\u002Fcode\u003E 之前加载策略,就需要将 \u003Ccode\u003Eexceve\u003C\u002Fcode\u003E 系统调用加白名单,有点不安全,但是可以在 \u003Ccode\u003Eseccomp\u003C\u002Fcode\u003E 参数中指定 \u003Ccode\u003Eexceve\u003C\u002Fcode\u003E 的执行参数,第一个参数就是文件路径,必须得匹配才行,否则就会 kill 掉。可以将指定的文件名加白名单。\u003C\u002Fp\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Ccode class=\"language-c\"\u003E\u003Cspan class=\"cp\"\u003E#include\u003C\u002Fspan\u003E \u003Cspan class=\"cpf\"\u003E<stdio.h>\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E\n\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E#include\u003C\u002Fspan\u003E \u003Cspan class=\"cpf\"\u003E<unistd.h>\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E\n\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E#include\u003C\u002Fspan\u003E \u003Cspan class=\"cpf\"\u003E<seccomp.h>\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E\n\u003C\u002Fspan\u003E\u003Cspan class=\"cp\"\u003E\u003C\u002Fspan\u003E\n\u003Cspan class=\"kt\"\u003Eint\u003C\u002Fspan\u003E \u003Cspan class=\"nf\"\u003Emain\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E()\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E{\u003C\u002Fspan\u003E\n \u003Cspan class=\"kt\"\u003Echar\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Efile_name\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E[\u003C\u002Fspan\u003E\u003Cspan class=\"mi\"\u003E30\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E]\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\"s\"\u003E"\u002Fbin\u002Fls"\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E;\u003C\u002Fspan\u003E\n \u003Cspan class=\"kt\"\u003Echar\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Efile_name1\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E[\u003C\u002Fspan\u003E\u003Cspan class=\"mi\"\u003E30\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E]\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\"s\"\u003E"xxxxxx"\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E;\u003C\u002Fspan\u003E\n \u003Cspan class=\"kt\"\u003Echar\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Eargv\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E[]\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\"s\"\u003E"\u002F"\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"nb\"\u003ENULL\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E};\u003C\u002Fspan\u003E\n \u003Cspan class=\"kt\"\u003Echar\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E*\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Eenv\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E[]\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\"p\"\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\"nb\"\u003ENULL\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E};\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003Eprintf\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"s\"\u003E"unrestricted\u003C\u002Fspan\u003E\u003Cspan class=\"se\"\u003E\\n\u003C\u002Fspan\u003E\u003Cspan class=\"s\"\u003E"\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E);\u003C\u002Fspan\u003E\n\n \u003Cspan class=\"c1\"\u003E\u002F\u002F Init the filter\n\u003C\u002Fspan\u003E\u003Cspan class=\"c1\"\u003E\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Escmp_filter_ctx\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Ectx\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E;\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003Ectx\u003C\u002Fspan\u003E \u003Cspan class=\"o\"\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Eseccomp_init\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003ESCMP_ACT_ALLOW\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E);\u003C\u002Fspan\u003E\n\n \u003Cspan class=\"n\"\u003Eseccomp_rule_add\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Ectx\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003ESCMP_ACT_KILL\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003ESCMP_SYS\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Eexecve\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E),\u003C\u002Fspan\u003E \u003Cspan class=\"mi\"\u003E1\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003ESCMP_A0\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003ESCMP_CMP_NE\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Efile_name\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E));\u003C\u002Fspan\u003E\n\n \u003Cspan class=\"n\"\u003Eseccomp_load\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Ectx\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E);\u003C\u002Fspan\u003E\n \u003Cspan class=\"n\"\u003Eexecve\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\"n\"\u003Efile_name\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Eargv\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\"n\"\u003Eenv\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E);\u003C\u002Fspan\u003E\n \u003Cspan class=\"k\"\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\"mi\"\u003E0\u003C\u002Fspan\u003E\u003Cspan class=\"p\"\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\"p\"\u003E}\u003C\u002Fspan\u003E\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E如果改成\u003Ccode\u003Eexecve(file_name1, argv, env);\u003C\u002Fcode\u003E,就没法执行了。\u003C\u002Fp\u003E\u003Cp\u003E当然要注意的是,\u003Ccode\u003Eexecve\u003C\u002Fcode\u003E 第一个参数匹配是内存地址匹配,毕竟是一个指针,而不是字符串匹配。Linux 系统开启 ASLR 之后,内存地址会随机化,用户代码几乎不可能简单的在相同的地址下面再放置一个路径。但是如果 \u003Ccode\u003Efile_name\u003C\u002Fcode\u003E 不在栈上或者是指定地址加载的,那用户代码也可能通过 mmap 来加载到同一个地址上,可以参考 \u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=https%3A\u002F\u002Fdangokyo.me\u002F2018\u002F07\u002F12\u002Fgooglectf-2018-qual-pwn-execve-sandbox-write-up\u002F\" class=\" wrap external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003EGoogle CTF\u003C\u002Fa\u003E 的一道题。\u003C\u002Fp\u003E\u003Ch2\u003Eseccomp 应该怎么用\u003C\u002Fh2\u003E\u003Cp\u003E文档看 \u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fman7.org\u002Flinux\u002Fman-pages\u002Fman3\u002Fseccomp_rule_add.3.html\" class=\" external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003E\u003Cspan class=\"invisible\"\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\"visible\"\u003Eman7.org\u002Flinux\u002Fman-page\u003C\u002Fspan\u003E\u003Cspan class=\"invisible\"\u003Es\u002Fman3\u002Fseccomp_rule_add.3.html\u003C\u002Fspan\u003E\u003Cspan class=\"ellipsis\"\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E 就够了,可以看到 seccomp 是支持某个参数的原始数据大小比较和掩码后数据一致比较的。\u003C\u002Fp\u003E\u003Cp\u003E对于 C\u002FC++ 等,我们可以开放\u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=https%3A\u002F\u002Fgithub.com\u002FQingdaoU\u002FJudger\u002Fblob\u002Fnewnew\u002Fsrc\u002Frules\u002Fc_cpp.c%23L10\" class=\" wrap external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003E白名单\u003C\u002Fa\u003E,类似 execve 这种需要特殊处理。 \u003C\u002Fp\u003E\u003Ch2\u003E控制写文件\u003C\u002Fh2\u003E\u003Cp\u003E我们不期望这些程序可以写任何文件。这种想法的直觉是限制 \u003Ccode\u003Ewrite\u003C\u002Fcode\u003E 的第一个参数 fd 不能大于 stderr,但是实际是可绕过的,那就是 \u003Ccode\u003Emmap\u003C\u002Fcode\u003E。 参考 \u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fman7.org\u002Flinux\u002Fman-pages\u002Fman2\u002Fmmap.2.html\" class=\" external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003E\u003Cspan class=\"invisible\"\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\"visible\"\u003Eman7.org\u002Flinux\u002Fman-page\u003C\u002Fspan\u003E\u003Cspan class=\"invisible\"\u003Es\u002Fman2\u002Fmmap.2.html\u003C\u002Fspan\u003E\u003Cspan class=\"ellipsis\"\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003Cp\u003E页面最下面的例子修改下然后 strace 运行就会发现只需要 open 然后 mmap 也可以写文件的。\u003C\u002Fp\u003E\u003Cp\u003E正确的方法是限制 \u003Ccode\u003Eopen\u003C\u002Fcode\u003E,不能带写权限。\u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fman7.org\u002Flinux\u002Fman-pages\u002Fman2\u002Fopen.2.html\" class=\" wrap external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003Eopen 的 man page\u003C\u002Fa\u003E 中说\u003C\u002Fp\u003E\u003Cblockquote\u003E The argument flags must include one of the following access modes: O_RDONLY, O_WRONLY, or O_RDWR\u003Cbr\u002F\u003E \u003C\u002Fblockquote\u003E\u003Cp\u003E所以这里就需要之前的掩码后比较了,其实掩码操作就是使用掩码和原数据进行与操作,\u003Ccode\u003ESCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY | O_RDWR, 0)\u003C\u002Fcode\u003E 就是说这两位上都是0才可以通过。\u003C\u002Fp\u003E\u003Cp\u003E和 \u003Ccode\u003Emmap\u003C\u002Fcode\u003E 类似的是 \u003Ccode\u003Ecreat\u003C\u002Fcode\u003E 系统调用,也可以创建一个文件。\u003C\u002Fp\u003E\u003Cp\u003E这种问题的根本解决办法是修改文件系统的用户权限。\u003C\u002Fp\u003E\u003Ch2\u003E__x32_compat 系统调用\u003C\u002Fh2\u003E\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=https%3A\u002F\u002Fgithub.com\u002Ftorvalds\u002Flinux\u002Fblob\u002Fmaster\u002Farch\u002Fx86\u002Fentry\u002Fsyscalls\u002Fsyscall_64.tbl%23L353\" class=\" external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003E\u003Cspan class=\"invisible\"\u003Ehttps:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\"visible\"\u003Egithub.com\u002Ftorvalds\u002Flin\u003C\u002Fspan\u003E\u003Cspan class=\"invisible\"\u003Eux\u002Fblob\u002Fmaster\u002Farch\u002Fx86\u002Fentry\u002Fsyscalls\u002Fsyscall_64.tbl#L353\u003C\u002Fspan\u003E\u003Cspan class=\"ellipsis\"\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E 有一些 \u003Ccode\u003E__x32_compat\u003C\u002Fcode\u003E 开头的系统调用,很容易忽略它们,没有加入黑名单,这些系统调用和不带 \u003Ccode\u003E_x32_compat\u003C\u002Fcode\u003E 的用法基本一致。\u003C\u002Fp\u003E\u003Ch2\u003E资源占用的限制\u003C\u002Fh2\u003E\u003Ch2\u003ECPU 时间限制,是 setrlimit 还是 setitimer\u003C\u002Fh2\u003E\u003Cp\u003E主要是的区别是子进程能否继承限制,进程能否捕获超时错误。\u003C\u002Fp\u003E\u003Cp\u003E当 \u003Ccode\u003Esetitimer\u003C\u002Fcode\u003E 定时器计时结束时,系统就会给进程发送一个信号。\u003C\u002Fp\u003E\u003Cp\u003E需要关心的两个计数器分别是 \u003Ccode\u003EITIMER_REAL\u003C\u002Fcode\u003E 进程实际运行时间计数器,结束的时候发送 \u003Ccode\u003ESIGALRM\u003C\u002Fcode\u003E 信号;\u003Ccode\u003EITIMER_VIRTUAL\u003C\u002Fcode\u003E 进程 CPU 时间计数器,结束的时候发送 \u003Ccode\u003ESIGVTALRM\u003C\u002Fcode\u003E 信号。我们设置好定时器之后,如果捕获到了对应的信号,说明当前进程运行超时。\u003C\u002Fp\u003E\u003Cp\u003E具体实现代码如下\u003C\u002Fp\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Ccode class=\"language-text\"\u003Eint set_timer(int sec, int ms, int is_cpu_time) {\n struct itimerval time_val;\n time_val.it_interval.tv_sec = time_val.it_interval.tv_usec = 0;\n time_val.it_value.tv_sec = sec;\n time_val.it_value.tv_usec = ms * 1000;\n if (setitimer(is_cpu_time?ITIMER_VIRTUAL:ITIMER_REAL, &time_val, NULL)) {\n LOG_FATAL("setitimer failed, errno %d", errno);\n return SETITIMER_FAILED;\n }\n return SUCCESS;\n}\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E但是有一点是需要注意的,\u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fman7.org\u002Flinux\u002Fman-pages\u002Fman2\u002Fsetitimer.2.html\" class=\" wrap external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003Esetitimer 不能限制子进程的 CPU 和实际运行时间\u003C\u002Fa\u003E。\u003C\u002Fp\u003E\u003Cp\u003E在部分只限制资源占用而不启用沙箱的场景下,这可能导致资源限制失效,因为进程可以取消这个设定。\u003C\u002Fp\u003E\u003Cp\u003ELinux 中 \u003Ccode\u003Esetrlimit\u003C\u002Fcode\u003E 函数可以用来限制进程的资源占用, 其中支持 \u003Ccode\u003ERLIMIT_CPU\u003C\u002Fcode\u003E、\u003Ccode\u003ERLIMIT_AS\u003C\u002Fcode\u003E 等参数, 同时子进程会继承父进程的设置。RLIMIT_CPU 也可以控制进程 CPU 时间, 所以要设置为 CPU 时间向上取整的值,然后和最后获取的时间再比较。\u003C\u002Fp\u003E\u003Ch2\u003E限制内存和最大输出大小\u003C\u002Fh2\u003E\u003Cp\u003E\u003Ccode\u003ERLIMIT_AS\u003C\u002Fcode\u003E 是限制进程最大内存地址空间,超过这个地址空间的将不能 分配成功,影响 \u003Ccode\u003Ebrk\u003C\u002Fcode\u003E、\u003Ccode\u003Emmap\u003C\u002Fcode\u003E、\u003Ccode\u003Emremap\u003C\u002Fcode\u003E 等系统调用。 \u003Ccode\u003ERLIMIT_FSIZE\u003C\u002Fcode\u003E 是限制进程最大输出或者写文件的大小,估计是限制了 \u003Ccode\u003Ewrite\u003C\u002Fcode\u003E 等。\u003C\u002Fp\u003E\u003Ch2\u003E实际运行时间\u003C\u002Fh2\u003E\u003Cp\u003E这个也很重要,如果一个进程啥都不做只 \u003Ccode\u003Esleep\u003C\u002Fcode\u003E 的话,CPU 时间几乎不会超,这里我的方案是新开一个线程一直监视某个 PID,超时就 kill 掉。\u003C\u002Fp\u003E\u003Ch2\u003ERLIMIT_NPROC 有点坑\u003C\u002Fh2\u003E\u003Cp\u003E很多人都知道 \u003Ccode\u003Ewhile(1) fork()\u003C\u002Fcode\u003E 可以卡死机器,怎么防?尤其是 go 这类这种天生就要开线程的语言。\u003C\u002Fp\u003E\u003Cblockquote\u003E The maximum number of processes (or, more precisely on Linux, threads) that can be created for the real user ID of the calling process. Upon encountering this limit, fork(2) fails with the error EAGAIN\u003Cbr\u002F\u003E \u003C\u002Fblockquote\u003E\u003Cp\u003E如果简单的使用 \u003Ccode\u003Enproc\u003C\u002Fcode\u003E 限制是不可以的,原因是 \u003Ccode\u003Ereal user ID\u003C\u002Fcode\u003E 这个其实不仅仅是进程的,和用户也有关。一个用户已经有10个进程了,那你给进程设置 \u003Ccode\u003Enproc=10\u003C\u002Fcode\u003E 是没用的,因为已经满了,而设置更低的数字可能导致进程无法启动。\u003C\u002Fp\u003E\u003Cp\u003E也许给每个进程都设置一个单独的用户可破?没有试\u003C\u002Fp\u003E\u003Ch2\u003E还有哪里容易出现问题\u003C\u002Fh2\u003E\u003Ch2\u003E编译器安全\u003C\u002Fh2\u003E\u003Cp\u003E这是一个容易被忽视的方面,目前已知的主要有以下几种。\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E引用某些可以无限输出的文件,比如 \u003Ccode\u003E#include<\u002Fdev\u002Frandom>\u003C\u002Fcode\u003E,编译器会一直读取, 导致卡死\u003C\u002Fli\u003E\u003Cli\u003E让编译器产生大量的错误信息,比如下面一段代码,可以让 g++ 编译器产生数 G 的错误日志\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Ccode class=\"language-text\"\u003Eint main() {\n struct x struct z<x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(y,x(y><y*,x(y*w>v<y*,w,x{}\n return 0; \n}\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E处理方法就是编译器运行的时候也要控制 CPU 时间和实际运行时间还有最大输出,同时使用编译器参数 \u003Ccode\u003E-fmax-errors=N\u003C\u002Fcode\u003E 来控制最大错误数量\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003EC++ 的模板元编程,部分代码是编译期执行的,可以构造出让编译器产生大量计算的代码。类似的有 Python 的编译器常量优化等等。\u003C\u002Fli\u003E\u003Cli\u003E引用一些敏感文件可能导致信息泄露,比如 \u003Ccode\u003E#include<\u002Fetc\u002Fshadow\u002F>\u003C\u002Fcode\u003E 或者测试用例等,会在编译错误的信息中泄露文件开头的内容。需要给编译器和运行代码设置单独的用户。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Ch2\u003E上面说的基础环境其实都在 Docker 里面\u003C\u002Fh2\u003E\u003Cp\u003EDocker 默认会\u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=https%3A\u002F\u002Fdocs.docker.com\u002Fengine\u002Fsecurity\u002Fsecurity\u002F\" class=\" wrap external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003E屏蔽一些系统调用和 capability\u003C\u002Fa\u003E,所以上面的很多方案都是基于这个前提的,否则需要自己处理 Docker 默认屏蔽的系统调用调用黑名单和降权。\u003C\u002Fp\u003E\u003Cp\u003E开源 \u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=https%3A\u002F\u002Fgithub.com\u002FQingdaoU\u002FJudger\" class=\" external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003E\u003Cspan class=\"invisible\"\u003Ehttps:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\"visible\"\u003Egithub.com\u002FQingdaoU\u002FJud\u003C\u002Fspan\u003E\u003Cspan class=\"invisible\"\u003Eger\u003C\u002Fspan\u003E\u003Cspan class=\"ellipsis\"\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003Cp\u003E参考 \u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fmanpages.ubuntu.com\u002Fmanpages\u002Fsaucy\u002Fman3\u002Fseccomp_rule_add.3.html\" class=\" external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003E\u003Cspan class=\"invisible\"\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\"visible\"\u003Emanpages.ubuntu.com\u002Fman\u003C\u002Fspan\u003E\u003Cspan class=\"invisible\"\u003Epages\u002Fsaucy\u002Fman3\u002Fseccomp_rule_add.3.html\u003C\u002Fspan\u003E\u003Cspan class=\"ellipsis\"\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=https%3A\u002F\u002Ffilippo.io\u002Flinux-syscall-table\u002F\" class=\" external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003E\u003Cspan class=\"invisible\"\u003Ehttps:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\"visible\"\u003Efilippo.io\u002Flinux-syscal\u003C\u002Fspan\u003E\u003Cspan class=\"invisible\"\u003El-table\u002F\u003C\u002Fspan\u003E\u003Cspan class=\"ellipsis\"\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Ca href=\"https:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F23067497\" class=\"internal\"\u003E\u003Cspan class=\"invisible\"\u003Ehttps:\u002F\u002Fwww.\u003C\u002Fspan\u003E\u003Cspan class=\"visible\"\u003Ezhihu.com\u002Fquestion\u002F2306\u003C\u002Fspan\u003E\u003Cspan class=\"invisible\"\u003E7497\u003C\u002Fspan\u003E\u003Cspan class=\"ellipsis\"\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E再加个广告,我们开发的 OnlineJudge 系统 \u003Ca href=\"https:\u002F\u002Flink.zhihu.com\u002F?target=https%3A\u002F\u002Fgithub.com\u002FQingdaoU\u002FOnlineJudge\" class=\" wrap external\" target=\"_blank\" rel=\"nofollow noreferrer\"\u003EQingdaoU\u002FOnlineJudge: Open source online judge based on Python, Django and Docker.\u003C\u002Fa\u003E 也开源了,欢迎给个 star。\u003C\u002Fp\u003E","editableContent":"","excerpt":"转载自我的 blog OnlineJudge 沙箱实现思路 - virusdefender's blog (^-^)V 限制系统调用目前常用的有 ptrace 和 seccomp。ptrace 很惨听说 ptrace 存在效率问题,可能会让你的代码运行时间增加很多,这个是可以简单测试 看出来的。而加载 seccomp 需要主动的在自己的代码中加载策略,也就是说需要修改已有的代码,但是去修改用户提交的代码是不大可能的。然后就想到了下面几个方法:LD_PRELOAD hook LD_PRELOAD加载动态链接库…","collapsedBy":"nobody","collapseReason":"","annotationAction":null,"markInfos":[],"relevantInfo":{"isRelevant":false,"relevantType":"","relevantText":""},"suggestEdit":{"reason":"","status":false,"tip":"","title":"","unnormalDetails":{"status":"","description":"","reason":"","reasonId":0,"note":""},"url":""},"isLabeled":false,"contentMark":null,"rewardInfo":{"canOpenReward":false,"isRewardable":false,"rewardMemberCount":0,"rewardTotalMoney":0,"tagline":""},"relationship":{"isAuthor":false,"isAuthorized":false,"isNothelp":false,"isThanked":false,"isRecognized":false,"voting":0,"upvotedFollowees":[]},"adAnswer":null}},"articles":{},"columns":{},"topics":{},"roundtables":{},"favlists":{},"comments":{},"notifications":{},"ebooks":{},"activities":{},"feeds":{},"pins":{},"promotions":{},"drafts":{},"chats":{},"posts":{},"clubs":{},"clubTags":{},"zvideos":{},"zvideoContributions":{}},"currentUser":"","account":{"lockLevel":{},"unlockTicketStatus":false,"unlockTicket":null,"challenge":[],"errorStatus":false,"message":"","isFetching":false,"accountInfo":{},"urlToken":{"loading":false},"cardUserInfo":{"vipInfo":{}},"handleWidget":{},"widgetList":[],"userWidgetId":""},"settings":{"socialBind":null,"inboxMsg":null,"notification":{},"email":{},"privacyFlag":null,"blockedUsers":{"isFetching":false,"paging":{"pageNo":1,"pageSize":6},"data":[]},"blockedFollowees":{"isFetching":false,"paging":{"pageNo":1,"pageSize":6},"data":[]},"ignoredTopics":{"isFetching":false,"paging":{"pageNo":1,"pageSize":6},"data":[]},"restrictedTopics":null,"laboratory":{}},"notification":{},"people":{"profileStatus":{},"activitiesByUser":{},"answersByUser":{},"answersSortByVotesByUser":{},"answersIncludedByUser":{},"votedAnswersByUser":{},"thankedAnswersByUser":{},"voteAnswersByUser":{},"thankAnswersByUser":{},"topicAnswersByUser":{},"zvideosByUser":{},"articlesByUser":{},"articlesSortByVotesByUser":{},"articlesIncludedByUser":{},"pinsByUser":{},"questionsByUser":{},"commercialQuestionsByUser":{},"favlistsByUser":{},"followingByUser":{},"followersByUser":{},"mutualsByUser":{},"followingColumnsByUser":{},"followingQuestionsByUser":{},"followingFavlistsByUser":{},"followingTopicsByUser":{},"publicationsByUser":{},"columnsByUser":{},"allFavlistsByUser":{},"brands":null,"creationsByUser":{},"creationsSortByVotesByUser":{},"creationsFeed":{},"infinity":{},"batchUsers":{}},"env":{"ab":{"config":{"experiments":[{"expId":"launch-qa_cl_guest-2","expPrefix":"qa_cl_guest","isDynamicallyUpdated":true,"isRuntime":false,"includeTriggerInfo":false},{"expId":"launch-vd_andplay_d-2","expPrefix":"vd_andplay_d","isDynamicallyUpdated":true,"isRuntime":false,"includeTriggerInfo":false},{"expId":"launch-vd_hookupplay_an-2","expPrefix":"vd_hookupplay_an","isDynamicallyUpdated":true,"isRuntime":false,"includeTriggerInfo":false},{"expId":"launch-vd_timeguide-2","expPrefix":"vd_timeguide","isDynamicallyUpdated":true,"isRuntime":false,"includeTriggerInfo":false},{"expId":"launch-vd_video_replay-3","expPrefix":"vd_video_replay","isDynamicallyUpdated":true,"isRuntime":false,"includeTriggerInfo":false},{"expId":"launch-vd_zvideo_link-10","expPrefix":"vd_zvideo_link","isDynamicallyUpdated":true,"isRuntime":false,"includeTriggerInfo":false},{"expId":"launch-zanswer-2","expPrefix":"zanswer","isDynamicallyUpdated":false,"isRuntime":false,"includeTriggerInfo":false},{"expId":"se_guess_hot-1_v1","expPrefix":"se_guess_hot","isDynamicallyUpdated":false,"isRuntime":false,"includeTriggerInfo":false}],"params":[{"id":"web_column_auto_invite","type":"String","value":"0","layerId":"webqa_layer_1"},{"id":"ge_newcard","type":"String","value":"3","chainId":"_gene_","layerId":"geus_layer_839","key":2997},{"id":"ge_hard_s_ma","type":"String","value":"0","chainId":"_gene_","layerId":"geli_layer_856","key":3031},{"id":"web_audit_01","type":"String","value":"case1","layerId":"webre_layer_1"},{"id":"ge_relation2","type":"String","value":"1","chainId":"_gene_","layerId":"gese_layer_815","key":2796},{"id":"ge_search_ui","type":"String","value":"1","chainId":"_gene_","layerId":"gese_layer_838","key":2898},{"id":"gue_profile_video","type":"String","value":"1","layerId":"guevd_layer_5"},{"id":"gue_v_serial","type":"String","value":"1","layerId":"guevd_layer_695"},{"id":"hw_aa_30","type":"Int","value":"0","chainId":"_gene_","layerId":"hw_aa_30","key":361},{"id":"se_zhiplus_ecpm","type":"Int","value":"0","chainId":"_gene_","layerId":"mr6i","key":855},{"id":"ffzix_xgdzwz","type":"Int","value":"0","layerId":"ffzix_xgdzwz"},{"id":"hwtj_bottom_btn","type":"Int","value":"1","layerId":"l-jrhg"},{"id":"rec_new2th","type":"Int","value":"0","chainId":"_gene_","layerId":"Hump","key":320},{"id":"xuanpinceshi","type":"Int","value":"0","layerId":"xuanpinceshi"},{"id":"andserial","type":"Int","value":"0","chainId":"_gene_","layerId":"CAxI","key":711},{"id":"se_tabcombine","type":"Int","value":"1","chainId":"_gene_","layerId":"se_tabcombine","key":907},{"id":"gue_goods_card","type":"String","value":"0","layerId":"gueqa_layer_1"},{"id":"gue_card_test","type":"String","value":"1","layerId":"gueqa_layer_2"},{"id":"userlinkv2","type":"Int","value":"0","layerId":"userlinkv2"},{"id":"km_detail_knn","type":"Int","value":"0","layerId":"l-TY59"},{"id":"book_ebook","type":"Int","value":"0","chainId":"_gene_","layerId":"book_ebook","key":758},{"id":"ge_sxzx","type":"String","value":"0","chainId":"_gene_","layerId":"gere_layer_990","key":3060},{"id":"office_xp","type":"Int","value":"1111","layerId":"office_xp"},{"id":"editor","type":"Int","value":"0","layerId":"editor"},{"id":"se_ffzx_jushen1","type":"String","value":"0","chainId":"_all_","layerId":"sese_layer_4"},{"id":"gue_repost","type":"String","value":"1","layerId":"gueqa_layer_671"},{"id":"ge_meta_ss","type":"String","value":"0","chainId":"_gene_","layerId":"gese_layer_834","key":3079},{"id":"web_login","type":"String","value":"0","layerId":"webgw_layer_759"},{"id":"gue_bulletmb","type":"String","value":"0","layerId":"guevd_layer_812"},{"id":"click_new_tb","type":"Int","value":"0","chainId":"_gene_","layerId":"1vYQ","key":422},{"id":"se_zhiplus_cpc","type":"Int","value":"0","chainId":"_gene_","layerId":"se_zhiplus_cpc","key":716},{"id":"gue_playh_an","type":"String","value":"1","layerId":"guevd_layer_622"},{"id":"gue_andplayd","type":"String","value":"1","layerId":"guevd_layer_686"},{"id":"use_bff_profit","type":"Int","value":"0","layerId":"use_bff_profit"},{"id":"web_sem_ab","type":"String","value":"1","layerId":"webgw_layer_3"},{"id":"account_sdk","type":"Int","value":"1","chainId":"_gene_","layerId":"account_sdk","key":810},{"id":"gue_messrec","type":"String","value":"0","layerId":"gueqa_layer_769"},{"id":"ge_sug_rep","type":"String","value":"1","chainId":"_gene_","layerId":"gese_layer_1034","key":3158},{"id":"ge_guess","type":"String","value":"0","chainId":"_gene_","layerId":"gese_layer_938","key":2912},{"id":"ge_entity","type":"String","value":"0","chainId":"_gene_","layerId":"gese_layer_946","key":3036},{"id":"ge_emoji","type":"String","value":"0","chainId":"_gene_","layerId":"getp_layer_827","key":3209},{"id":"meta_ebook","type":"Int","value":"0","layerId":"meta_ebook"},{"id":"se_cp_answer","type":"Int","value":"0","chainId":"_gene_","layerId":"WpRW","key":705},{"id":"tp_dingyue_video","type":"String","value":"0","chainId":"_all_","layerId":"tptp_layer_4"},{"id":"gue_vid_tab","type":"String","value":"0","layerId":"guevd_layer_900"},{"id":"zr_expslotpaid","type":"String","value":"1","chainId":"_all_","layerId":"zrrec_layer_11"},{"id":"gue_q_share","type":"String","value":"0","layerId":"gueqa_layer_647"},{"id":"web_answerlist_ad","type":"String","value":"0","layerId":"webqa_layer_1"},{"id":"book_kpwz","type":"Int","value":"0","chainId":"_gene_","layerId":"Zyox","key":671},{"id":"se_cp_post3","type":"Int","value":"0","chainId":"_gene_","layerId":"VZLx","key":706},{"id":"qap_question_visitor","type":"String","value":" 0","chainId":"_all_","layerId":"qapqa_layer_2"},{"id":"creator_hot_rec","type":"Int","value":"1","layerId":"ju92"},{"id":"edu_cd1","type":"Int","value":"0","layerId":"l-l18Y"},{"id":"plus_panel","type":"Int","value":"0","chainId":"_gene_","layerId":"2CDt","key":818},{"id":"web_answer_list_ad","type":"String","value":"1","layerId":"webqa_layer_4"},{"id":"gue_video_replay","type":"String","value":"2","layerId":"guevd_layer_3"},{"id":"pfd_newbie","type":"Int","value":"0","chainId":"_gene_","layerId":"pfd_newbie","key":63},{"id":"io_video_tab","type":"Int","value":"0","chainId":"_gene_","layerId":"io_video_tab","key":728},{"id":"se_4a","type":"Int","value":"0","chainId":"_gene_","layerId":"rtiq","key":335},{"id":"ge_prf_rec","type":"String","value":"0","chainId":"_gene_","layerId":"getop_layer_991","key":3040},{"id":"ge_video","type":"String","value":"0","chainId":"_gene_","layerId":"geli_layer_856","key":2831},{"id":"gue_art2qa","type":"String","value":"0","layerId":"gueqa_layer_579"},{"id":"ad_com_zhi","type":"Int","value":"0","chainId":"_gene_","layerId":"ad_com_zhi","key":571},{"id":"Re_Collection","type":"Int","value":"0","chainId":"_gene_","layerId":"9olk","key":847},{"id":"ge_newyanzhi","type":"String","value":"0","chainId":"_gene_","layerId":"geus_layer_1019","key":2788},{"id":"web_scl_rec","type":"String","value":"0","layerId":"webgw_layer_759"},{"id":"zr_slotpaidexp","type":"String","value":"1","chainId":"_all_","layerId":"zrrec_layer_5"},{"id":"tp_zrec","type":"String","value":"0","chainId":"_all_","layerId":"tptp_layer_619"},{"id":"gue_bullet_second","type":"String","value":"1","layerId":"guevd_layer_1"},{"id":"iserial","type":"Int","value":"0","chainId":"_gene_","layerId":"iserial","key":928},{"id":"web_heifetz_grow_ad","type":"String","value":"1","layerId":"webgw_layer_3"},{"id":"gue_fo_recom","type":"String","value":"0","layerId":"gueqa_layer_780"},{"id":"ge_infinity6","type":"String","value":"0","chainId":"_gene_","layerId":"gese_layer_815","key":2817},{"id":"hw_aa_50","type":"Int","value":"0","chainId":"_gene_","layerId":"hw_aa_50","key":362},{"id":"gue_visit_n_artcard","type":"String","value":"1","layerId":"gueqa_layer_579"},{"id":"se_mixer_km","type":"Int","value":"0","chainId":"_gene_","layerId":"se_mixer_km","key":649},{"id":"android_serial","type":"Int","value":"0","chainId":"_gene_","layerId":"android_serial","key":929},{"id":"club_fn","type":"Int","value":"1","layerId":"club_fn"},{"id":"se_fix_ebook","type":"Int","value":"0","chainId":"_gene_","layerId":"se_fix_ebook","key":103},{"id":"haojiakp","type":"Int","value":"0","layerId":"haojiakp"},{"id":"test_3","type":"Int","value":"0","chainId":"_gene_","layerId":"dABe","key":637},{"id":"comment","type":"Int","value":"0","chainId":"_gene_","layerId":"comment","key":644},{"id":"iosserial","type":"Int","value":"0","chainId":"_gene_","layerId":"m7Id","key":714},{"id":"an_video_tab","type":"Int","value":"0","chainId":"_gene_","layerId":"an_video_tab","key":727},{"id":"gue_recmess","type":"String","value":"0","layerId":"gueqa_layer_795"},{"id":"webpImg","type":"Int","value":"1","layerId":"JnVt"},{"id":"test_rec","type":"Int","value":"10","layerId":"test_rec"},{"id":"tp_topic_style","type":"String","value":"0","chainId":"_all_","layerId":"tptp_layer_4"},{"id":"gue_sharp","type":"String","value":"1","layerId":"guevd_layer_686"},{"id":"se_cvr_boost","type":"Int","value":"0","chainId":"_gene_","layerId":"se_cvr_boost","key":183},{"id":"Test_Punk","type":"Int","value":"0","layerId":"Test_Punk"},{"id":"gue_cdzixun","type":"String","value":"0","layerId":"gueqa_layer_3"},{"id":"qap_question_author","type":"String","value":"0","chainId":"_all_","layerId":"qapqa_layer_2"},{"id":"top_test_4_liguangyi","type":"String","value":"1","chainId":"_all_","layerId":"iosus_layer_1"},{"id":"xuanpinab","type":"Int","value":"0","layerId":"xuanpinab"},{"id":"h5_signin","type":"Int","value":"0","layerId":"h5_signin"},{"id":"se_images","type":"Int","value":"0","chainId":"_gene_","layerId":"ulTc","key":652},{"id":"web_collection_guest","type":"String","value":"1","layerId":"webqa_layer_4"},{"id":"gue_art_ui","type":"String","value":"0","layerId":"gueqa_layer_647"},{"id":"gue_video_guide","type":"String","value":"1","layerId":"guevd_layer_625"},{"id":"correct_cnn","type":"Int","value":"0","chainId":"_gene_","layerId":"correct_cnn","key":397},{"id":"And_Collection","type":"Int","value":"0","chainId":"_gene_","layerId":"VbMB","key":848},{"id":"se_cp_question","type":"Int","value":"0","chainId":"_gene_","layerId":"6w98","key":704},{"id":"ge_rec_2th","type":"String","value":"11","chainId":"_gene_","layerId":"geli_layer_965","key":3023},{"id":"ge_dipin_pre","type":"String","value":"0","chainId":"_gene_","layerId":"gese_layer_1000","key":3124},{"id":"ge_item","type":"String","value":"0","chainId":"_gene_","layerId":"gese_layer_945","key":2971},{"id":"vdox_cmt","type":"Int","value":"0","layerId":"l-9YBb"},{"id":"show_ad","type":"Int","value":"0","chainId":"_gene_","layerId":"show_ad","key":27},{"id":"ge_v_rank_v3","type":"Int","value":"0","chainId":"_gene_","layerId":"FPcB","key":581},{"id":"se_dwd_all","type":"Int","value":"0","chainId":"_gene_","layerId":"se_dwd_all","key":621},{"id":"ge_usercard1","type":"String","value":"0","chainId":"_gene_","layerId":"gese_layer_742","key":2740},{"id":"tp_contents","type":"String","value":"2","chainId":"_all_","layerId":"tptp_layer_627"},{"id":"pf_noti_entry_num","type":"String","value":"0","chainId":"_all_","layerId":"pfus_layer_718"},{"id":"ts_refresh","type":"Int","value":"1","layerId":"EBn6"},{"id":"ts_cardtitle","type":"Int","value":"0","layerId":"l-ZED7"},{"id":"ge_yuzhi_v1","type":"String","value":"1","chainId":"_gene_","layerId":"gese_layer_1029","key":3127},{"id":"gue_iosplay","type":"String","value":"0","layerId":"guevd_layer_810"},{"id":"pfd_newbie2","type":"Int","value":"0","chainId":"_gene_","layerId":"pfd_newbie2","key":71},{"id":"Full_ans_fav","type":"Int","value":"0","chainId":"_gene_","layerId":"Pnd6","key":372},{"id":"gue_bullet_guide","type":"String","value":"发个弹幕聊聊…","layerId":"guevd_layer_0"},{"id":"recnew_2th","type":"Int","value":"24","chainId":"_gene_","layerId":"l-recnew_2th","key":67},{"id":"se_personal_ab","type":"Int","value":"0","chainId":"_gene_","layerId":"BJ58","key":554},{"id":"recommend_list","type":"Int","value":"0","chainId":"_gene_","layerId":"ejiC","key":921},{"id":"pf_adjust","type":"String","value":"0","chainId":"_all_","layerId":"pfus_layer_9"},{"id":"gue_zvideo_link","type":"String","value":"1","layerId":"guevd_layer_2"},{"id":"ge_newbie3","type":"Int","value":"0","chainId":"_gene_","layerId":"ge_newbie3","key":180},{"id":"rec_3th","type":"Int","value":"11","chainId":"_gene_","layerId":"pRqt","key":697},{"id":"se_guess_hot","type":"Int","value":"0","chainId":"_gene_","layerId":"wRzK","key":882},{"id":"pc_editorplugin","type":"Int","value":"0","layerId":"pc_editorplugin"},{"id":"zanswer","type":"Int","value":"1","layerId":"l-zanswer"}],"chains":[{"chainId":"_all_"}],"encodedParams":"Cny1C9cL7ApSC2kBVwNAAccCiwP2AvQLBwymAcwCKgNWDGAL3AuJDMECnwLCAjIDPwDYAk8B4AsPCzsCTwPkCqADAQtqAYkCoQNnAH0ChALKAtcCtwCMAo0BUAPAAs8LNAybCxsARQJtArQKNwxHAHQBQwAqApkDtAC5AnIDEj4DAAEBAAAAAAEAAAAAAAEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAAAAEAABgAAAALAA=="},"triggers":{}},"userAgent":{"Edge":false,"IE":false,"Wechat":false,"Weibo":false,"QQ":false,"MQQBrowser":false,"Qzone":false,"Mobile":false,"Android":false,"iOS":false,"isAppleDevice":false,"Zhihu":false,"ZhihuHybrid":false,"isBot":false,"Tablet":false,"UC":false,"Sogou":false,"Qihoo":false,"Baidu":false,"BaiduApp":false,"Safari":false,"GoogleBot":false,"AndroidDaily":false,"iOSDaily":false,"WxMiniProgram":false,"BaiduMiniProgram":false,"QQMiniProgram":false,"JDMiniProgram":false,"isWebView":false,"isMiniProgram":false,"origin":"Mozilla\u002F5.0 (Windows NT 6.1; Win64; x64; rv:89.0) Gecko\u002F20100101 Firefox\u002F89.0"},"appViewConfig":{},"ctx":{"path":"\u002Fquestion\u002F23067497","query":{},"href":"http:\u002F\u002Fwww.zhihu.com\u002Fquestion\u002F23067497","host":"www.zhihu.com"},"trafficSource":"production","edition":{"beijing":false,"baidu":false,"sogou":false,"baiduBeijing":false,"sogouBeijing":false,"sogouInput":false,"baiduSearch":false,"googleSearch":false,"miniProgram":false,"xiaomi":false},"theme":"light","enableShortcut":true,"referer":"","xUDId":"AeBcvVUPVxOPTqf1-nz6EsysuCo13mr3byc=","mode":"ssr","conf":{},"xTrafficFreeOrigin":"","ipInfo":{},"logged":false,"vars":{"passThroughHeaders":{}}},"me":{"columnContributions":[]},"label":{"recognizerLists":{}},"ecommerce":{},"comments":{"pagination":{},"collapsed":{},"reverse":{},"reviewing":{},"conversation":{},"parent":{}},"commentsV2":{"stickers":[],"commentWithPicPermission":{},"notificationsComments":{},"pagination":{},"collapsed":{},"reverse":{},"reviewing":{},"conversation":{},"conversationMore":{},"parent":{}},"pushNotifications":{"default":{"isFetching":false,"isDrained":false,"ids":[]},"follow":{"isFetching":false,"isDrained":false,"ids":[]},"vote_thank":{"isFetching":false,"isDrained":false,"ids":[]},"currentTab":"default","notificationsCount":{"default":0,"follow":0,"vote_thank":0}},"messages":{"data":{},"currentTab":"common","messageCount":0},"register":{"registerValidateSucceeded":null,"registerValidateErrors":{},"registerConfirmError":null,"sendDigitsError":null,"registerConfirmSucceeded":null},"login":{"loginUnregisteredError":false,"loginBindWechatError":false,"loginConfirmError":null,"sendDigitsError":null,"needSMSIdentify":false,"validateDigitsError":false,"loginConfirmSucceeded":null,"qrcodeLoginToken":"","qrcodeLoginScanStatus":0,"qrcodeLoginError":null,"qrcodeLoginReturnNewToken":false},"switches":{},"captcha":{"captchaNeeded":false,"captchaValidated":false,"captchaBase64String":null,"captchaValidationMessage":null,"loginCaptchaExpires":false},"sms":{"supportedCountries":[]},"chat":{"chats":{},"inbox":{"recents":{"isFetching":false,"isDrained":false,"isPrevDrained":false,"result":[],"next":null,"key":null},"strangers":{"isFetching":false,"isDrained":false,"isPrevDrained":false,"result":[],"next":null,"key":null},"friends":{"isFetching":false,"isDrained":false,"isPrevDrained":false,"result":[],"next":null,"key":null},"search":{"isFetching":false,"isDrained":false,"isPrevDrained":false,"result":[],"next":null,"key":null},"config":{"newCount":0,"strangerMessageSwitch":false,"strangerMessageUnread":false,"friendCount":0}},"global":{"isChatMqttExisted":false}},"emoticons":{"emoticonGroupList":[],"emoticonGroupDetail":{}},"creator":{"currentCreatorUrlToken":null,"homeData":{"recommendQuestions":[]},"tools":{"question":{"invitationCount":{"questionFolloweeCount":0,"questionTotalCount":0},"goodatTopics":[]},"customPromotion":{"itemLists":{}},"recommend":{"recommendTimes":{}}},"explore":{"academy":{"tabs":[],"article":{}}},"rights":[],"rightsStatus":{},"levelUpperLimit":10,"account":{"growthLevel":{}},"mcn":{},"applyStatus":{},"videoSupport":{},"mcnManage":{},"tasks":{},"recentlyCreated":[],"analysis":{"all":{},"answer":{},"zvideo":{},"article":{},"pin":{},"singleContent":{}},"announcement":{},"school":{"tabs":[],"contents":[],"banner":null,"entities":{}}},"question":{"followers":{},"concernedFollowers":{},"answers":{"23067497":{"isFetching":false,"isDrained":false,"ids":[23538675,82308751,40878704,77491830,23509924],"newIds":[23538675,82308751,40878704,77491830,23509924],"totals":21,"error":false,"isPrevDrained":true,"previous":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fquestions\u002F23067497\u002Fanswers?include=data%5B%2A%5D.is_normal%2Cadmin_closed_comment%2Creward_info%2Cis_collapsed%2Cannotation_action%2Cannotation_detail%2Ccollapse_reason%2Cis_sticky%2Ccollapsed_by%2Csuggest_edit%2Ccomment_count%2Ccan_comment%2Ccontent%2Ceditable_content%2Cattachment%2Cvoteup_count%2Creshipment_settings%2Ccomment_permission%2Ccreated_time%2Cupdated_time%2Creview_info%2Crelevant_info%2Cquestion%2Cexcerpt%2Cis_labeled%2Cpaid_info%2Cpaid_info_content%2Crelationship.is_authorized%2Cis_author%2Cvoting%2Cis_thanked%2Cis_nothelp%2Cis_recognized%3Bdata%5B%2A%5D.mark_infos%5B%2A%5D.url%3Bdata%5B%2A%5D.author.follower_count%2Cvip_info%2Cbadge%5B%2A%5D.topics%3Bdata%5B%2A%5D.settings.table_of_content.enabled&limit=5&offset=0&platform=desktop&sort_by=default","next":"https:\u002F\u002Fwww.zhihu.com\u002Fapi\u002Fv4\u002Fquestions\u002F23067497\u002Fanswers?include=data%5B%2A%5D.is_normal%2Cadmin_closed_comment%2Creward_info%2Cis_collapsed%2Cannotation_action%2Cannotation_detail%2Ccollapse_reason%2Cis_sticky%2Ccollapsed_by%2Csuggest_edit%2Ccomment_count%2Ccan_comment%2Ccontent%2Ceditable_content%2Cattachment%2Cvoteup_count%2Creshipment_settings%2Ccomment_permission%2Ccreated_time%2Cupdated_time%2Creview_info%2Crelevant_info%2Cquestion%2Cexcerpt%2Cis_labeled%2Cpaid_info%2Cpaid_info_content%2Crelationship.is_authorized%2Cis_author%2Cvoting%2Cis_thanked%2Cis_nothelp%2Cis_recognized%3Bdata%5B%2A%5D.mark_infos%5B%2A%5D.url%3Bdata%5B%2A%5D.author.follower_count%2Cvip_info%2Cbadge%5B%2A%5D.topics%3Bdata%5B%2A%5D.settings.table_of_content.enabled&limit=5&offset=5&platform=desktop&sort_by=default"}},"hiddenAnswers":{},"updatedAnswers":{},"collapsedAnswers":{},"notificationAnswers":{},"invitedQuestions":{"total":{"count":null,"isEnd":false,"isLoading":false,"questions":[]},"followees":{"count":null,"isEnd":false,"isLoading":false,"questions":[]}},"laterQuestions":{"count":null,"isEnd":false,"isLoading":false,"questions":[]},"waitingQuestions":{"recommend":{"isEnd":false,"isLoading":false,"questions":[]},"hot":{"isEnd":false,"isLoading":false,"questions":[]},"newest":{"isEnd":false,"isLoading":false,"questions":[]},"invite":{"isEnd":false,"isLoading":false,"questions":[]}},"invitationCandidates":{},"inviters":{},"invitees":{},"similarQuestions":{},"questionBanners":{},"relatedCommodities":{},"bio":{},"brand":{},"permission":{},"adverts":{"3":{"ad":{"adVerb":"","brand":{"id":0,"logo":"https:\u002F\u002Fpic1.zhimg.com\u002Fv2-742b70686c0a04f6d77a011904d9d704_250x250.jpeg","name":"彼岸教育"},"category":1,"clickTracks":["https:\u002F\u002Fsugar.zhihu.com\u002Fplutus_adreaper?tu=https%3A%2F%2Fwww.beaconedu.com%2Flpv1%2Fiit-0826%3Fcb%3D__CALLBACK__&pdi=1550736547726776&ut=80d5a113a65e43b2a8faa3a2c5308e81&au=43864&ed=CjEEfh4wM31_RzNSV2gqVUYmDiwNbm55fB1_X1dpeR0NcQspASZpI3pGNlMXMTYNWXYPbFkqPn1_EWFQA2d-FhssBHwMc2x0dwMxDgxheAhddAx5HiAufXwDMQgMYXsFRXAKegpwb3J2FGVRAGZ6Fgk1BHsAdXwsOxhiQUQ5cQFZdxd4CnZ0dX8LY14IdjhDVnQPeA1zbnB4EWtBUCdxAILwilXIjuSj&pf=4&idi=11003&ar=0.00045370020167953177&nt=0"],"closeTrack":"https:\u002F\u002Fsugar.zhihu.com\u002Fplutus_adreaper?nt=0&ut=80d5a113a65e43b2a8faa3a2c5308e81&tu=https%3A%2F%2Fwww.beaconedu.com%2Flpv1%2Fiit-0826%3Fcb%3D__CALLBACK__&ar=0.00045370020167953177&idi=11003&au=43864&pdi=1550736547726776&pf=4&ed=CjEEfR4wM31_RzNSV2gqVUYmDiwNbm55fB1_X1dpeR0NcQspASZpI3pGNlMXMTYNWXYPbFkqPn1_EWFQA2d-FhssBHwMc2x0dwMxDgxheAhddAx5HiAufXwDMQgMYXsFRXAKegpwb3J2FGVRAGZ6Fgk1BHsAdXwsOxhiQUQ5cQFZdxd4CnZ0dX8LY14IdjhDVnQPeA1zbnB4EWtBUCdxAN72MeS2-lO5","closeTracks":["https:\u002F\u002Fsugar.zhihu.com\u002Fplutus_adreaper?nt=0&ut=80d5a113a65e43b2a8faa3a2c5308e81&tu=https%3A%2F%2Fwww.beaconedu.com%2Flpv1%2Fiit-0826%3Fcb%3D__CALLBACK__&ar=0.00045370020167953177&idi=11003&au=43864&pdi=1550736547726776&pf=4&ed=CjEEfR4wM31_RzNSV2gqVUYmDiwNbm55fB1_X1dpeR0NcQspASZpI3pGNlMXMTYNWXYPbFkqPn1_EWFQA2d-FhssBHwMc2x0dwMxDgxheAhddAx5HiAufXwDMQgMYXsFRXAKegpwb3J2FGVRAGZ6Fgk1BHsAdXwsOxhiQUQ5cQFZdxd4CnZ0dX8LY14IdjhDVnQPeA1zbnB4EWtBUCdxAN72MeS2-lO5"],"conversionTracks":["https:\u002F\u002Fsugar.zhihu.com\u002Fplutus_adreaper?ar=0.00045370020167953177&idi=11003&pdi=1550736547726776&ut=80d5a113a65e43b2a8faa3a2c5308e81&ed=CjEEfx4wM31_RzNSV2gqVUYmDiwNbm55fB1_X1dpeR0NcQspASZpI3pGNlMXMTYNWXYPbFkqPn1_EWFQA2d-FhssBHwMc2x0dwMxDgxheAhddAx5HiAufXwDMQgMYXsFRXAKegpwb3J2FGVRAGZ6Fgk1BHsAdXwsOxhiQUQ5cQFZdxd4CnZ0dX8LY14IdjhDVnQPeA1zbnB4EWtBUCdxADCCjchZ8l9C&au=43864&tu=https%3A%2F%2Fwww.beaconedu.com%2Flpv1%2Fiit-0826%3Fcb%3D__CALLBACK__&pf=4&nt=0"],"creatives":[{"appPromotionUrl":"","brand":{"id":0,"logo":"https:\u002F\u002Fpic1.zhimg.com\u002Fv2-742b70686c0a04f6d77a011904d9d704_250x250.jpeg","name":"彼岸教育"},"cta":{"value":"查看详情"},"description":"伊利诺伊理工大学来华招生,免联考,在职可读,课程教授与本校同步,毕业拿全日制硕士证书,点击测试是否符合报考条件","footer":{"value":""},"landingUrl":"https:\u002F\u002Fwww.beaconedu.com\u002Flpv1\u002Fiit-0826?cb=https%3A%2F%2Fsugar.zhihu.com%2Fplutus_adreaper_callback%3Fsi%3D1ba5f8fe-c7f5-4928-8f95-f42c9e3c4cd4%26os%3D3%26zid%3D236%26zaid%3D1437272%26zcid%3D1486153%26cid%3D1486152%26event%3D__EVENTTYPE__%26value%3D__EVENTVALUE__%26ts%3D__TIMESTAMP__%26cts%3D__TS__%26mh%3D__MEMBERHASHID__","title":"海外名校来华招生!想读在职名校硕士的小伙伴不要错过!"}],"debugTracks":["https:\u002F\u002Fsugar.zhihu.com\u002Fplutus_adreaper?idi=11003&ar=0.00045370020167953177&tu=https%3A%2F%2Fwww.beaconedu.com%2Flpv1%2Fiit-0826%3Fcb%3D__CALLBACK__&ut=80d5a113a65e43b2a8faa3a2c5308e81&ed=CjEEcx4wM31_RzNSV2gqVUYmDiwNbm55fB1_X1dpeR0NcQspASZpI3pGNlMXMTYNWXYPbFkqPn1_EWFQA2d-FhssBHwMc2x0dwMxDgxheAhddAx5HiAufXwDMQgMYXsFRXAKegpwb3J2FGVRAGZ6Fgk1BHsAdXwsOxhiQUQ5cQFZdxd4CnZ0dX8LY14IdjhDVnQPeA1zbnB4EWtBUCdxAPZZedHNEHWe&pdi=1550736547726776&pf=4&au=43864&nt=0"],"displayAdvertisingTag":true,"downloadSilent":false,"experimentInfo":"{}","id":1437272,"impressionTracks":["https:\u002F\u002Fsugar.zhihu.com\u002Fplutus_adreaper?ut=80d5a113a65e43b2a8faa3a2c5308e81&pdi=1550736547726776&nt=0&au=43864&ar=0.00045370020167953177&idi=11003&tu=https%3A%2F%2Fwww.beaconedu.com%2Flpv1%2Fiit-0826%3Fcb%3D__CALLBACK__&ed=CjEEeB4wM31_RzNSV2gqVUYmDiwNbm55fB1_X1dpeR0NcQspASZpI3pGNlMXMTYNWXYPbFkqPn1_EWFQA2d-FhssBHwMc2x0dwMxDgxheAhddAx5HiAufXwDMQgMYXsFRXAKegpwb3J2FGVRAGZ6Fgk1BHsAdXwsOxhiQUQ5cQFZdxd4CnZ0dX8LY14IdjhDVnQPeA1zbnB4EWtBUCdxAISQy4TFActm&pf=4"],"isEvergreen":false,"isNewWebview":true,"isSpeeding":false,"isWebp":false,"landPrefetch":false,"name":"","nativePrefetch":true,"partyId":-2,"revertCloseTrack":"https:\u002F\u002Fsugar.zhihu.com\u002Fplutus_adreaper?ed=CjEEch4wM31_RzNSV2gqVUYmDiwNbm55fB1_X1dpeR0NcQspASZpI3pGNlMXMTYNWXYPbFkqPn1_EWFQA2d-FhssBHwMc2x0dwMxDgxheAhddAx5HiAufXwDMQgMYXsFRXAKegpwb3J2FGVRAGZ6Fgk1BHsAdXwsOxhiQUQ5cQFZdxd4CnZ0dX8LY14IdjhDVnQPeA1zbnB4EWtBUCdxAIn9CE7NF7Na&ar=0.00045370020167953177&nt=0&tu=https%3A%2F%2Fwww.beaconedu.com%2Flpv1%2Fiit-0826%3Fcb%3D__CALLBACK__&pdi=1550736547726776&ut=80d5a113a65e43b2a8faa3a2c5308e81&pf=4&au=43864&idi=11003","template":"web_word","viewTrack":"https:\u002F\u002Fsugar.zhihu.com\u002Fplutus_adreaper?pdi=1550736547726776&pf=4&idi=11003&tu=https%3A%2F%2Fwww.beaconedu.com%2Flpv1%2Fiit-0826%3Fcb%3D__CALLBACK__&nt=0&au=43864&ed=CjEEeR4wM31_RzNSV2gqVUYmDiwNbm55fB1_X1dpeR0NcQspASZpI3pGNlMXMTYNWXYPbFkqPn1_EWFQA2d-FhssBHwMc2x0dwMxDgxheAhddAx5HiAufXwDMQgMYXsFRXAKegpwb3J2FGVRAGZ6Fgk1BHsAdXwsOxhiQUQ5cQFZdxd4CnZ0dX8LY14IdjhDVnQPeA1zbnB4EWtBUCdxAGBTH44T0Y7r&ut=80d5a113a65e43b2a8faa3a2c5308e81&ar=0.00045370020167953177","viewTracks":["https:\u002F\u002Fsugar.zhihu.com\u002Fplutus_adreaper?pdi=1550736547726776&pf=4&idi=11003&tu=https%3A%2F%2Fwww.beaconedu.com%2Flpv1%2Fiit-0826%3Fcb%3D__CALLBACK__&nt=0&au=43864&ed=CjEEeR4wM31_RzNSV2gqVUYmDiwNbm55fB1_X1dpeR0NcQspASZpI3pGNlMXMTYNWXYPbFkqPn1_EWFQA2d-FhssBHwMc2x0dwMxDgxheAhddAx5HiAufXwDMQgMYXsFRXAKegpwb3J2FGVRAGZ6Fgk1BHsAdXwsOxhiQUQ5cQFZdxd4CnZ0dX8LY14IdjhDVnQPeA1zbnB4EWtBUCdxAGBTH44T0Y7r&ut=80d5a113a65e43b2a8faa3a2c5308e81&ar=0.00045370020167953177"],"zaAdInfo":"CNjcVxDsASIBMV1OuMFOYMnaWg==","zaAdInfoJson":"{\"ad_id\":1437272,\"ad_zone_id\":236,\"category\":\"1\",\"timestamp\":1625040600,\"creative_id\":1486153}"},"adjson":"{\"ads\":[{\"id\":1437272,\"ad_zone_id\":236,\"template\":\"web_word\",\"impression_tracks\":[\"https:\u002F\u002Fsugar.zhihu.com\u002Fplutus_adreaper?idi=11003\\u0026tu=https%3A%2F%2Fwww.beaconedu.com%2Flpv1%2Fiit-0826%3Fcb%3D__CALLBACK__\\u0026pf=4\\u0026au=43864\\u0026pdi=1550736547726776\\u0026ar=0.00045370020167953177\\u0026nt=0\\u0026ut=80d5a113a65e43b2a8faa3a2c5308e81\\u0026ed=CjEEeB4wM31_RzNSV2gqVUYmDiwNbm55fB1_X1dpeR0NcQspASZpI3pGNlMXMTYNWXYPbFkqPn1_EWFQA2d-FhssBHwMc2x0dwMxDgxheAhddAx5HiAufXwDMQgMYXsFRXAKegpwb3J2FGVRAGZ6Fgk1BHsAdXwsOxhiQUQ5cQFZdxd4CnZ0dX8LY14IdjhDVnQPeA1zbnB4EWtBUCdxAISQy4TFActm\"],\"view_tracks\":[\"https:\u002F\u002Fsugar.zhihu.com\u002Fplutus_adreaper?ed=CjEEeR4wM31_RzNSV2gqVUYmDiwNbm55fB1_X1dpeR0NcQspASZpI3pGNlMXMTYNWXYPbFkqPn1_EWFQA2d-FhssBHwMc2x0dwMxDgxheAhddAx5HiAufXwDMQgMYXsFRXAKegpwb3J2FGVRAGZ6Fgk1BHsAdXwsOxhiQUQ5cQFZdxd4CnZ0dX8LY14IdjhDVnQPeA1zbnB4EWtBUCdxAGBTH44T0Y7r\\u0026tu=https%3A%2F%2Fwww.beaconedu.com%2Flpv1%2Fiit-0826%3Fcb%3D__CALLBACK__\\u0026ut=80d5a113a65e43b2a8faa3a2c5308e81\\u0026idi=11003\\u0026nt=0\\u0026pdi=1550736547726776\\u0026au=43864\\u0026pf=4\\u0026ar=0.00045370020167953177\"],\"click_tracks\":[\"https:\u002F\u002Fsugar.zhihu.com\u002Fplutus_adreaper?tu=https%3A%2F%2Fwww.beaconedu.com%2Flpv1%2Fiit-0826%3Fcb%3D__CALLBACK__\\u0026pdi=1550736547726776\\u0026nt=0\\u0026idi=11003\\u0026ar=0.00045370020167953177\\u0026au=43864\\u0026ut=80d5a113a65e43b2a8faa3a2c5308e81\\u0026ed=CjEEfh4wM31_RzNSV2gqVUYmDiwNbm55fB1_X1dpeR0NcQspASZpI3pGNlMXMTYNWXYPbFkqPn1_EWFQA2d-FhssBHwMc2x0dwMxDgxheAhddAx5HiAufXwDMQgMYXsFRXAKegpwb3J2FGVRAGZ6Fgk1BHsAdXwsOxhiQUQ5cQFZdxd4CnZ0dX8LY14IdjhDVnQPeA1zbnB4EWtBUCdxAILwilXIjuSj\\u0026pf=4\"],\"close_tracks\":[\"https:\u002F\u002Fsugar.zhihu.com\u002Fplutus_adreaper?pdi=1550736547726776\\u0026tu=https%3A%2F%2Fwww.beaconedu.com%2Flpv1%2Fiit-0826%3Fcb%3D__CALLBACK__\\u0026pf=4\\u0026ar=0.00045370020167953177\\u0026ed=CjEEfR4wM31_RzNSV2gqVUYmDiwNbm55fB1_X1dpeR0NcQspASZpI3pGNlMXMTYNWXYPbFkqPn1_EWFQA2d-FhssBHwMc2x0dwMxDgxheAhddAx5HiAufXwDMQgMYXsFRXAKegpwb3J2FGVRAGZ6Fgk1BHsAdXwsOxhiQUQ5cQFZdxd4CnZ0dX8LY14IdjhDVnQPeA1zbnB4EWtBUCdxAN72MeS2-lO5\\u0026au=43864\\u0026nt=0\\u0026idi=11003\\u0026ut=80d5a113a65e43b2a8faa3a2c5308e81\"],\"debug_tracks\":[\"https:\u002F\u002Fsugar.zhihu.com\u002Fplutus_adreaper?pf=4\\u0026ut=80d5a113a65e43b2a8faa3a2c5308e81\\u0026au=43864\\u0026tu=https%3A%2F%2Fwww.beaconedu.com%2Flpv1%2Fiit-0826%3Fcb%3D__CALLBACK__\\u0026idi=11003\\u0026ar=0.00045370020167953177\\u0026ed=CjEEcx4wM31_RzNSV2gqVUYmDiwNbm55fB1_X1dpeR0NcQspASZpI3pGNlMXMTYNWXYPbFkqPn1_EWFQA2d-FhssBHwMc2x0dwMxDgxheAhddAx5HiAufXwDMQgMYXsFRXAKegpwb3J2FGVRAGZ6Fgk1BHsAdXwsOxhiQUQ5cQFZdxd4CnZ0dX8LY14IdjhDVnQPeA1zbnB4EWtBUCdxAPZZedHNEHWe\\u0026pdi=1550736547726776\\u0026nt=0\"],\"conversion_tracks\":[\"https:\u002F\u002Fsugar.zhihu.com\u002Fplutus_adreaper?ed=CjEEfx4wM31_RzNSV2gqVUYmDiwNbm55fB1_X1dpeR0NcQspASZpI3pGNlMXMTYNWXYPbFkqPn1_EWFQA2d-FhssBHwMc2x0dwMxDgxheAhddAx5HiAufXwDMQgMYXsFRXAKegpwb3J2FGVRAGZ6Fgk1BHsAdXwsOxhiQUQ5cQFZdxd4CnZ0dX8LY14IdjhDVnQPeA1zbnB4EWtBUCdxADCCjchZ8l9C\\u0026ar=0.00045370020167953177\\u0026pf=4\\u0026tu=https%3A%2F%2Fwww.beaconedu.com%2Flpv1%2Fiit-0826%3Fcb%3D__CALLBACK__\\u0026ut=80d5a113a65e43b2a8faa3a2c5308e81\\u0026au=43864\\u0026nt=0\\u0026idi=11003\\u0026pdi=1550736547726776\"],\"extra_conversion_tracks\":{\"call_back\":[\"https:\u002F\u002Fsugar.zhihu.com\u002Fplutus_adreaper_callback?si=1ba5f8fe-c7f5-4928-8f95-f42c9e3c4cd4\\u0026os=3\\u0026zid=236\\u0026zaid=1437272\\u0026zcid=1486153\\u0026cid=1486152\\u0026event=__EVENTTYPE__\\u0026value=__EVENTVALUE__\\u0026ts=__TIMESTAMP__\\u0026cts=__TS__\\u0026mh=__MEMBERHASHID__\"]},\"za_ad_info\":\"CNjcVxDsASIBMV1OuMFOYMnaWg==\",\"za_ad_info_json\":\"{\\\"ad_id\\\":1437272,\\\"ad_zone_id\\\":236,\\\"category\\\":\\\"1\\\",\\\"timestamp\\\":1625040600,\\\"creative_id\\\":1486153}\",\"creatives\":[{\"id\":1486153,\"asset\":{\"brand_name\":\"彼岸教育\",\"brand_logo\":\"https:\u002F\u002Fpic1.zhimg.com\u002Fv2-742b70686c0a04f6d77a011904d9d704_250x250.jpeg\",\"title\":\"海外名校来华招生!想读在职名校硕士的小伙伴不要错过!\",\"desc\":\"伊利诺伊理工大学来华招生,免联考,在职可读,课程教授与本校同步,毕业拿全日制硕士证书,点击测试是否符合报考条件\",\"landing_url\":\"https:\u002F\u002Fwww.beaconedu.com\u002Flpv1\u002Fiit-0826?cb=https%3A%2F%2Fsugar.zhihu.com%2Fplutus_adreaper_callback%3Fsi%3D1ba5f8fe-c7f5-4928-8f95-f42c9e3c4cd4%26os%3D3%26zid%3D236%26zaid%3D1437272%26zcid%3D1486153%26cid%3D1486152%26event%3D__EVENTTYPE__%26value%3D__EVENTVALUE__%26ts%3D__TIMESTAMP__%26cts%3D__TS__%26mh%3D__MEMBERHASHID__\",\"img_size\":0,\"cta\":\"查看详情\",\"native_asset\":{}}}],\"expand\":{\"display_advertising_tag\":true,\"download_silent\":false,\"is_new_webview\":true,\"is_cdn_speeding\":false,\"is_apk_market_direct\":false,\"interactive\":{\"deliver_time\":\"25 分钟前\",\"browse_string\":\"8 万\",\"participate_string\":\"177 \",\"slide_time_one\":3,\"slide_time_two\":10,\"slide_end\":true,\"deep_link_jump_time\":10}},\"experiment_info\":\"{}\",\"view_x_tracks\":[\"https:\u002F\u002Fsugar.zhihu.com\u002Fplutus_adreaper?pf=4\\u0026idi=11003\\u0026pdi=1550736547726776\\u0026ar=0.00045370020167953177\\u0026au=43864\\u0026nt=0\\u0026ut=80d5a113a65e43b2a8faa3a2c5308e81\\u0026ed=CjEEewhlKSlzFDAGBDZ0Vg5oWn1ednd0dxdqSgk2dQVGIw14W3o_cy0RMQMFdi1KVncKfB4iMyRzFGZUBmJ7Ak01UHcOd2p2ehx0BFhtfQRTcwh_C2U5NHMXdARebX0HXmsMeQhxaXV8HWNQB2F6Bk0nSXcJe2xmIlBvVxclJQ1adwtkCnFvbnsUfFYIaWpEGHgIfAp2anR-E2ZeFzE7DVsI072F2FUWKQ%3D%3D\\u0026tu=https%3A%2F%2Fwww.beaconedu.com%2Flpv1%2Fiit-0826%3Fcb%3D__CALLBACK__\"],\"mobile_experiment\":{\"ad_backPlugin\":\"0\",\"ad_bannerShow\":\"0\",\"ad_bannerView\":\"0\",\"ad_comm_70\":\"0\",\"ad_dep_mac\":\"0\",\"ad_ht\":\"0\",\"ad_markPlugin\":\"0\",\"ad_new_rt\":\"0\",\"ad_pausePlugin\":\"0\",\"ad_pause_dialog\":\"0\",\"ad_pre_web\":\"0\",\"ad_ps_ab\":\"0\",\"ad_resume_ab\":\"0\",\"ad_room_delete\":\"0\",\"ad_sdk_skip\":\"0\",\"ad_wake_lock\":\"0\",\"adx_verify\":\"0\",\"andr_pre_web\":\"0\",\"back_plugin\":\"0\",\"canvas_mp2wc\":\"0\",\"dd_send\":\"0\",\"diamond_city_rb\":\"0\",\"dsp_replace\":\"0\",\"feed_adv_new\":\"0\",\"feed_advance\":\"0\",\"ins_add_click\":\"0\",\"launch_ad_end\":\"0\",\"mark_plugin\":\"0\",\"notify_new\":\"0\",\"notify_page\":\"0\",\"outside_banner\":\"0\",\"pause_plugin\":\"0\"}}]}"}},"advancedStyle":{},"commonAnswerCount":0,"hiddenAnswerCount":0,"meta":{},"bluestarRanklist":{},"relatedSearch":{},"autoInvitation":{},"simpleConcernedFollowers":{},"draftStatus":{},"disclaimers":{},"isShowMobileSignInModal":false},"shareTexts":{},"answers":{"voters":{},"copyrightApplicants":{},"favlists":{},"newAnswer":{},"concernedUpvoters":{},"simpleConcernedUpvoters":{},"paidContent":{},"settings":{}},"banner":{},"topic":{"bios":{},"hot":{},"newest":{},"top":{},"unanswered":{},"questions":{},"followers":{},"contributors":{},"parent":{},"children":{},"bestAnswerers":{},"wikiMeta":{},"index":{},"intro":{},"meta":{},"schema":{},"creatorWall":{},"wikiEditInfo":{},"committedWiki":{},"landingBasicData":{},"landingExcellentItems":[],"landingExcellentEditors":[],"landingCatalog":[],"landingEntries":{}},"explore":{"recommendations":{},"specials":{"entities":{},"order":[]},"roundtables":{"entities":{},"order":[]},"collections":{},"columns":{}},"articles":{"voters":{},"concernedUpvoters":{}},"favlists":{"relations":{}},"pins":{"reviewing":{}},"topstory":{"recommend":{"isFetching":false,"isDrained":false,"afterId":0,"items":[],"next":null},"follow":{"isFetching":false,"isDrained":false,"afterId":0,"items":[],"next":null},"room":{"meta":{},"isFetching":false,"afterId":0,"items":[],"next":null},"followWonderful":{"isFetching":false,"isDrained":false,"afterId":0,"items":[],"next":null},"sidebar":null,"announcement":{},"hotListCategories":[],"hotList":[],"guestFeeds":{"isFetching":false,"isDrained":false,"afterId":0,"items":[],"next":null},"followExtra":{"isNewUser":null,"isFetched":false,"followCount":0,"followers":[]},"hotDaily":{"data":[],"paging":{}},"hotHighlight":{"isFetching":false,"isDrained":false,"data":[],"paging":{}},"banner":{}},"upload":{},"video":{"data":{},"shareVideoDetail":{},"last":{}},"zvideos":{"campaigns":{},"tagoreCategory":[],"recommendations":{},"insertable":{},"recruit":{"form":{"platform":"","nickname":"","followerCount":"","domain":"","contact":""},"submited":false,"ranking":[]},"club":{},"qyActivityData":{},"talkActivityData":{},"batchVideos":{},"contribution":{"selectedContribution":null,"configs":{},"contributionLists":{},"recommendQuestions":{"isLoading":true,"paging":{"isEnd":false,"isStart":true,"totals":0},"data":[]},"questionSearchResults":{"isLoading":true,"paging":{"isEnd":false,"isStart":true,"totals":0},"data":[]}},"creationReferences":{}},"guide":{"guide":{"isFetching":false,"isShowGuide":false}},"reward":{"answer":{},"article":{},"question":{}},"search":{"recommendSearch":[],"topSearch":{},"searchValue":{},"suggestSearch":{},"attachedInfo":{},"nextOffset":{},"topicReview":{},"calendar":{},"scores":null,"majors":{},"university":{},"generalByQuery":{},"generalByQueryInADay":{},"generalByQueryInAWeek":{},"generalByQueryInThreeMonths":{},"peopleByQuery":{},"clubentityByQuery":{},"clubPostByQuery":{},"topicByQuery":{},"zvideoByQuery":{},"columnByQuery":{},"liveByQuery":{},"albumByQuery":{},"eBookByQuery":{},"kmGeneralByQuery":{}},"publicEditPermission":{},"vessay":{"common":{"draftId":null,"source":{"type":null,"id":null},"autoSave":true,"blockUnload":true,"isCalibratingEditing":false,"editingTrackData":{"editingOutlines":[],"editingVideos":[]},"newAddMaterialData":{},"audioCache":{},"showTimbreRecordPanel":false},"loading":{"isLoading":false,"text":"正在加载中"},"player":{"currentTime":0,"totalTime":0,"playing":false},"library":{"material":{},"materialSearchResult":{},"music":{},"musicLibraryCategories":[],"musicUrls":{}},"track":{"trackData":{"dataVersion":1,"videoTrack":[],"audioTrack":[],"musicTrack":[],"voiceOverData":{}},"previewEditingTrackData":{"editingSubtitleItem":{},"editingVideoItem":{}},"selectedTrackItems":[],"outlineRemoveMaterial":{},"outlineAppliedStyle":{},"timbres":[],"timbreId":"","timbreTests":[],"newRecordBlob":{},"exportErrorUrls":[]}},"readStatus":{},"draftHistory":{"history":{},"drafts":{}},"notifications":{"recent":{"isFetching":false,"isDrained":false,"isPrevDrained":false,"result":[],"next":null,"key":null},"history":{"isFetching":false,"isDrained":false,"isPrevDrained":false,"result":[],"next":null,"key":null},"notificationActors":{"isFetching":false,"isDrained":false,"isPrevDrained":false,"result":[],"next":null,"key":null},"recentNotificationEntry":"all"},"specials":{"entities":{},"all":{"data":[],"paging":{},"isLoading":false}},"collections":{"hot":{"data":[],"paging":{},"isLoading":false},"collectionFeeds":{}},"userProfit":{"permission":{"permissionStatus":{"zhiZixuan":0,"recommend":-1,"task":0,"plugin":0,"infinity":0},"visible":false}},"mcn":{"bindInfo":{},"memberCategoryList":[],"producerList":[],"categoryList":[],"lists":{},"banners":{},"protocolStatus":{"isAgreedNew":true,"isAgreedOld":true},"probationCountdownDays":0},"mcnActivity":{"household":{"products":{},"rankList":{"total":{},"yesterday":{}}}},"brand":{"contentPlugin":{}},"host":{"roundtable":{"subjects":{},"applications":{"total":0},"online":{"total":0},"applies":{},"details":{},"includedResource":{},"hotQuestions":{},"warmupContents":{},"batchInclude":{}},"special":{"applications":{"total":0,"pages":{},"entities":{}},"censorHistory":{},"drafts":{}}},"campaign":{"single":{},"list":{},"videoMakerAcq":{},"vote":{},"cardCollecting":{"message":null,"profile":{"balance":"0","chance":0,"coinNum":0,"gatherClose":false,"isGotMagicCard":false,"isPay":false,"partitionStart":false,"totalDone":0,"withdrawStart":false},"sharePoster":{"share":"","sendCard":"","invite":""},"shareLink":null,"shareIntention":"share","shareKey":null,"shareCardId":null,"inviterInfo":null,"giverInfo":null,"prize":null,"receivedCard":null,"newCoinCount":null,"newCardList":[],"newUserCardCount":1,"taskList":[],"prizeList":null,"cardList":null,"panel":{"showTaskPanel":false,"showRewardPanel":false},"modal":{"showWelcomeModal":false,"showFusionModal":false,"showFusionPromptModal":false,"showShareModal":false,"showBackModal":false}},"zhiboPandian2020":null,"boarding":{},"searchGaokaoSubPage":{},"searchHealth":{},"superBrain":{"info":{"national_rank_list":[],"child_rank_list":[],"user_info":{"wisdomScore":0}},"rank":{"items":[],"isLoading":false,"isDrained":false},"search":[]}},"knowledgePlan":{"lists":{},"allCreationRankList":{},"featuredQuestions":{}},"wallE":{"protectHistory":{"total":0,"pages":{},"entities":{}}},"roundtables":{"hotQuestions":{},"warmupContents":{},"hotDiscussions":{},"selectedContents":{},"roundtables":{}},"helpCenter":{"entities":{"question":{},"category":{}},"categories":[],"commonQuestions":[],"relatedQuestions":{}},"republish":{},"commercialReport":{"commercialTypes":[]},"creatorMCN":{"mcn":{},"mcnStatistics":{},"isNoAuth":false,"creatorManageData":[],"creatorManageDataTotal":1,"mcnDomains":[]},"commentManage":{"commentList":{"ids":[],"entities":{},"nextOffset":0,"urlToken":""},"subCommentList":{"ids":[],"entities":{},"paging":{"next":"","isEnd":false}}},"zhiPlus":{"permissionStatus":9999},"streaming":{}},"subAppName":"main"}</script><script crossorigin="" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/vendor.js"></script><script crossorigin="" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/main_005.js"></script><script crossorigin="" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/main_006.js"></script><script src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/hm.js" async=""></script><script crossorigin="" src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/zap.js"></script><script src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/push.js"></script><div><div style="display: none;">想来知乎工作?请发送邮件到 jobs@zhihu.com</div></div><div><div><div class="css-8pdeid"></div></div></div><script src="Online%20Judge%20%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E5%88%A4%E9%A2%98%E7%AB%AF%E5%AE%89%E5%85%A8%E6%80%A7%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E_files/cm.js" defer="defer" id="baidu-ad-js"></script></body></html>