Toon posts:

Correcte HTTP post voor vBulletin fora...

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik zit nu al een tijdje te priegelen met een stukje Java-script dat kan inloggen op een willekeurig vBulletin forum.

De bijbehorende broncode voor de login-form op een vBulletin forum is als volgt:

HTML: LOG-IN FORM op een vBulletin-forum
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
        <!-- login form -->
        <form action="login.php?do=login" method="post" onsubmit="md5hash(vb_login_password, vb_login_md5password, vb_login_md5password_utf, 0)">
        <script type="text/javascript" src="clientscript/vbulletin_md5.js?v=384"></script>
        <table cellpadding="0" cellspacing="3" border="0">
        <tr>
            <td class="smallfont" style="white-space: nowrap;"><label for="navbar_username">Gebruikersnaam</label></td>
            <td><input type="text" class="bginput" style="font-size: 11px" name="vb_login_username" id="navbar_username" size="10" accesskey="u" tabindex="101" value="Gebruikersnaam" onfocus="if (this.value == 'Gebruikersnaam') this.value = '';" /></td>
            <td class="smallfont" nowrap="nowrap"><label for="cb_cookieuser_navbar"><input type="checkbox" name="cookieuser" value="1" tabindex="103" id="cb_cookieuser_navbar" accesskey="c" checked="checked" />Onthoudt gegevens</label></td>

        </tr>
        <tr>
            <td class="smallfont"><label for="navbar_password">Wachtwoord</label></td>
            <td><input type="password" class="bginput" style="font-size: 11px" name="vb_login_password" id="navbar_password" size="10" tabindex="102" /></td>
            <td><input type="submit" class="button" value="Log in" tabindex="104" title="Type hier je gebruikersnaam en wachtwoord om in te loggen!" accesskey="s" /></td>
        </tr>
        </table>
        <input type="hidden" name="s" value="" />
        <input type="hidden" name="do" value="login" />
        <input type="hidden" name="vb_login_md5password" />
        <input type="hidden" name="vb_login_md5password_utf" />
        </form>
        <!-- / login form -->


De code van het Java script is als volgt:

Java: CONSTANTEN:
1
2
3
4
5
6
7
    String POST_CONTENT_TYPE = "application/x-www-form-urlencoded";
    String LOGIN_ACTION_NAME = "login";
    String LOGIN_USER_NAME_PARAMETER_NAME = "vb_login_username";
    String LOGIN_PASSWORD_PARAMETER_NAME = "vb_login_password";
    String LOGIN_USER_NAME = "éénofanderegebruikersnaam";
    String LOGIN_PASSWORD = "methetbijbehorendewachtwoord";
    String TARGET_URL = "http://www.eenvBulletinforum.nl";

Java: MAIN:
1
2
3
4
5
public void httpPostLogin () {
            String urlEncodedContent = preparePostContent(LOGIN_USER_NAME, LOGIN_PASSWORD);
            ...
            ...
    }

Java: HTTPPOST-VOORBEREIDEN
1
2
3
4
5
6
7
8
private String preparePostContent(String loginUserName, String loginPassword) throws UnsupportedEncodingException
    {
        String encodedLoginUserName = URLEncoder.encode(loginUserName, "UTF-8");
        String encodedLoginPassword = URLEncoder.encode(loginPassword, "UTF-8");
        String content = "login.php?do=" + LOGIN_ACTION_NAME +" &" + LOGIN_USER_NAME_PARAMETER_NAME +"="
        + encodedLoginUserName + "&" + LOGIN_PASSWORD_PARAMETER_NAME + "=" + encodedLoginPassword;
        return content;
    }
Wat is nu het probleem?
Het probleem ligt bij String content in HTTPPOST-VOORBEREIDEN. Het is namelijk niet geoptimaliseerd voor een vBulletin forum! Die hele regel achter String content moet aangepast worden zodat het script een verbinding kan aanleggen met een vBulletin forum om in te loggen. Maar dat gaat echt mijn pet te boven. Vooral omdat er ook md5hash in het spel zit (zie LOG-IN FORM).

Ik heb al gezocht naar een oplossing, en heb tot zoverre twee links gevonden waarin hetzelfde probleem voorgelegd werd bij anderen maar vervelend genoeg geen oplossing als resultaat had. Ik zal deze hier plaatsen zodra ik ze weer gevonden heb.

