재미와 이익을 위해 API 제한 우회
최근에 저는 사용자가 해당 기능과 쉽게 상호 작용할 수 있도록 나머지 API 엔드포인트와 함께 대시보드 액세스를 제공하는 애플리케이션을 로컬에서 다운로드하고 테스트하기 시작했습니다. 그러나 사용 가능한 문서를 사용하여 API를 가지고 노는 동안 일부 API에 액세스할 수 없다는 것을 깨달았습니다. 오류 메시지에 따라 사용할 수 없는 API를 사용하려면 프리미엄 버전의 앱을 구입해야 한다는 것을 깨달았습니다. 이 블로그에서는 어떻게 제한을 우회할 수 있었는지 이야기합니다. 간단히 하기 위해 블로그에서 사용된 모든 앱 구성 요소에 태그를 지정하겠습니다.
- 앱은 redacted.com 입니다.
- 사용 가능한 API는 GET /start/transaction 입니다.
- 프리 티어에서 사용할 수 없는 API(현재 로컬에서 사용되지만 프리미엄 버전에서 사용 가능)는 POST /stop/transaction 입니다.
{
"API is accessible only from dashboard. Please upgrade to premium for programmatic access."
}
Burp Suite를 통해 모든 대시보드 트래픽을 프록시하기 시작했습니다. 놀랍게도 정확한 엔드포인트가 대시보드에서 재사용되어 엔드포인트의 존재를 확인했습니다. 이제 애플리케이션이 어떻게 내 Postman 요청을 차단하지만 대시보드에서는 작동하는 것처럼 보이는지 질문이 남습니다.
요청 헤더를 분석하기 시작했습니다. 아래는 Burp를 통해 트랜잭션 중지 끝점으로 전송된 요청입니다.
POST /stop/transaction
Host: redacted.com
Content-Length: 3144
Sec-Ch-Ua: “Chromium”;v=”109", “Not_A Brand”;v=”99"
Sec-Ch-Ua-Platform: “macOS”
X-Api-Token: "$api_token"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.120 Safari/537.36
X-Cookie: token="$token"
Content-Type: application/json
Accept: */*
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://redacted.com/
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Connection: close
{
"Json data"
}
- 생성된 API 키와 다른 토큰이 있는 X-Api-Token 필드.
- 아마도 세션 토큰이었던 X-Cookie 필드.
이제 목표가 명확해졌습니다. 엔드포인트를 API로 사용하려면 다음과 같은 요청을 작성해야 합니다.
- X-Api-Token 헤더 값이 있습니다.
- 세션 토큰을 계산하고 추가하십시오.
- 올바른 콘텐츠 길이를 계산하고 추가하십시오.
세션 토큰의 경우 Burp를 통한 로그인 워크플로를 분석했습니다. 로그인 요청은 다음과 같았습니다.
POST /session HTTP/1.1
Host: redacted.com
Content-Length: 55
Sec-Ch-Ua: "Chromium";v="109", "Not_A Brand";v="99"
Sec-Ch-Ua-Platform: "macOS"
X-Api-Token: "$api_token"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.120 Safari/537.36
Content-Type: application/json
Accept: */*
Origin: https://redacted.com
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://redacted.com/
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Connection: close
{"username":"admin","password":"admin"}
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store, must-revalidate
X-Frame-Options: DENY
Content-Type: application/json
Connection: close
Content-Length: 179
Expires: 0
Expect-CT: max-age=0
Pragma: no-cache
{"token":"$token"}
API 제한을 우회한 최종 스크립트는 다음과 같습니다.
import requests
import json
#Credentials needed to automate session
username= "admin"
password= "admin"
x_api_token="1AB-345-678"
#Function to generate headers for Login
def headers_data(request_data,if_login,token=0):
data_len= str(len(request_data))
headers_request = {
'Content-Length': data_len,
'Content-Type': 'application/json',
'X-API-Token': x_api_token
}
if if_login:
return headers_request
else:
headers_request['X-Cookie']= 'token='+token
return headers_request
#Login to application and store token
login_data= '{"username":' + '"' + username + '"'+',"password":' + '"' + password + '"'+'}'
login_headers = headers_data(login_data,True)
try:
login_tokens = requests.post('https://redacted.com/session', headers=login_headers, data=login_data, verify=False)
token= login_tokens.json().get('token')
print("Login Successful !")
except:
raise Exception("Login Automation failed")
#Post request to stop endpoint.
payload_data= { "Some json data to be posted to stop transaction"}
update_ip_headers = headers_data(payload_data,False,token)
stop_transaction_response= requests.put('https://redacted.com/stop/transaction', headers=update_ip_headers, data=payload_data, verify=False)
print("Transaction stopped via API")
이 애플리케이션에 미치는 영향이 크지는 않았지만 무엇을 접하게 될지 알 수 없습니다 :p . 이 블로그가 버그 현상금 사냥꾼에게 유용하기를 바랍니다!

![연결된 목록이란 무엇입니까? [1 부]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































