简介:
紧接上述技巧(1),技巧(2)和技巧(3),这次总结一些常用的命令,重定向和一些整数溢出需要了解的知识点,还有一些接收发送的命令
shell命令
(1)$IFS$1
它是一个 shell 变量,用于定义分隔符来进行单词分割。$1 是 shell 脚本中的位置参数,表示第一个参数。(2)tac${IFS}f*
tac${IFS}f* 是一个 shell 命令,它使用 tac 命令来反向连接文件。${IFS} 表示 IFS 变量的值,它用于在 tac 和 f* 之间添加分隔符。f* 是一个文件名模式,它表示当前目录中以 f 开头的所有文件。(3)nl${IFS}f*
nl${IFS}f* 是一个 shell 命令,它使用 nl 命令来为文件添加行号。${IFS} 表示 IFS 变量的值,它用于在 nl 和 f* 之间添加分隔符。f* 是一个文件名模式,它表示当前目录中以 f 开头的所有文件。 因此,这个命令的作用是为当前目录中以 f 开头的所有文件添加行号。(4)tail ./*
tail ./* 是一个 shell 命令,它使用 tail 命令来显示文件的最后几行。./ 表示当前目录,* 是一个通配符,它表示当前目录中的所有文件和目录。 因此,这个命令的作用是显示当前目录中所有文件的最后几行。默认情况下,tail 命令显示每个文件的最后 10 行。(5)exec 1>&0 &&tac fl*
tac fl*>&0
tac fl*>&2
解释见 FSCTF 2023 PWN
重定向
在Linux shell中,>&0
、>&1
和>&2
都是重定向操作符,用于将输出重定向到不同的地方:
-
>&0
:这个操作符将输出重定向到文件描述符0,也就是标准输入。然而,这通常没有什么实际用途,因为标准输入通常用于读取输入,而不是写入输出。 -
>&1
:这个操作符将输出重定向到文件描述符1,也就是标准输出。这是默认的输出目标,所以你通常不需要显式地使用这个操作符。然而,在某些情况下,你可能会想要将错误输出重定向到标准输出,那么你可以使用2>&1
。 -
>&2
:这个操作符将输出重定向到文件描述符2,也就是标准错误输出。这通常用于输出错误信息。例如,如果你有一个命令可能会产生错误,你可以使用这个操作符将错误信息重定向到一个文件,如:command 2> error.txt
。
常见的重定向命令:
exec 1>&0
它将标准输出(文件描述符1)重定向到标准输入(文件描述符0)
整数溢出
整数溢出是指在计算机中对整数类型进行运算时,结果超出了该类型所能表示的范围
char 是一个有符号的字符类型,取值范围是 -128 ~ 127 ,占 1 个字节
unsigned char 是一个无符号的字符类型,取值范围是 0 ~ 255 ,占 1 个字节
short 是一个有符号的 16 位整数类型,取值范围是 -32768 ~ 32767 ,占 2 个字节
unsigned short 是一个无符号的 16 位整数类型,取值范围是 0 ~ 65535 ,占 2 个字节
int 8 是一个有符号的 8 位整数类型,取值范围是 -128 ~ 127 ,占 1 个字节
unsigned int 8 是一个无符号 8 位整数类型,取值范围是 0 ~ 255 ,占 1 个字节
int 16 是一个有符号的 16 位整数类型,取值范围是 -32768 ~ 32767 ,占 2 个字节
unsigned int 16 是一个无符号的 16 位整数类型,取值范围是 0 ~ 65535,占 2 个字节
int 32 (占 4 个字节):
有符号整数范围: -2147483648 ~ 2147483647
无符号整数范围: 0 ~ 4294967295
int 64 (占 8 个字节):
有符号整数范围: - 9223372036854775808 ~ 9223372036854775807
无符号整数范围: 0 ~ 18446744073709551615
long 32 (占 4 个字节):
有符号整数范围: -2147483648 ~ 2147483647
无符号整数范围: 0 ~ 4294967295
long 64 (占 8 个字节):
有符号整数范围: -9223372036854775808 ~ 9223372036854775807
无符号整数范围: 0 ~ 18446744073709551615
Pwntools
利用pwntools工具来接收发送数据,在做题的时候我认为还是非常重要的,所以记录一手,大家一起共勉~_~
发送数据
p.send(data) : 发送数据data
p.sendline(data) : 发送一行数据data,然后在在数据末尾加\n换行
p.sendafter(data, payload): 接收到data后,再发送payload
p.sendlineafter(data, payload): 接收到data后,再发送payload ,最后换行
接收数据
p.recv(n) : 接受指定 n 个字节的数据
p.recvn(n) : 接受 n(数字) 字符
p.recvall() : 接受所有的数据
p.recvline() : 只接收一行输出,遇到换行 \n 为止
p.recvlines(n) : 接收 n 行输出的数据
p.recvuntil(data) : 接收到 data 为止
p.recvuntil(data, drop =True) : 这行代码接收来自远程服务器的数据,直到遇到字符串"\nTell"为止
1,怎么接收到 0x4038f64e0f1c4200
num = int(p.recv(18), 16) 或者
p.recvuntil(b'0x')
num =int(p.recvline(),16) 或者p.recvuntil(b"0x")
puts_addr = int(p.recv(16),16)
2. p.recv()和p.recvn()有什么区别
3.32位怎么接受字符串
num = u32(p.recvuntil(b'\xf7')[-4:])
python切片:[-4:],代码可以确保仅提取接收到的数据的最后四个字节,而不考虑数据的前面部分
4.64位怎么接受字符串
num = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) 或者
num = u64(p.recvuntil(b'\x7f')[:6].ljust(8, b'\x00')) 或者
num =u64(p.recv(6).ljust(8,b'\x00'))
Fmtstr
fmtstr_payload(offset, {address:data}, numbwritten=0, write_size='byte')
offset表示格式化字符串的偏移
numbwritten表示已经输出的字符个数
write_size表示写入方式,是按字节(byte)、按双字节(short)还是按四字节(int),对应
着hhn、hn和n,默认值是byte,即按hhn写
注意:部分题目会限制时间,导致pwntools生成的payload失效。一般这一类题目可以通过仅
修改低地址等操作减小输出长度,这时需要手动构造payload。
总结:
多做多总结,慢慢的要开始进攻堆了,加油加油,冲冲冲!!!