python3-pyppeteer实现批量网页截图

上一版结合pychrome模块截图,实验发现各种问题,就有了这篇文

代码

pip install pyppeteer

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
import asyncio
from pyppeteer import launch
import time
import sys
import xmltodict
from urllib.parse import urlparse
# 从文本文档读取域名列表
def read_txt(txt_file):
with open(txt_file,encoding='utf-8') as fp:
urls = []
lines = (line.strip() for line in fp)
for url in lines:
urls.append(url)
return urls
#从nmap的xml文件读取ip与端口
def nmap_xml(xml_file):
with open(xml_file,encoding='utf-8') as fp:
xml_url = []
xml_obj = xmltodict.parse(fp.read())
host = xml_obj['nmaprun']['host']
for entry in host:
port = str(entry['ports']['port']['@portid'])
if port:
addr = entry['address']['@addr']
url = addr + ':' + port
xml_url.append(url)
return xml_url
async def HCS():
num = 0
start = time.time()
browser = await launch(headless=True)
page = await browser.newPage()
if sys.argv[1] == '-txt' or sys.argv[1] == '-TXT':
url_list = [ x for x in read_txt(sys.argv[2])]
elif sys.argv[1] == '-xml' or sys.argv[1] == '-XML':
url_list = [x for x in nmap_xml(sys.argv[2])]
for url in url_list:
if '://' not in url:
if ':443' in url:
url = 'https://' + url
else:
url = 'http://' + url
print('[+]Getting a domain name:'+ url)
try:
await page.goto(url)
await page.waitFor(1000)
domain_title = await page.evaluate('''() => {
return {
title:document.querySelector('title').innerText,
}
}''')
url_title = (domain_title['title'][:4]).strip()
url_domain = urlparse(url).netloc
Screenshots = 'image/'+ url_domain + '_' + url_title + '.png'
await page.screenshot({'path': Screenshots})
num += 1
print(num)
print(url)
print(url_title)
except Exception as e:
print (e)
end = time.time()
print ("共截图:"+str(num)+"张")
print ("用时:"+ str(int(end-start))+"秒")
await browser.close()
if __name__ == '__main__':
info = '''
info:
Use python3 Headless_Chrome_Screenshot.py -txt domain.txt --> The text containing the url
Use python3 Headless_Chrome_Screenshot.py -xml domain_nmap.xml --> Xml format nmap scan file
'''
if len(sys.argv) != 3:
print (info)
else:
asyncio.get_event_loop().run_until_complete(HCS())

结果

this is screenshot


namp端口监控导入mysql【单文件版】

很早以前写的代码,写出来以备忘

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
<?php
$mysql_server_name='localhost';
$mysql_username='';
$mysql_password='';
$mysql_database='';
$link = mysqli_connect($mysql_server_name,$mysql_username,$mysql_password,$mysql_database);
mysqli_set_charset ($link,'utf8');
if(!$link) {
printf("Can't connect to MySQL Server. Errorcode: %s ", mysqli_connect_error());
exit;
}
function CheckEmptyString($C_char){
if (!is_string($C_char)) return false;
if (empty($C_char)) return false;
if ($C_char=='') return false;
return true;
}
$xml = simplexml_load_file("nmap.xml");
foreach ($xml as $host => $value) {
if((string)$host == "host"){
$addr = (string) $value->address["addr"];
echo $addr;
$str1='';
foreach ($value->ports->port as $port){
if (CheckEmptyString($port) == false){
$ports = $port["portid"].",";
$str1 = $str1.$ports;
}
}
$str2 = trim($str1,',');
$sql = "insert into port (ip,port,date) VALUES ('$addr','$str2',now())";
mysqli_query($link,$sql);
}
}
echo "\r\nend!!";
?>


利用burp拦截指定domain的request

参考Burp Proxy Options

注意呢

拦截规则,意思就是要保证intercept is on的状态

例子呢

这里以墨迹天气为例
添加request及response规则,注意规则顺序,匹配规则是从上至下依次匹配的
this is screenshot

效果呢

