SoFunction
Updated on 2025-04-13

PJBlog security analysis

PJBlog2 is a free ASP + Access personal blog system developed by PuterJam. I want to make a blog to play with these days, but after selecting PJBlog2 with relatively good functions and interfaces. After trial, I felt that the blog was pretty good, and I also found several small security issues, so I sent out my little insights. The version I analyzed is the version PJBlog2 v2.4.1211 released on December 11, 2005.

1. Password encryption algorithm
PJBlog2 does not use the commonly used MD5 algorithm to encrypt user passwords, but uses the SHA1 algorithm. The SHA1 algorithm is similar to MD5 and is also a one-way hash function, but it processes data of any length to output 160-bit values.
When creating a new user, PJBlog2 will randomly generate a 6-bit string Salt. The user's plaintext password plus this Salt value and hash it to get the encrypted password. That is: Password = SHA1(user_pwd & Salt). The advantage of doing this is that even the result after two identical passwords hash is completely different. This slightly "alternative" algorithm makes it a bit difficult to crack the password.
Haha, it doesn’t mean it cannot be cracked. There are no ready-made programs on the Internet, so you need to write them yourself. Because .NET provides SHA1 class, it was originally written. Since the problem of resource consumption has not been solved, it has to change to C. I searched the source code for implementing SHA1 with C for a long time before I found it on a foreigner's website. It's not bad. Haha, if you are interested, you can check out the SHA1 category of foreigner: /cpp/
The program can be downloaded here (http:///lake2/program/). It is under the command line. It has weak functions and is super slow in single threading. There may be bugs. I will change many problems later.

2. Login authentication
The authentication method of PJBlog2 is to use cookies plus IP. When the user logs in successfully, the system randomly generates a Hashkey to write it to the cookies and records it to the database, and then judges the user by the Hashkey, Username and IP in the cookies. Cookies are easy to deal with, and you can use cross-site, database and other methods. If this IP is difficult, it seems that the possibility of cookies fraud is very small. Haha, then I won’t look at this.

3. Several places are not strictly filtered
The first is that the referer filtering of statistical access is not strictly performed. look:
 

Copy the codeThe code is as follows:

       Guest_Refer=Trim(("HTTP_REFERER"))
         ("INSERT INTO blog_Counter(coun_IP,coun_OS,coun_Browser,coun_Referer) VALUES ('"&Guest_IP&"','"&Guest_Browser(1)&"','"&Guest_Browser(0)&"','"&CheckStr(Guest_Refer)&"')")
 


Haha, just filter the referer and check it with CheckStr and see the CheckStr code:
 
Copy the codeThe code is as follows:

'*************************************
'Filter special characters
'*************************************
Function CheckStr(byVal ChkStr) 
         Dim Str:Str=ChkStr
         Str=Trim(Str)
         If IsNull(Str) Then
                   CheckStr = ""
                   Exit Function 
         End If
    Str = Replace(Str, "&", "&")
    Str = Replace(Str,"'","'")
    Str = Replace(Str,"""",""")
         Dim re
         Set re=new RegExp
          =True
         =True
         ="(w)(here)"
    Str = (Str,"$1here")
         ="(s)(elect)"
    Str = (Str,"$1elect")
         ="(i)(nsert)"
    Str = (Str,"$1nsert")
         ="(c)(reate)"
    Str = (Str,"$1reate")
         ="(d)(rop)"
    Str = (Str,"$1rop")
         ="(a)(lter)"
    Str = (Str,"$1lter")
         ="(d)(elete)"
    Str = (Str,"$1elete")
         ="(u)(pdate)"
    Str = (Str,"$1pdate")
         ="(\s)(or)"
    Str = (Str,"$1or")
         Set re=Nothing
         CheckStr=Str
End Function
 


Single quotes, double quotes, connectors, etc. are filtered, but the most important "<" and ">" are not filtered. Haha, cross-site scripting attacks are useful again. Note that only the first 40 characters are displayed on the page, so it should be constructed well.
The second is that when entering usernames for tourists' comments, checkStr is also used to filter. The username database is limited, with 24 characters. It is even more difficult to construct CSS here, but it can be used for other purposes. For details, haha, detailed in the following text.
Some blog owners prohibit tourists from commenting, so they had to register and comment before they were commenting. However, after registration, the text box of the comment name is set to the registered name and read-only. What should I do? Haha, it doesn't matter, you can submit data externally.
Another one is the blog message board plug-in, or the username is not filtered, which is even more difficult to use, with only 20 characters.

IV. Database issues
The default database name of PJBlog2 is, although there is a blog_Notdownload table that seems to be anti-download in the database, haha, try accessing the database, you can download it.
Since you can download it, of course you can insert the asp code to run. Inserting the asp code in some places (such as the content of the tourist comments) will cause it torn apart. I don’t know the reason and I’m depressed.
The ASP code can be inserted in the name of the test comment. As mentioned earlier, the filtering here is not strictly done, so that the asp inserted into the database will not be displayed. All I see is a guy with no name and is whining, haha. This needs to be constructed well, 24 characters and "filtered. I thought about it and found the shortest one, which is exactly 24 characters: <%eval request(chr(9))%>
The contents of the message version can also be inserted into the Asp code, but the administrator can see it when reading the message.
Haha, of course most webmasters should have changed the database name, but during the test, I still found that a few people did not change it...

5. Upload files
For security reasons, PJBlog2 limits the uploaded file types, including asp, asa, aspx, cer, cdx, and htr. In fact, many virtual hosts now not only support Asp, but also support Aspx, PHP, Perl, and can also upload Shtml and other formats. Therefore, if you want to limit the types of all server execution files, it is best to limit the types of all server execution files together.
There are still some problems with uploading the file, see the code in it:
 
Copy the codeThe code is as follows:

Dim F_File,F_Type
Set F_File=("File")
F_Name=randomStr(1)&Year(now)&Month(now)&Day(now)&Hour(now)&Minute(now)&Second(now)&"."&F_File.FileExt
F_Type=FixName(F_File.FileExt)
IF F_File.FileSize > Int(UP_FileSize) Then
("<div style=""padding:6px""><a href=''>File size exceeds, please return to upload again</a></div>")
ElseIF IsvalidFile(UCase(F_Type)) = False Then
("<div style=""padding:6px""><a href=''>File format is illegal, please return to upload again</a></div>")
Else
         F_File.SaveAs ("attachments/"&D_Name&"/"&F_Name)
          "<script>addUploadItem('"&F_Type&"','attachments/"&D_Name&"/"&F_Name&"',"&("MSave")&")</script>"
("<div style=""padding:6px""><a href=''>The file upload was successful, please return to continue uploading</a></div>")
End IF

 

The suffix of the saved file is F_File.FileExt, and the suffix that is processed by the FixName() function is checked. Let's take a look at the fixname function definition, in:
 
Copy the codeThe code is as follows:

'*************************************
'Filter file name
'*************************************
Function FixName(UpFileExt)
         If IsEmpty(UpFileExt) Then Exit Function
         FixName = Ucase(UpFileExt)
         FixName = Replace(FixName,Chr(0),"")
         FixName = Replace(FixName,".","")
         FixName = Replace(FixName,"ASP","")
         FixName = Replace(FixName,"ASA","")
         FixName = Replace(FixName,"ASPX","")
         FixName = Replace(FixName,"CER","")
         FixName = Replace(FixName,"CDX","")
         FixName = Replace(FixName,"HTR","")
End Function
 


Haha, it filters the dangerous suffix. If my file suffix is ​​asp(0x00)gif, then when checking, chr(0) and asp will be filtered, and the suffix will become gif. Pass, and when saving it is asp(0x00)gif. Theoretically, it's right. I haven't done it for a long time, so I'm depressed. Anyone who knows it will tell me.
However, we can use this upload aspx format. Haha, we upload the aspx file, the fixname function filters the asp, so the suffix becomes x. As long as x is set to upload format, you can pass the aspx file.

6. Attachment management issues
After the administrator logs in, there is an attachment management function. It looks like http://localhost/blog/?Fmenu=SQLFile&Smenu=Attachments&AttPath=attachments/month_0512. You can browse the web directory by specifying AttPath.
However, the system restricts data submission on the site, so the URL cannot be changed directly, so it is "save the country in a curve". Find the friendly link to add functions, fill in the url we constructed, save, and click View to bypass the restrictions outside the site. Note that the first character of the constructed AttPath cannot be "." and "/", the program has checked it. In this way, we can jump to the blog root directory: http://localhost/blog/?Fmenu=SQLFile&Smenu=Attachments&AttPath=attachments/..

 
Haha, finally I hope everyone supports PJBlog2, it is really very useful. I hope the author will continue to work hard and do this blog system better, so as to benefit many netizens.
PS: The author is so diligent, the patch has come out, haha