Mijn vraag is: kan iemand me uitleggen hoe ik de regel na String content kan aanpassen zodat het in overeenstemming is met de bovenstaande LOG-IN script van een vBulletin forum?

Acties:
  • 0 Henk 'm!

  • DamadmOO
  • Registratie: Maart 2005
  • Laatst online: 01-10 22:05
Je bent je ervan bewust dat vBulletin een POST request gebruikt in hun form en dat door alles in je query string te mikken je het als en GET opstuurd?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Excuus, ik had had beter ook de volgende methode erbij kunnen geven:

(er vindt namelijk weldegelijk een POST-request plaats)

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    public HttpURLConnection doHttpPost(String targetUrl, String content) throws IOException {
        HttpURLConnection urlConnection = null;
        DataOutputStream dataOutputStream = null;

            urlConnection = (HttpURLConnection)(new URL(targetUrl).openConnection());
            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(true);
            urlConnection.setRequestProperty("Content-Type", POST_CONTENT_TYPE);
            urlConnection.setRequestMethod("POST");
            dataOutputStream = new DataOutputStream(urlConnection.getOutputStream());
            dataOutputStream.writeBytes(content);
            dataOutputStream.flush();
            dataOutputStream.close();

            return urlConnection;
    }


De bovengenoemde MAIN ziet er dan als volgt uit:

Java:
1
2
3
4
5
    public void httpPostLogin () {

            String urlEncodedContent = preparePostContent(LOGIN_USER_NAME, LOGIN_PASSWORD);
            HttpURLConnection urlConnection = doHttpPost(TARGET_URL, urlEncodedContent);
     }        


Ik heb de bovenstaande code van deze link gehaald. De logica erachter snap ik, ook inclusief de voorbeeldform die ze erbij hadden gegeven om de POST request op toe te passen, het punt is echter dat deze voorbeeldform dermate afwijkt van een vBulletin form dat ik die omschakeling maar niet kan maken.

Ik heb wel de constanten in zekere mate aangepast naar de vBulletin-termen (zoals username, password, login-action, et cetera). Maar meer dan dat lukt het me niet, ik zit met name in de knoop bij String content in HTTP-POST VOORBEREIDEN.

Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Nu online

MueR

Admin Tweakers Discord

is niet lief

Voor zover ik weet geef je post requests niet door in de query string, zelfs al zeg je dat het post is. Ook bij een post kan je namelijk get parameters meegeven. Maar als je nou eens een simpele testcase maakt, zeg een php file die alle GET en POST waarden opslaat in een tekstbestand, dan kan je zien wat je werkelijk stuurt.

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
^ Ik heb eerlijk gezegd geen idee hoe ik dat moet doen. Ik kwam toevallig nog een scriptje tegen waarmee je naar verluid kunt inloggen. Het is echter niet op een vBulletin forum maar op een simpele log-in voorbeeldsite.
|
|
Java: Sending a POST Request Using a URL
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
        try { 
            //LOG-DATA OPGEVEN, username=test, password=test
            String data = URLEncoder.encode("username", "UTF-8") + "=" + URLEncoder.encode("test", "UTF-8"); 
            data += "&" + URLEncoder.encode("password", "UTF-8") + "=" + URLEncoder.encode("test", "UTF-8"); 
            
            //LOG-DATA VERZENDEN:
            URL urladres = new URL("http://www.1your.com/drupal/sample_login.php"); 
            URLConnection verbinding = urladres.openConnection(); 
            verbinding.setDoOutput(true); 
            OutputStreamWriter wr = new OutputStreamWriter(verbinding.getOutputStream()); 
            wr.write(data); 
            wr.flush();
            
            //RESPONSE VERKRIJGEN EN WEERGEVEN:
            BufferedReader rd = new BufferedReader(new InputStreamReader(verbinding.getInputStream())); 
            String line; 
            while ((line = rd.readLine()) != null) { 
                System.out.println(line);
            } 
            
            //SYSTEEM AFSLUITEN:
            
            wr.close(); 
            rd.close(); 
        } 


Maar ook deze werkt niet! Pfff, ik word hier echt gek van.

Misschien moet ik maar eens naar HTTPclient kijken...

Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Nu online

MueR

Admin Tweakers Discord

is niet lief