就是只有www.moji.com的请求及返回会被拦截,其他域名请求,虽会被代理但不会拦截。

适用环境呢

汗!谁知道呢,说不定某天就用上了呢


再一次认识列表推导式

列表推导式

第一次觉得列表推导式这么好用
今天写代码时遇到一个这种情况

1
2
3
4
5
6
if sys.argv[1] == '***' or sys.argv[1] == '***':
for x in read_txt(sys.argv[2])
..........................................
elif sys.argv[1] == '###' or sys.argv[1] == '###':
for x in nmap_xml(sys.argv[2])
..........................................

其实省略号的部分都是对x的操作,但是呢,x是从文本或者xml读取来的
我只是想先判断他来自于哪,是txt还是xml,然后对获取的x进行相关操作就行了
笨方法就是像上面那样每个条件下面都执行一遍
但是,我在想有没有一种可能,把两种情况获取的值,都放在一个列表里,比如url_list

1
2
3
4
5
if sys.argv[1] == '***' or sys.argv[1] == '***':
url_list = [x for x in read_txt(sys.argv[2])]
elif sys.argv[1] == '###' or sys.argv[1] == '###':
url_list = [x for x in nmap_xml(sys.argv[2])]
..........................................

那么下面的代码只针对于url_list这个列表进行相关操作就行了


python3结合Headless Chrome网页截图

首先启动Headless Chrome

可以使用Docker 来启动

1
docker run -it --rm --name alpine-chrome -p 9222:9222 einverne/alpine-chrome

启动之后可以访问: http://localhost:9222/json 来查看是否启动成功。

安装pychrome模块

1
pip install -U pychrome

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import pychrome
import base64
def screenshot(browser, url, filename):
tab = browser.new_tab()
tab.start()
tab.call_method('Page.navigate', url=url, _timeout=5)
tab.wait(10)
screen_base64 = tab.call_method("Page.captureScreenshot")
image_data = screen_base64.get('data', '')
with open(filename, 'wb') as f:
f.write(base64.b64decode(image_data))
tab.stop()
browser.close_tab(tab)
if __name__ == '__main__':
browser = pychrome.Browser(url="http://127.0.0.1:9222")
screenshot(browser, 'http://baidu.com', 'filename.png')

一键安装hydra

一键安装hydra

参考https://pkgs.org/download/hydra
只需三条命令
Install Howto

Download the latest atomic-release rpm from

http://www6.atomicorp.com/channels/atomic/centos/6/i386/RPMS/

Install atomic-release rpm:

# rpm -Uvh atomic-release*rpm

Install hydra rpm package:

# yum install hydra

Django学习之一

Django学习之一

Python 3.6.4Django 2.0.1

创建项目

1
django-admin startproject 项目名

会创建一个以项目名命名的文件夹,这里假设项目名为mysite,目录结构为

1
2
3
4
5
6
7
8
mysite/ //自定义的项目名
manage.py //命令行工具
//mysite目录下是你导入任何东西时将需要使用的Python包的名字(例如 mysite.urls)
mysite/
__init__.py //一个空文件,它告诉Python这个目录应该被看做一个Python包
settings.py //该Django 项目的设置/配置
urls.py //该Django项目的URL声明;你的Django站点的“目录”
wsgi.py //用于你的项目的与WSGI兼容的Web服务器入口

创建应用

1
python manage.py 应用程序名

会创建一个以应用程序名命名的文件夹,这里假设项目名为myapp,目录结构为

1
2
3
4
5
6
7
8
9
myapp/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py

编写一个视图

  • 打开myapp下的views.py文件,添加以下代码
1
2
3
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world.")

可以看出这是返回的字符串内容,要调用视图,需要将它映射到一个url上

  • myapp目录下创建一个名为urls.py的文件,添加以下代码
1
2
3
4
5
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
  • 将项目mysite的url配置指向应用myapp的url模块

mysite/urls.py中,引入django.urls.include的import, 然后插入一个 include()函数 在 urlpatterns 列表中

