2017-03-01 1 views
0

Shodan 쿼리 결과를 구문 분석하고 설정 한 기준과 일치하는 결과 만있는 새 JSON 파일을 작성하려고합니다.위치 기반 Shodan 쿼리 결과 필터링

예 JSON 항목 :

{ 
    "matches": [ 
    { 
     "product": "Microsoft IIS httpd", 
     "hostnames": [], 
     "hash": -1722221328, 
     "ip": 1261462342, 
     "isp": "AT&T Internet Services", 
     "transport": "tcp", 
     "cpe": [ 
     "cpe:/a:microsoft:iis:7.5", 
     "cpe:/o:microsoft:windows" 
     ], 
     "data": "", 
     "asn": "AS7018", 
     "port": 631, 
     "version": "7.5", 
     "link": "Ethernet or modem", 
     "location": { 
     "city": null, 
     "region_code": null, 
     "area_code": null, 
     "longitude": -97.822, 
     "country_code3": "USA", 
     "latitude": 37.751000000000005, 
     "postal_code": null, 
     "dma_code": null, 
     "country_code": "US", 
     "country_name": "United States" 
     }, 
     "timestamp": "2017-02-28T23:55:24.306344", 
     "domains": [], 
     "org": "AT&T Internet Services", 
     "os": null, 
     "_shodan": { 
     "crawler": "122dd688b363c3b45b0e7582622da1e725444808", 
     "id": null, 
     "module": "http-simple-new", 
     "options": {} 
     }, 
     "ip_str": "75.48.99.70" 
    }, 
    { 
     "hash": 605323305, 
     "ip": 1757819678, 
     "isp": "Google Cloud", 
     "transport": "tcp", 
     "data": "", 
     "asn": "AS15169", 
     "port": 9000, 
     "hostnames": [ 
     "30.51.198.104.bc.googleusercontent.com" 
     ], 
     "location": { 
     "city": "Mountain View", 
     "region_code": "CA", 
     "area_code": 650, 
     "longitude": -122.0574, 
     "country_code3": "USA", 
     "latitude": 37.41919999999999, 
     "postal_code": "94043", 
     "dma_code": 807, 
     "country_code": "US", 
     "country_name": "United States" 
     }, 
     "timestamp": "2017-02-28T23:51:35.997036", 
     "domains": [ 
     "googleusercontent.com" 
     ], 
     "org": "Google Cloud", 
     "os": null, 
     "_shodan": { 
     "crawler": "545144fc95e7a7ef13ece5dbceb98ee386b37950", 
     "id": null, 
     "module": "https-simple-new", 
     "options": {} 
     }, 
     "ip_str": "104.198.51.30" 
    } 
    ], 
    "total": 2 
} 

내 희망은 "미국"의 위치 COUNTRY_CODE를 갖는 기준과 일치하지 않는 경우 요소를 제거, JSON 파일을로드하고 요소의 집합을 반복하는 것입니다 . 다음과 같이