Verwijderd schreef op zondag 07 februari 2010 @ 13:35:
^ Ik heb eerlijk gezegd geen idee hoe ik dat moet doen.
Dat is toch niet zo moeilijk? Het enige wat je nodig hebt is de PHP manual pages.

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • MacWolf
  • Registratie: Januari 2004
  • Laatst online: 06-09-2024
MueR schreef op zondag 07 februari 2010 @ 12:45:
Voor zover ik weet geef je post requests niet door in de query string, zelfs al zeg je dat het post is. Ook bij een post kan je namelijk get parameters meegeven. Maar als je nou eens een simpele testcase maakt, zeg een php file die alle GET en POST waarden opslaat in een tekstbestand, dan kan je zien wat je werkelijk stuurt.
Vermoedelijk worden POST requests wel altijd meegegeven in de query string, ik ben namelijk hetzelfde gedaan voor een Obj-C project waar ik mee bezig ben. De code lijkt zelfs veel op de Java code die ik hierboven zie. Ik ga ervan uit dat de query string een onderdeel is van de HTTP body (misschien zie ik dit verkeerd).

Voorbeeld code uit een project waar ik mee bezig ben:

C:
1
2
3
4
5
6
7
8
9
10
11
    
    NSString *url = @"url=";
    NSString *actualVal = [NSString stringWithFormat:@"actualval=%@", fieldUsername];
    NSString *username = [NSString stringWithFormat:@"%@=user1234", fieldUsername];
    NSString *password = @"password=123456";
    NSString *login = @"login=+Check+Mail+";
    NSString *requestBody = [NSString stringWithFormat:@"%@&%@&%@&%@&%@", url, actualVal, username, password, login];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.website.com/login.aspx"]];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:[requestBody dataUsingEncoding:NSUTF8StringEncoding]];
    [_webView loadRequest:request];


Zoals je ziet wordt in de HTTP body de query string meegestuurd. De topicstarter zou eventueel kunnen controleren of zijn query string ook aanwezig is in de HTTP body. Dit kan je controleren door bijvoorbeeld een plug-in voor Firefox te gebruiken (Live HTTP Headers).

Ik denk dat het grootste probleem is voor de topicstarter dat hij zijn querystring eerst moet encoden met die MD5 hash. In Objective-C is het mogelijk om een Javascript uit te voeren. Het zou dan mogelijk zijn om de Javascript code uit de site te gebruiken om de string te encoderen met de MD5 hash. Wellicht bestaat een dergelijke functie ook in Java? Mocht een dergelijke functie niet bestaan, dan zou je de code van deze site kunnen proberen om je string te encoderen voor je hem in de HTTP body plaatst:

Java:
1
2
3
4
5
6
7
8
9
10
11
   1 import java.security.*;
    2 import java.math.*;
    3 
    4 public class MD5 {
    5    public static void main(String args[]) throws Exception{
    6       String s="This is a test";
    7       MessageDigest m=MessageDigest.getInstance("MD5");
    8       m.update(s.getBytes(),0,s.length());
    9       System.out.println("MD5: "+new BigInteger(1,m.digest()).toString(16));
   10    }
   11 }

Microsoft Windows: A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
@MacWolf,

Aangezien jijzelf ook met een dergelijk project bezig bent, de volgende C# code vond ik toevallig op internet, met dit scriptje kun je wel inloggen op een vBulletin forum. Zie deze link voor de gehele topic. Misschien hebben we hier beiden wat aan.

C#:
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
    private void button1_Click(object sender, EventArgs e)
    {
      const string login = @"sknake";
      const string password = @"";
      const string md5 = @"";

      CookieContainer cookieMonster = new CookieContainer();
      string postArgs = string.Format(
        @"raw_login_password={0}&do=login&url=%2Fforum%2Fusercp.php&vb_login_md5password={2}&vb_login_md5password_utf={2}&s=&securitytoken=guest&vb_login_username={1}&vb_login_password=",
        password,
        login,
        md5
         );

      HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("http://www.thinkdigit.com/forum/login.php?do=login");
      req.Method = "POST";
      req.CookieContainer = cookieMonster;
      req.Referer = @"http://www.thinkdigit.com/forum/usercp.php";
      req.ContentType = @"application/x-www-form-urlencoded";
      byte[] buffer = System.Text.ASCIIEncoding.UTF8.GetBytes(postArgs);
      req.ContentLength = buffer.Length;
      req.AllowAutoRedirect = true;
      using (Stream reqStream = req.GetRequestStream())
      {
        reqStream.Write(buffer, 0, buffer.Length);
        reqStream.Close();
      }
      HttpWebResponse response = (HttpWebResponse)req.GetResponse();
      using (Stream respStream = response.GetResponseStream())
      {
        using (StreamReader sr = new StreamReader(respStream))
        {
          string s = sr.ReadToEnd();
          System.Diagnostics.Debugger.Break();
        }
      }
    }