1
2
3
4
5
6
from django.urls import include, path
from django.contrib import admin
urlpatterns = [
path('myapp/', include('myapp.urls')),
path('admin/', admin.site.urls),
]

  • 现在已经将一个index视图连接到了URLconf中。 让我们验证它的工作,运行以下命令:
1
python manage.py runserver
  • 注意下path()函数

path()函数传入四个参数,两个是必需的:routeview,以及两个可选的:kwargs ,和name.
route
route是一个包含URL模式的字符串。处理请求时,Django从urlpatterns中的第一个模式开始,并在列表中向下,比较请求的URL和每个模式,直到找到匹配的模式。模式不搜索GET和POST参数或域名。 例如,在对https://www.example.com/myapp/的请求中,URLconf将查找myapp/。https://www.example.com/myapp/?page=3的请求中,URLconf也会查找myapp/。
view
当Django找到匹配的模式时,它会以HttpRequest对象作为第一个参数和路由中的任何“捕获”值作为关键字参数来调用指定的视图函数。
kwargs
任意关键字参数可以在字典中传递给目标视图。
name
命名您的URL可以让您从Django的其他地方明确地引用它,特别是在模板中。 这个强大的功能使您可以对项目的URL模式进行全局更改,而只触摸单个文件。


一次XSS审计学习

一次XSS审计学习

参考http://www.secist.com/archives/5388.html
参考https://html5sec.org/#html

  • 过滤脚本
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
/**
* 去除XSS(跨站脚本攻击)
* @param string $val
* @return string
**/
public function RemoveXSS($val)
{
$val = preg_replace('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/', '', $val);
$search = 'abcdefghijklmnopqrstuvwxyz';
$search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$search .= '1234567890!@#$%^&*()';
$search .= '~`";:?+/={}[]-_|\'\\';
for ($i = 0; $i < strlen($search); $i++)
{
$val = preg_replace('/(&#[xX]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val);
$val = preg_replace('/(&#0{0,8}'.ord($search[$i]).';?)/', $search[$i], $val);
}
$ra1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'base', 'style');
$ra2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
$ra = array_merge($ra1, $ra2);
$found = true;
while ($found == true)
{
$val_before = $val;
for ($i = 0; $i < sizeof($ra); $i++)
{
$pattern = '/';
for ($j = 0; $j < strlen($ra[$i]); $j++)
{
if ($j > 0)
{
$pattern .= '(';
$pattern .= '(&#[xX]0{0,8}([9ab]);)';
$pattern .= '|';
$pattern .= '|(&#0{0,8}([9|10|13]);)';
$pattern .= ')*';
}
$pattern .= $ra[$i][$j];
}
$pattern .= '/i';
$replacement = substr($ra[$i], 0, 2).'<xss>'.substr($ra[$i], 2);
$val = preg_replace($pattern, $replacement, $val);
if ($val_before == $val)
{
$found = false;
}
}
}
return $val;
}

可以看出主要是以黑名单的方式,针对标签与事件做过滤,那么就看看有没有漏网之鱼?
测试环境为:
Sougou-7.5.5.26904Firefox-58.0Google Chrome-63.0
搜索触发

1
<input type="search" onsearch="alert(1)">

sougou \ firefox \ Google Chrome
无需用户交互

1
<details open ontoggle="alert(1)">

sougou \ firefox \ Google Chrome


kali安装搜狗输入法

kali安装搜狗输入法

原来的方式缺少依赖。需用修改后的安装包安装 下载

下载完毕后安装

1
2
3
4
5
dpkg -i sogoupinyin_2.2.0.0102_amd64_edit.deb
apt-get -f install
dpkg -i sogoupinyin_2.2.0.0102_amd64_edit.deb
rm /etc/apt/sources.list.d/sogoupinyin.list
reboot

sqlmap注入json格式数据

sqlmap注入json格式数据

遇到json格式数据存在注入时,sqlmap会无法判断;
可人工修改下注入的json数据,使sqlmap能够识别注入参数;

无法识别的json数据如:

1
{"name":["string"]}

将其修改为

1
{"name":["string*"]}

或者

1
{"name":"string"}