n0js case1 writeup

跟着蘑菇老师学前端安全第一弹[二哈]

地址:

http://server.n0tr00t.com/n0js/case1.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
function test(a1, a2, a3) {
console.log(`${a1}`);
eval(`${a2}`);
console.warn(`${a3}`)
};
var x = location.hash;
l1 = escape(x.split('#')[1]);
l2 = x.split('#')[2];
l3 = x.split('#')[3];
if (l1 === 'undefined' || l1.length >= 30) {
a1
};
if (l2 === 'undefined' || l2.length >= 35) {
a2
};
var v = ['1', l2, '3'];
if (l1.indexOf(';') >= 0 || l2.indexOf('(') >= 0) {
a3
};
if (l2.indexOf('/') >= 0) {
b1
};
if (l3.indexOf(']') >= 0 || l3.length >= 2) {
c3
}; {
d = l1 + 'v' + l3.trim();
eval('test(' + d + ')')
};

记一下PythonWeb代码审计应该注意的地方

《Code Review For Python-Based Web Apps》(《PythonWebApp代码审计》)做的笔记,正好自己也在写相关的文章:讨论PythonWeb开发中可能会遇到的安全问题,所以就翻译了一下作者原文,省去一些不必要的口水,并添加了一些自己的想法。

SQL注入

安全的做法:

1
2
stmt = "SELECT * FROM table WHERE id=?"
connection.execute(stmt, (value,))

不安全的做法:

1
2
3
"SELECT * FROM table WHERE id=" + value
"SELECT * FROM table WHERE id=%s" % value
"SELECT * FROM table WHERE id={0}".format(value)

大部分Python操作数据库的第三方模块,如pymysql、sqlite3等,执行sql语句的函数,都支持参数化查询,如上安全的做法所示,可以给sql语句传递参数,这个参数经过过滤。而下面的字符串拼接是不经过过滤。所以会出现sql注入。

使用PyQt4.QtWebKit降低自动化XSS检测的误报

一直以来的一个想法,现在有新的思路的就写出来看看。

自动化Web漏洞扫描器是渗透测试亘古不变的话题。把当前一直重复的手工劳动和新的思路转化为自动化工具,利用技术和程序实现为自己节省时间是一件非常有趣的事情。然而,自动化的路坑却不少。其中误报就是一件比较蛋疼的事情,XSS的误报尤其蛋疼。当前众多扫描器的XSS插件都存在误报的情况,我们来看一下大部分扫描器的XSS检测思路,我写了一个简单的Python函数来描述它,当然实际的通用XSS检测插件肯定会比这个要复杂的多,我只截取了一部分来说明思路:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import requests
headers={}

def xss_detect(method='GET', querylist=[], url=''):
params = {}
resp = None
# 这里有更多的payload,如onfocus=alert(2333)
payload = '-->\'"><script>alert(1);</script>'
if method == 'GET':
for query in querylist:
# url = '{url}?{query}={payload}'.format(url=url,query=query,payload=payload)
params[query] = payload
resp = requests.get(url, params=params, headers=headers)
# 此处省略POST
if resp:
# 这里有更多的正则匹配规则
if '<script>alert(1);</script>' in resp.content:
return True
else:
return False

讨论PythonWeb开发中可能会遇到的安全问题之SQL注入

前言

好久没写文章了,最近一直都是在看文章。
近期写了好几个PythonWeb项目,在实现需求的过程中,一直在思考PythonWeb开发过程中会遇到哪些常见的Web安全问题呢?这些问题又在什么情况下会被利用者GetShell呢?下面就分类来讨论这些问题:(这也是重新启用博客的第一篇文章,顺便投给90Sec也不知道能不能过QAQ。)

常见漏洞分析

SQLI

SQL注入所产生的条件是用户输入可构造sql语句并带入数据库执行。在Web应用中,容易产生SQL注入的输入一般是GET或POST请求参数。在PythonWeb开发中,以Flask框架为例,Flask里获取GET或POST请求数据的方式分别是request.args.get('id', 0, type=int)request.form.get('id', 0, type=int)两种方式,另外Flask还支持在URL路由里带入变量:@app.route('/news/<int:id>'),当程序员定义了这样的URL,则id这个变量在该视图里就是可以调用的。两种方法获取都是可以限定参数的类型,前者如果程序指定type为int,当用户传入无法转换成整形的字符串时,就返回None(若指定了默认值则为默认值,例子的默认值为0),后者出现这种情况则直接返回404.

PythonWeb开发中,在处理数据库的过程中经常使用orm库进行数据库处理,orm库是防SQL注入的好手。Flask和Tornado经常使用Sqlalchemy,而Django有自己自带的orm引擎。举一个用Sqlalchemy建模型类,并使用模型类查询用户数据的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from datetime import datetime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, DateTime

engine = create_engine('mysql+pymysql://user:[email protected]/test')
DBSession = sessionmaker(bind=engine)
session = DBSession()
Base = declarative_base()

class user_t(Base):
__tablename__ = 'user_t'
user_id = Column(Integer, primary_key=True)
username = Column(String)
userpassword = Column(String)
createtime = Column(DateTime, default=datetime.utcnow)