Ik ga nu even aan de slag met jouw voorstel over het gebruik van Live HTTP Headers.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb even met Tamper Data gekeken naar de POSTDATA die ontstaat bij het inloggen op een vBulletin forum
code:
1
2
3
4
5
6
7
8
9
POSTDATA.=
vb_login_username=[b]gebruikersnaam[/b]
&cookieuser=1
&vb_login_password=[b]wachtwoordwordtnietweergegeven[/b]
&s=4b3c4271cb915d3dblablablablablablablabla
&securitytoken=guest
&do=login
&vb_login_md5password=16c944742ef0ablablablablabla
&vb_login_md5password_utf=16c944742ef0ablablablablabla



Ander vBulletin forum (zonder cookie):

code:
1
2
3
4
5
6
7
8
POSTDATA=
vb_login_username=[b]gebruikersnaam[/b]
&vb_login_password=[b]wachtwoordwordtnietweergegeven[/b]
&s=d8e9e4ff3c183d1blablablablablabla
&securitytoken=guest
&do=login
&vb_login_md5password=16c944742ef0ablablablablabla
&vb_login_md5password_utf=16c944742ef0ablablablablabla


(de md5hashes zijn hetzelfde - ik heb ze weliswaar gefingeerd - omdat ik op beide fora hetzelfde wachtwoord heb gebruikt)

De string met &data moet natuurlijk allemaal aan elkaar. Maar de structuur van de POSTDATA heb ik tenminste door. Het MD5Hash scriptje is volgens mij niet benodigd omdat de omzetting van je wachtwoord naar een md5hash altijd hetzelfde resultaat geeft, dan kan ik in principe gewoon de md5hash van mijn wachtwoord in de string plaatsen. Het enige waar ik nochtans mijn hoofd over breek, is wat die &s voortstelt...

Acties:
  • 0 Henk 'm!

  • MacWolf
  • Registratie: Januari 2004
  • Laatst online: 06-09-2024
...

De string met &data moet natuurlijk allemaal aan elkaar. Maar de structuur van de POSTDATA heb ik tenminste door. Het MD5Hash scriptje is volgens mij niet benodigd omdat de omzetting van je wachtwoord naar een md5hash altijd hetzelfde resultaat geeft, dan kan ik in principe gewoon de md5hash van mijn wachtwoord in de string plaatsen. Het enige waar ik nochtans mijn hoofd over breek, is wat die &s voortstelt...
Voor het hobby-project waar ik mee bezig ben zijn die MD5 hashes niet nodig overigens. Dus wat betreft mijn eigen project het ik het login gedeelte al werkende (ik probeer een bepaalde site te 'vertalen' naar een iPhone app, gezien de site niet goed op de iPhone kan worden weergegeven).

Je geeft aan dat je niet precies het nut van die '&' tekens begrijpt? Het is eigenlijk gewoon hetzelfde als een GET querystring die meegestuurd wordt. Zo zie je in de bovenstaande code die ik gepost heb dat ik zelf ook strings samenvoeg en tussen ieder argument een '&' teken plaats:

