1、举例详细解释什么是Return-orientd Programming ROP?(至少两个例子:x86 和arm)
2、举例描述一个远程缓冲区溢出,思考和本地溢出的区别,攻击难点在哪里?
3、描述arm和x64下的缓冲区溢出,比较和x86的差异。
1、网上搜索和阅读SQL Injection with MySQL这篇文章,描述SQL Injection的原因和危害,注意其中提到的单引号双引号和井号等特殊字符。思考如何才能防止SQL Injection。
2、SQL Injection过程中,需要猜测未知的数据表名和字段名以及密码,描述一下常用的猜测手段。
3、(一定要看)阅读Basic SQL Tutorial。
http://www.w3schools.com/sql/
http://www.w3schools.com/php/
以及
http://www.unixwiz.net/techtips/sql-injection.html
4、(选做,实在搞不定可以网上搜索walkthrough)HTS Realistic 4。先去http://www.hackthissite.org/注册,然后利用SQL Injection完成下面这一关,目的是获得a list of the email addresses。
Fischer’s Animal Products: A company slaughtering animals and turning their skin into overpriced products sold to rich bastards! Help animal rights activists increase political awareness by hacking their mailing list.
From: SaveTheWhales
Message: Hello, I was referred to you by a friend who says you know how to hack into computers and web sites - well I was wondering if you could help me out here. There’s this local store who is killing hundreds of animals a day exclusively for the purpose of selling jackets and purses etc out of their skin! I have been to their website and they have an email list for their customers. I was wondering if you could somehow hack in and send me every email address on that list? I want to send them a message letting them know of the murder they are wearing. Just reply to this message with a list of the email addresses. Please? Their website is at http://www.hackthissite.org/missions/realistic/4/. Thanks so much!!
Homework 7
ROP,即“返回导向编程技术”。是指在整个进程空间内现存的函数中寻找适合指令片断(gadget),并通过精心设计返回堆栈把各个gadget拼接起来,从而达到恶意攻击的目的。可以用来绕过现代操作系统的各种通用防御(比如栈不可执行等)。
ROP可以使所有的恶意攻击都通过现存函数的指令片断串连而成。这种指令片断通过跳转指令(x86上是RET和JMP, ARM上是pc的相关指令)可以相互连接的逻辑片断,称为gadget。ROP攻击最终的体现就是一串gadgets。
X86:
#!c
#include
#include
#include
void vulnerable_function() {
char buf[128];
read(STDIN_FILENO, buf, 256);
}
int main(int argc, char** argv) {
vulnerable_function();
write(STDOUT_FILENO, "Hello, World\n", 13);
}
如上,这是一个有明显缓冲区溢出的程序。如果我们编译时关掉DEP和Stack Protector,再关掉整个linux系统的ASLR保护。那么这个漏洞程序,我们就可以按照之前的缓冲区溢出来做,把shellcode放到栈里。如果我们打开DEP,即栈不可执行,那么我们原始的方法就失效了。这时候我们可以通过ret2libc绕过DEP防护,这个方法的基本原理是让漏洞程序调转到现存的代码(比如已经载入内存的libc库中的system()函数等)来实现我们的攻击。但是如果我们再打开地址随机化, ret2libc方法也失效了,这时候我们可以通过ROP绕过DEP和ASLR防护。
stack,libc,heap的地址都是随机的,但程序本身在内存中的地址并不是随机的。所以我们只要把返回值设置到程序本身就可执行我们期望的指令了。
$ objdump -R level2
//got表
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
08049ff0 R_386_GLOB_DAT __gmon_start__
0804a000 R_386_JUMP_SLOT read
0804a004 R_386_JUMP_SLOT __gmon_start__
0804a008 R_386_JUMP_SLOT __libc_start_main
0804a00c R_386_JUMP_SLOT write
因为system()函数和write()在libc.so中的相对地址是不变的,所以如果我们得到了write()的地址并且拥有libc.so就可以计算出system()在内存中的地址了。再return回上面我们的漏洞函数,就能调用system(),获取shell。
Arm:
首先,由于x86跟ARM的规范不同,其指令格式也不一致。而且其寄存器作用也不相同。其中最重要的,r0 – r3,保存参数的前三个参数,如果存在四个参数,则放入堆栈,这个是ARM跟x86最大的区别。
#include
#include
int bof(FILE *badfile){
char buffer[20];
fread(buffer, sizeof(char), 100, badfile);
return 1;
}
int main(){
FILE *badfile;
badfile = fopen("badfile", "r");
bof(badfile);
printf("Returned Properly\n");
fclose(badfile);
return 0;
}
如上这也是一个缓冲区溢出漏洞程序。
我们需要先寻找libc.so的基地址,再计算出system地址和/system/bin/sh地址。并且,我们需要借助适合的gadget来完成对r0的赋值,如mallinfo指令。我们可以先跳到mallinfo指令的pop r4 pc,即0x16F72处,把“/system/bin/sh”的地址赋值给r4,接着控制pc,跳转至0x16F70,这样就间接把“/system/bin/sh”赋值给r0了。然后再把pc指向system即可。最后再执行即可完成攻击。
拿上一题的漏洞程序而言,我们把这个程序作为一个服务绑定到服务器的某个端口上,如:
socat TCP4-LISTEN:10001,fork EXEC:./level1
随后这个程序的IO就被重定向到10001这个端口上了,可以使用 nc 127.0.0.1 10001来访问我们的目标程序服务了。我们可以使用exp进行远程溢出。
不同于本地溢出,利用网络发动远程攻击时,攻击者无法直接修改被攻击程序,只能通过I/O交互来发送攻击代码,通过缓冲区溢出用近乎暴力的方法改写相邻的内存而直接跳过系统的检查。
远程攻击的难点在于,无论是因程序设计考虑不全的普通溢出,还是精心设计的攻击溢出,都需要发送一个超长的字符串作为输入参数的数据包到缓冲区里造成溢出。
x64与x86的区别:
1、内存地址的范围由32位变成了64位。
2、函数参数的传递方式发生了改变,x86中参数都是保存在栈上,但在x64中的前六个参数依次保存在RDI, RSI, RDX, RCX, R8和 R9中,如果还有更多的参数的话才会保存在栈上。
arm与x86的区别:
1、x86跟ARM的规范不同,其指令格式也不一致。
2、两者寄存器作用不相同。其中最重要的,x86中参数都是保存在栈上,而arm的r0–r3保存参数的前三个参数,如果还有更多的参数的话才会保存在栈上。
sql注入(SQL Injection):就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
原因:1、由不安全的数据库配置或数据库平台的漏洞所致;2、程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。
危害:1、非法读取、篡改、添加、删除数据库中的数据;2、数据库信息泄漏;3、网页篡改;4、网站被挂马;5、服务器被远程控制,被安装后门等。
防范:1、检查变量数据类型和格式;2、过滤特殊符号;3、绑定变量,使用预编译语句等。
1、猜表一般的表的名称无非是admin adminuser user pass password 等。如:and 0<>(select count(*) from admin) ---判断是否存在admin这张表。
2、猜帐号数目 如果遇到0< 返回正确页面, 1<返回错误页面,说明帐号数目就是1个。and 0<(select count(*) from admin)。
3、猜解字段名称 在len( ) 括号里面加上我们想到的字段名称。如:and 1=(select count(*) from admin where len(password)>0)。
4、猜解各个字段的长度 猜解长度就是把>0变换 直到返回正确页面为止。如:and 1=(select count(*) from admin where len(name)>6)。
5、猜解字符。如:and 1=(select count(*) from admin where left(name,1)=a) ---猜解用户帐号的第一位。
http://www.w3schools.com/sql/
http://www.w3schools.com/php/
以及
http://www.unixwiz.net/techtips/sql-injection.html
第一篇文章介绍的是SQL的基本语法和用法,包括数据库的建立和删除;表的建立和删除;表的主码、外部码、视图、索引;对表中数据的选择、插入、删除、排序、最大最小、计数、平均值、求和、更新、连接等等,可以说是很全面地介绍了SQL数据库的基本内容。由于我们已经学过数据库课程,这部分的难度不算太大。
第二篇文章主要介绍的是PHP语言。文章首先介绍了PHP的基本语法、数据类型、输出、字符串、常量、循环、函数、数组等。接着还介绍了PHP表单的基本处理方法和一些更高级的PHP语法。文章还在其中讲解了MySQL数据库,以及其他的和网页相关的知识。因为现在网站的后台大多都是使用PHP写的,所以如果我们要完成SQL注入,有必要了解PHP语言的有关知识。
第三篇文章主要介绍的是一个SQL注入实例。文章先尝试了一些输入,包括普通的输入和编造的输入,如WHERE field =' anything'or'x'='x ';,这个语句就使得原先的字符串的单引号提前结束,后面换上了一个或语句。作者通过这样的方式观察到各种输入三种不同的反应:“您的登录信息已邮寄至电子邮件 ”、“我们无法识别您的电子邮件地址”、“服务器错误”。
接着文章开始猜测一些字段名称,包括电子邮件、passwd文件、登录ID等。当我们直到字段名称后,我们开始猜测这些字段所在的表名。接着寻找一些用户表中的成员,这里可以说是一个猜测过程,凭运气。最后,文章通过更新表的方式,使用"I lost my password"跟新邮件地址,结果顺利收到了电子邮件的密码提示。
网对于输入有两种反应:Error inserting into table "email"! Email not valid! Please contact an administrator of Fischer's以及Email added successfully.
网上并没有找到相应的walkthrough,网站好像是跟新过了。拿着上一题第三篇文章的内容尝试了一下,没有成功。