Quero encontrar todos os diretórios sem um conjunto específico de permissões. Como pode ser visto na imagem abaixo, find
imprime diretórios que não devem ser listados.
Alguém pode descrever por quê?
Por que o seguinte redirecionamento de saída resulta na impressão de duas linhas?
As >&2
cópias stdout para stderr e >/dev/stderr
também redirecionam stdout para stderr.
Espero apenas uma única linha de saída, pois echo foo
a saída é redirecionada para stderr.
Por que não vejo duas linhas de saída para: echo foo >/dev/stderr 2>&1
e echo foo >/dev/stdout 2>&1
?
➜ app git:(python3.10-pipeline) ✗ echo foo >/dev/stderr >&2
foo
foo
➜ app git:(python3.10-pipeline) ✗ echo foo >/dev/stdout >&2
foo
foo
Bash Strict Mode é definido da seguinte forma:
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
http://redsymbol.net/articles/unofficial-bash-strict-mode/
Considere a seguinte análise de parâmetros posicionais em um script Bash:
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
usage() {
echo ""
echo "usage:"
echo "$0 [options]"
echo " -r | --redirect-uri: redirect uri"
echo " -a | --app-role: app role id"
echo " -h | --help: help"
echo ""
}
redirect_uri=""
app_role=""
while [ "$1" != "" ]; do
case $1 in
-r | --redirect-uri)
shift
redirect_uri="$1"
;;
-a | --app-role)
shift
app_role="$1"
;;
-h | --help)
usage
exit 0
;;
*)
usage
exit 1
;;
esac
shift
done
...
Isso não funciona com o seguinte erro, por exemplo:
$ ./app.sh -r https://example.net:8080/auth/callback -a 53b37b21-2c6e-4731-a5e5-15b98052c686
./app.sh: line 18: $1: unbound variable
Acho que o motivo é a verificação final na while
condição, após shift
, onde $1
é indefinido.
Como posso encerrar a análise de parâmetros na while
instrução sem causar a falha do script ao usar o Bash Strict Mode?
Por que são copy_from_user()
e copy_to_user()
necessários, quando o kernel é mapeado no mesmo espaço de endereço virtual que o próprio processo?
Tendo desenvolvido alguns módulos de kernel (de brinquedo) para fins de aprendizado, rapidamente percebi isso copy_from_user()
e copy_to_user()
precisei copiar dados de/para buffers de espaço do usuário; caso contrário, erros relacionados a endereços inválidos resultaram em falhas.
Mas se 0x1fffff
é um endereço virtual apontando para um buffer de espaço do usuário, por que esse endereço não é válido no kernel? O kernel está no mesmo espaço de endereço virtual, portanto, 0x1fffff
seria mapeado para a mesma memória física.
Geralmente é seguro compilar e instalar manualmente um novo kernel do kernel.org usando:
make -j 8
make install
make modules_install
ou a distribuição, por exemplo, Debian, pode quebrar, porque assume que gerencia atualizações do kernel por meio de apt
?
Intuitivamente, tudo deve continuar funcionando, pois o kernel preserva uma API syscall estável e os drivers são compatíveis com versões anteriores.
Depois de ler este artigo sobre como executar programas arbitrários alterando o PT_INTERP
para um interpretador personalizado, tentei experimentar isso localmente:
$ cat flag.c
#include <stdio.h>
int main(int argc, char **argv) {
printf("Hello World!\n");
return 0;
}
$ gcc -static flag.c -o flag
$ cat solution.c
const char interp_section[] __attribute__((section(".interp"))) = "./flag";
$ gcc -s -fno-ident -Wl,--build-id=none -Wl,-e,0 -static -nostdlib solution.c -o solution
$ ./solution
Segmentation fault
$ ./flag
Hello World!
Este
PT_INTERP
cabeçalho do programa contém um caminho, que é o caminho do interpretador (arquivo executável) em que nosso ELF será executado
Desde os solution
pedidos ./flag
como seu interpretador, por que não ./flag
roda e imprime a mensagem "Hello World", quando solution
é executado? Em vez disso, ocorre uma falha de segmentação, que é diferente do comportamento no artigo.
Como posso registrar e executar com sucesso um interpretador personalizado em PT_INTERP
?
$ readelf -l solution
Elf file type is EXEC (Executable file)
Entry point 0x0
There are 4 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x00000000000000e0 0x00000000000000e0 R 0x8
INTERP 0x0000000000000120 0x0000000000400120 0x0000000000400120
0x0000000000000007 0x0000000000000007 R 0x1
[Requesting program interpreter: ./flag]
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x0000000000000127 0x0000000000000127 R 0x1000
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp
03
ps
trunca a saída quando a saída padrão é um terminal para acomodar a largura do terminal.
Vejo a partir ps --help output
disso ps
suportes --width
e --lines
opções para controlar a largura e a altura da tela, respectivamente.
Acho estranho especificar um grande número arbitrário como --width 1000
, então existe algum valor ou opção que define a largura da tela "ilimitada"?
root@controlplane:~# apt list --installed procps
Listing... Done
procps/now 2:3.3.12-3ubuntu1.2 amd64 [installed,local]
Extra: É possível usar padrões de pesquisa com -C <cmd>
para evitar ter que digitar o cmd
texto?
Exemplo
root@controlplane:~# ps -f -C kubelet
UID PID PPID C STIME TTY TIME CMD
root 9231 1 0 08:20 ? 00:00:07 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/
root@controlplane:~# ps -f -C kubelet | cat
UID PID PPID C STIME TTY TIME CMD
root 9231 1 0 08:20 ? 00:00:08 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --network-plugin=cni --pod-infra-container-image=k8s.gcr.io/pause:3.2
Como verificar o número do dispositivo de um dispositivo em /proc/1/ns/{ns}
?
Eu li o código para uma biblioteca Go (veja abaixo), que afirma que é possível determinar se um contêiner está no namespace do host ou não: o número do dispositivo de um sem namespace /proc/1/ns/{ns}
é 4 e qualquer outra coisa é maior.
Agora, em um novo contêiner Debian sem namespace de usuário ou cgroup, executo o seguinte comando:
root@54d74f795843:/# ls -la /proc/1/ns
total 0
dr-x--x--x 2 root root 0 Feb 29 17:18 .
dr-xr-xr-x 9 root root 0 Feb 29 17:18 ..
lrwxrwxrwx 1 root root 0 Feb 29 17:18 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Feb 29 17:18 ipc -> 'ipc:[4026532290]'
lrwxrwxrwx 1 root root 0 Feb 29 17:18 mnt -> 'mnt:[4026532288]'
lrwxrwxrwx 1 root root 0 Feb 29 17:18 net -> 'net:[4026532293]'
lrwxrwxrwx 1 root root 0 Feb 29 17:18 pid -> 'pid:[4026532291]'
lrwxrwxrwx 1 root root 0 Feb 29 17:18 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Feb 29 17:18 uts -> 'uts:[4026532289]'
O que o 4026531837 'user:[4026531837]'
significa aqui? Não posso ser o número do dispositivo, porque o contêiner está usando o mesmo namespace de usuário que o host (verifiquei isso).
Como posso listar os números de dispositivo dos arquivos /proc/1/ns/{ns}
? O ls -la
comando mostra que esses arquivos são links simbólicos, então como eles podem ter um número de dispositivo?
amicontained/vendor/github.com/jessfraz/bpfd/proc/proc.go/
// HasNamespace determines if a container is using a particular namespace or the
// host namespace.
// The device number of an unnamespaced /proc/1/ns/{ns} is 4 and anything else is
// higher.
// Only works from inside a container.
func HasNamespace(ns string) (bool, error) {
file := fmt.Sprintf("/proc/1/ns/%s", ns)
// Use Lstat to not follow the symlink.
var info syscall.Stat_t
if err := syscall.Lstat(file, &info); err != nil {
return false, &os.PathError{Op: "lstat", Path: file, Err: err}
}
// Get the device number. If it is higher than 4 it is in a namespace.
if info.Dev > 4 {
return true, nil
}
return false, nil
}
Suporta tmux
qualquer documentação de ajuda através do modo de comando ( C-b :
) como vim
's :help
?
Muitas vezes, quero exibir a documentação de ajuda para um tmux
comando específico, digamos kill-window
, incluindo pelo menos os parâmetros do comando.
Posso exibir essas informações tmux
sem consultar a man
página ou a documentação online?
Qual é a definição de uma string no Bash?
Bash usa o termo "string" em vários lugares em sua documentação, por exemplo, para documentar o =~
operador usado para correspondência de expressões regulares:
Um operador binário adicional, =~, está disponível, com a mesma precedência que == e !=. Quando usado, a string à direita do operador é considerada uma expressão regular estendida POSIX e correspondida de acordo (como em regex(3)).
Na seção DEFINITIONS
, não vejo nenhuma definição de strings:
DEFINITIONS
The following definitions are used throughout the rest of this document.
blank A space or tab.
word A sequence of characters considered as a single unit by the shell. Also known as a token.
name A word consisting only of alphanumeric characters and underscores, and beginning with an alphabetic character or an underscore. Also referred to as an identifier.
metacharacter
A character that, when unquoted, separates words. One of the following:
| & ; ( ) < > space tab newline
control operator
A token that performs a control function. It is one of the following symbols:
|| & && ; ;; ;& ;;& ( ) | |& <newline>
Então, o que exatamente são strings no Bash? Eles podem conter espaços em branco ou caracteres na IFS
variável de ambiente?
NB: Eu sei que as strings são normalmente definidas como uma série de símbolos em um alfabeto.
Não entendo por que "${ARRAY[@]}"
é expandido para várias palavras, quando é citado ( "..."
)?
Tome este exemplo:
IFS=":" read -ra ARRAY <<< "foo:bar:baz"
for e in "${ARRAY[@]}"; do echo $e; done
foo
bar
baz
Qualquer outra variável que eu expanda entre aspas, digamos "${VAR}"
, resulta em uma única palavra:
VAR="foo bar baz"
for a in "${VAR}"; do echo $a; done
foo bar baz
Alguém pode explicar isso para um usuário iniciante do Linux?
Eu criei a seguinte combinação de teclas para sincronizar todos os painéis em uma janela, para que eu pudesse, por exemplo clear
, todos eles simultaneamente:
bind C-s setw synchronize-panes \; display-message "█▓░ synchronize"
A combinação de teclas simplesmente nega o valor da synchronize-panes
opção da janela: "on" ou "off".
Embora a combinação de teclas funcione, sou um pouco perfeccionista, então gostaria display-message
que mostrasse o "█▓░ synchronize {new-option-value}"
.
Isso é possível?
Eu quero instalar o pacote "file" usando apt
, já que meu contêiner do Docker está sem o file
comando. Antes de instalar, estou verificando os detalhes do pacote (veja abaixo).
Como posso ver a data em que esses pacotes foram lançados/atualizados? Suas descrições dizem que eles são suportados por 5 anos, mas isso não faz sentido, quando eu não consigo ver quando eles foram lançados/atualizados?
Além disso, por que está apt
listando dois pacotes de "arquivos"? Qual desses seria instalado, quando eu executar apt install file
?
root@eca1fcd5655a:/mnt/dotnetcore# apt show -a file
Package: file
Version: 1:5.32-2ubuntu0.3
Priority: important
Section: utils
Origin: Ubuntu
Maintainer: Ubuntu Developers <[email protected]>
Original-Maintainer: Christoph Biedl <[email protected]>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 81.9 kB
Depends: libc6 (>= 2.4), libmagic1 (= 1:5.32-2ubuntu0.3)
Homepage: http://www.darwinsys.com/file/
Task: minimal
Supported: 5y
Download-Size: 22.1 kB
APT-Sources: http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages
Description: Recognize the type of data in a file using "magic" numbers
Package: file
Version: 1:5.32-2
Priority: important
Section: utils
Origin: Ubuntu
Maintainer: Ubuntu Developers <[email protected]>
Original-Maintainer: Christoph Biedl <[email protected]>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 81.9 kB
Depends: libc6 (>= 2.4), libmagic1 (= 1:5.32-2)
Homepage: http://www.darwinsys.com/file/
Task: minimal
Supported: 5y
Download-Size: 22.1 kB
APT-Sources: http://archive.ubuntu.com/ubuntu bionic/main amd64 Packages
Description: Recognize the type of data in a file using "magic" numbers
Acho útil grep para texto, por exemplo, opções específicas, em páginas man a partir da linha de comando.
No entanto, grep
não funciona como esperado, ao operar em páginas man, como pode ser visto abaixo, onde o padrão "-f"
apenas corresponde "-"
e o padrão "--file"
não corresponde a nada ( alias grep='grep --color=always'
):
nlykkei-mbp:~ nlykkei$ alias grep
alias grep='grep --color=always'
nlykkei-mbp:~ nlykkei$ man grep | grep -e "-f"
[-e pattern] [-f file] [--binary-files=value] [--color[=when]]
-F, --fixed-strings
-f file, --file=file
-h, --no-filename
--binary-file=without-match option.
-L, --files-without-match
-l, --files-with-matches
--binary-files=value
and the behaviour of the -f flag when used with an empty pattern file is
nlykkei-mbp:~ nlykkei$ man grep | grep -e "--file"
nlykkei-mbp:~ nlykkei$ echo "--file" | grep -e "--file"
--file
nlykkei-mbp:~ nlykkei$ ▒
Em contraste, a correspondência de texto canalizado de echo
obras conforme o esperado, então isso tem algo a ver com a formatação "invisível" de páginas de manual? É possível um texto grep confiável em páginas de manual?
Nota: eu sei man -k
e man -K
, mas estes não resolvem exatamente o que estou tentando alcançar.
Considere as dependências de objetos compartilhados de /bin/bash
, que incluem /lib64/ld-linux-x86-64.so.2
(ligador/carregador dinâmico):
ldd /bin/bash
linux-vdso.so.1 (0x00007fffd0887000)
libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f57a04e3000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f57a04de000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f57a031d000)
/lib64/ld-linux-x86-64.so.2 (0x00007f57a0652000)
A inspeção /lib64/ld-linux-x86-64.so.2
mostra que é um link simbólico para /lib/x86_64-linux-gnu/ld-2.28.so
:
ls -la /lib64/ld-linux-x86-64.so.2
lrwxrwxrwx 1 root root 32 May 1 19:24 /lib64/ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.28.so
Além disso, os próprios file
relatórios /lib/x86_64-linux-gnu/ld-2.28.so
são vinculados dinamicamente:
file -L /lib64/ld-linux-x86-64.so.2
/lib64/ld-linux-x86-64.so.2: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=f25dfd7b95be4ba386fd71080accae8c0732b711, stripped
Eu gostaria de saber:
/lib64/ld-linux-x86-64.so.2
) pode ser vinculado dinamicamente? Ele se conecta em tempo de execução?/lib/x86_64-linux-gnu/ld-2.28.so
está documentado para lidar com binários a.out ( man ld.so
), mas /bin/bash
um ELF é executável?O programa ld.so lida com binários a.out, um formato usado há muito tempo; ld-linux.so* (/lib/ld-linux.so.1 para libc5, /lib/ld-linux.so.2 para glibc2) lida com ELF, que todo mundo vem usando há anos.
Por que a chroot
operação resulta em erro: " bash: /root/.bashrc: Permission denied
"?
Eu tenho testado chroot
para fins de aprendizado e encontrei o seguinte erro ao executar /bin/bash
:
nlykkei@debian:~$ id
uid=1000(nlykkei) gid=1000(nlykkei) groups=1000(nlykkei),27(sudo)
nlykkei@debian:~$ sudo chroot --userspec nlykkei:root --groups sudo / /bin/bash
bash: /root/.bashrc: Permission denied
nlykkei@debian:/$ id
uid=1000(nlykkei) gid=0(root) groups=0(root),27(sudo)
Parece que /bin/bash
está tentando acessar root em .bashrc
vez de nlykkei
's?
Além disso, não posso fazer NEWROOT
eg ~
e executar /bin/bash
criando ~/bin/bash
(copiar):
nlykkei@debian:~$ ls -la ~/bin/bash
-rwxr-xr-x 1 nlykkei nlykkei 1168776 Sep 23 10:49 /home/nlykkei/bin/bash
nlykkei@debian:~$ sudo chroot --userspec nlykkei:root --groups sudo /home/nlykkei/ /bin/bash
chroot: failed to run command ‘/bin/bash’: No such file or directory
Alguma maneira de resolver esses problemas?
nlykkei@debian:~$ uname -a
Linux debian 4.19.0-5-amd64 #1 SMP Debian 4.19.37-5 (2019-06-19) x86_64 GNU/Linux
Não tenho certeza se o vinculador dinâmico /usr/bin/ld
é invocado automaticamente pelo sistema operacional, quando o arquivo ELF é carregado ou se é invocado pelo código incorporado no arquivo ELF?
Quando uso r2
para depurar um arquivo ELF, ele para na primeira instrução a ser executada, que deveria ser um código vinculador dinâmico, mas não sei se esse código faz parte do arquivo ELF.
Não tenho certeza se devo interpretar /dev/tcp/localhost/9999
como um inteiro (descritor de arquivo) ou como um nome de arquivo.
Consequentemente, não tenho certeza se a seção " Redirecionando a saída padrão e o erro padrão " (1) ou a seção " Duplicando descritores de arquivo " (2) do manual do Bash se aplica ao redirecionamento acima.
O redirecionamento funciona tanto se n
for especificado ou não, mas (1) não recebe um n
argumento, implicando que (1) não é usado?
Além disso, se /dev/tcp/localhost/9999
é considerado um nome de arquivo (não um número inteiro), por que o <&1
comando a seguir funciona?:
/bin/bash >&/dev/tcp/localhost/9999 <&1
Nesse caso, 1
(stdout) não é um descritor de arquivo aberto para falha de entrada (2)?
Os arquivos systemd graváveis mundialmente .service
criados como links simbólicos /etc/systemd/system
impõem uma ameaça à segurança?
Seria possível modificar de alguma forma os links para direcionar .service
arquivos arbitrários no sistema e fazer o systemd executar esses arquivos como root?
As permissões para o /etc/systemd/system
diretório são as seguintes:
drwxr-xr-x. 11 root root 4096 Aug 30 12:57 /etc/systemd/system/
e os links graváveis por todo o mundo neste diretório são:
1050594 0 lrwxrwxrwx 1 root root 9 Apr 9 11:53 /etc/systemd/system/ctrl-alt-del.target -> /dev/null
1050595 0 lrwxrwxrwx 1 root root 9 Apr 9 11:54 /etc/systemd/system/sensu-server.service -> /dev/null
1052003 0 lrwxrwxrwx 1 root root 9 Apr 9 11:54 /etc/systemd/system/sensu-api.service -> /dev/null
1052037 0 lrwxrwxrwx 1 root root 9 Apr 9 11:55 /etc/systemd/system/dataeng.service -> /dev/null
Eu tenho usado /proc/self
por um longo tempo para ler informações relacionadas ao processo, como /proc/self/maps
etc.
No entanto, em algumas variantes do UNIX, como o macOS, o sistema de procfs
arquivos não é implementado; mas como este link indica, deve ser possível obter informações semelhantes usando sysctl
.
Lendo a saída de sysctl -a
, acho que as informações não estão diretamente associadas a nenhum processo específico, mas estão relacionadas ao sistema ou kernel.
Então, como posso usar sysctl
para ler as informações, normalmente presentes nas /proc/self
distribuições Linux, em variantes do UNIX como o macOS?
Eu quero, por exemplo, entrar /proc/self/maps
no macOS.