-
Notifications
You must be signed in to change notification settings - Fork 0
/
Analyze_Pathconfusion.py
1701 lines (1513 loc) · 69.2 KB
/
Analyze_Pathconfusion.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
import json,os,sys,time,subprocess,random,hashlib,re,glob
from os.path import exists
import tldextract
import urllib.parse
from urllib.parse import urlparse
from subprocess import PIPE
###auxiliary function--network dump analysis---------
def find_identifiers(string):
identifiers=[]
start=string.find("code")
end=string.find("state")
if(start == -1):
print("Code not present inspect dump file!!!!!!")
identifiers.append(string[start+5:end-1])
identifiers.append(string[end+6:-4])
identifiers.append(string[:-4])
return identifiers
def FB_find_accessToken_in_content(received):
bcut=received.find("access_token=")
if(bcut== -1):
print("unable to find access_token")
return["-1"]
else:
ecut=received.find("&",bcut)
if(ecut==-1):
print("unable to find end of parameter")
return ["-1"]
else:
token=received[bcut:ecut]
return token
def FB_find_redirectLink_in_content(received):
#try to remove everything before url param and get identifiers from there
bcut=received.find("window.location.href")
ecut=received.find("#_=_")
if(bcut== -1 or ecut== -1):
print("unable to slice redirect url")
return["-1"]
else:
link=received[bcut+22:ecut]
link= link.replace("\\","")
return link
def TW_find_redirectLink_in_content(received):
#try to remove everything before url param and get identifiers from there
bcut=received.find("0;url=")
ecut=received.rfind("<script",bcut)
if(bcut== -1 or ecut== -1):
print("unable to slice redirect url")
return[-1]
else:
link=received[bcut+6:ecut]
look=link.find(">")
link=link[:look-1]
link= link.replace("amp;","")
return link
def Orcid_find_redirectLink_in_content(received):
#try to remove everything before url param and get identifiers from there
bcut=received.find("redirectUrl")
ecut=received.rfind("responseType",bcut)
if(bcut== -1 or ecut== -1):
print("Orcid unable to slice redirect url")
return["-1"]
else:
link=received[bcut+14:ecut-3]
if("code="not in link):
return["-1"]
return link
def Yan_find_redirectLink_in_content(received):
#try to remove everything before url param and get identifiers from there
bcut=received.find("URL='")
ecut=received.rfind("'\">",bcut)
if(bcut== -1 or ecut== -1):
print("unable to slice redirect url")
return[-1]
else:
link=received[bcut+5:ecut]
return link
def findOauthredirect(Networkdump,idp,site,pathconfusion):
print(f'Findoauthredirect received len network log: {len(Networkdump)}\nidp: {idp}\nsite: {site}')
marker=[]
if(idp =="github.com"):
marker=findOauthredirect_gh(Networkdump,idp,site,pathconfusion)
return marker
if(idp=="facebook.com"):
marker=findOauthredirect_fb2(Networkdump,idp,site,pathconfusion)
return marker
if(idp=="atlassian.com"):
marker=findOauthredirect_at(Networkdump,idp,site,pathconfusion)
return marker
if(idp=="linkedin.com"):
marker=findOauthredirect_lk(Networkdump,idp,site,pathconfusion)
return marker
if(idp=="microsoftonline.com"):
marker=findOauthredirect_mic(Networkdump,idp,site,pathconfusion)
return marker
if(idp=="live.com"):
marker=findOauthredirect_mic(Networkdump,idp,site,pathconfusion)
return marker
if(idp=="line.me"):
marker=findOauthredirect_line(Networkdump,idp,site,pathconfusion)
return marker
if(idp=="kakao.com"):
marker=findOauthredirect_kakao(Networkdump,idp,site,pathconfusion)
return marker
if(idp=="twitter.com"):
marker=findOauthredirect_tw(Networkdump,idp,site,pathconfusion)
return marker
if(idp=="yandex.ru"):
marker=findOauthredirect_yan(Networkdump,idp,site,pathconfusion)
return marker
if(idp=="orcid.org"):
marker=findOauthredirect_orcid(Networkdump,idp,site,pathconfusion)
return marker
if(idp=="slack.com"):
marker=findOauthredirect_slack(Networkdump,idp,site,pathconfusion)
return marker
if(idp=="ok.ru"):
marker=findOauthredirect_ok(Networkdump,idp,site,pathconfusion)
return marker
if(idp=="reddit.com"):
marker=findOauthredirect_reddit(Networkdump,idp,site,pathconfusion)
return marker
if(idp=="vk.com"):
marker=findOauthredirect_vk(Networkdump,idp,site,pathconfusion)
return marker
print(f'idp:{idp} NOT SUPPORTED!!')
return ["-1","Eror in exctracting redirect url"]
def FindPathconfusioninRequest(request,pathconfusion):
inrequest=False
inresponse=False
inredirect_uri=False
error=False
accesstoken=False
botblock=False
botmessage=["We limit how often you can post, comment or do other things in a given amount of time in order to help protect the community from spam. You can try again later."]
login_deact=False
logindisabled=["attualmente disponibile per questa app."]
errors=["The+redirect_uri+MUST+match+the+registered+callback+URL","redirect_uri_mismatch","The provided value for the input parameter 'redirect_uri' is not valid. The expected value is a URI which matches a redirect URI registered for this client application.",
"This integration is misconfigured. Contact the vendor for assistance.","Assicurati che l'accesso OAuth client e quello web siano attivi e aggiungi tutti i domini dell'app come URI di reindirizzamento OAuth validi."]
for key in request["request"].keys():
if(key=="url" or key=="Referer"):
print(f'use key={key}request url to analyze: {request["request"]["url"]}')
if("redirect_uri" in str(request["request"][key])):
print(f'url request has redirecrt uri')
#here extract redirect_uri and inspect if pathconfusion in redirect uri
#string find redirect uri and search for & or %3F and cut string
#search for marker in this string and it true very vulnerable!!!!
indices_object = re.finditer(pattern='redirect_uri', string=str(request["request"][key]))
indices = [index.start() for index in indices_object]
if(len(indices)<=1):
cut=""
a=str(request["request"][key]).find("redirect_uri")
b=str(request["request"][key]).find("&",a)
b2=str(request["request"][key]).find('%26',a)
c=str(request["request"][key]).find('%3F',a)
c2=str(request["request"][key]).find("?",a)
#se encoded ma non normale allora encoded
if((b==-1 and b2>0) or (b>0 and b2>0 and b2<b)):
#if the encoded char is present but not normal use encoded position or both but encoded before
b=b2
if((c==-1 and c2>0) or(c>0 and c2>0 and c2<c) ):
#if the encoded char is present but not normal use encoded position or both but encoded before
c=c2
print(f'position parameters:{a},{b},{c}')
if((b>0 and b<c and c>0) or (b>0 and (c==-1))):
cut=str(request["request"][key])[a+13:b]
print(f'cut string with & final:{cut}')
elif((c>0 and c<b and b>0) or(c>0 and (b==-1)) ):
cut=str(request["request"][key])[a+13:c]
print(f'cut string with ? final:{cut}')
elif(b<0 and c<0):
print(f'end of the string no parameters or ?')
cut=str(request["request"][key])[a+13:]
if(pathconfusion in cut):
print(f'cut string in url is this one:{cut}')
print(f'This one is REALLY vulnerable!!!!')
inredirect_uri=True
else:
print(f'cut string in url is this one:{cut}')
print(f'confusion in something else')
else:
print(f'multi redirect uri parameters where to search it?')
else:
print(f'url request does not contains redirecrt uri')
for key in request["request"].keys():
if(pathconfusion in str(request["request"][key])):
#print(f'path confusion in request field {key}:{request["request"][key]}')
inrequest=True
for key in request["response"].keys():
if(pathconfusion in str(request["response"][key])):
#print(f'path confusion in response field {key}:{request["response"][key]}')
inresponse=True
for key in request["response"].keys():
for e in errors:
if(e in str(request["response"][key])):
#print(f'path confusion in response field {key}:{request["response"][key]}')
error=True
print(f'error detected from IDP')
for key in request["response"].keys():
for e in botmessage:
if(e in str(request["response"][key])):
botblock=True
print(f'Bot detection triggered by IDP')
for key in request["response"].keys():
for e in logindisabled:
if(e in str(request["response"][key])):
login_deact=True
print(f'Login deactivated!!!')
for key in request["response"].keys():
if("access_token" in str(request["response"][key])):
accesstoken=True
print(f'access token in response not a usefull oauthflow!!')
print(f'before evaluating the poisoned cases:\ninredirect_uri:{inredirect_uri}\ninrequest:{inrequest}\ninresponse:{inresponse}\nerror:{error}\naccesstoken:{accesstoken}\nBot protection:{botblock}\nlogin deactivated:{login_deact}')
if(inredirect_uri and not inresponse and not error and not accesstoken and not botblock and not login_deact):
print(f'REDIRECT_URI poisoned in final request')
return "redirect uri request only poisoned"
if(inredirect_uri and inresponse and not error and not accesstoken and not botblock and not login_deact):
print(f'REDIRECT_URI and response poisoned')
return "redirect uri and response poisoned"
if(inresponse and not inredirect_uri and not error and not accesstoken and not botblock and not login_deact):
print(f'Response poisoned but not in request redirect_uri!!!')
return "only Response poisoned"
if(inrequest and not inresponse and not error and not accesstoken and not botblock and not login_deact):
print(f'this is an idp melt not in redirect uri of req but in request')
return "idp melt"
if(inrequest and not inresponse and not error and accesstoken and not botblock and not login_deact):
print(f'Access token as response not a usefull oauthflow')
return "not usable oauthflow"
if(not inrequest and not inresponse and not error and not accesstoken and not botblock and not login_deact):
print(f'request sanitized')
return "idp sanitized"
if(inresponse and inrequest and not error and not botblock and not login_deact):
print(f'in response and in request PathConfusion')
return "both poisoned"
if(error and not botblock and not login_deact):
return "idp blocked attack"
if(botblock and not login_deact):
return "Bot defence triggered"
if(login_deact):
return "Login deactivated"
return "end of FUNCTION"
def findOauthredirect_reddit(Networkdump,idp,site,pathconfusion):
marker=[]
if(marker):return link
for request in Networkdump:
if(request["response"]["status_code"]==302 and request["response"]["status_text"]=="Found"):
print("look for right reddit request")
if("https://ssl.reddit.com/api/v1/authorize" in request["request"]["url"]):
print(f'right request extract from location url look for capitol and not capitol location')
try:
url=request["response"]["headers"]["Location"]
if(not("code=" in url)):continue
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
try:
url=request["response"]["headers"]["location"]
if(not("code=" in url)):continue
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
print("unable to extract identifier check this file!!")
error=["invalid redirect_uri parameter."]
#search for error in login process
for request in Networkdump:
if(request["response"]["status_code"]==400 and request["response"]["status_text"]=="Bad Request"):
print("look for error or bot detection in reddit response")
if("https://ssl.reddit.com/api/v1/authorize" in request["request"]["url"]):
for key in request["response"].keys():
for e in error:
if(e in str(request["response"][key])):
print(f'error in response')
marker.append("-1")
marker.append("idp blocked attack")
return marker
print(f'[{idp}-error]if here error in finding the right request manually check it')
return ["-1","Eror in exctracting redirect url"]
def findOauthredirect_ok(Networkdump,idp,site,pathconfusion):
marker=[]
if(marker):return link
for request in Networkdump:
if(request["response"]["status_code"]==302):
print("look for right ok.ru request")
if("https://connect.ok.ru/dk?st.cmd=OAuth2Permissions" in request["request"]["url"]):
print(f'right request extract from location url look for capitol and not capitol location')
try:
url=request["response"]["headers"]["Location"]
if(not("code=" in url)):continue
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
try:
url=request["response"]["headers"]["location"]
if(not("code=" in url)):continue
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
print("unable to extract identifier check this file!!")
error=["Indicated redirect_uri is not registered in App settings."]
for request in Networkdump:
if(request["response"]["status_code"]==200):
print("look for error or bot detection in slack response")
if("https://connect.ok.ru/dk?st.cmd=OAuth2Permissions" in request["request"]["url"]):
for key in request["response"].keys():
for e in error:
if(e in str(request["response"][key])):
print(f'error in response')
marker.append("-1")
marker.append("idp blocked attack")
return marker
print(f'[{idp}-error]if here error in finding the right request manually check it')
return ["-1","Eror in exctracting redirect url"]
def findOauthredirect_slack(Networkdump,idp,site,pathconfusion):
marker=[]
if(marker):return link
for request in Networkdump:
if(request["response"]["status_code"]==302 and request["response"]["status_text"]=="Found"):
print("look for right slack.com request")
if(request['request']['method']=="POST" and "https://tommycalltext.slack.com/oauth/" in request["request"]["url"]):
print(f'right request extract from location url look for capitol and not capitol location')
try:
url=request["response"]["headers"]["Location"]
if(not("code=" in url)):continue
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
try:
url=request["response"]["headers"]["location"]
if(not("code=" in url)):continue
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
print("unable to extract identifier check this file!!")
#search for bot protection and errors
error=["Enter your authentication code"]
#search for error in login process
for request in Networkdump:
if(request["response"]["status_code"]==200 and request["response"]["status_text"]=="OK"):
print("look for error or bot detection in slack response")
if("https://tommycalltext.slack.com/" in request["request"]["url"]):
for key in request["response"].keys():
for e in error:
if(e in str(request["response"][key])):
print(f'error in response')
marker.append("-1")
marker.append("Bot defence triggered")
return marker
print(f'[{idp}-error]if here error in finding the right request manually check it')
return ["-1","Eror in exctracting redirect url"]
def findOauthredirect_orcid(Networkdump,idp,site,pathconfusion):
marker=[]
if(marker):return link
for request in Networkdump:
if(request['request']['method']=="POST" and "https://orcid.org/oauth/custom/init.json?" in request['request']['url'] or "https://orcid.org/oauth/custom/authorize.json"== request['request']['url']):
print("look for right orcid.id request")
try:
if(request["response"]['content']):
temp=Orcid_find_redirectLink_in_content(request["response"]['content'])
print(f'received this from search in content:{temp} len:{len(temp)} temp[0]:{temp[0]}')
if(not(len(temp)==1)):
marker.append(temp)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
else:
print(f'received an error from extracting url check it')
except Exception as e:
print(f'exception e :{e}')
print("SEARCHING FOR CODE/STATE PARAMETERS IN CONTENT ERROR------>LOOK AT THIS FILE AND UNDERSTAND WHY")
if(marker):
return marker
["-1","Eror in exctracting redirect url"]
def findOauthredirect_yan(Networkdump,idp,site,pathconfusion):
marker=[]
if(marker):return link
for request in Networkdump:
if(request["response"]["status_code"]==200 and request["response"]["status_text"]=="OK"):
if(request['request']['method']=="GET" and "https://oauth.yandex.ru/authorize?client_id=" in request['request']['url'] or request['request']['method']=="POST" and "https://oauth.yandex.ru/authorize/allow" in request['request']['url']):
print("look for right yandex.ru request")
try:
if(request["response"]['content']):
print(f'search in content yandex')
temp=Yan_find_redirectLink_in_content(request["response"]['content'])
marker.append(temp)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except Exception as e:
print("SEARCHING FOR CODE/STATE PARAMETERS IN CONTENT ERROR------>LOOK AT THIS FILE AND UNDERSTAND WHY")
#search for error in login and blocked requests
error=["Callback URL,"]
print(f'look for error in login yandex')
for request in Networkdump:
if(request["response"]["status_code"]==400 and request["response"]["status_text"]=="Bad Request"):
if(request['request']['method']=="GET" and "https://oauth.yandex.ru/authorize?client_id=" in request['request']['url']):
print("look for right yandex.ru request")
for key in request["response"].keys():
for e in error:
if(e in str(request["response"][key])):
print(f'error in response')
marker.append("-1")
marker.append("idp blocked attack")
return marker
print(f'return from search in content marker:{marker}')
print(f'[{idp}-error]if here error in finding the right request manually check it')
return ["-1","Error extraction redirect url"]
def findOauthredirect_tw(Networkdump,idp,site,pathconfusion):
marker=[]
if(marker):return link
for request in Networkdump:
if(request['request']['method']=="POST" and "https://api.twitter.com/oauth/authenticate"==request['request']['url'] or "https://api.twitter.com/oauth/authorize"==request['request']['url']):
print("look for right twitter request")
try:
if(request["response"]['content']):
temp=TW_find_redirectLink_in_content(request["response"]['content'])
marker.append(temp)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
except Exception as e:
print("SEARCHING FOR CODE/STATE PARAMETERS IN CONTENT ERROR------>LOOK AT THIS FILE AND UNDERSTAND WHY")
print("return from search in contentTW")
if(marker):
return marker
["-1","Eror in exctracting redirect url"]
def findAccess_token_fb2(Networkdump,idp,site,pathconfusion):
marker=[]
#search for access token in request
for request in Networkdump:
if(request["response"]["status_code"]==200 and request["response"]["status_text"]=="OK"):
if(request['request']['method']=="POST" and "/dialog/oauth/read" in request['request']['url'] and "https://www.facebook.com/" in request['request']['url'] or\
request['request']['method']=="POST" and "https://www.facebook.com/login/device-based/regular/login/" in request['request']['url'] or\
request['request']['method']=="POST" and "/dialog/oauth/confirm/" in request['request']['url'] and "https://www.facebook.com/" in request['request']['url'] or\
request['request']['method']=="GET" and "/dialog/oauth?"in request['request']['url'] and "https://www.facebook.com/" in request['request']['url']):
try:
print("search for access_token in content Facebook")
if(request["response"]['content']):
temp=FB_find_accessToken_in_content(request["response"]['content'])
print(f'return from Access_token in content:{temp}')
if(len(temp)==2):
print("len temp==2")
if(not int(temp)==-1):
print("int temp==-1")
marker.append(temp)
print(f'provide this request:{request["request"]["timestamp_start"]}')
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
print("THE REST")
marker.append(temp)
print(f'provide this request:{request["request"]["timestamp_start"]}')
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
except Exception as e:
print(f'exception e:{e}')
print("SEARCHING FOR CODE/STATE PARAMETERS IN CONTENT ERROR------>LOOK AT THIS FILE AND UNDERSTAND WHY")
print(f'return from Access_token facebook marker:{marker}')
if(marker):
return marker
["-1","Eror in exctracting redirect url"]
def findOauthredirect_fb2(Networkdump,idp,site,pathconfusion):
marker=[]
for request in Networkdump:
if(request['request']['method']=="POST" and "/dialog/oauth/" in request['request']['url'] and "https://www.facebook.com/" in request['request']['url']):
try:
if(request["response"]['content']):
print(f'provide this request:{request["request"]["timestamp_start"]}')
temp=FB_find_redirectLink_in_content(request["response"]['content'])
print(f'returned from search in content:{temp}')
if(not len(temp)==2):
#this is a link extracted from content
marker.append(temp)
print(f'provide this request:{request["request"]["timestamp_start"]}')
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
else:
print(f'Facebook return content problem:{temp}')
except Exception as e:
print(f'exception e:{e}')
print("SEARCHING FOR CODE/STATE PARAMETERS IN CONTENT ERROR------>LOOK AT THIS FILE AND UNDERSTAND WHY")
print("return from search in contentFB")
if(marker):
if(not len(marker[0])==2):
return marker
else:
marker=findAccess_token_fb2(Networkdump,idp,site,pathconfusion)
if(marker):
return marker
else:
marker=[]
#identify redirection response and extract link
print(f'search in location of response')
for request in Networkdump:
if(request["response"]["status_code"]==302 and request["response"]["status_text"]=="Found"):
print(f'look for right facebook.com request timestamp request start:{request["request"]["timestamp_start"]}')
if(request["response"]["status_code"]==302 and request["response"]["status_text"]=="Found" and \
"https://www.facebook.com/" in request['request']['url'] and "/dialog/oauth" in request['request']['url'] and\
request['request']['method']=="GET"):
print(f'right request extract from location url look for capitol and not capitol location')
url=""
#also include the access_token= case in location
try:
url=request["response"]["headers"]["Location"]
if("access_token=" in url):
b=url.find("access_token=")
marker.append(url[b:])
print(f'provide this request:{request["request"]["timestamp_start"]}')
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
else:
if(not("code=" in url)):continue
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
try:
url=request["response"]["headers"]["location"]
if("access_token=" in url):
b=url.find("access_token=")
marker.append(url[b:])
print(f'povide this request:{request["request"]["timestamp_start"]}')
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
else:
if(not("code=" in url)):continue
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
print("unable to extract identifier check this file!!")
#look for RP site misconfigured
error=["To be able to load this URL, add all domains and subdomains of your app to the App Domains field in your app settings",
"attualmente disponibile per questa app."]
for request in Networkdump:
if(request["response"]["status_code"]==200 and request["response"]["status_text"]=="OK"):
print(f'look for right facebook.com request timestamp request start:{request["request"]["timestamp_start"]}')
if("https://www.facebook.com/login.php?" in request['request']['url'] and\
request['request']['method']=="GET"):
print(f'check if misconfigured RP site')
for key in request["response"].keys():
for e in error:
if(e in str(request["response"][key])):
print(f'error detected from IDP RP site misconfigured')
marker.append("-1")
marker.append("RP misconfigured")
return marker
print(f'[{idp}-error]if here error in finding the right request manually check it')
return ["-1","Error extraction redirect url"]
def findOauthredirect_kakao(Networkdump,idp,site,pathconfusion):
#identify redirection response and extract link
marker=[]
for request in Networkdump:
if(request["response"]["status_code"]==302 and request["response"]["status_text"]=="Found"):
print("look for right kakao.com request")
if("https://kauth.kakao.com/oauth/authorize?" in request["request"]["url"]):
print(f'right request extract from location url look for capitol and not capitol location:{request["request"]["timestamp_start"]}')
try:
url=request["response"]["headers"]["Location"]
if(not("code=" in url)):continue
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
print("use lowecase location")
try:
url=request["response"]["headers"]["location"]
if(not("code=" in url)):continue
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
return marker
except KeyError:
print("unable to extract identifier check this file!!")
#seach for eventual error
error=["Admin Settings Issue (KOE006)"]
for request in Networkdump:
if(request["response"]["status_code"]==400 and request["response"]["status_text"]=="Bad Request"):
print("look for error in kakao.com response")
if("https://kauth.kakao.com/oauth/authorize?" in request["request"]["url"]):
print(f'right request extract from location url look for capitol and not capitol location:{request["request"]["timestamp_start"]}')
for key in request["response"].keys():
for e in error:
if(e in str(request["response"][key])):
print(f'error in response')
marker.append("-1")
marker.append("idp blocked attack")
return marker
print(f'[{idp}-error]if here error in finding the right request manually check it')
return ["-1","Eror in exctracting redirect url"]
def findOauthredirect_line(Networkdump,idp,site,pathconfusion):
#identify redirection response and extract link
marker=[]
for request in Networkdump:
if(request["response"]["status_code"]==302 and request["response"]["status_text"]=="Moved Temporarily"):
print("look for right line.me request")
if("https://access.line.me/dialog/oauth/approve?" in request["request"]["url"] or "https://access.line.me/oauth2/v2.1/authorize/consent" in request["request"]["url"] or\
"https://access.line.me/dialog/oauth/authenticate" in request["request"]["url"]):
print(f'right request extract from location url look for capitol and not capitol location')
try:
url=request["response"]["headers"]["Location"]
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
try:
url=request["response"]["headers"]["location"]
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
print("unable to extract identifier check this file!!")
error=["Invalid request path"]
#search for error in login process
for request in Networkdump:
if(request["response"]["status_code"]==400 and request["response"]["status_text"]=="Bad Request"):
print("look for right line.me request")
if("https://access.line.me/oauth" in request["request"]["url"] or "/authorize?" in request["request"]["url"]):
for key in request["response"].keys():
for e in error:
if(e in str(request["response"][key])):
print(f'error in response')
marker.append("-1")
marker.append("idp blocked attack")
return marker
print(f'[{idp}-error]if here error in finding the right request manually check it')
return ["-1","Eror in exctracting redirect url"]
def findincontentMic(text):
b=text.find("action=\"")
f=text.find("><",b)
if(b==-1):
print("not found return link")
else:
f=text.find("><",b)
if(f==-1):
print("not found the cut")
else:
temp=text[b+8:f]
return temp
def findOauthredirect_mic(Networkdump,idp,site,pathconfusion):
marker=[]
for request in Networkdump:
if(request["response"]["status_code"]==200 and request["response"]["status_text"]=="OK"):
print(f'look for right microsoftonline.com/live.com request request timestamp_start: {request["request"]["timestamp_start"]}')
if("https://login.microsoftonline.com/common/federation" in request["request"]["url"]):
print(f'right request extract from location url look for capitol and not capitol location')
#abort if code not in request
if("code=" not in request["request"]["content"]):break
#extract from content url microsoft
add=findincontentMic(request["response"]["content"])
print(f'returned this url:{add}')
marker.append(add)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
#identify redirection response and extract link
marker=[]
for request in Networkdump:
if(request["response"]["status_code"]==302 and request["response"]["status_text"]=="Found" or request["response"]["status_code"]==200 and request["response"]["status_text"]=="OK"):
print(f'look for right microsoftonline.com/live.com request request timestamp_start: {request["request"]["timestamp_start"]}')
if("https://login.live.com/ppsecure/post.srf" in request["request"]["url"] or "https://login.live.com/oauth20_authorize.srf?" in request["request"]["url"]):
print(f'right request extract from location url look for capitol and not capitol location')
try:
url=request["response"]["headers"]["Location"]
marker.append(url)
print("inspect for pathconfusion effect like errors")
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
try:
url=request["response"]["headers"]["location"]
marker.append(url)
print("inspect for pathconfusion effect like errors")
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
#case of login stuck in idp with error message
print("final exception inspect for pathconfusion effect like errors")
marker.append("-1")
add=FindPathconfusioninRequest(request,pathconfusion)
if(add!="end of FUNCTION"):
marker.append(add)
return marker
print("unable to extract identifier check this file!!")
print(f'[{idp}-error]if here error in finding the right request manually check it')
return ["-1","Eror in exctracting redirect url"]
def findOauthredirect_lk(Networkdump,idp,site,pathconfusion):
#identify redirection response and extract link
marker=[]
for request in Networkdump:
if(request["response"]["status_code"]==303 and request["response"]["status_text"]=="See Other"):
print("look for right linkedin request")
if("linkedin.com/oauth/v2/login-success" in request["request"]["url"] or "linkedin.com/oauth/v2/authorization-submit" in request["request"]["url"]):
print(f'right request extract from location url look for capitol and not capitol location')
try:
url=request["response"]["headers"]["Location"]
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
try:
url=request["response"]["headers"]["location"]
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
print("unable to extract identifier check this file!!")
print("if here error in finding the right request manually check it")
return ["-1","Eror in exctracting redirect url"]
def findOauthredirect_vk(Networkdump,idp,site,pathconfusion):
#identify redirection response and extract link
marker=[]
for request in Networkdump:
if(request["response"]["status_code"]==302 and request["response"]["status_text"]=="Found"):
print("look for right vk request")
if("login.vk.com/?act=grant_access"in request["request"]["url"]):
print(f'right request extract from location url look for capitol and not capitol location')
try:
url=request["response"]["headers"]["Location"]
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
try:
url=request["response"]["headers"]["location"]
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
print("unable to extract identifier check this file!!")
print("if here error in finding the right request manually check it")
return ["-1","Eror in exctracting redirect url"]
def findOauthredirect_at(Networkdump,idp,site,pathconfusion):
#identify redirection response and extract link
marker=[]
for request in Networkdump:
if(request["response"]["status_code"]==200 and request["response"]["status_text"]=="OK"):
if("data-redirect" in request["response"]["content"]):
print("identified the right request for atlassian with the right content")
temp=request["response"]["content"]
cut=temp.find("data-redirect")
if(cut<0):
print("error in cutting content")
else:
remain=temp[cut:]
end=remain.find(">")
temp=remain[:end]
print(f'temp:{temp}')
temp=temp.replace('data-redirect=',"")
temp=temp.replace('\\',"")
temp=temp.replace('&',"&")
temp=temp.replace('"',"")
marker.append(temp)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
for request in Networkdump:
if(request["response"]["status_code"]==302 and request["response"]["status_text"]=="Found"):
print("look for right atlassian request")
if("https://bitbucket.org/site/oauth" in request["request"]["url"]):
print(f'right request extract from location url look for capitol and not capitol location')
try:
url=request["response"]["headers"]["Location"]
if(site not in urlparse(url).netloc):continue
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
try:
url=request["response"]["headers"]["location"]
if(site not in urlparse(url).netloc):continue
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
print("unable to extract identifier check this file!!")
for request in Networkdump:
if(request["response"]["status_code"]==200 and request["response"]["status_text"]=="OK"):
print("look for right atlassian request")
if("https://bitbucket.org/site/oauth" in request["request"]["url"]):
print(f'right request extract from location url look for capitol and not capitol location')
try:
url=request["response"]["headers"]["Location"]
if(site not in urlparse(url).netloc):continue
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
try:
url=request["response"]["headers"]["location"]
if(site not in urlparse(url).netloc):continue
marker.append(url)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
except KeyError:
print(f'inspect for idp block')
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
print("unable to extract identifier check this file!!")
print("if here error in finding the right request manually check it")
return ["-1","Eror in exctracting redirect url"]
def findOauthredirect_gh(Networkdump,idp,site,pathconfusion):
#identify redirection response and extract link
marker=[]
for request in Networkdump:
if("github.com/login/oauth/authorize" in request["request"]["url"]):
print("found the right request now look at the content")
if("js-manual-authorize-redirect" in request["response"]["content"] and "code=" in request["response"]["content"]):
print("identified the right request with the right content")
temp=request["response"]["content"]
cut=temp.find("js-manual-authorize-redirect")
if(cut<0):
print("error in cutting content")
else:
remain=temp[cut:]
f=remain.find("href")
end=remain.find(">",f)
temp=remain[f:end]
print(f'temp:{temp}')
temp=temp.replace('\\',"")
temp=temp.replace('&',"&")
temp=temp.replace('href=',"")
temp=temp.replace('"',"")
marker.append(temp)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
if(marker):
return marker
else:
print(f'github second round code not identified search for blocked url')
for request in Networkdump:
if("github.com/login/oauth/authorize" in request["request"]["url"]):
print("found the right request now look at the content")
if("js-manual-authorize-redirect" in request["response"]["content"]):
print("identified the right request with the right content")
temp=request["response"]["content"]
cut=temp.find("js-manual-authorize-redirect")
if(cut<0):
print("error in cutting content")
else:
remain=temp[cut:]
f=remain.find("href")
end=remain.find(">",f)
temp=remain[f:end]
print(f'temp:{temp}')
temp=temp.replace('\\',"")
temp=temp.replace('&',"&")
temp=temp.replace('href=',"")
temp=temp.replace('"',"")
marker.append(temp)
add=FindPathconfusioninRequest(request,pathconfusion)
marker.append(add)
return marker
print(f'[{idp}-error]if here error in finding the right request manually check it')
return ["-1","Eror in exctracting redirect url"]
def Find_OauthLekage(output,idp,site,identifiers,redirect_domain):
#reserved domain excluded from leakages
#excluded_domains=["cdn"]
#search identifiers in request that are not directed to site or idp-->leakages
site=site
result=tldextract.extract(site)
domainsite=result.domain
idp=idp.split(".")[0]
print(f'oauthleakage received site:{site}, domainsite:{domainsite}, redirect_domain:{redirect_domain}, idp: {idp}, identifiers: {identifiers}')
Leakages=dict()
### if no redirect domain consider domainsite as redirect domain
if(redirect_domain==""):
#print(f'SITE WITH NO REDIRECT domain!!!check it')
redirect_domain=domainsite
for n in output:
netloc=urlparse(n["request"]["url"]).netloc
print(f'this is networkloc to check:{netloc}')
'''
#exclude reserved domains as CDN if you wants to consider them as a trusted party
for l in excluded_domains:
if(l in netloc):
break
'''
if(domainsite not in netloc and idp not in netloc and redirect_domain not in netloc):
#search for identifiers in all the request fields and report leakage
for elem in n["request"]:
for i in identifiers:
#print(f'analyze req: {n["request"][elem]}')
if(i in str(n["request"][elem])):
#build structure for leakage content
req_info=str(n["request"]["timestamp_start"])+"##"+str(netloc)+"##"+str(n["request"]["method"])+"##"+str(n["request"]["url"])
if(req_info not in Leakages.keys()):
Leakages[req_info]=dict()