내가 가진 코드 (https://gist.github.com/madonnellyIterate over JsonObject properties의 의례)입니다 :

import java.io.FileNotFoundException; 
import java.io.FileReader; 
import java.util.Map; 
import java.util.Set; 

import com.google.gson.JsonArray; 
import com.google.gson.JsonElement; 
import com.google.gson.JsonObject; 
import com.google.gson.JsonParser; 

public class ParseJSON { 

    public static void main(String[] args) { 
     JsonObject shodanJSON = convertFileToJSON("<Path to JSON file>"); 

     Set<Map.Entry<String,JsonElement>> queryResults = shodanJSON.entrySet(); 

     for (Map.Entry<String, JsonElement> queryResult : queryResults) { 
      JsonArray locArray = queryResult.getValue().getAsJsonObject().getAsJsonArray("location"); 
      for (JsonElement locData : locArray) { 
       if (locData.getAsJsonObject().getAsJsonPrimitive("country_code").equals("US")) { 
        System.out.println(locData.getAsString()); 
       } 
      } 
     } 
    } 

    public static JsonObject convertFileToJSON(String fileName) { 

     // Read from File to String 
     JsonObject jsonObject = new JsonObject(); 

     try { 
      JsonParser parser = new JsonParser(); 
      JsonElement jsonElement = parser.parse(new FileReader(fileName)); 
      jsonObject = jsonElement.getAsJsonObject(); 
     } catch (FileNotFoundException e) { 

     } 
     return jsonObject; 
    } 
} 

내 코드를 실행

내가 스레드 "기본"자바 오류

예외를 수신하고 있습니다. lang.IllegalStateException : JSON이 아닙니다 개체 : [{ "product": "Microsoft IIS httpd", "호스트 이름": [], "해시": 1722221328, "ip": 1261462342, "isp": "AT & T 인터넷 서비스 ","전송 ": ...}] com.cti.shodan.ParseJSON.main (ParseJSON.java:22)에서 com.google.gson.JsonElement.getAsJsonObject (JsonElement.java:90)

에서 나는 톤을 만드는 중이라서 확신 나는 실수를 지적하고 누군가가 내가 만든 오류를 지적 할 수 있기를 바라고있다. 미리 감사드립니다!

+0

당신이 읽어보세요나요 Gson javadoc? [여기에 대한 링크가 있습니다] (http://www.javadoc.io/doc/com.google.code.gson/gson/2.8.0). 'JsonElement' 클래스의 문서를 보시고'getAsJsonObject()'를 보시면 예외가 무엇을 의미하는지 알려 드리겠습니다. – ajb

+0

javadoc은 다소 도움이됩니다. 이제 JSON 파일이 일치하는 배열이므로이를 적절히 처리해야합니다. 수정 코드 : ('의 Map.Entry <문자열 JsonElement> queryResult : queryResults) 대. { \t \t \t JsonArray 일치 queryResult.getValue =() getAsJsonArray(); (JsonElement 일치 : 일치)에 대한 \t \t \t \t \t \t {;' 하지만 난 위치 데이터에 액세스 할 방법으로 지금 분실하고있다. – cbarreras

답변

1

실제 구조를 충족시키지 않는 구체적인 JSON 문서 구문 분석에 대한 몇 가지 가정 사항이 있습니다. 하위 프로퍼티 값 ($.matches.*.location.country_code)을 필터링하여 일치하는 결과 ($.matches)를 표시한다고 가정합니다. 자바 8

for (final Entry<String, JsonElement> queryResult : shodanJsonObject.entrySet()) { 
     final JsonElement value = queryResult.getValue(); 
     // This is necessary to skip <"total": 2> 
     if (value.isJsonArray()) { 
      // Here comes an array, and should be iterated, rather than taken as an object 
      for (final JsonElement match : value.getAsJsonArray()) { 
       // This was the root cause, not an array 
       final JsonObject location = match.getAsJsonObject().getAsJsonObject("location"); 
       // Previously jsonPrimitive.equals("US") -- convert the JSON primitive to a string first 
       if (location.getAsJsonPrimitive("country_code").getAsString().equals("US")) { 
        // Previously getAsString() -- it requires a JSON string literal, just remove it 
        System.out.println(match); 
       } 
      } 
     } 
    } 

이 약간 더 간단 할 수 있습니다

shodanJsonObject.entrySet() 
     .stream() 
     .map(Entry::getValue) 
     .filter(JsonElement::isJsonArray) 
     .map(JsonElement::getAsJsonArray) 
     .flatMap(jsonElements -> StreamSupport.stream(jsonElements.spliterator(), false)) 
     .peek(System.out::println) 
     .map(JsonElement::getAsJsonObject) 
     .map(jsonObject -> jsonObject.getAsJsonObject("location")) 
     .filter(location -> location.getAsJsonPrimitive("country_code").getAsString().equals("US")) 
     .forEach(jsonObject -> { 
     }); // forEach is a terminal operation and it "pushes" the entire chain above 

그리고 아마도 가장 표현 방법이 JsonPath 같은 라이브러리를 조회 사용할 수 있는지 :

final JsonPath jsonPath = JsonPath.compile("$.matches.*[?(@.location.country_code=='US')]"); 
for (final Object match : jsonPath.<JSONArray>read(JSON)) { 
    System.out.println(match); 
} 
+0

첫번째 옵션은 저에게 큰 도움이됩니다. 전문 지식을 공유해 주셔서 감사합니다. null 값을 처리하기 위해 country_code를 검사 할 때'! location.get ("country_code"). isJsonNull()'을 추가했습니다. – cbarreras

+0

@cbarreras 문제 없어, 내가 도와 줄 수있어서 기쁩니다. :) –