C:
1
[NSString stringWithFormat:@"%@&%@&%@&%@&%@", url, actualVal, username, password, login];
(merk op: iedere %@ wordt vervangen met een variable, dus de 1e keer %@ wordt vervangen door de variable url, daarna volgt een & teken, daarna de volgende variable, etc... In iedere variable zit weer een string, voor url bijvoorbeeld "url=http://www.apple.com".

Als je gewoon de querystring in je HTTP header zo veel mogelijk namaakt moet de site werken. Voor de site waar ik zelf mee bezig was moest ik overigens 2 waardes niet meesturen, anders werkte de login niet - misschien dat je zelf ook iets dergelijks tegenkomt. Belangrijkste is in ieder geval dat je ieder form field terug ziet komen in de querystring en dat je iedere veldnaam en waarde toevoegt volgens de notatie: [veld]=[waarde]&[veld]=[waarde]& etc...

Mocht je niet precies weten hoe je zo'n string netjes kan samenvoegen in de taal die je gebruikt, Google dan naar termen zoals: 'string concatenation java'.

Microsoft Windows: A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
MacWolf schreef op zondag 07 februari 2010 @ 22:36:
Je geeft aan dat je niet precies het nut van die '&' tekens begrijpt? Het is eigenlijk gewoon hetzelfde als een GET querystring die meegestuurd wordt. Zo zie je in de bovenstaande code die ik gepost heb dat ik zelf ook strings samenvoeg en tussen ieder argument een '&' teken plaats:
Jawel joh :*) dat stukje begrijp ik wel. Wat ik niet snap is wat die "&s=..." voorstelt in beide POSTDATA's. Het ziet er naar uit dat dit bij iedere log-in een andere waarde toegekend krijgt.
(merk op: iedere %@ wordt vervangen met een variable, dus de 1e keer %@ wordt vervangen door de variable url, daarna volgt een & teken, daarna de volgende variable, etc... In iedere variable zit weer een string, voor url bijvoorbeeld "url=http://www.apple.com".
Haha klopt, godzijdank hebben mijn bescheiden Java-skills me nog niet de rug toegekeerd :P Dat stukje begrijp ik ook wel, toch bedankt voor de uitleg.
Als je gewoon de querystring in je HTTP header zo veel mogelijk namaakt moet de site werken. Voor de site waar ik zelf mee bezig was moest ik overigens 2 waardes niet meesturen, anders werkte de login niet - misschien dat je zelf ook iets dergelijks tegenkomt. Belangrijkste is in ieder geval dat je ieder form field terug ziet komen in de querystring en dat je iedere veldnaam en waarde toevoegt volgens de notatie: [veld]=[waarde]&[veld]=[waarde]& etc...
Dat was precies mijn idee! Alleen het lot wil dat dit evenzo niet werkt. Ik heb in alle pragmatiek gewoon letterlijk de query string uit Tamper Data geplukt en deze geplaatst achter 'String content = ...' (zie HTTPPOST VOORBEREIDEN in topicpost) en wat er eerst na het is-teken kwam gewoon verwijderd. Dat werkte dus niet.

Mogelijk heeft het nog te maken met het login.php?do=login stukje dat vooraf aan de query string dient te gaan.

Daar ga ik even mee worstelen. Mocht iemand nog een lumineus idee hebben, dan hoor ik het wel.

Acties:
  • 0 Henk 'm!

  • MacWolf
  • Registratie: Januari 2004
  • Laatst online: 06-09-2024
Verwijderd schreef op maandag 08 februari 2010 @ 00:41:
[...]

Jawel joh :*) dat stukje begrijp ik wel. Wat ik niet snap is wat die "&s=..." voorstelt in beide POSTDATA's. Het ziet er naar uit dat dit bij iedere log-in een andere waarde toegekend krijgt.


[...]


Haha klopt, godzijdank hebben mijn bescheiden Java-skills me nog niet de rug toegekeerd :P Dat stukje begrijp ik ook wel, toch bedankt voor de uitleg.


[...]


Dat was precies mijn idee! Alleen het lot wil dat dit evenzo niet werkt. Ik heb in alle pragmatiek gewoon letterlijk de query string uit Tamper Data geplukt en deze geplaatst achter 'String content = ...' (zie HTTPPOST VOORBEREIDEN in topicpost) en wat er eerst na het is-teken kwam gewoon verwijderd. Dat werkte dus niet.

Mogelijk heeft het nog te maken met het login.php?do=login stukje dat vooraf aan de query string dient te gaan.

Daar ga ik even mee worstelen. Mocht iemand nog een lumineus idee hebben, dan hoor ik het wel.
Mogelijk staat &s= voor een sessionId, oftewel een gegenereerde waarde. In dat geval moet je die waarde niet meesturen met je querystring. Dat is dus zo'n waarde die ik zelf niet meegestuurd heb, anders werkte de request voor mijn project niet. Een sessionId zou automatisch gegenereerd moeten worden als je een request uitvoert.

Microsoft Windows: A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition.

Pagina: 1