day2
sql注入原理
注入攻击的本质,是把用户的输入数据当作代码执行。它的发生有两个前提条件:1.用户可以控制输入 2.原本会执行的程序代码与输入数据相拼接,sql注入即是输入数据与程序的sql代码相结合产生的。
如一段sql语句:" select * from table where column = ' " + $variable$ + " ' "
这里的$variable$变量的值是通过我们的输入得到的,若我们输入str' and select * from table#,则其完整语句就会变为" select * from table where column = 'str' and select * from table#' ”,这样就执行了我们自己构造的sql语句。
字符型注入:还是上方那段sql语句,若我们输入的是 1' or '1' = '1,则最终结果为" select * from table where column = '1' or '1' = '1' ",就会返回表的所有信息,这时的列名为字符串类型,需要用单引号引起来。
数字型注入:若我们将sql语句改为" select * from table where column = " + $variable$,这时我们输入1 or 1 = 1即可达到同样的效果,因为此时列为数字类型,不需要引号。
回显错误是我们检测是否有注入点的一种方式,我们通过错误的输入来获取系统的报错信息,这些信息中往往存在一些敏感信息,如数据库版本号,数据库类型等,常使用单引号来检测。
floor回显报错:使用group by与count(*)以及floor(rand(0)*2)组合的方式使系统报错。如一串sql语句:select count(*), floor(rand(0)*2) as x from table group by x,当该语句执行成功时,就会引发报错,流程如下:
floor(rand(0)*2)会依次产生一串固定的序列011011···,当执行group by x语句时,会判断是否有相同的x存在,使得x列不会出现相同的值,count(*)建立一个虚表,当产生一个新的x时插入计数为1,已有的话则计数加1。第一次x为0,判断x不存在,执行插入,但插入时会再次取floor(rand(0)*2)的值,此时变为了1,所以插入的值为1,计数为1。第二次进行判断时x为1( floor(rand(0)*2)执行的第三次 ),已存在,计数变为2。同理第三次进行判断时x为0,执行插入,这时再次取floor(rand(0)*2)的值为1( 第5次),插入1,但1已经存在于x列中,由于执行了group by x操作,所以x是不能存在相同的两行的,于是产生了报错。产生这种报错时,会返回具体是什么值重复了,我们可以通过一些函数返回的固定信息与x拼接起来达到返回敏感信息的效果。如这样的sql语句:select count(*), concat(version, floor(rand(0)*2)) as x from table group by x,concat函数会直接连接两个参数为字符串作为结果,而version()返回的是数据库的版本,为固定信息,也会产生报错的效果,此时我们就得到了版本信息。
information_schema是mysql数据库中固定存在的一个数据库。其中的information_schema.tables表保存了元数据信息,它的实质为一个视图,是只读的。有以下属性:
- table_schema: 记录数据库名;
- table_name: 记录数据表名;
- engine : 存储引擎;
- table_rows: 关于表的粗略行估计;
- data_length : 记录表的大小(单位字节);
- index_length : 记录表的索引的大小;
- row_format: 可以查看数据表是否压缩过
可见前两个属性对我们获取数据库信息十分有帮助,甚至是决定性的关键 。
Win32 SDK
我们通常将程序在客户区显示图像或文字的过程称为绘制。
WM_PAINT消息会通知窗口过程绘制或重绘客户区。它是一种非队列消息,窗口过程往往会频繁的收到该消息来绘制窗口。在消息循环前的UpdateWindow函数便传递了该消息,其他情况例如移动窗口,调整窗口大小,滚动窗口等都会向窗口过程传递该消息。绘制窗口的客户区需要调用GDI(图形设备接口)函数,DrawText和TextOut函数就属于这类函数。当我们调用该类函数时,需要一个HDC(设备环境)类型的句柄作为参数,DC的实质是GDI内部维护的一个数据结构,它通常与特定的显示设备相关联;视频显示时,它会与某个特定窗口相关联;DC中保存了使GDI函数工作的细节字段。绘制完成后,必须释放HDC,且其不能在两个消息过程间传递。
WM_PAINT消息的处理过程中,通常会调用BeginPaint和EndPaint函数,BeginPaint函数接受一个窗口句柄和PAINTSTRUCT结构指针,BeginPaint函数会填充PAINTSTRUCT结构,然后创建并返回一个HDC,而EndPaint便是释放该HDC。
PAINTSTRUCT结构是Windows维护的一个绘制信息结构,它的定义如下:
1 typedef struct{ 2 HDC hdc; 3 BOOL fErase; 4 RECT rcPaint; 5 BOOL fRestore; 6 BOOL fIncUpdate; 7 BYTE rgbReserved[32]; 8 } PAINTSTRUCT;
该结构前三个字段可供程序使用,其余由Windows内部使用。hdc就是设备环境句柄,BeginPaint返回的也是该值。fErase表示BeginPaint是否已经擦除无效区域的背景,false表确定。rcPaint表示一个被剪裁的一个无效矩形,窗口的绘制也会局限在该无效矩形中。除了BeginPaint函数外,我们还可以通过GetDC函数来获取HDC,它接受一个窗口句柄作为参数,这个设备环境裁剪的无效矩形是整个客户区,HDC使用完成后,需用ReleaseDC函数来释放。
明日:文本输出,滚动条。C++动态内存。